General:
authorJoe Ludwig <joe@valvesoftware.com>
Mon Sep 02 11:39:10 2013 -0700 (2013-09-02)
changeset 154de0151ff6a3
parent 14 d5aadd140e8d
child 16 d68c4587dc00
General:
* Fixed a variety of server browser issues with mods based on this SDK
* Fixed many warnings on various platforms
* Added source code for fgdlib and raytrace
* Updated many source files with the latest shared source from TF2.

OSX:
* Added support for Xcode 4.6
* Switched OSX builds to use Xcode instead of makefiles
* Moved libs from src/lib/osx32 to src/lib/public/osx32 or src/lib/common/osx32 to match windows better.

Linux:
* Moved libs from src/lib/linux32 to src/lib/public/linux32 or src/lib/common/linux32 to match windows better.
devtools/base.xcconfig
devtools/bin/osx32/xcode_ccache_wrapper
devtools/bin/vpc.exe
devtools/bin/vpc_linux
devtools/bin/vpc_osx
devtools/debug.xcconfig
devtools/makefile_base_posix.mak
devtools/release.xcconfig
dx10sdk/Utilities/dx9_30/dx_proxy.dll
dx9sdk/utilities/dx_proxy.dll
fgdlib/fgdlib.vpc
fgdlib/gamedata.cpp
fgdlib/gdclass.cpp
fgdlib/gdvar.cpp
fgdlib/inputoutput.cpp
fgdlib/wckeyvalues.cpp
game/client/c_baseentity.cpp
game/client/c_baseentity.h
game/client/c_baseplayer.cpp
game/client/cdll_client_int.cpp
game/client/client_base.vpc
game/client/client_hl2mp.vpc
game/client/death.cpp
game/protobuf_include.vpc
game/server/ai_behavior_lead.cpp
game/server/ai_networkmanager.cpp
game/server/ai_tacticalservices.cpp
game/server/baseentity.cpp
game/server/baseentity.h
game/server/client.cpp
game/server/doors.cpp
game/server/doors.h
game/server/episodic/npc_hunter.cpp
game/server/hl2/npc_barnacle.cpp
game/server/hl2/npc_zombine.cpp
game/server/player.h
game/server/props.cpp
game/server/server_base.vpc
game/server/testfunctions.cpp
game/server/util.cpp
game/shared/GameStats.cpp
game/shared/playernet_vars.h
game/shared/shareddefs.h
lib/common/libcurl.lib
lib/common/linux32/libcrypto.a
lib/common/linux32/libcurl.a
lib/common/linux32/libcurlssl.a
lib/common/linux32/libssl.a
lib/linux32/libcurl.a
lib/linux32/libcurlssl.a
lib/linux32/libssl.a
lib/linux32/libsteam_api.so
lib/linux32/release/libcrypto.a
lib/linux32/release/libprotobuf.a
lib/osx32/bitmap.a
lib/osx32/choreoobjects.a
lib/osx32/dmxloader.a
lib/osx32/libcurl.dylib
lib/osx32/libsteam_api.dylib
lib/osx32/libtier0.dylib
lib/osx32/libvstdlib.dylib
lib/osx32/matsys_controls.a
lib/osx32/particles.a
lib/osx32/release/libprotobuf.a
lib/osx32/shaderlib.a
lib/osx32/tier2.a
lib/osx32/tier3.a
lib/osx32/vtf.a
lib/public/appframework.lib
lib/public/bitmap.lib
lib/public/choreoobjects.lib
lib/public/dmxloader.lib
lib/public/fgdlib.lib
lib/public/libprotobuf.lib
lib/public/libz.lib
lib/public/linux32/bitmap.a
lib/public/linux32/choreoobjects.a
lib/public/linux32/dmxloader.a
lib/public/linux32/libprotobuf.a
lib/public/linux32/libsteam_api.so
lib/public/linux32/libtier0.so
lib/public/linux32/libvstdlib.so
lib/public/linux32/libz.a
lib/public/linux32/matsys_controls.a
lib/public/linux32/particles.a
lib/public/linux32/shaderlib.a
lib/public/linux32/tier2.a
lib/public/linux32/tier3.a
lib/public/linux32/vtf.a
lib/public/mathlib.lib
lib/public/matsys_controls.lib
lib/public/nvtristrip.lib
lib/public/osx32/bitmap.a
lib/public/osx32/choreoobjects.a
lib/public/osx32/dmxloader.a
lib/public/osx32/libprotobuf.a
lib/public/osx32/libsteam_api.dylib
lib/public/osx32/libtier0.dylib
lib/public/osx32/libvstdlib.dylib
lib/public/osx32/mathlib.a
lib/public/osx32/matsys_controls.a
lib/public/osx32/particles.a
lib/public/osx32/raytrace.a
lib/public/osx32/shaderlib.a
lib/public/osx32/tier1.a
lib/public/osx32/tier2.a
lib/public/osx32/tier3.a
lib/public/osx32/vgui_controls.a
lib/public/osx32/vtf.a
lib/public/particles.lib
lib/public/raytrace.lib
lib/public/shaderlib.lib
lib/public/tier0.lib
lib/public/tier1.lib
lib/public/tier2.lib
lib/public/tier3.lib
lib/public/vgui_controls.lib
lib/public/vmpi.lib
lib/public/vstdlib.lib
lib/public/vtf.lib
lib/win32/debug/vs2010/libprotobuf.lib
lib/win32/release/vs2010/libprotobuf.lib
materialsystem/stdshaders/game_shader_dx9_base.vpc
mathlib/mathlib.vpc
public/XUnzip.cpp
public/bone_setup.cpp
public/cdll_int.h
public/engine/IStaticPropMgr.h
public/engine/ivmodelrender.h
public/game/server/pluginvariant.h
public/inputsystem/iinputsystem.h
public/tier0/dbg.h
public/tier0/platform.h
public/tier1/fmtstr.h
public/tier1/utlstring.h
public/vgui_controls/Panel.h
raytrace/raytrace.cpp
raytrace/raytrace.vpc
raytrace/trace2.cpp
raytrace/trace3.cpp
tier0/tier0_exclude.vpc
tier1/bitbuf.cpp
tier1/strtools.cpp
tier1/tier1.vpc
utils/captioncompiler/captioncompiler.vpc
utils/glview/glview.vpc
utils/height2normal/height2normal.vpc
utils/motionmapper/motionmapper.vpc
utils/phonemeextractor/phonemeextractor.vpc
utils/phonemeextractor/phonemeextractor_ims.vpc
utils/qc_eyes/qc_eyes.vpc
utils/serverplugin_sample/serverplugin_empty.vpc
utils/tgadiff/tgadiff.vpc
utils/vbsp/vbsp.vpc
utils/vice/vice.vpc
utils/vrad/vrad_dll.vpc
utils/vrad_launcher/vrad_launcher.vpc
utils/vtf2tga/vtf2tga.vpc
utils/vtfdiff/vtfdiff.vpc
utils/vvis/vvis_dll.vpc
utils/vvis_launcher/vvis_launcher.vpc
vgui2/vgui_controls/TextEntry.cpp
vgui2/vgui_controls/vgui_controls.vpc
vpc_scripts/definitions/win32_2010.def
vpc_scripts/groups.vgc
vpc_scripts/platform_dirs.vpc
vpc_scripts/projects.vgc
vpc_scripts/protobuf_builder.vpc
vpc_scripts/source_base.vpc
vpc_scripts/source_dll_base.vpc
vpc_scripts/source_dll_linux_base.vpc
vpc_scripts/source_dll_posix_base.vpc
vpc_scripts/source_dll_qt_base.vpc
vpc_scripts/source_dll_win32_base.vpc
vpc_scripts/source_dll_win32_debug.vpc
vpc_scripts/source_dll_win32_release.vpc
vpc_scripts/source_exe_base.vpc
vpc_scripts/source_exe_con_base.vpc
vpc_scripts/source_exe_con_win32_base.vpc
vpc_scripts/source_exe_posix_base.vpc
vpc_scripts/source_exe_qt_base.vpc
vpc_scripts/source_exe_qt_con_base.vpc
vpc_scripts/source_exe_qt_win32_base.vpc
vpc_scripts/source_exe_win_win32_base.vpc
vpc_scripts/source_exe_win_win32_debug.vpc
vpc_scripts/source_exe_win_win32_release.vpc
vpc_scripts/source_lib_base.vpc
vpc_scripts/source_lib_posix_base.vpc
vpc_scripts/source_lib_qt_base.vpc
vpc_scripts/source_lib_qt_win32_base.vpc
vpc_scripts/source_lib_win32_base.vpc
vpc_scripts/source_lib_win32_debug.vpc
vpc_scripts/source_lib_win32_release.vpc
vpc_scripts/source_linux_base_project.vpc
vpc_scripts/source_mll_qt_base.vpc
vpc_scripts/source_posix_base.vpc
vpc_scripts/source_video_base.vpc
vpc_scripts/source_win32_base.vpc
vpc_scripts/version.vpc
vstdlib/vstdlib_exclude.vpc
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/devtools/base.xcconfig	Mon Sep 02 11:39:10 2013 -0700
     1.3 @@ -0,0 +1,46 @@
     1.4 +ALWAYS_SEARCH_USER_PATHS = YES
     1.5 +HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS) $(SDKROOT)/usr/include/malloc
     1.6 +
     1.7 +ARCHS = i386
     1.8 +ONLY_ACTIVE_ARCH = NO
     1.9 +COPY_PHASE_STRIP = NO
    1.10 +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
    1.11 +
    1.12 +DEAD_CODE_STRIPPING = YES
    1.13 +PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES
    1.14 +
    1.15 +GCC_C_LANGUAGE_STANDARD = gnu99
    1.16 +GCC_ENABLE_OBJC_EXCEPTIONS = YES
    1.17 +GCC_SYMBOLS_PRIVATE_EXTERN = YES
    1.18 +GCC_INLINES_ARE_PRIVATE_EXTERN = YES
    1.19 +GCC_REUSE_STRINGS = YES
    1.20 +
    1.21 +// CPP11_NO_LIBCXX is used to gate some C++11 features that require that we
    1.22 +// switch to libc++. We haven't switched to libc++11 because we have been unable
    1.23 +// to find a clean way to build libcef_dll_wrapper with libc++. 
    1.24 +// We currently build libcef for Steam which needs to run on 10.5, and Xcode
    1.25 +// does not support linking with libc++ and targeting 10.5.
    1.26 +// Once libcef_dll_wrapper has been built with libc++, and you rebuild protobuf
    1.27 +// with libc++ (which is trivial), you can remove CPP11_NO_LIBCXX and add the
    1.28 +// following line to the xcconfig:
    1.29 +// CLANG_CXX_LIBRARY = libc++
    1.30 +GCC_PREPROCESSOR_DEFINITIONS = _DLL_EXT=.dylib NO_MALLOC_OVERRIDE=1 VPROF_LEVEL=1 NO_HOOK_MALLOC=1 PNG_NO_PEDANTIC_WARNINGS CPP11_NO_LIBCXX
    1.31 +BASE_CFLAGS= -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE
    1.32 +
    1.33 +GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO
    1.34 +WARNING_CFLAGS = -Wno-deprecated-writable-strings -Wno-switch-enum -Wno-switch -Wno-unused-value -Wno-parentheses -Wno-logical-op-parentheses -Wno-c++11-narrowing
    1.35 +
    1.36 +// CLANG - and use the ccache wrapper
    1.37 +GCC_VERSION = com.apple.compilers.llvm.clang.1_0
    1.38 +CC = $(SOURCE_ROOT)/devtools/bin/osx32/xcode_ccache_wrapper
    1.39 +LDPLUSPLUS = $(DT_TOOLCHAIN_DIR)/usr/bin/clang++
    1.40 +CLANG_WARN_CXX0X_EXTENSIONS = NO
    1.41 +CLANG_CXX_LANGUAGE_STANDARD = gnu++11
    1.42 +
    1.43 +// include <memory.h> gets confused, 'cause ivp has one, and the system has one, and only one
    1.44 +// gets into the header map, so sacrifice speed for corectness.
    1.45 +USE_HEADERMAP = NO
    1.46 +
    1.47 +SDKROOT = macosx10.7
    1.48 +MACOSX_DEPLOYMENT_TARGET = 10.5
    1.49 +GCC_FAST_MATH = YES
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/devtools/bin/osx32/xcode_ccache_wrapper	Mon Sep 02 11:39:10 2013 -0700
     2.3 @@ -0,0 +1,3 @@
     2.4 +#!/bin/bash
     2.5 +
     2.6 +exec $(dirname $0)/ccache "${DT_TOOLCHAIN_DIR}"/usr/bin/clang -Qunused-arguments "[email protected]"
     3.1 Binary file devtools/bin/vpc.exe has changed
     4.1 Binary file devtools/bin/vpc_linux has changed
     5.1 Binary file devtools/bin/vpc_osx has changed
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/devtools/debug.xcconfig	Mon Sep 02 11:39:10 2013 -0700
     6.3 @@ -0,0 +1,4 @@
     6.4 +#include "base.xcconfig"
     6.5 +GCC_OPTIMIZATION_LEVEL = 0
     6.6 +OTHER_CFLAGS = $(derived) $(BASE_CFLAGS)
     6.7 +
     7.1 --- a/devtools/makefile_base_posix.mak	Tue Jul 30 15:10:15 2013 -0700
     7.2 +++ b/devtools/makefile_base_posix.mak	Mon Sep 02 11:39:10 2013 -0700
     7.3 @@ -42,7 +42,7 @@
     7.4  # In -std=gnu++0x mode we get lots of errors about "error: narrowing conversion". -fpermissive
     7.5  # turns these into warnings in gcc, and -Wno-c++11-narrowing suppresses them entirely in clang 3.1+.
     7.6  ifeq ($(CXX),clang++)
     7.7 -	CXXFLAGS = $(CFLAGS) -Wno-c++11-narrowing -Wno-dangling-else
     7.8 +	CXXFLAGS = $(CFLAGS) -Wno-c++11-narrowing
     7.9  else
    7.10  	CXXFLAGS = $(CFLAGS) -fpermissive
    7.11  endif
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/devtools/release.xcconfig	Mon Sep 02 11:39:10 2013 -0700
     8.3 @@ -0,0 +1,4 @@
     8.4 +#include "base.xcconfig"
     8.5 +
     8.6 +GCC_OPTIMIZATION_LEVEL = 2
     8.7 +OTHER_CFLAGS = $(derived) $(BASE_CFLAGS) -ftree-vectorize -fpredictive-commoning -funswitch-loops
     9.1 Binary file dx10sdk/Utilities/dx9_30/dx_proxy.dll has changed
    10.1 Binary file dx9sdk/utilities/dx_proxy.dll has changed
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/fgdlib/fgdlib.vpc	Mon Sep 02 11:39:10 2013 -0700
    11.3 @@ -0,0 +1,40 @@
    11.4 +//-----------------------------------------------------------------------------
    11.5 +//	FGDLIB.VPC
    11.6 +//
    11.7 +//	Project Script
    11.8 +//-----------------------------------------------------------------------------
    11.9 +
   11.10 +$Macro SRCDIR		".."
   11.11 +$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
   11.12 +
   11.13 +$Configuration
   11.14 +{
   11.15 +	$Compiler
   11.16 +	{
   11.17 +		$AdditionalIncludeDirectories		"$BASE,$SRCDIR\utils\common"
   11.18 +	}
   11.19 +}
   11.20 +
   11.21 +$Project "Fgdlib"
   11.22 +{
   11.23 +	$Folder	"Source Files"
   11.24 +	{
   11.25 +		$File	"gamedata.cpp"
   11.26 +		$File	"gdclass.cpp"
   11.27 +		$File	"gdvar.cpp"
   11.28 +		$File	"inputoutput.cpp"
   11.29 +		$File	"wckeyvalues.cpp"
   11.30 +	}
   11.31 +
   11.32 +	$Folder	"Header Files"
   11.33 +	{
   11.34 +		$File	"$SRCDIR\public\fgdlib\fgdlib.h"
   11.35 +		$File	"$SRCDIR\public\fgdlib\gamedata.h"
   11.36 +		$File	"$SRCDIR\public\fgdlib\gdclass.h"
   11.37 +		$File	"$SRCDIR\public\fgdlib\gdvar.h"
   11.38 +		$File	"$SRCDIR\public\fgdlib\helperinfo.h"
   11.39 +		$File	"$SRCDIR\public\fgdlib\ieditortexture.h"
   11.40 +		$File	"$SRCDIR\public\fgdlib\inputoutput.h"
   11.41 +		$File	"$SRCDIR\public\fgdlib\wckeyvalues.h"
   11.42 +	}
   11.43 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/fgdlib/gamedata.cpp	Mon Sep 02 11:39:10 2013 -0700
    12.3 @@ -0,0 +1,886 @@
    12.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
    12.5 +//
    12.6 +//=============================================================================
    12.7 +
    12.8 +#include <windows.h>
    12.9 +#include <tier0/dbg.h>
   12.10 +#include <io.h>
   12.11 +#include <WorldSize.h>
   12.12 +#include "fgdlib/GameData.h"
   12.13 +#include "fgdlib/HelperInfo.h"
   12.14 +#include "KeyValues.h"
   12.15 +#include "filesystem_tools.h"
   12.16 +#include "tier1/strtools.h"
   12.17 +#include "utlmap.h"
   12.18 +
   12.19 +// memdbgon must be the last include file in a .cpp file!!!
   12.20 +#include "tier0/memdbgon.h"
   12.21 +
   12.22 +#pragma warning(disable:4244)
   12.23 +
   12.24 +
   12.25 +const int MAX_ERRORS = 5;
   12.26 +
   12.27 +
   12.28 +static GameDataMessageFunc_t g_pMsgFunc = NULL;
   12.29 +
   12.30 +
   12.31 +//-----------------------------------------------------------------------------
   12.32 +// Sets the function used for emitting error messages while loading gamedata files.
   12.33 +//-----------------------------------------------------------------------------
   12.34 +void GDSetMessageFunc(GameDataMessageFunc_t pFunc)
   12.35 +{
   12.36 +	g_pMsgFunc = pFunc;
   12.37 +}
   12.38 +
   12.39 +
   12.40 +//-----------------------------------------------------------------------------
   12.41 +// Purpose: Fetches the next token from the file.
   12.42 +// Input  : tr - 
   12.43 +//			ppszStore - Destination buffer, one of the following:
   12.44 +//				pointer to NULL - token will be placed in an allocated buffer
   12.45 +//				pointer to non-NULL buffer - token will be placed in buffer
   12.46 +//			ttexpecting - 
   12.47 +//			pszExpecting - 
   12.48 +// Output : 
   12.49 +//-----------------------------------------------------------------------------
   12.50 +static bool DoGetToken(TokenReader &tr, char **ppszStore, int nSize, trtoken_t ttexpecting, const char *pszExpecting)
   12.51 +{
   12.52 +	trtoken_t ttype;
   12.53 +
   12.54 +	if (*ppszStore != NULL)
   12.55 +	{
   12.56 +		// Reads the token into the given buffer.
   12.57 +		ttype = tr.NextToken(*ppszStore, nSize);
   12.58 +	}
   12.59 +	else
   12.60 +	{
   12.61 +		// Allocates a buffer to hold the token.
   12.62 +		ttype = tr.NextTokenDynamic(ppszStore);
   12.63 +	}
   12.64 +
   12.65 +	if (ttype == TOKENSTRINGTOOLONG)
   12.66 +	{
   12.67 +		GDError(tr, "unterminated string or string too long");
   12.68 +		return false;
   12.69 +	}
   12.70 +
   12.71 +	//
   12.72 +	// Check for a bad token type.
   12.73 +	//
   12.74 +	char *pszStore = *ppszStore;
   12.75 +	bool bBadTokenType = false;
   12.76 +	if ((ttype != ttexpecting) && (ttexpecting != TOKENNONE))
   12.77 +	{
   12.78 +		//
   12.79 +		// If we were expecting a string and got an integer, don't worry about it.
   12.80 +		// We can translate from integer to string.
   12.81 +		//
   12.82 +		if (!((ttexpecting == STRING) && (ttype == INTEGER)))
   12.83 +		{
   12.84 +			bBadTokenType = true;
   12.85 +		}
   12.86 +	}
   12.87 +
   12.88 +	if (bBadTokenType && (pszExpecting == NULL))
   12.89 +	{
   12.90 +		//
   12.91 +		// We didn't get the expected token type but no expected
   12.92 +		// string was specified.
   12.93 +		//
   12.94 +		char *pszTokenName;
   12.95 +		switch (ttexpecting)
   12.96 +		{
   12.97 +			case IDENT:
   12.98 +			{
   12.99 +				pszTokenName = "identifier";
  12.100 +				break;
  12.101 +			}
  12.102 +
  12.103 +			case INTEGER:
  12.104 +			{
  12.105 +				pszTokenName = "integer";
  12.106 +				break;
  12.107 +			}
  12.108 +
  12.109 +			case STRING:
  12.110 +			{
  12.111 +				pszTokenName = "string";
  12.112 +				break;
  12.113 +			}
  12.114 +
  12.115 +			case OPERATOR:
  12.116 +			default:
  12.117 +			{
  12.118 +				pszTokenName = "symbol";
  12.119 +				break;
  12.120 +			}
  12.121 +		}
  12.122 +		
  12.123 +		GDError(tr, "expecting %s", pszTokenName);
  12.124 +		return false;
  12.125 +	}
  12.126 +	else if (bBadTokenType || ((pszExpecting != NULL) && !IsToken(pszStore, pszExpecting)))
  12.127 +	{
  12.128 +		//
  12.129 +		// An expected string was specified, and we got either the wrong type or
  12.130 +		// the right type but the wrong string,
  12.131 +		//
  12.132 +		GDError(tr, "expecting '%s', but found '%s'", pszExpecting, pszStore);
  12.133 +		return false;
  12.134 +	}
  12.135 +
  12.136 +	return true;
  12.137 +}
  12.138 +
  12.139 +
  12.140 +//-----------------------------------------------------------------------------
  12.141 +// Purpose: 
  12.142 +// Input  : tr - 
  12.143 +//			error - 
  12.144 +// Output : 
  12.145 +//-----------------------------------------------------------------------------
  12.146 +bool GDError(TokenReader &tr, const char *error, ...)
  12.147 +{
  12.148 +	char szBuf[128];
  12.149 +	va_list vl;
  12.150 +	va_start(vl, error);
  12.151 +	vsprintf(szBuf, error, vl);
  12.152 +	va_end(vl);
  12.153 +
  12.154 +	if (g_pMsgFunc)
  12.155 +	{
  12.156 +		// HACK: should use an enumeration for error level
  12.157 +		g_pMsgFunc(1, tr.Error(szBuf));
  12.158 +	}
  12.159 +	
  12.160 +	if (tr.GetErrorCount() >= MAX_ERRORS)
  12.161 +	{
  12.162 +		if (g_pMsgFunc)
  12.163 +		{
  12.164 +			// HACK: should use an enumeration for error level
  12.165 +			g_pMsgFunc(1, "   - too many errors; aborting.");
  12.166 +		}
  12.167 +		
  12.168 +		return false;
  12.169 +	}
  12.170 +
  12.171 +	return true;
  12.172 +}
  12.173 +
  12.174 +
  12.175 +//-----------------------------------------------------------------------------
  12.176 +// Purpose: Fetches the next token from the file.
  12.177 +// Input  : tr - The token reader object with which to fetch the token.
  12.178 +//			pszStore - Buffer in which to place the token, NULL to discard the token.
  12.179 +//			ttexpecting - The token type that we are expecting. If this is not TOKENNONE
  12.180 +//				and token type read is different, the operation will fail.
  12.181 +//			pszExpecting - The token string that we are expecting. If this string
  12.182 +//				is not NULL and the token string read is different, the operation will fail.
  12.183 +// Output : Returns TRUE if the operation succeeded, FALSE if there was an error.
  12.184 +//			If there was an error, the error will be reported in the message window.
  12.185 +//-----------------------------------------------------------------------------
  12.186 +bool GDGetToken(TokenReader &tr, char *pszStore, int nSize, trtoken_t ttexpecting, const char *pszExpecting)
  12.187 +{
  12.188 +	Assert(pszStore != NULL);
  12.189 +	if (pszStore != NULL)
  12.190 +	{
  12.191 +		return DoGetToken(tr, &pszStore, nSize, ttexpecting, pszExpecting);
  12.192 +	}
  12.193 +
  12.194 +	return false;
  12.195 +}
  12.196 +
  12.197 +
  12.198 +//-----------------------------------------------------------------------------
  12.199 +// Purpose: Fetches the next token from the file.
  12.200 +// Input  : tr - The token reader object with which to fetch the token.
  12.201 +//			pszStore - Buffer in which to place the token, NULL to discard the token.
  12.202 +//			ttexpecting - The token type that we are expecting. If this is not TOKENNONE
  12.203 +//				and token type read is different, the operation will fail.
  12.204 +//			pszExpecting - The token string that we are expecting. If this string
  12.205 +//				is not NULL and the token string read is different, the operation will fail.
  12.206 +// Output : Returns TRUE if the operation succeeded, FALSE if there was an error.
  12.207 +//			If there was an error, the error will be reported in the message window.
  12.208 +//-----------------------------------------------------------------------------
  12.209 +bool GDSkipToken(TokenReader &tr, trtoken_t ttexpecting, const char *pszExpecting)
  12.210 +{
  12.211 +	//
  12.212 +	// Read the next token into a buffer and discard it.
  12.213 +	//
  12.214 +	char szDiscardBuf[MAX_TOKEN];
  12.215 +	char *pszDiscardBuf = szDiscardBuf;
  12.216 +	return DoGetToken(tr, &pszDiscardBuf, sizeof(szDiscardBuf), ttexpecting, pszExpecting);
  12.217 +}
  12.218 +
  12.219 +
  12.220 +//-----------------------------------------------------------------------------
  12.221 +// Purpose: Fetches the next token from the file, allocating a buffer exactly
  12.222 +//			large enough to hold the token.
  12.223 +// Input  : tr - 
  12.224 +//			ppszStore - 
  12.225 +//			ttexpecting - 
  12.226 +//			pszExpecting - 
  12.227 +// Output : 
  12.228 +//-----------------------------------------------------------------------------
  12.229 +bool GDGetTokenDynamic(TokenReader &tr, char **ppszStore, trtoken_t ttexpecting, const char *pszExpecting)
  12.230 +{
  12.231 +	if (ppszStore == NULL)
  12.232 +	{
  12.233 +		return false;
  12.234 +	}
  12.235 +
  12.236 +	*ppszStore = NULL;
  12.237 +	return DoGetToken(tr, ppszStore, -1, ttexpecting, pszExpecting);
  12.238 +}
  12.239 +
  12.240 +
  12.241 +//-----------------------------------------------------------------------------
  12.242 +// Purpose: Constructor.
  12.243 +//-----------------------------------------------------------------------------
  12.244 +GameData::GameData(void)
  12.245 +{
  12.246 +	m_nMaxMapCoord = 8192;
  12.247 +	m_nMinMapCoord = -8192;
  12.248 +	m_InstanceClass = NULL;
  12.249 +}
  12.250 +
  12.251 +
  12.252 +//-----------------------------------------------------------------------------
  12.253 +// Purpose: Destructor.
  12.254 +//-----------------------------------------------------------------------------
  12.255 +GameData::~GameData(void)
  12.256 +{
  12.257 +	ClearData();
  12.258 +}
  12.259 +
  12.260 +
  12.261 +//-----------------------------------------------------------------------------
  12.262 +// Purpose: 
  12.263 +//-----------------------------------------------------------------------------
  12.264 +void GameData::ClearData(void)
  12.265 +{
  12.266 +	// delete classes.
  12.267 +	int nCount = m_Classes.Count();
  12.268 +	for (int i = 0; i < nCount; i++)
  12.269 +	{
  12.270 +		GDclass *pm = m_Classes.Element(i);
  12.271 +		delete pm;
  12.272 +	}
  12.273 +	m_Classes.RemoveAll();
  12.274 +}
  12.275 +
  12.276 +
  12.277 +//-----------------------------------------------------------------------------
  12.278 +// Purpose: Loads a gamedata (FGD) file into this object.
  12.279 +// Input  : pszFilename - 
  12.280 +// Output : Returns TRUE on success, FALSE on failure.
  12.281 +//-----------------------------------------------------------------------------
  12.282 +BOOL GameData::Load(const char *pszFilename)
  12.283 +{
  12.284 +	TokenReader tr;
  12.285 +
  12.286 +	if(GetFileAttributes(pszFilename) == 0xffffffff)
  12.287 +		return FALSE;
  12.288 +
  12.289 +	if(!tr.Open(pszFilename))
  12.290 +		return FALSE;
  12.291 +
  12.292 +	trtoken_t ttype;
  12.293 +	char szToken[128];
  12.294 +
  12.295 +	while (1)
  12.296 +	{
  12.297 +		if (tr.GetErrorCount() >= MAX_ERRORS)
  12.298 +		{
  12.299 +			break;
  12.300 +		}
  12.301 +
  12.302 +		ttype = tr.NextToken(szToken, sizeof(szToken));
  12.303 +
  12.304 +		if(ttype == TOKENEOF)
  12.305 +			break;
  12.306 +
  12.307 +		if(ttype != OPERATOR || !IsToken(szToken, "@"))
  12.308 +		{
  12.309 +			if(!GDError(tr, "expected @"))
  12.310 +				return FALSE;
  12.311 +		}
  12.312 +
  12.313 +		// check what kind it is, and parse a new object
  12.314 +		if (tr.NextToken(szToken, sizeof(szToken)) != IDENT)
  12.315 +		{
  12.316 +			if(!GDError(tr, "expected identifier after @"))
  12.317 +				return FALSE;
  12.318 +		}
  12.319 +
  12.320 +		if (IsToken(szToken, "baseclass") || IsToken(szToken, "pointclass") || IsToken(szToken, "solidclass") || IsToken(szToken, "keyframeclass") ||
  12.321 +			IsToken(szToken, "moveclass") || IsToken(szToken, "npcclass") || IsToken(szToken, "filterclass"))
  12.322 +		{
  12.323 +			//
  12.324 +			// New class.
  12.325 +			//
  12.326 +			GDclass *pNewClass = new GDclass;
  12.327 +			if (!pNewClass->InitFromTokens(tr, this))
  12.328 +			{
  12.329 +				tr.IgnoreTill(OPERATOR, "@");	// go to next section
  12.330 +				delete pNewClass;
  12.331 +			}
  12.332 +			else
  12.333 +			{
  12.334 +				if (IsToken(szToken, "baseclass"))			// Not directly available to user.
  12.335 +				{
  12.336 +					pNewClass->SetBaseClass(true);
  12.337 +				}
  12.338 +				else if (IsToken(szToken, "pointclass"))	// Generic point class.
  12.339 +				{
  12.340 +					pNewClass->SetPointClass(true);
  12.341 +				}
  12.342 +				else if (IsToken(szToken, "solidclass"))	// Tied to solids.
  12.343 +				{
  12.344 +					pNewClass->SetSolidClass(true);
  12.345 +				}
  12.346 +				else if (IsToken(szToken, "npcclass"))		// NPC class - can be spawned by npc_maker.
  12.347 +				{
  12.348 +					pNewClass->SetPointClass(true);
  12.349 +					pNewClass->SetNPCClass(true);
  12.350 +				}
  12.351 +				else if (IsToken(szToken, "filterclass"))	// Filter class - can be used as a filter
  12.352 +				{
  12.353 +					pNewClass->SetPointClass(true);
  12.354 +					pNewClass->SetFilterClass(true);
  12.355 +				}
  12.356 +				else if (IsToken(szToken, "moveclass"))		// Animating
  12.357 +				{
  12.358 +					pNewClass->SetMoveClass(true);
  12.359 +					pNewClass->SetPointClass(true);
  12.360 +				}
  12.361 +				else if (IsToken(szToken, "keyframeclass"))	// Animation keyframes
  12.362 +				{
  12.363 +					pNewClass->SetKeyFrameClass(true);
  12.364 +					pNewClass->SetPointClass(true);
  12.365 +				}
  12.366 +
  12.367 +				// Check and see if this new class matches an existing one. If so we will override the previous definition.
  12.368 +				int nExistingClassIndex = 0;
  12.369 +				GDclass *pExistingClass = ClassForName(pNewClass->GetName(), &nExistingClassIndex);
  12.370 +				if (NULL != pExistingClass)
  12.371 +				{
  12.372 +					m_Classes.InsertAfter(nExistingClassIndex, pNewClass);
  12.373 +					m_Classes.Remove(nExistingClassIndex);
  12.374 +				}
  12.375 +				else
  12.376 +				{
  12.377 +					m_Classes.AddToTail(pNewClass);
  12.378 +				}
  12.379 +			}
  12.380 +		}
  12.381 +		else if (IsToken(szToken, "include"))
  12.382 +		{
  12.383 +			if (GDGetToken(tr, szToken, sizeof(szToken), STRING))
  12.384 +			{
  12.385 +				// Let's assume it's in the same directory.
  12.386 +				char justPath[MAX_PATH], loadFilename[MAX_PATH];
  12.387 +				if ( Q_ExtractFilePath( pszFilename, justPath, sizeof( justPath ) ) )
  12.388 +				{
  12.389 +					Q_snprintf( loadFilename, sizeof( loadFilename ), "%s%s", justPath, szToken );
  12.390 +				}
  12.391 +				else
  12.392 +				{
  12.393 +					Q_strncpy( loadFilename, szToken, sizeof( loadFilename ) );
  12.394 +				}
  12.395 +
  12.396 +				// First try our fully specified directory
  12.397 +				if (!Load(loadFilename))
  12.398 +				{
  12.399 +					// Failing that, try our start directory
  12.400 +					if (!Load(szToken))
  12.401 +					{
  12.402 +						GDError(tr, "error including file: %s", szToken);
  12.403 +					}
  12.404 +				}
  12.405 +			}
  12.406 +		}
  12.407 +		else if (IsToken(szToken, "mapsize"))
  12.408 +		{
  12.409 +			if (!ParseMapSize(tr))
  12.410 +			{
  12.411 +				// Error in map size specifier, skip to next @ sign. 
  12.412 +				tr.IgnoreTill(OPERATOR, "@");
  12.413 +			}
  12.414 +		}
  12.415 +		else if ( IsToken( szToken, "materialexclusion" ) )
  12.416 +		{
  12.417 +			if ( !LoadFGDMaterialExclusions( tr ) )
  12.418 +			{
  12.419 +				// FGD exclusions not defined; skip to next @ sign. 
  12.420 +				tr.IgnoreTill(OPERATOR, "@");
  12.421 +			}
  12.422 +		}
  12.423 +		else if ( IsToken( szToken, "autovisgroup" ) )
  12.424 +		{
  12.425 +			if ( !LoadFGDAutoVisGroups( tr ) )
  12.426 +			{
  12.427 +				// FGD AutoVisGroups not defined; skip to next @ sign. 
  12.428 +				tr.IgnoreTill(OPERATOR, "@");
  12.429 +			}
  12.430 +		}
  12.431 +		else
  12.432 +		{
  12.433 +			GDError(tr, "unrecognized section name %s", szToken);
  12.434 +			tr.IgnoreTill(OPERATOR, "@");
  12.435 +		}
  12.436 +	}
  12.437 +
  12.438 +	if (tr.GetErrorCount() > 0)
  12.439 +	{
  12.440 +		return FALSE;
  12.441 +	}
  12.442 +
  12.443 +	tr.Close();
  12.444 +
  12.445 +	return TRUE;
  12.446 +}
  12.447 +
  12.448 +
  12.449 +//-----------------------------------------------------------------------------
  12.450 +// Purpose: Parses the "mapsize" specifier, which should be of the form:
  12.451 +//
  12.452 +//			mapsize(min, max)
  12.453 +//
  12.454 +//			ex: mapsize(-8192, 8192)
  12.455 +//
  12.456 +// Input  : tr - 
  12.457 +// Output : Returns true on success, false on failure.
  12.458 +//-----------------------------------------------------------------------------
  12.459 +bool GameData::ParseMapSize(TokenReader &tr)
  12.460 +{
  12.461 +	if (!GDSkipToken(tr, OPERATOR, "("))
  12.462 +	{
  12.463 +		return false;
  12.464 +	}
  12.465 +
  12.466 +	char szToken[128];
  12.467 +	if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  12.468 +	{
  12.469 +		return false;
  12.470 +	}
  12.471 +	int nMin = atoi(szToken);	
  12.472 +
  12.473 +	if (!GDSkipToken(tr, OPERATOR, ","))
  12.474 +	{
  12.475 +		return false;
  12.476 +	}
  12.477 +
  12.478 +	if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  12.479 +	{
  12.480 +		return false;
  12.481 +	}
  12.482 +	int nMax = atoi(szToken);	
  12.483 +
  12.484 +	if (nMin != nMax)
  12.485 +	{
  12.486 +		m_nMinMapCoord = min(nMin, nMax);
  12.487 +		m_nMaxMapCoord = max(nMin, nMax);
  12.488 +	}
  12.489 +
  12.490 +	if (!GDSkipToken(tr, OPERATOR, ")"))
  12.491 +	{
  12.492 +		return false;
  12.493 +	}
  12.494 +
  12.495 +	return true;
  12.496 +}
  12.497 +
  12.498 +
  12.499 +//-----------------------------------------------------------------------------
  12.500 +// Purpose: 
  12.501 +// Input  : pszName - 
  12.502 +//			piIndex - 
  12.503 +// Output : 
  12.504 +//-----------------------------------------------------------------------------
  12.505 +GDclass *GameData::ClassForName(const char *pszName, int *piIndex)
  12.506 +{
  12.507 +	int nCount = m_Classes.Count();
  12.508 +	for (int i = 0; i < nCount; i++)
  12.509 +	{
  12.510 +		GDclass *mp = m_Classes.Element(i);
  12.511 +		if(!strcmp(mp->GetName(), pszName))
  12.512 +		{
  12.513 +			if(piIndex)
  12.514 +				piIndex[0] = i;
  12.515 +			return mp;
  12.516 +		}
  12.517 +	}
  12.518 +
  12.519 +	return NULL;
  12.520 +}
  12.521 +
  12.522 +
  12.523 +// These are 'standard' keys that every entity uses, but they aren't specified that way in the .fgd
  12.524 +static const char *RequiredKeys[] =
  12.525 +{
  12.526 +	"Origin",
  12.527 +	"Angles",
  12.528 +	NULL
  12.529 +};
  12.530 +
  12.531 +//-----------------------------------------------------------------------------
  12.532 +// Purpose: this function will set up the initial class about to be instanced
  12.533 +// Input  : pszClassName - the class name of the entity to be instanced
  12.534 +//			pszInstancePrefix - the prefix to be used for all name fields
  12.535 +//			Origin - the origin offset of the instance
  12.536 +//			Angles - the angle rotation of the instance
  12.537 +// Output : if successful, will return the game data class of the class name
  12.538 +//-----------------------------------------------------------------------------
  12.539 +GDclass *GameData::BeginInstanceRemap( const char *pszClassName, const char *pszInstancePrefix, Vector &Origin, QAngle &Angle )
  12.540 +{
  12.541 +	m_InstanceOrigin = Origin;
  12.542 +	m_InstanceAngle = Angle;
  12.543 +	AngleMatrix( m_InstanceAngle, m_InstanceOrigin, m_InstanceMat );
  12.544 +
  12.545 +	strcpy( m_InstancePrefix, pszInstancePrefix );
  12.546 +
  12.547 +	if ( m_InstanceClass )
  12.548 +	{
  12.549 +		delete m_InstanceClass;
  12.550 +		m_InstanceClass = NULL;
  12.551 +	}
  12.552 +
  12.553 +	if ( strcmpi( pszClassName, "info_overlay_accessor" ) == 0 )
  12.554 +	{	// yucky hack for a made up entity in the bsp process
  12.555 +		pszClassName = "info_overlay";
  12.556 +	}
  12.557 +
  12.558 +	GDclass	*BaseClass = ClassForName( pszClassName );
  12.559 +	if ( BaseClass )
  12.560 +	{
  12.561 +		m_InstanceClass = new GDclass();
  12.562 +		m_InstanceClass->Parent = this;
  12.563 +		m_InstanceClass->AddBase( BaseClass );
  12.564 +
  12.565 +		for( int i = 0; RequiredKeys[ i ]; i++ )
  12.566 +		{
  12.567 +			if ( m_InstanceClass->VarForName( RequiredKeys[ i ] ) == NULL )
  12.568 +			{
  12.569 +				BaseClass = ClassForName( RequiredKeys[ i ] );
  12.570 +				if ( BaseClass )
  12.571 +				{
  12.572 +					m_InstanceClass->AddBase( BaseClass );
  12.573 +				}
  12.574 +			}
  12.575 +		}
  12.576 +	}
  12.577 +	else
  12.578 +	{
  12.579 +		m_InstanceClass = NULL;
  12.580 +	}
  12.581 +
  12.582 +	return m_InstanceClass;
  12.583 +}
  12.584 +
  12.585 +
  12.586 +enum tRemapOperation
  12.587 +{
  12.588 +	REMAP_NAME = 0,
  12.589 +	REMAP_POSITION,
  12.590 +	REMAP_ANGLE,
  12.591 +	REMAP_ANGLE_NEGATIVE_PITCH,
  12.592 +};
  12.593 +
  12.594 +
  12.595 +static CUtlMap< GDIV_TYPE, tRemapOperation > RemapOperation;
  12.596 +
  12.597 +
  12.598 +//-----------------------------------------------------------------------------
  12.599 +// Purpose: function to sort the class type for the RemapOperations map
  12.600 +// Input  : type1 - the first type to compare against
  12.601 +//			type2 - the second type to compare against
  12.602 +// Output : returns true if the first type is less than the second one
  12.603 +//-----------------------------------------------------------------------------
  12.604 +static bool CUtlType_LessThan( const GDIV_TYPE &type1, const GDIV_TYPE &type2 )
  12.605 +{
  12.606 +	return ( type1 < type2 );
  12.607 +}
  12.608 +
  12.609 +
  12.610 +//-----------------------------------------------------------------------------
  12.611 +// Purpose: this function will attempt to remap a key's value
  12.612 +// Input  : pszKey - the name of the key
  12.613 +//			pszInvalue - the original value
  12.614 +//			AllowNameRemapping - only do name remapping if this parameter is true.  
  12.615 +//				this is generally only false on the instance level.
  12.616 +// Output : returns true if the value changed
  12.617 +//			pszOutValue - the new value if changed
  12.618 +//-----------------------------------------------------------------------------
  12.619 +bool GameData::RemapKeyValue( const char *pszKey, const char *pszInValue, char *pszOutValue, TNameFixup NameFixup )
  12.620 +{
  12.621 +	if ( RemapOperation.Count() == 0 )
  12.622 +	{
  12.623 +		RemapOperation.SetLessFunc( &CUtlType_LessThan );
  12.624 +		RemapOperation.Insert( ivAngle, REMAP_ANGLE );
  12.625 +		RemapOperation.Insert( ivTargetDest, REMAP_NAME );
  12.626 +		RemapOperation.Insert( ivTargetSrc, REMAP_NAME );
  12.627 +		RemapOperation.Insert( ivOrigin, REMAP_POSITION );
  12.628 +		RemapOperation.Insert( ivAxis, REMAP_ANGLE );
  12.629 +		RemapOperation.Insert( ivAngleNegativePitch, REMAP_ANGLE_NEGATIVE_PITCH );
  12.630 +	}
  12.631 +
  12.632 +	if ( !m_InstanceClass )
  12.633 +	{
  12.634 +		return false;
  12.635 +	}
  12.636 +
  12.637 +	GDinputvariable *KVVar = m_InstanceClass->VarForName( pszKey );
  12.638 +	if ( !KVVar )
  12.639 +	{
  12.640 +		return false;
  12.641 +	}
  12.642 +
  12.643 +	GDIV_TYPE	KVType = KVVar->GetType();
  12.644 +	int			KVRemapIndex = RemapOperation.Find( KVType );
  12.645 +	if ( KVRemapIndex == RemapOperation.InvalidIndex() )
  12.646 +	{
  12.647 +		return false;
  12.648 +	}
  12.649 +
  12.650 +	strcpy( pszOutValue, pszInValue );
  12.651 +
  12.652 +	switch( RemapOperation[ KVRemapIndex ] )
  12.653 +	{
  12.654 +		case REMAP_NAME:
  12.655 +			if ( KVType != ivInstanceVariable )
  12.656 +			{
  12.657 +				RemapNameField( pszInValue, pszOutValue, NameFixup );
  12.658 +			}
  12.659 +			break;
  12.660 +
  12.661 +		case REMAP_POSITION:
  12.662 +			{
  12.663 +				Vector	inPoint( 0.0f, 0.0f, 0.0f ), outPoint;
  12.664 +
  12.665 +				sscanf ( pszInValue, "%f %f %f", &inPoint.x, &inPoint.y, &inPoint.z );
  12.666 +				VectorTransform( inPoint, m_InstanceMat, outPoint );
  12.667 +				sprintf( pszOutValue, "%g %g %g", outPoint.x, outPoint.y, outPoint.z );
  12.668 +			}
  12.669 +			break;
  12.670 +			
  12.671 +		case REMAP_ANGLE:
  12.672 +			if ( m_InstanceAngle.x != 0.0f || m_InstanceAngle.y != 0.0f || m_InstanceAngle.z != 0.0f )
  12.673 +			{
  12.674 +				QAngle		inAngles( 0.0f, 0.0f, 0.0f ), outAngles;
  12.675 +				matrix3x4_t angToWorld, localMatrix;
  12.676 +
  12.677 +				sscanf ( pszInValue, "%f %f %f", &inAngles.x, &inAngles.y, &inAngles.z );
  12.678 +
  12.679 +				AngleMatrix( inAngles, angToWorld );
  12.680 +				MatrixMultiply( m_InstanceMat, angToWorld, localMatrix );
  12.681 +				MatrixAngles( localMatrix, outAngles );
  12.682 +
  12.683 +				sprintf( pszOutValue, "%g %g %g", outAngles.x, outAngles.y, outAngles.z );
  12.684 +			}
  12.685 +			break;
  12.686 +
  12.687 +		case REMAP_ANGLE_NEGATIVE_PITCH:
  12.688 +			if ( m_InstanceAngle.x != 0.0f || m_InstanceAngle.y != 0.0f || m_InstanceAngle.z != 0.0f )
  12.689 +			{
  12.690 +				QAngle		inAngles( 0.0f, 0.0f, 0.0f ), outAngles;
  12.691 +				matrix3x4_t angToWorld, localMatrix;
  12.692 +
  12.693 +				sscanf ( pszInValue, "%f", &inAngles.x );	// just the pitch
  12.694 +				inAngles.x = -inAngles.x;
  12.695 +
  12.696 +				AngleMatrix( inAngles, angToWorld );
  12.697 +				MatrixMultiply( m_InstanceMat, angToWorld, localMatrix );
  12.698 +				MatrixAngles( localMatrix, outAngles );
  12.699 +
  12.700 +				sprintf( pszOutValue, "%g", -outAngles.x );	// just the pitch
  12.701 +			}
  12.702 +			break;
  12.703 +	}
  12.704 +
  12.705 +	return ( strcmpi( pszInValue, pszOutValue ) != 0 );
  12.706 +}
  12.707 +
  12.708 +
  12.709 +//-----------------------------------------------------------------------------
  12.710 +// Purpose: this function will attempt to remap a name field.
  12.711 +// Input  : pszInvalue - the original value
  12.712 +//			AllowNameRemapping - only do name remapping if this parameter is true.  
  12.713 +//				this is generally only false on the instance level.
  12.714 +// Output : returns true if the value changed
  12.715 +//			pszOutValue - the new value if changed
  12.716 +//-----------------------------------------------------------------------------
  12.717 +bool GameData::RemapNameField( const char *pszInValue, char *pszOutValue, TNameFixup NameFixup )
  12.718 +{
  12.719 +	strcpy( pszOutValue, pszInValue );
  12.720 +
  12.721 +	if ( pszInValue[ 0 ] && pszInValue[ 0 ] != '@' )
  12.722 +	{	// ! at the start of a value means it is global and should not be remaped
  12.723 +		switch( NameFixup )
  12.724 +		{
  12.725 +			case NAME_FIXUP_PREFIX:
  12.726 +				sprintf( pszOutValue, "%s-%s", m_InstancePrefix, pszInValue );
  12.727 +				break;
  12.728 +
  12.729 +			case NAME_FIXUP_POSTFIX:
  12.730 +				sprintf( pszOutValue, "%s-%s", pszInValue, m_InstancePrefix );
  12.731 +				break;
  12.732 +		}
  12.733 +	}
  12.734 +
  12.735 +	return ( strcmpi( pszInValue, pszOutValue ) != 0 );
  12.736 +}
  12.737 +
  12.738 +
  12.739 +//-----------------------------------------------------------------------------
  12.740 +// Purpose: Gathers any FGD-defined material directory exclusions
  12.741 +// Input  : 
  12.742 +// Output : 
  12.743 +//-----------------------------------------------------------------------------
  12.744 +bool GameData::LoadFGDMaterialExclusions( TokenReader &tr )
  12.745 +{
  12.746 +	if ( !GDSkipToken( tr, OPERATOR, "[" ) )
  12.747 +	{
  12.748 +		return false;
  12.749 +	}
  12.750 +	while ( 1 )
  12.751 +	{
  12.752 +		char szToken[128];
  12.753 +		bool bMatchFound = false;
  12.754 +
  12.755 +		if ( tr.PeekTokenType( szToken, sizeof( szToken ) ) == OPERATOR )
  12.756 +		{
  12.757 +			break;
  12.758 +		}
  12.759 +		else if ( GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
  12.760 +		{		
  12.761 +			// Make sure we haven't loaded this from another FGD
  12.762 +			for ( int i = 0; i < m_FGDMaterialExclusions.Count(); i++ )
  12.763 +			{
  12.764 +				if ( !stricmp( szToken, m_FGDMaterialExclusions[i].szDirectory ) )
  12.765 +				{			
  12.766 +					bMatchFound = true;
  12.767 +					break;
  12.768 +				}
  12.769 +			}
  12.770 +
  12.771 +			// Parse the string
  12.772 +			if ( bMatchFound == false )
  12.773 +			{
  12.774 +				int index = m_FGDMaterialExclusions.AddToTail();
  12.775 +				Q_strncpy( m_FGDMaterialExclusions[index].szDirectory, szToken, sizeof( m_FGDMaterialExclusions[index].szDirectory ) );
  12.776 +				m_FGDMaterialExclusions[index].bUserGenerated = false;
  12.777 +			}
  12.778 +		}
  12.779 +	}
  12.780 +
  12.781 +	//
  12.782 +	// Closing square brace.
  12.783 +	//
  12.784 +	if ( !GDSkipToken( tr, OPERATOR, "]" ) )
  12.785 +	{
  12.786 +		return( FALSE );
  12.787 +	}
  12.788 +
  12.789 +	return true;
  12.790 +}
  12.791 +
  12.792 +//-----------------------------------------------------------------------------
  12.793 +// Purpose: Gathers any FGD-defined Auto VisGroups
  12.794 +// Input  : 
  12.795 +// Output : 
  12.796 +//-----------------------------------------------------------------------------
  12.797 +bool GameData::LoadFGDAutoVisGroups( TokenReader &tr )
  12.798 +{
  12.799 +	int gindex = 0; // Index of AutoVisGroups
  12.800 +	int cindex = 0;	// Index of Classes
  12.801 +
  12.802 +	char szToken[128];
  12.803 +	
  12.804 +	// Handle the Parent -- World Geometry, Entities, World Detail
  12.805 +	if ( GDSkipToken( tr, OPERATOR, "=" ) )
  12.806 +	{
  12.807 +		// We expect a name
  12.808 +		if ( !GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
  12.809 +		{
  12.810 +			return( FALSE );
  12.811 +		}
  12.812 +		
  12.813 +		gindex = m_FGDAutoVisGroups.AddToTail();
  12.814 +		Q_strncpy( m_FGDAutoVisGroups[gindex].szParent, szToken, sizeof( m_FGDAutoVisGroups[gindex].szParent ) );
  12.815 +
  12.816 +		// We expect a Class
  12.817 +		if ( !GDSkipToken( tr, OPERATOR, "[" ) )
  12.818 +		{
  12.819 +			return( FALSE );
  12.820 +		}
  12.821 +	}
  12.822 +
  12.823 +	// Handle the Class(es) -- Brush Entities, Occluders, Lights
  12.824 +	while ( 1 )
  12.825 +	{
  12.826 +		if ( GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
  12.827 +		{
  12.828 +			cindex = m_FGDAutoVisGroups[gindex].m_Classes.AddToTail();
  12.829 +			Q_strncpy( m_FGDAutoVisGroups[gindex].m_Classes[cindex].szClass, szToken, sizeof( m_FGDAutoVisGroups[gindex].m_Classes[cindex].szClass ) );
  12.830 +
  12.831 +			if ( !GDSkipToken( tr, OPERATOR, "[" ) )
  12.832 +			{
  12.833 +				return( FALSE );
  12.834 +			}
  12.835 +
  12.836 +			// Parse objects/entities -- func_detail, point_template, light_spot
  12.837 +			while ( 1 )
  12.838 +			{
  12.839 +				if ( tr.PeekTokenType( szToken, sizeof( szToken ) ) == OPERATOR )
  12.840 +				{
  12.841 +					break;
  12.842 +				}
  12.843 +
  12.844 +				if ( !GDGetToken( tr, szToken, sizeof( szToken ), STRING ) )
  12.845 +				{
  12.846 +					return( FALSE );
  12.847 +				}
  12.848 +
  12.849 +				m_FGDAutoVisGroups[gindex].m_Classes[cindex].szEntities.CopyAndAddToTail( szToken );
  12.850 +
  12.851 +			}
  12.852 +
  12.853 +			if ( !GDSkipToken( tr, OPERATOR, "]" ) )
  12.854 +			{
  12.855 +				return( FALSE );
  12.856 +			}
  12.857 +
  12.858 +			// See if we have another Class coming up
  12.859 +			if ( tr.PeekTokenType( szToken, sizeof( szToken ) ) == STRING )
  12.860 +			{
  12.861 +				continue;
  12.862 +			}
  12.863 +
  12.864 +			// If no more Classes, we now expect a terminating ']'
  12.865 +			if ( !GDSkipToken( tr, OPERATOR, "]" ) )
  12.866 +			{
  12.867 +				return( FALSE );
  12.868 +			}
  12.869 +
  12.870 +			// We're done
  12.871 +			return true;
  12.872 +		}
  12.873 +		// We don't have another Class; look for a terminating brace
  12.874 +		else
  12.875 +		{
  12.876 +			if ( !GDSkipToken( tr, OPERATOR, "]" ) )
  12.877 +			{
  12.878 +				return( FALSE );
  12.879 +			}
  12.880 +		}
  12.881 +	}
  12.882 +
  12.883 +	// Safety net
  12.884 +	GDError( tr, "Malformed AutoVisGroup -- Last processed:  %s", szToken );
  12.885 +	return( FALSE );
  12.886 +}
  12.887 +
  12.888 +// memdbgon must be the last include file in a .cpp file!!!
  12.889 +#include "tier0/memdbgoff.h"
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/fgdlib/gdclass.cpp	Mon Sep 02 11:39:10 2013 -0700
    13.3 @@ -0,0 +1,1041 @@
    13.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
    13.5 +//
    13.6 +// Purpose: 
    13.7 +//
    13.8 +//=============================================================================
    13.9 +
   13.10 +#include "fgdlib/GameData.h" // FGDLIB: eliminate dependency
   13.11 +#include "fgdlib/GDClass.h"
   13.12 +
   13.13 +// memdbgon must be the last include file in a .cpp file!!!
   13.14 +#include <tier0/memdbgon.h>
   13.15 +
   13.16 +
   13.17 +//-----------------------------------------------------------------------------
   13.18 +// Purpose: Constructor.
   13.19 +//-----------------------------------------------------------------------------
   13.20 +GDclass::GDclass(void)
   13.21 +{
   13.22 +	m_nVariables = 0;
   13.23 +	m_bBase = false;
   13.24 +	m_bSolid = false;
   13.25 +	m_bBase = false;
   13.26 +	m_bSolid = false;
   13.27 +	m_bModel = false;
   13.28 +	m_bMove = false;
   13.29 +	m_bKeyFrame = false;
   13.30 +	m_bPoint = false;
   13.31 +	m_bNPC = false;
   13.32 +	m_bFilter = false;
   13.33 +
   13.34 +	m_bHalfGridSnap = false;
   13.35 +
   13.36 +	m_bGotSize = false;
   13.37 +	m_bGotColor = false;
   13.38 +
   13.39 +	m_rgbColor.r = 220;
   13.40 +	m_rgbColor.g = 30;
   13.41 +	m_rgbColor.b = 220;
   13.42 +	m_rgbColor.a = 0;
   13.43 +
   13.44 +	m_pszDescription = NULL;
   13.45 +
   13.46 +	for (int i = 0; i < 3; i++)
   13.47 +	{
   13.48 +		m_bmins[i] = -8;
   13.49 +		m_bmaxs[i] = 8;
   13.50 +	}
   13.51 +}
   13.52 +
   13.53 +
   13.54 +//-----------------------------------------------------------------------------
   13.55 +// Purpose: Destructor. Frees variable and helper lists.
   13.56 +//-----------------------------------------------------------------------------
   13.57 +GDclass::~GDclass(void)
   13.58 +{
   13.59 +	//
   13.60 +	// Free variables.
   13.61 +	//
   13.62 +	int nCount = m_Variables.Count();
   13.63 +	for (int i = 0; i < nCount; i++)
   13.64 +	{
   13.65 +		GDinputvariable *pvi = m_Variables.Element(i);
   13.66 +		delete pvi;
   13.67 +	}
   13.68 +	m_Variables.RemoveAll();
   13.69 +
   13.70 +	//
   13.71 +	// Free helpers.
   13.72 +	//
   13.73 +	nCount = m_Helpers.Count();
   13.74 +	for (int i = 0; i < nCount; i++)
   13.75 +	{
   13.76 +		CHelperInfo *pHelper = m_Helpers.Element(i);
   13.77 +		delete pHelper;
   13.78 +	}
   13.79 +	m_Helpers.RemoveAll();
   13.80 +
   13.81 +	//
   13.82 +	// Free inputs.
   13.83 +	//
   13.84 +	nCount = m_Inputs.Count();
   13.85 +	for (int i = 0; i < nCount; i++)
   13.86 +	{
   13.87 +		CClassInput *pInput = m_Inputs.Element(i);
   13.88 +		delete pInput;
   13.89 +	}
   13.90 +	m_Inputs.RemoveAll();
   13.91 +
   13.92 +	//
   13.93 +	// Free outputs.
   13.94 +	//
   13.95 +	nCount = m_Outputs.Count();
   13.96 +	for (int i = 0; i < nCount; i++)
   13.97 +	{
   13.98 +		CClassOutput *pOutput = m_Outputs.Element(i);
   13.99 +		delete pOutput;
  13.100 +	}
  13.101 +	m_Outputs.RemoveAll();
  13.102 +
  13.103 +	delete m_pszDescription;
  13.104 +}
  13.105 +
  13.106 +
  13.107 +//-----------------------------------------------------------------------------
  13.108 +// Purpose: Adds the base class's variables to our variable list. Acquires the
  13.109 +//			base class's bounding box and color, if any.
  13.110 +// Input  : pszBase - Name of base class to add.
  13.111 +//-----------------------------------------------------------------------------
  13.112 +void GDclass::AddBase(GDclass *pBase)
  13.113 +{
  13.114 +	int iBaseIndex;
  13.115 +	Parent->ClassForName(pBase->GetName(), &iBaseIndex);
  13.116 +
  13.117 +	//
  13.118 +	// Add variables from base - update variable table
  13.119 +	//
  13.120 +	for (int i = 0; i < pBase->GetVariableCount(); i++)
  13.121 +	{
  13.122 +		GDinputvariable *pVar = pBase->GetVariableAt(i);
  13.123 +		AddVariable(pVar, pBase, iBaseIndex, i);
  13.124 +	}
  13.125 +
  13.126 +	//
  13.127 +	// Add inputs from the base.
  13.128 +	// UNDONE: need to use references to inputs & outputs to conserve memory
  13.129 +	//
  13.130 +	int nCount = pBase->GetInputCount();
  13.131 +	for (int i = 0; i < nCount; i++)
  13.132 +	{
  13.133 +		CClassInput *pInput = pBase->GetInput(i);
  13.134 +
  13.135 +		CClassInput *pNew = new CClassInput;
  13.136 +		*pNew = *pInput;
  13.137 +		AddInput(pNew);
  13.138 +	}
  13.139 +
  13.140 +	//
  13.141 +	// Add outputs from the base.
  13.142 +	//
  13.143 +	nCount = pBase->GetOutputCount();
  13.144 +	for (int i = 0; i < nCount; i++)
  13.145 +	{
  13.146 +		CClassOutput *pOutput = pBase->GetOutput(i);
  13.147 +
  13.148 +		CClassOutput *pNew = new CClassOutput;
  13.149 +		*pNew = *pOutput;
  13.150 +		AddOutput(pNew);
  13.151 +	}
  13.152 +
  13.153 +	//
  13.154 +	// If we don't have a bounding box, try to get the base's box.
  13.155 +	//
  13.156 +	if (!m_bGotSize)
  13.157 +	{
  13.158 +		if (pBase->GetBoundBox(m_bmins, m_bmaxs))
  13.159 +		{
  13.160 +			m_bGotSize = true;
  13.161 +		}
  13.162 +	}
  13.163 +
  13.164 +	//
  13.165 +	// If we don't have a color, use the base's color.
  13.166 +	//
  13.167 +	if (!m_bGotColor)
  13.168 +	{
  13.169 +		m_rgbColor = pBase->GetColor();
  13.170 +		m_bGotColor = true;
  13.171 +	}	
  13.172 +}
  13.173 +
  13.174 +
  13.175 +//-----------------------------------------------------------------------------
  13.176 +// Purpose: Adds the given GDInputVariable to this GDClass's list of variables.
  13.177 +// Input  : pVar - 
  13.178 +//			pBase - 
  13.179 +//			iBaseIndex - 
  13.180 +//			iVarIndex - 
  13.181 +// Output : Returns TRUE if the pVar pointer was copied directly into this GDClass,
  13.182 +//			FALSE if not. If this function returns TRUE, pVar should not be
  13.183 +//			deleted by the caller.
  13.184 +//-----------------------------------------------------------------------------
  13.185 +BOOL GDclass::AddVariable(GDinputvariable *pVar, GDclass *pBase, int iBaseIndex, int iVarIndex)
  13.186 +{
  13.187 +	int iThisIndex;
  13.188 +	GDinputvariable *pThisVar = VarForName(pVar->GetName(), &iThisIndex);
  13.189 +	
  13.190 +	//
  13.191 +	// Check to see if we are overriding an existing variable definition.
  13.192 +	//
  13.193 +	if (pThisVar != NULL)
  13.194 +	{
  13.195 +		//
  13.196 +		// Same name, different type. Flag this as an error.
  13.197 +		//
  13.198 +		if (pThisVar->GetType() != pVar->GetType())
  13.199 +		{
  13.200 +			return(false);
  13.201 +		}
  13.202 +
  13.203 +		GDinputvariable *pAddVar;
  13.204 +		bool bReturn;
  13.205 +
  13.206 +		//
  13.207 +		// Check to see if we need to combine a choices/flags array.
  13.208 +		//
  13.209 +		if (pVar->GetType() == ivFlags || pVar->GetType() == ivChoices)
  13.210 +		{
  13.211 +			//
  13.212 +			// Combine two variables' flags into a new variable. Add the new
  13.213 +			// variable to the local variable list and modify the old variable's
  13.214 +			// position in our variable map to reflect the new local variable.
  13.215 +			// This way, we can have multiple inheritance.
  13.216 +			//
  13.217 +			GDinputvariable *pNewVar = new GDinputvariable;
  13.218 +
  13.219 +			*pNewVar = *pVar;
  13.220 +			pNewVar->Merge(*pThisVar);
  13.221 +
  13.222 +			pAddVar = pNewVar;
  13.223 +			bReturn = false;
  13.224 +		}
  13.225 +		else
  13.226 +		{
  13.227 +			pAddVar = pVar;
  13.228 +			bReturn = true;
  13.229 +		}
  13.230 +
  13.231 +		if (m_VariableMap[iThisIndex][0] == -1)
  13.232 +		{
  13.233 +			//
  13.234 +			// "pThisVar" is a leaf variable - we can remove since it is overridden.
  13.235 +			//
  13.236 +			int nIndex = m_Variables.Find(pThisVar);
  13.237 +			Assert(nIndex != -1);
  13.238 +			delete pThisVar;
  13.239 +
  13.240 +			m_Variables.Element(nIndex) = pAddVar;
  13.241 +
  13.242 +			//
  13.243 +			// No need to modify variable map - we just replaced
  13.244 +			// the pointer in the local variable list.
  13.245 +			//
  13.246 +		}
  13.247 +		else
  13.248 +		{
  13.249 +			//
  13.250 +			// "pThisVar" was declared in a base class - we can replace the reference in
  13.251 +			// our variable map with the new variable.
  13.252 +			//
  13.253 +			m_VariableMap[iThisIndex][0] = iBaseIndex;
  13.254 +
  13.255 +			if (iBaseIndex == -1)
  13.256 +			{
  13.257 +				m_Variables.AddToTail(pAddVar);
  13.258 +				m_VariableMap[iThisIndex][1] = m_Variables.Count() - 1;
  13.259 +			}
  13.260 +			else
  13.261 +			{
  13.262 +				m_VariableMap[iThisIndex][1] = iVarIndex;
  13.263 +			}
  13.264 +		}
  13.265 +
  13.266 +		return(bReturn);
  13.267 +	}
  13.268 +	
  13.269 +	//
  13.270 +	// New variable.
  13.271 +	//
  13.272 +	if (iBaseIndex == -1)
  13.273 +	{
  13.274 +		//
  13.275 +		// Variable declared in the leaf class definition - add it to the list.
  13.276 +		//
  13.277 +		m_Variables.AddToTail(pVar);
  13.278 +	}
  13.279 +
  13.280 +	//
  13.281 +	// Too many variables already declared in this class definition - abort.
  13.282 +	//
  13.283 +	if (m_nVariables == GD_MAX_VARIABLES)
  13.284 +	{
  13.285 +		//CUtlString str;
  13.286 +		//str.Format("Too many gamedata variables for class \"%s\"", m_szName);
  13.287 +		//AfxMessageBox(str);
  13.288 +
  13.289 +		return(false);
  13.290 +	}
  13.291 +
  13.292 +	//
  13.293 +	// Add the variable to our list.
  13.294 +	//
  13.295 +	m_VariableMap[m_nVariables][0] = iBaseIndex;
  13.296 +	m_VariableMap[m_nVariables][1] = iVarIndex;
  13.297 +	++m_nVariables;
  13.298 +	
  13.299 +	//
  13.300 +	// We added the pointer to our list of items (see Variables.AddToTail, above) so
  13.301 +	// we must return true here.
  13.302 +	//
  13.303 +	return(true);
  13.304 +}
  13.305 +
  13.306 +
  13.307 +//-----------------------------------------------------------------------------
  13.308 +// Finds an input by name.
  13.309 +//-----------------------------------------------------------------------------
  13.310 +CClassInput *GDclass::FindInput(const char *szName)
  13.311 +{
  13.312 +	int nCount = GetInputCount();
  13.313 +	for (int i = 0; i < nCount; i++)
  13.314 +	{
  13.315 +		CClassInput *pInput = GetInput(i);
  13.316 +		if (!stricmp(pInput->GetName(), szName))
  13.317 +		{
  13.318 +			return(pInput);
  13.319 +		}
  13.320 +	}
  13.321 +
  13.322 +	return(NULL);
  13.323 +}
  13.324 +
  13.325 +
  13.326 +//-----------------------------------------------------------------------------
  13.327 +// Finds an output by name.
  13.328 +//-----------------------------------------------------------------------------
  13.329 +CClassOutput *GDclass::FindOutput(const char *szName)
  13.330 +{
  13.331 +	int nCount = GetOutputCount();
  13.332 +	for (int i = 0; i < nCount; i++)
  13.333 +	{
  13.334 +		CClassOutput *pOutput = GetOutput(i);
  13.335 +		if (!stricmp(pOutput->GetName(), szName))
  13.336 +		{
  13.337 +			return(pOutput);
  13.338 +		}
  13.339 +	}
  13.340 +
  13.341 +	return(NULL);
  13.342 +}
  13.343 +
  13.344 +
  13.345 +//-----------------------------------------------------------------------------
  13.346 +// Purpose: Gets the mins and maxs of the class's bounding box as read from the
  13.347 +//			FGD file. This controls the onscreen representation of any entities
  13.348 +//			derived from this class.
  13.349 +// Input  : pfMins - Receives minimum X, Y, and Z coordinates for the class.
  13.350 +//			pfMaxs - Receives maximum X, Y, and Z coordinates for the class.
  13.351 +// Output : Returns TRUE if this class has a specified bounding box, FALSE if not.
  13.352 +//-----------------------------------------------------------------------------
  13.353 +BOOL GDclass::GetBoundBox(Vector& pfMins, Vector& pfMaxs)
  13.354 +{
  13.355 +	if (m_bGotSize)
  13.356 +	{
  13.357 +		pfMins[0] = m_bmins[0];
  13.358 +		pfMins[1] = m_bmins[1];
  13.359 +		pfMins[2] = m_bmins[2];
  13.360 +
  13.361 +		pfMaxs[0] = m_bmaxs[0];
  13.362 +		pfMaxs[1] = m_bmaxs[1];
  13.363 +		pfMaxs[2] = m_bmaxs[2];
  13.364 +	}
  13.365 +
  13.366 +	return(m_bGotSize);
  13.367 +}
  13.368 +
  13.369 +
  13.370 +//-----------------------------------------------------------------------------
  13.371 +//-----------------------------------------------------------------------------
  13.372 +CHelperInfo *GDclass::GetHelper(int nIndex)
  13.373 +{
  13.374 +	return m_Helpers.Element(nIndex);
  13.375 +}
  13.376 +
  13.377 +
  13.378 +//-----------------------------------------------------------------------------
  13.379 +//-----------------------------------------------------------------------------
  13.380 +CClassInput *GDclass::GetInput(int nIndex)
  13.381 +{
  13.382 +	return m_Inputs.Element(nIndex);
  13.383 +}
  13.384 +
  13.385 +
  13.386 +//-----------------------------------------------------------------------------
  13.387 +//-----------------------------------------------------------------------------
  13.388 +CClassOutput *GDclass::GetOutput(int nIndex)
  13.389 +{
  13.390 +	return m_Outputs.Element(nIndex);
  13.391 +}
  13.392 +
  13.393 +
  13.394 +//-----------------------------------------------------------------------------
  13.395 +// Purpose: 
  13.396 +// Input  : tr - 
  13.397 +//			pGD - 
  13.398 +// Output : Returns TRUE if worth continuing, FALSE otherwise.	
  13.399 +//-----------------------------------------------------------------------------
  13.400 +BOOL GDclass::InitFromTokens(TokenReader& tr, GameData *pGD)
  13.401 +{
  13.402 +	Parent = pGD;
  13.403 +
  13.404 +	//
  13.405 +	// Initialize VariableMap
  13.406 +	//
  13.407 +	for (int i = 0; i < GD_MAX_VARIABLES; i++)
  13.408 +	{
  13.409 +		m_VariableMap[i][0] = -1;
  13.410 +		m_VariableMap[i][1] = -1;
  13.411 +	}
  13.412 +
  13.413 +	//
  13.414 +	// Parse all specifiers (base, size, color, etc.)
  13.415 +	//
  13.416 +	if (!ParseSpecifiers(tr))
  13.417 +	{
  13.418 +		return(FALSE);
  13.419 +	}
  13.420 +
  13.421 +	//
  13.422 +	// Specifiers should be followed by an "="
  13.423 +	//
  13.424 +	if (!GDSkipToken(tr, OPERATOR, "="))
  13.425 +	{
  13.426 +		return(FALSE);
  13.427 +	}
  13.428 +
  13.429 +	//
  13.430 +	// Parse the class name.
  13.431 +	//
  13.432 +	if (!GDGetToken(tr, m_szName, sizeof(m_szName), IDENT))
  13.433 +	{
  13.434 +		return(FALSE);
  13.435 +	}
  13.436 +
  13.437 +	//
  13.438 +	// Check next operator - if ":", we have a description - if "[",
  13.439 +	// we have no description.
  13.440 +	//
  13.441 +	char szToken[MAX_TOKEN];
  13.442 +	if ((tr.PeekTokenType(szToken,sizeof(szToken)) == OPERATOR) && IsToken(szToken, ":"))
  13.443 +	{
  13.444 +		// Skip ":"
  13.445 +		tr.NextToken(szToken, sizeof(szToken));
  13.446 +
  13.447 +		//
  13.448 +		// Free any existing description and set the pointer to NULL so that GDGetToken
  13.449 +		// allocates memory for us.
  13.450 +		//
  13.451 +		delete m_pszDescription;
  13.452 +		m_pszDescription = NULL;
  13.453 +
  13.454 +		// Load description
  13.455 +		if (!GDGetTokenDynamic(tr, &m_pszDescription, STRING))
  13.456 +		{
  13.457 +			return(FALSE);
  13.458 +		}
  13.459 +	}
  13.460 +
  13.461 +	//
  13.462 +	// Opening square brace.
  13.463 +	//
  13.464 +	if (!GDSkipToken(tr, OPERATOR, "["))
  13.465 +	{
  13.466 +		return(FALSE);
  13.467 +	}
  13.468 +
  13.469 +	//
  13.470 +	// Get class variables.
  13.471 +	//
  13.472 +	if (!ParseVariables(tr))
  13.473 +	{
  13.474 +		return(FALSE);
  13.475 +	}
  13.476 +
  13.477 +	//
  13.478 +	// Closing square brace.
  13.479 +	//
  13.480 +	if (!GDSkipToken(tr, OPERATOR, "]"))
  13.481 +	{
  13.482 +		return(FALSE);
  13.483 +	}
  13.484 +
  13.485 +	return(TRUE);
  13.486 +}
  13.487 +
  13.488 +
  13.489 +//-----------------------------------------------------------------------------
  13.490 +// Purpose: 
  13.491 +// Input  : &tr - 
  13.492 +// Output : Returns true on success, false on failure.
  13.493 +//-----------------------------------------------------------------------------
  13.494 +bool GDclass::ParseBase(TokenReader &tr)
  13.495 +{
  13.496 +	char szToken[MAX_TOKEN];
  13.497 +
  13.498 +	while (1)
  13.499 +	{
  13.500 +		if (!GDGetToken(tr, szToken, sizeof(szToken), IDENT))
  13.501 +		{
  13.502 +			return(false);
  13.503 +		}
  13.504 +
  13.505 +		//
  13.506 +		// Find base class in list of classes.
  13.507 +		//
  13.508 +		GDclass *pBase = Parent->ClassForName(szToken);
  13.509 +		if (pBase == NULL)
  13.510 +		{
  13.511 +			GDError(tr, "undefined base class '%s", szToken);
  13.512 +			return(false);
  13.513 +		}
  13.514 +
  13.515 +		AddBase(pBase);
  13.516 +
  13.517 +		if (!GDGetToken(tr, szToken, sizeof(szToken), OPERATOR))
  13.518 +		{
  13.519 +			return(false);
  13.520 +		}
  13.521 +
  13.522 +		if (IsToken(szToken, ")"))
  13.523 +		{
  13.524 +			break;
  13.525 +		}
  13.526 +		else if (!IsToken(szToken, ","))
  13.527 +		{
  13.528 +			GDError(tr, "expecting ',' or ')', but found %s", szToken);
  13.529 +			return(false);
  13.530 +		}
  13.531 +	}
  13.532 +
  13.533 +	return(true);
  13.534 +}
  13.535 +
  13.536 +
  13.537 +//-----------------------------------------------------------------------------
  13.538 +// Purpose: 
  13.539 +// Input  : &tr - 
  13.540 +// Output : Returns true on success, false on failure.
  13.541 +//-----------------------------------------------------------------------------
  13.542 +bool GDclass::ParseColor(TokenReader &tr)
  13.543 +{
  13.544 +	char szToken[MAX_TOKEN];
  13.545 +
  13.546 +	//
  13.547 +	// Red.
  13.548 +	//
  13.549 +	if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  13.550 +	{
  13.551 +		return(false);
  13.552 +	}
  13.553 +	BYTE r = atoi(szToken);
  13.554 +
  13.555 +	//
  13.556 +	// Green.
  13.557 +	//
  13.558 +	if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  13.559 +	{
  13.560 +		return(false);
  13.561 +	}
  13.562 +	BYTE g = atoi(szToken);
  13.563 +
  13.564 +	//
  13.565 +	// Blue.
  13.566 +	//
  13.567 +	if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  13.568 +	{
  13.569 +		return(false);
  13.570 +	}
  13.571 +	BYTE b = atoi(szToken);
  13.572 +
  13.573 +	m_rgbColor.r = r;
  13.574 +	m_rgbColor.g = g;
  13.575 +	m_rgbColor.b = b;
  13.576 +	m_rgbColor.a = 0;
  13.577 +
  13.578 +	m_bGotColor = true;
  13.579 +
  13.580 +	if (!GDGetToken(tr, szToken, sizeof(szToken), OPERATOR, ")"))
  13.581 +	{
  13.582 +		return(false);
  13.583 +	}
  13.584 +	
  13.585 +	return(true);
  13.586 +}
  13.587 +
  13.588 +
  13.589 +//-----------------------------------------------------------------------------
  13.590 +// Purpose: Parses a helper from the FGD file. Helpers are of the following format:
  13.591 +//
  13.592 +//			<helpername>(<parameter 0> <parameter 1> ... <parameter n>)
  13.593 +//
  13.594 +//			When this function is called, the helper name has already been parsed.
  13.595 +// Input  : tr - Tokenreader to use for parsing.
  13.596 +//			pszHelperName - Name of the helper being declared.
  13.597 +// Output : Returns true on success, false on failure.
  13.598 +//-----------------------------------------------------------------------------
  13.599 +bool GDclass::ParseHelper(TokenReader &tr, char *pszHelperName)
  13.600 +{
  13.601 +	char szToken[MAX_TOKEN];
  13.602 +
  13.603 +	CHelperInfo *pHelper = new CHelperInfo;
  13.604 +	pHelper->SetName(pszHelperName);
  13.605 +
  13.606 +	bool bCloseParen = false;
  13.607 +	while (!bCloseParen)
  13.608 +	{
  13.609 +		trtoken_t eType = tr.PeekTokenType(szToken,sizeof(szToken));
  13.610 +
  13.611 +		if (eType == OPERATOR)
  13.612 +		{
  13.613 +			if (!GDGetToken(tr, szToken, sizeof(szToken), OPERATOR))
  13.614 +			{
  13.615 +				delete pHelper;
  13.616 +				return(false);
  13.617 +			}
  13.618 +
  13.619 +			if (IsToken(szToken, ")"))
  13.620 +			{
  13.621 +				bCloseParen = true;
  13.622 +			}
  13.623 +			else if (IsToken(szToken, "="))
  13.624 +			{
  13.625 +				delete pHelper;
  13.626 +				return(false);
  13.627 +			}
  13.628 +		}
  13.629 +		else
  13.630 +		{
  13.631 +			if (!GDGetToken(tr, szToken, sizeof(szToken), eType))
  13.632 +			{
  13.633 +				delete pHelper;
  13.634 +				return(false);
  13.635 +			}
  13.636 +			else
  13.637 +			{
  13.638 +				pHelper->AddParameter(szToken);
  13.639 +			}
  13.640 +		}
  13.641 +	}
  13.642 +
  13.643 +	m_Helpers.AddToTail(pHelper);
  13.644 +
  13.645 +	return(true);
  13.646 +}
  13.647 +
  13.648 +
  13.649 +//-----------------------------------------------------------------------------
  13.650 +// Purpose: 
  13.651 +// Input  : &tr - 
  13.652 +// Output : Returns true on success, false on failure.
  13.653 +//-----------------------------------------------------------------------------
  13.654 +bool GDclass::ParseSize(TokenReader &tr)
  13.655 +{
  13.656 +	char szToken[MAX_TOKEN];
  13.657 +
  13.658 +	//
  13.659 +	// Mins.
  13.660 +	//
  13.661 +	for (int i = 0; i < 3; i++)
  13.662 +	{
  13.663 +		if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  13.664 +		{
  13.665 +			return(false);
  13.666 +		}
  13.667 +
  13.668 +		m_bmins[i] = (float)atof(szToken);
  13.669 +	}
  13.670 +
  13.671 +	if (tr.PeekTokenType(szToken,sizeof(szToken)) == OPERATOR && IsToken(szToken, ","))
  13.672 +	{
  13.673 +		//
  13.674 +		// Skip ","
  13.675 +		//
  13.676 +		tr.NextToken(szToken, sizeof(szToken));
  13.677 +
  13.678 +		//
  13.679 +		// Get maxes.
  13.680 +		//
  13.681 +		for (int i = 0; i < 3; i++)
  13.682 +		{
  13.683 +			if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  13.684 +			{
  13.685 +				return(false);
  13.686 +			}
  13.687 +			m_bmaxs[i] = (float)atof(szToken);
  13.688 +		}
  13.689 +	}
  13.690 +	else
  13.691 +	{
  13.692 +		//
  13.693 +		// Split mins across origin.
  13.694 +		//
  13.695 +		for (int i = 0; i < 3; i++)
  13.696 +		{
  13.697 +			float div2 = m_bmins[i] / 2;
  13.698 +			m_bmaxs[i] = div2;
  13.699 +			m_bmins[i] = -div2;
  13.700 +		}
  13.701 +	}
  13.702 +
  13.703 +	m_bGotSize = true;
  13.704 +
  13.705 +	if (!GDGetToken(tr, szToken, sizeof(szToken), OPERATOR, ")"))
  13.706 +	{
  13.707 +		return(false);
  13.708 +	}
  13.709 +
  13.710 +	return(true);
  13.711 +}
  13.712 +
  13.713 +
  13.714 +//-----------------------------------------------------------------------------
  13.715 +// Purpose: 
  13.716 +// Input  : &tr - 
  13.717 +// Output : Returns true on success, false on failure.
  13.718 +//-----------------------------------------------------------------------------
  13.719 +bool GDclass::ParseSpecifiers(TokenReader &tr)
  13.720 +{
  13.721 +	char szToken[MAX_TOKEN];
  13.722 +
  13.723 +	while (tr.PeekTokenType() == IDENT)
  13.724 +	{
  13.725 +		tr.NextToken(szToken, sizeof(szToken));
  13.726 +
  13.727 +		//
  13.728 +		// Handle specifiers that don't have any parens after them.
  13.729 +		//
  13.730 +		if (IsToken(szToken, "halfgridsnap"))
  13.731 +		{
  13.732 +			m_bHalfGridSnap = true;
  13.733 +		}
  13.734 +		else
  13.735 +		{
  13.736 +			//
  13.737 +			// Handle specifiers require parens after them.
  13.738 +			//
  13.739 +			if (!GDSkipToken(tr, OPERATOR, "("))
  13.740 +			{
  13.741 +				return(false);
  13.742 +			}
  13.743 +
  13.744 +			if (IsToken(szToken, "base"))
  13.745 +			{
  13.746 +				if (!ParseBase(tr))
  13.747 +				{
  13.748 +					return(false);
  13.749 +				}
  13.750 +			}
  13.751 +			else if (IsToken(szToken, "size"))
  13.752 +			{
  13.753 +				if (!ParseSize(tr))
  13.754 +				{
  13.755 +					return(false);
  13.756 +				}
  13.757 +			}
  13.758 +			else if (IsToken(szToken, "color"))
  13.759 +			{
  13.760 +				if (!ParseColor(tr))
  13.761 +				{
  13.762 +					return(false);
  13.763 +				}
  13.764 +			}
  13.765 +			else if (!ParseHelper(tr, szToken))
  13.766 +			{
  13.767 +				return(false);
  13.768 +			}
  13.769 +		}
  13.770 +	}
  13.771 +
  13.772 +	return(true);
  13.773 +}
  13.774 +
  13.775 +
  13.776 +//-----------------------------------------------------------------------------
  13.777 +// Purpose: Reads an input using a given token reader. If the input is
  13.778 +//			read successfully, the input is added to this class. If not, a
  13.779 +//			parsing failure is returned.
  13.780 +// Input  : tr - Token reader to use for parsing.
  13.781 +// Output : Returns true on success, false on failure.
  13.782 +//-----------------------------------------------------------------------------
  13.783 +bool GDclass::ParseInput(TokenReader &tr)
  13.784 +{
  13.785 +	char szToken[MAX_TOKEN];
  13.786 +
  13.787 +	if (!GDGetToken(tr, szToken, sizeof(szToken), IDENT, "input"))
  13.788 +	{
  13.789 +		return(false);
  13.790 +	}
  13.791 +
  13.792 +	CClassInput *pInput = new CClassInput;
  13.793 +
  13.794 +	bool bReturn = ParseInputOutput(tr, pInput);
  13.795 +	if (bReturn)
  13.796 +	{
  13.797 +		AddInput(pInput);
  13.798 +	}
  13.799 +	else
  13.800 +	{
  13.801 +		delete pInput;
  13.802 +	}
  13.803 +
  13.804 +	return(bReturn);
  13.805 +}
  13.806 +
  13.807 +
  13.808 +//-----------------------------------------------------------------------------
  13.809 +// Purpose: Reads an input or output using a given token reader.
  13.810 +// Input  : tr - Token reader to use for parsing.
  13.811 +//			pInputOutput - Input or output to fill out.
  13.812 +// Output : Returns true on success, false on failure.
  13.813 +//-----------------------------------------------------------------------------
  13.814 +bool GDclass::ParseInputOutput(TokenReader &tr, CClassInputOutputBase *pInputOutput)
  13.815 +{
  13.816 +	char szToken[MAX_TOKEN];
  13.817 +
  13.818 +	//
  13.819 +	// Read the name.
  13.820 +	//
  13.821 +	if (!GDGetToken(tr, szToken, sizeof(szToken), IDENT))
  13.822 +	{
  13.823 +		return(false);
  13.824 +	}
  13.825 +
  13.826 +	pInputOutput->SetName(szToken);
  13.827 +
  13.828 +	//
  13.829 +	// Read the type.
  13.830 +	//
  13.831 +	if (!GDGetToken(tr, szToken, sizeof(szToken), OPERATOR, "("))
  13.832 +	{
  13.833 +		return(false);
  13.834 +	}
  13.835 +
  13.836 +	if (!GDGetToken(tr, szToken, sizeof(szToken), IDENT))
  13.837 +	{
  13.838 +		return(false);
  13.839 +	}
  13.840 +
  13.841 +	InputOutputType_t eType = pInputOutput->SetType(szToken);
  13.842 +	if (eType == iotInvalid)
  13.843 +	{
  13.844 +		GDError(tr, "bad input/output type '%s'", szToken);
  13.845 +		return(false);
  13.846 +	}
  13.847 +
  13.848 +	if (!GDGetToken(tr, szToken, sizeof(szToken), OPERATOR, ")"))
  13.849 +	{
  13.850 +		return(false);
  13.851 +	}
  13.852 +
  13.853 +	//
  13.854 +	// Check the next operator - if ':', we have a description.
  13.855 +	//
  13.856 +	if ((tr.PeekTokenType(szToken,sizeof(szToken)) == OPERATOR) && (IsToken(szToken, ":")))
  13.857 +	{
  13.858 +		//
  13.859 +		// Skip the ":".
  13.860 +		//
  13.861 +		tr.NextToken(szToken, sizeof(szToken));
  13.862 +
  13.863 +		//
  13.864 +		// Read the description.
  13.865 +		//
  13.866 +		char *pszDescription;
  13.867 +		if (!GDGetTokenDynamic(tr, &pszDescription, STRING))
  13.868 +		{
  13.869 +			return(false);
  13.870 +		}
  13.871 +
  13.872 +		pInputOutput->SetDescription(pszDescription);
  13.873 +	}
  13.874 +
  13.875 +	return(true);
  13.876 +}
  13.877 +
  13.878 +
  13.879 +//-----------------------------------------------------------------------------
  13.880 +// Purpose: Reads an output using a given token reader. If the output is
  13.881 +//			read successfully, the output is added to this class. If not, a
  13.882 +//			parsing failure is returned.
  13.883 +// Input  : tr - Token reader to use for parsing.
  13.884 +// Output : Returns true on success, false on failure.
  13.885 +//-----------------------------------------------------------------------------
  13.886 +bool GDclass::ParseOutput(TokenReader &tr)
  13.887 +{
  13.888 +	char szToken[MAX_TOKEN];
  13.889 +
  13.890 +	if (!GDGetToken(tr, szToken, sizeof(szToken), IDENT, "output"))
  13.891 +	{
  13.892 +		return(false);
  13.893 +	}
  13.894 +
  13.895 +	CClassOutput *pOutput = new CClassOutput;
  13.896 +
  13.897 +	bool bReturn = ParseInputOutput(tr, pOutput);
  13.898 +	if (bReturn)
  13.899 +	{
  13.900 +		AddOutput(pOutput);
  13.901 +	}
  13.902 +	else
  13.903 +	{
  13.904 +		delete pOutput;
  13.905 +	}
  13.906 +
  13.907 +	return(bReturn);
  13.908 +}
  13.909 +
  13.910 +
  13.911 +//-----------------------------------------------------------------------------
  13.912 +// Purpose: 
  13.913 +// Input  : &tr - 
  13.914 +// Output : Returns true on success, false on failure.
  13.915 +//-----------------------------------------------------------------------------
  13.916 +bool GDclass::ParseVariables(TokenReader &tr)
  13.917 +{
  13.918 +	while (1)
  13.919 +	{
  13.920 +		char szToken[MAX_TOKEN];
  13.921 +
  13.922 +		if (tr.PeekTokenType(szToken,sizeof(szToken)) == OPERATOR)
  13.923 +		{
  13.924 +			break;
  13.925 +		}
  13.926 +
  13.927 +		if (!stricmp(szToken, "input"))
  13.928 +		{
  13.929 +			if (!ParseInput(tr))
  13.930 +			{
  13.931 +				return(false);
  13.932 +			}
  13.933 +
  13.934 +			continue;
  13.935 +		}
  13.936 +
  13.937 +		if (!stricmp(szToken, "output"))
  13.938 +		{
  13.939 +			if (!ParseOutput(tr))
  13.940 +			{
  13.941 +				return(false);
  13.942 +			}
  13.943 +
  13.944 +			continue;
  13.945 +		}
  13.946 +
  13.947 +		if (!stricmp(szToken, "key"))
  13.948 +		{
  13.949 +			GDGetToken(tr, szToken, sizeof(szToken));
  13.950 +		}
  13.951 +
  13.952 +		GDinputvariable * var = new GDinputvariable;
  13.953 +		if (!var->InitFromTokens(tr))
  13.954 +		{
  13.955 +			delete var;
  13.956 +			return(false);
  13.957 +		}
  13.958 +
  13.959 +		int nDupIndex;
  13.960 +		GDinputvariable *pDupVar = VarForName(var->GetName(), &nDupIndex);
  13.961 +		
  13.962 +		// check for duplicate variable definitions
  13.963 +		if (pDupVar)
  13.964 +		{
  13.965 +			// Same name, different type.
  13.966 +			if (pDupVar->GetType() != var->GetType())
  13.967 +			{
  13.968 +				char szError[_MAX_PATH];
  13.969 +
  13.970 +				sprintf(szError, "%s: Variable '%s' is multiply defined with different types.", GetName(), var->GetName());
  13.971 +				GDError(tr, szError);
  13.972 +			}
  13.973 +		}
  13.974 +
  13.975 +		if (!AddVariable(var, this, -1, m_Variables.Count()))
  13.976 +		{
  13.977 +			delete var;
  13.978 +		}
  13.979 +	}
  13.980 +
  13.981 +	return(true);
  13.982 +}
  13.983 +
  13.984 +
  13.985 +//-----------------------------------------------------------------------------
  13.986 +// Purpose: 
  13.987 +// Input  : iIndex - 
  13.988 +// Output : GDinputvariable *
  13.989 +//-----------------------------------------------------------------------------
  13.990 +GDinputvariable *GDclass::GetVariableAt(int iIndex)
  13.991 +{
  13.992 +	if ( iIndex < 0 || iIndex >= m_nVariables )
  13.993 +		return NULL;
  13.994 +
  13.995 +	if (m_VariableMap[iIndex][0] == -1)
  13.996 +	{
  13.997 +		return m_Variables.Element(m_VariableMap[iIndex][1]);
  13.998 +	}
  13.999 +
 13.1000 +	// find var's owner
 13.1001 +	GDclass *pVarClass = Parent->GetClass(m_VariableMap[iIndex][0]);
 13.1002 +
 13.1003 +	// find var in pVarClass
 13.1004 +	return pVarClass->GetVariableAt(m_VariableMap[iIndex][1]);
 13.1005 +}
 13.1006 +
 13.1007 +
 13.1008 +//-----------------------------------------------------------------------------
 13.1009 +//-----------------------------------------------------------------------------
 13.1010 +GDinputvariable *GDclass::VarForName(const char *pszName, int *piIndex)
 13.1011 +{
 13.1012 +	for(int i = 0; i < GetVariableCount(); i++)
 13.1013 +	{
 13.1014 +		GDinputvariable *pVar = GetVariableAt(i);
 13.1015 +		if(!strcmpi(pVar->GetName(), pszName))
 13.1016 +		{
 13.1017 +			if(piIndex)
 13.1018 +				piIndex[0] = i;
 13.1019 +			return pVar;
 13.1020 +		}
 13.1021 +	}
 13.1022 +
 13.1023 +	return NULL;
 13.1024 +}
 13.1025 +
 13.1026 +void GDclass::GetHelperForGDVar( GDinputvariable *pVar, CUtlVector<const char *> *pszHelperName )
 13.1027 +{
 13.1028 +	const char *pszName = pVar->GetName();
 13.1029 +	for( int i = 0; i < GetHelperCount(); i++ )
 13.1030 +	{
 13.1031 +		CHelperInfo *pHelper = GetHelper( i );
 13.1032 +		int nParamCount = pHelper->GetParameterCount();
 13.1033 +		for ( int j = 0; j < nParamCount; j++ )
 13.1034 +		{
 13.1035 +			if ( !strcmpi( pszName, pHelper->GetParameter( j ) ) )
 13.1036 +			{
 13.1037 +				pszHelperName->AddToTail(pHelper->GetName());
 13.1038 +			}
 13.1039 +		}
 13.1040 +	}
 13.1041 +}
 13.1042 +
 13.1043 +
 13.1044 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/fgdlib/gdvar.cpp	Mon Sep 02 11:39:10 2013 -0700
    14.3 @@ -0,0 +1,729 @@
    14.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
    14.5 +//
    14.6 +//=============================================================================
    14.7 +
    14.8 +#include "fgdlib/fgdlib.h"
    14.9 +#include "fgdlib/GameData.h"
   14.10 +#include "fgdlib/WCKeyValues.h"
   14.11 +#include "fgdlib/gdvar.h"
   14.12 +
   14.13 +// memdbgon must be the last include file in a .cpp file!!!
   14.14 +#include <tier0/memdbgon.h>
   14.15 +
   14.16 +
   14.17 +typedef struct
   14.18 +{
   14.19 +	GDIV_TYPE eType;		// The enumeration of this type.
   14.20 +	char *pszName;			// The name of this type.
   14.21 +	trtoken_t eStoreAs;		// How this type is stored (STRING, INTEGER, etc).
   14.22 +} TypeMap_t;
   14.23 +
   14.24 +
   14.25 +//-----------------------------------------------------------------------------
   14.26 +// Maps type names to type enums and parsing logic for values.
   14.27 +//-----------------------------------------------------------------------------
   14.28 +static TypeMap_t TypeMap[] =
   14.29 +{
   14.30 +	{ ivAngle,				"angle",				STRING },
   14.31 +	{ ivChoices,			"choices",				STRING },
   14.32 +	{ ivColor1,				"color1",				STRING },
   14.33 +	{ ivColor255,			"color255",				STRING },
   14.34 +	{ ivDecal,				"decal",				STRING },
   14.35 +	{ ivFlags,				"flags",				INTEGER },
   14.36 +	{ ivInteger,			"integer",				INTEGER },
   14.37 +	{ ivSound,				"sound",				STRING },
   14.38 +	{ ivSprite,				"sprite",				STRING },
   14.39 +	{ ivString,				"string",				STRING },
   14.40 +	{ ivStudioModel,		"studio",				STRING },
   14.41 +	{ ivTargetDest,			"target_destination",	STRING },
   14.42 +	{ ivTargetSrc,			"target_source",		STRING },
   14.43 +	{ ivTargetNameOrClass,	"target_name_or_class",	STRING },	// Another version of target_destination that accepts class names
   14.44 +	{ ivVector,				"vector",				STRING },
   14.45 +	{ ivNPCClass,			"npcclass",				STRING },
   14.46 +	{ ivFilterClass,		"filterclass",			STRING },
   14.47 +	{ ivFloat,				"float",				STRING },
   14.48 +	{ ivMaterial,			"material",				STRING },
   14.49 +	{ ivScene,				"scene",				STRING },
   14.50 +	{ ivSide,				"side",					STRING },
   14.51 +	{ ivSideList,			"sidelist",				STRING },
   14.52 +	{ ivOrigin,				"origin",				STRING },
   14.53 +	{ ivAxis,				"axis",					STRING },
   14.54 +	{ ivVecLine,			"vecline",				STRING },
   14.55 +	{ ivPointEntityClass,	"pointentityclass",		STRING },
   14.56 +	{ ivNodeDest,			"node_dest",			INTEGER },
   14.57 +	{ ivInstanceFile,		"instance_file",		STRING },
   14.58 +	{ ivAngleNegativePitch,	"angle_negative_pitch",	STRING },
   14.59 +	{ ivInstanceVariable,	"instance_variable",	STRING },
   14.60 +	{ ivInstanceParm,		"instance_parm",		STRING },
   14.61 +};
   14.62 +
   14.63 +
   14.64 +char *GDinputvariable::m_pszEmpty = "";
   14.65 +
   14.66 +
   14.67 +//-----------------------------------------------------------------------------
   14.68 +//-----------------------------------------------------------------------------
   14.69 +GDinputvariable::GDinputvariable(void)
   14.70 +{
   14.71 +	m_szDefault[0] = 0;
   14.72 +	m_nDefault = 0;
   14.73 +	m_szValue[0] = 0;
   14.74 +	m_bReportable = FALSE;
   14.75 +	m_bReadOnly = false;
   14.76 +	m_pszDescription = NULL;
   14.77 +}
   14.78 +
   14.79 +
   14.80 +//-----------------------------------------------------------------------------
   14.81 +// Purpose: construct generally used for creating a temp instance parm type
   14.82 +// Input  : szType - the textual type of this variable
   14.83 +//			szName - the name description of this variable
   14.84 +//-----------------------------------------------------------------------------
   14.85 +GDinputvariable::GDinputvariable( const char *szType, const char *szName )
   14.86 +{
   14.87 +	m_szDefault[0] = 0;
   14.88 +	m_nDefault = 0;
   14.89 +	m_szValue[0] = 0;
   14.90 +	m_bReportable = FALSE;
   14.91 +	m_bReadOnly = false;
   14.92 +	m_pszDescription = NULL;
   14.93 +
   14.94 +	m_eType = GetTypeFromToken( szType );
   14.95 +	strcpy( m_szName, szName );
   14.96 +}
   14.97 +
   14.98 +
   14.99 +//-----------------------------------------------------------------------------
  14.100 +// Purpose: Destructor.
  14.101 +//-----------------------------------------------------------------------------
  14.102 +GDinputvariable::~GDinputvariable(void)
  14.103 +{
  14.104 +	delete [] m_pszDescription;
  14.105 +	m_Items.RemoveAll();
  14.106 +}
  14.107 +
  14.108 +
  14.109 +//-----------------------------------------------------------------------------
  14.110 +// Purpose: Implements the copy operator.
  14.111 +//-----------------------------------------------------------------------------
  14.112 +GDinputvariable &GDinputvariable::operator =(GDinputvariable &Other)
  14.113 +{
  14.114 +	m_eType = Other.GetType();
  14.115 +	strcpy(m_szName, Other.m_szName);
  14.116 +	strcpy(m_szLongName, Other.m_szLongName);
  14.117 +	strcpy(m_szDefault, Other.m_szDefault);
  14.118 +
  14.119 +	//
  14.120 +	// Copy the description.
  14.121 +	//
  14.122 +	delete [] m_pszDescription;
  14.123 +	if (Other.m_pszDescription != NULL)
  14.124 +	{
  14.125 +		m_pszDescription = new char[strlen(Other.m_pszDescription) + 1];
  14.126 +		strcpy(m_pszDescription, Other.m_pszDescription);
  14.127 +	}
  14.128 +	else
  14.129 +	{
  14.130 +		m_pszDescription = NULL;
  14.131 +	}
  14.132 +
  14.133 +	m_nDefault = Other.m_nDefault;
  14.134 +	m_bReportable = Other.m_bReportable;
  14.135 +	m_bReadOnly = Other.m_bReadOnly;
  14.136 +
  14.137 +	m_Items.RemoveAll();
  14.138 +	
  14.139 +	int nCount = Other.m_Items.Count();
  14.140 +	for (int i = 0; i < nCount; i++)
  14.141 +	{
  14.142 +		m_Items.AddToTail(Other.m_Items.Element(i));
  14.143 +	}
  14.144 +
  14.145 +	return(*this);
  14.146 +}
  14.147 +
  14.148 +
  14.149 +//-----------------------------------------------------------------------------
  14.150 +// Purpose: Returns the storage format of a given variable type.
  14.151 +// Input  : pszToken - Sting containing the token.
  14.152 +// Output : GDIV_TYPE corresponding to the token in the string, ivBadType if the
  14.153 +//			string does not correspond to a valid type.
  14.154 +//-----------------------------------------------------------------------------
  14.155 +trtoken_t GDinputvariable::GetStoreAsFromType(GDIV_TYPE eType)
  14.156 +{
  14.157 +	for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
  14.158 +	{
  14.159 +		if (TypeMap[i].eType == eType)
  14.160 +		{
  14.161 +			return(TypeMap[i].eStoreAs);
  14.162 +		}
  14.163 +	}
  14.164 +
  14.165 +	Assert(FALSE);
  14.166 +	return(STRING);
  14.167 +}
  14.168 +
  14.169 +
  14.170 +//-----------------------------------------------------------------------------
  14.171 +// Purpose: Returns the enumerated type of a string token.
  14.172 +// Input  : pszToken - Sting containing the token.
  14.173 +// Output : GDIV_TYPE corresponding to the token in the string, ivBadType if the
  14.174 +//			string does not correspond to a valid type.
  14.175 +//-----------------------------------------------------------------------------
  14.176 +GDIV_TYPE GDinputvariable::GetTypeFromToken(const char *pszToken)
  14.177 +{
  14.178 +	for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
  14.179 +	{
  14.180 +		if (IsToken(pszToken, TypeMap[i].pszName))
  14.181 +		{
  14.182 +			return(TypeMap[i].eType);
  14.183 +		}
  14.184 +	}
  14.185 +
  14.186 +	return(ivBadType);
  14.187 +}
  14.188 +
  14.189 +
  14.190 +//-----------------------------------------------------------------------------
  14.191 +// Purpose: Returns a string representing the type of this variable, eg. "integer".
  14.192 +//-----------------------------------------------------------------------------
  14.193 +const char *GDinputvariable::GetTypeText(void)
  14.194 +{
  14.195 +	for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
  14.196 +	{
  14.197 +		if (TypeMap[i].eType == m_eType)
  14.198 +		{
  14.199 +			return(TypeMap[i].pszName);
  14.200 +		}
  14.201 +	}
  14.202 +
  14.203 +	return("unknown");
  14.204 +}
  14.205 +
  14.206 +
  14.207 +//-----------------------------------------------------------------------------
  14.208 +// Purpose: 
  14.209 +// Input  : tr - 
  14.210 +// Output : Returns TRUE on success, FALSE on failure.
  14.211 +//-----------------------------------------------------------------------------
  14.212 +BOOL GDinputvariable::InitFromTokens(TokenReader& tr)
  14.213 +{
  14.214 +	char szToken[128];
  14.215 +
  14.216 +	if (!GDGetToken(tr, m_szName, sizeof(m_szName), IDENT))
  14.217 +	{
  14.218 +		return FALSE;
  14.219 +	}
  14.220 +
  14.221 +	if (!GDSkipToken(tr, OPERATOR, "("))
  14.222 +	{
  14.223 +		return FALSE;
  14.224 +	}
  14.225 +
  14.226 +	// check for "reportable" marker
  14.227 +	trtoken_t ttype = tr.NextToken(szToken, sizeof(szToken));
  14.228 +	if (ttype == OPERATOR)
  14.229 +	{
  14.230 +		if (!strcmp(szToken, "*"))
  14.231 +		{
  14.232 +			m_bReportable = true;
  14.233 +		}
  14.234 +	}
  14.235 +	else
  14.236 +	{
  14.237 +		tr.Stuff(ttype, szToken);
  14.238 +	}
  14.239 +
  14.240 +	// get type
  14.241 +	if (!GDGetToken(tr, szToken, sizeof(szToken), IDENT))
  14.242 +	{
  14.243 +		return FALSE;
  14.244 +	}
  14.245 +
  14.246 +	if (!GDSkipToken(tr, OPERATOR, ")"))
  14.247 +	{
  14.248 +		return FALSE;
  14.249 +	}
  14.250 +
  14.251 +	//
  14.252 +	// Check for known variable types.
  14.253 +	//
  14.254 +	m_eType = GetTypeFromToken(szToken);
  14.255 +	if (m_eType == ivBadType)
  14.256 +	{
  14.257 +		GDError(tr, "'%s' is not a valid variable type", szToken);
  14.258 +		return FALSE;
  14.259 +	}
  14.260 +
  14.261 +	//
  14.262 +	// Look ahead at the next token.
  14.263 +	//
  14.264 +	ttype = tr.PeekTokenType(szToken,sizeof(szToken));
  14.265 +
  14.266 +	//
  14.267 +	// Check for the "readonly" specifier.
  14.268 +	//
  14.269 +	if ((ttype == IDENT) && IsToken(szToken, "readonly"))
  14.270 +	{
  14.271 +		tr.NextToken(szToken, sizeof(szToken));
  14.272 +		m_bReadOnly = true;
  14.273 +
  14.274 +		//
  14.275 +		// Look ahead at the next token.
  14.276 +		//
  14.277 +		ttype = tr.PeekTokenType(szToken,sizeof(szToken));
  14.278 +	}
  14.279 +
  14.280 +	//
  14.281 +	// Check for the ':' indicating a long name.
  14.282 +	//
  14.283 +	if (ttype == OPERATOR && IsToken(szToken, ":"))
  14.284 +	{
  14.285 +		//
  14.286 +		// Eat the ':'.
  14.287 +		//
  14.288 +		tr.NextToken(szToken, sizeof(szToken));
  14.289 +
  14.290 +		if (m_eType == ivFlags)
  14.291 +		{
  14.292 +			GDError(tr, "flag sets do not have long names");
  14.293 +			return FALSE;
  14.294 +		}
  14.295 +
  14.296 +		//
  14.297 +		// Get the long name.
  14.298 +		//
  14.299 +		if (!GDGetToken(tr, m_szLongName, sizeof(m_szLongName), STRING))
  14.300 +		{
  14.301 +			return(FALSE);
  14.302 +		}
  14.303 +
  14.304 +		//
  14.305 +		// Look ahead at the next token.
  14.306 +		//
  14.307 +		ttype = tr.PeekTokenType(szToken,sizeof(szToken));
  14.308 +
  14.309 +		//
  14.310 +		// Check for the ':' indicating a default value.
  14.311 +		//
  14.312 +		if (ttype == OPERATOR && IsToken(szToken, ":"))
  14.313 +		{
  14.314 +			//
  14.315 +			// Eat the ':'.
  14.316 +			//
  14.317 +			tr.NextToken(szToken, sizeof(szToken));
  14.318 +
  14.319 +			//
  14.320 +			// Look ahead at the next token.
  14.321 +			//
  14.322 +			ttype = tr.PeekTokenType(szToken,sizeof(szToken));
  14.323 +			if (ttype == OPERATOR && IsToken(szToken, ":"))
  14.324 +			{
  14.325 +				//
  14.326 +				// No default value provided, skip to the description.
  14.327 +				//
  14.328 +			}
  14.329 +			else
  14.330 +			{
  14.331 +				//
  14.332 +				// Determine how to parse the default value. If this is a choices field, the
  14.333 +				// default could either be a string or an integer, so we must look ahead and
  14.334 +				// use whichever is there.
  14.335 +				//
  14.336 +				trtoken_t eStoreAs = GetStoreAsFromType(m_eType);
  14.337 +
  14.338 +				if (eStoreAs == STRING)
  14.339 +				{
  14.340 +					if (!GDGetToken(tr, m_szDefault, sizeof(m_szDefault), STRING))
  14.341 +					{
  14.342 +						return(FALSE);
  14.343 +					}
  14.344 +				}
  14.345 +				else if (eStoreAs == INTEGER)
  14.346 +				{
  14.347 +					if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  14.348 +					{
  14.349 +						return(FALSE);
  14.350 +					}
  14.351 +
  14.352 +					m_nDefault = atoi(szToken);
  14.353 +				}
  14.354 +
  14.355 +				//
  14.356 +				// Look ahead at the next token.
  14.357 +				//
  14.358 +				ttype = tr.PeekTokenType(szToken,sizeof(szToken));
  14.359 +			}
  14.360 +		}
  14.361 +
  14.362 +		//
  14.363 +		// Check for the ':' indicating a description.
  14.364 +		//
  14.365 +		if (ttype == OPERATOR && IsToken(szToken, ":"))
  14.366 +		{
  14.367 +			//
  14.368 +			// Eat the ':'.
  14.369 +			//
  14.370 +			tr.NextToken(szToken, sizeof(szToken));
  14.371 +
  14.372 +			//
  14.373 +			// Read the description.
  14.374 +			//
  14.375 +
  14.376 +			// If we've already read a description then free it to avoid memory leaks.
  14.377 +			if ( m_pszDescription )
  14.378 +			{
  14.379 +				delete [] m_pszDescription;
  14.380 +				m_pszDescription = NULL;
  14.381 +			}
  14.382 +			if (!GDGetTokenDynamic(tr, &m_pszDescription, STRING))
  14.383 +			{
  14.384 +				return(FALSE);
  14.385 +			}
  14.386 +
  14.387 +			//
  14.388 +			// Look ahead at the next token.
  14.389 +			//
  14.390 +			ttype = tr.PeekTokenType(szToken,sizeof(szToken));
  14.391 +		}
  14.392 +	}
  14.393 +	else
  14.394 +	{
  14.395 +		//
  14.396 +		// Default long name is short name.
  14.397 +		//
  14.398 +		strcpy(m_szLongName, m_szName);
  14.399 +	}
  14.400 +
  14.401 +	//
  14.402 +	// Check for the ']' indicating the end of the class definition.
  14.403 +	//
  14.404 +	if ((ttype == OPERATOR && IsToken(szToken, "]")) ||	ttype != OPERATOR)
  14.405 +	{
  14.406 +		if (m_eType == ivFlags || m_eType == ivChoices)
  14.407 +		{
  14.408 +			//
  14.409 +			// Can't define a flags or choices variable without providing any flags or choices.
  14.410 +			//
  14.411 +			GDError(tr, "no %s specified", m_eType == ivFlags ? "flags" : "choices");
  14.412 +			return(FALSE);
  14.413 +		}
  14.414 +		return(TRUE);
  14.415 +	}
  14.416 +
  14.417 +	if (!GDSkipToken(tr, OPERATOR, "="))
  14.418 +	{
  14.419 +		return(FALSE);
  14.420 +	}
  14.421 +
  14.422 +	if (m_eType != ivFlags && m_eType != ivChoices)
  14.423 +	{
  14.424 +		GDError(tr, "didn't expect '=' here");
  14.425 +		return(FALSE);
  14.426 +	}
  14.427 +
  14.428 +	// should be '[' to start flags/choices
  14.429 +	if (!GDSkipToken(tr, OPERATOR, "["))
  14.430 +	{
  14.431 +		return(FALSE);
  14.432 +	}
  14.433 +
  14.434 +	// get flags?
  14.435 +	if (m_eType == ivFlags)
  14.436 +	{
  14.437 +		GDIVITEM ivi;
  14.438 +
  14.439 +		while (1)
  14.440 +		{
  14.441 +			ttype = tr.PeekTokenType();
  14.442 +			if (ttype != INTEGER)
  14.443 +			{
  14.444 +				break;
  14.445 +			}
  14.446 +
  14.447 +			// store bitflag value
  14.448 +			GDGetToken(tr, szToken, sizeof(szToken), INTEGER);
  14.449 +			sscanf( szToken, "%lu", &ivi.iValue );
  14.450 +
  14.451 +			// colon..
  14.452 +			if (!GDSkipToken(tr, OPERATOR, ":"))
  14.453 +			{
  14.454 +				return FALSE;
  14.455 +			}
  14.456 +
  14.457 +			// get description
  14.458 +			if (!GDGetToken(tr, szToken, sizeof(szToken), STRING))
  14.459 +			{
  14.460 +				return FALSE;
  14.461 +			}
  14.462 +			strcpy(ivi.szCaption, szToken);
  14.463 +
  14.464 +			// colon..
  14.465 +			if (!GDSkipToken(tr, OPERATOR, ":"))
  14.466 +			{
  14.467 +				return FALSE;
  14.468 +			}
  14.469 +
  14.470 +			// get default setting
  14.471 +			if (!GDGetToken(tr, szToken, sizeof(szToken), INTEGER))
  14.472 +			{
  14.473 +				return FALSE;
  14.474 +			}
  14.475 +			ivi.bDefault = atoi(szToken) ? TRUE : FALSE;
  14.476 +
  14.477 +			// add item to array of items
  14.478 +			m_Items.AddToTail(ivi);
  14.479 +		}
  14.480 +		
  14.481 +		// Set the default value.
  14.482 +		unsigned long nDefault = 0;
  14.483 +		for (int i = 0; i < m_Items.Count(); i++)
  14.484 +		{
  14.485 +			if (m_Items[i].bDefault)
  14.486 +				nDefault |= m_Items[i].iValue;
  14.487 +		}
  14.488 +		m_nDefault = (int)nDefault;
  14.489 +		Q_snprintf( m_szDefault, sizeof( m_szDefault ), "%d", m_nDefault );
  14.490 +	}
  14.491 +	else if (m_eType == ivChoices)
  14.492 +	{
  14.493 +		GDIVITEM ivi;
  14.494 +
  14.495 +		while (1)
  14.496 +		{
  14.497 +			ttype = tr.PeekTokenType();
  14.498 +			if ((ttype != INTEGER) && (ttype != STRING))
  14.499 +			{
  14.500 +				break;
  14.501 +			}
  14.502 +
  14.503 +			// store choice value
  14.504 +			GDGetToken(tr, szToken, sizeof(szToken), ttype);
  14.505 +			ivi.iValue = 0;
  14.506 +			strcpy(ivi.szValue, szToken);
  14.507 +
  14.508 +			// colon
  14.509 +			if (!GDSkipToken(tr, OPERATOR, ":"))
  14.510 +			{
  14.511 +				return FALSE;
  14.512 +			}
  14.513 +
  14.514 +			// get description
  14.515 +			if (!GDGetToken(tr, szToken, sizeof(szToken), STRING))
  14.516 +			{
  14.517 +				return FALSE;
  14.518 +			}
  14.519 +
  14.520 +			strcpy(ivi.szCaption, szToken);
  14.521 +
  14.522 +			m_Items.AddToTail(ivi);
  14.523 +		}
  14.524 +	}
  14.525 +
  14.526 +	if (!GDSkipToken(tr, OPERATOR, "]"))
  14.527 +	{
  14.528 +		return FALSE;
  14.529 +	}
  14.530 +
  14.531 +	return TRUE;
  14.532 +}
  14.533 +
  14.534 +
  14.535 +//-----------------------------------------------------------------------------
  14.536 +// Purpose: Decodes a key value from a string.
  14.537 +// Input  : pkv - Pointer to the key value object containing string encoded value.
  14.538 +//-----------------------------------------------------------------------------
  14.539 +void GDinputvariable::FromKeyValue(MDkeyvalue *pkv)
  14.540 +{
  14.541 +	trtoken_t eStoreAs = GetStoreAsFromType(m_eType);
  14.542 +
  14.543 +	if (eStoreAs == STRING)
  14.544 +	{
  14.545 +		strcpy(m_szValue, pkv->szValue);
  14.546 +	}
  14.547 +	else if (eStoreAs == INTEGER)
  14.548 +	{
  14.549 +		m_nValue = atoi(pkv->szValue);
  14.550 +	}
  14.551 +}
  14.552 +
  14.553 +
  14.554 +//-----------------------------------------------------------------------------
  14.555 +// Purpose: Determines whether the given flag is set (assuming this is an ivFlags).
  14.556 +// Input  : uCheck - Flag to check.
  14.557 +// Output : Returns TRUE if flag is set, FALSE if not.
  14.558 +//-----------------------------------------------------------------------------
  14.559 +BOOL GDinputvariable::IsFlagSet(unsigned int uCheck)
  14.560 +{
  14.561 +	Assert(m_eType == ivFlags);
  14.562 +	return (((unsigned int)m_nValue & uCheck) == uCheck) ? TRUE : FALSE;
  14.563 +}
  14.564 +
  14.565 +
  14.566 +//-----------------------------------------------------------------------------
  14.567 +// Purpose: Combines the flags or choices items from another variable into our
  14.568 +//			list of flags or choices. Ours take priority if collisions occur.
  14.569 +// Input  : Other - The variable whose items are being merged with ours.
  14.570 +//-----------------------------------------------------------------------------
  14.571 +void GDinputvariable::Merge(GDinputvariable &Other)
  14.572 +{
  14.573 +	//
  14.574 +	// Only valid if we are of the same type.
  14.575 +	//
  14.576 +	if (Other.GetType() != GetType())
  14.577 +	{
  14.578 +		return;
  14.579 +	}
  14.580 +
  14.581 +	//
  14.582 +	// Add Other's items to this ONLY if there is no same-value entry
  14.583 +	// for a specific item.
  14.584 +	//
  14.585 +	bool bFound = false;
  14.586 +	int nOurItems = m_Items.Count();
  14.587 +	for (int i = 0; i < Other.m_Items.Count(); i++)
  14.588 +	{
  14.589 +		GDIVITEM &TheirItem = Other.m_Items[i];
  14.590 +		for (int j = 0; j < nOurItems; j++)
  14.591 +		{
  14.592 +			GDIVITEM &OurItem = m_Items[j];
  14.593 +			if (TheirItem.iValue == OurItem.iValue)
  14.594 +			{
  14.595 +				bFound = true;
  14.596 +				break;
  14.597 +			}
  14.598 +		}
  14.599 +
  14.600 +		if (!bFound)
  14.601 +		{
  14.602 +			//
  14.603 +			// Not found in our list - add their item to our list.
  14.604 +			//
  14.605 +			m_Items.AddToTail(TheirItem);
  14.606 +		}
  14.607 +	}
  14.608 +}
  14.609 +
  14.610 +
  14.611 +//-----------------------------------------------------------------------------
  14.612 +// Purpose: Determines whether the given flag is set (assuming this is an ivFlags).
  14.613 +// Input  : uFlags - Flags to set.
  14.614 +//			bSet - TRUE to set the flags, FALSE to clear them.
  14.615 +//-----------------------------------------------------------------------------
  14.616 +void GDinputvariable::SetFlag(unsigned int uFlags, BOOL bSet)
  14.617 +{
  14.618 +	Assert(m_eType == ivFlags);
  14.619 +	if (bSet)
  14.620 +	{
  14.621 +		m_nValue |= uFlags;
  14.622 +	}
  14.623 +	else
  14.624 +	{
  14.625 +		m_nValue &= ~uFlags;
  14.626 +	}
  14.627 +}
  14.628 +
  14.629 +
  14.630 +//-----------------------------------------------------------------------------
  14.631 +// Purpose: Sets this keyvalue to its default value.
  14.632 +//-----------------------------------------------------------------------------
  14.633 +void GDinputvariable::ResetDefaults(void)
  14.634 +{
  14.635 +	if (m_eType == ivFlags)
  14.636 +	{
  14.637 +		m_nValue = 0;
  14.638 +
  14.639 +		//
  14.640 +		// Run thru flags and set any default flags.
  14.641 +		//
  14.642 +		int nCount = m_Items.Count();
  14.643 +		for (int i = 0; i < nCount; i++)
  14.644 +		{
  14.645 +			if (m_Items[i].bDefault)
  14.646 +			{
  14.647 +				m_nValue |= GetFlagMask(i);
  14.648 +			}
  14.649 +		}
  14.650 +	}
  14.651 +	else
  14.652 +	{
  14.653 +		m_nValue = m_nDefault;
  14.654 +		strcpy(m_szValue, m_szDefault);
  14.655 +	}
  14.656 +}
  14.657 +
  14.658 +
  14.659 +//-----------------------------------------------------------------------------
  14.660 +// Purpose: Encodes a key value as a string.
  14.661 +// Input  : pkv - Pointer to the key value object to receive the encoded string.
  14.662 +//-----------------------------------------------------------------------------
  14.663 +void GDinputvariable::ToKeyValue(MDkeyvalue *pkv)
  14.664 +{
  14.665 +	strcpy(pkv->szKey, m_szName);
  14.666 +
  14.667 +	trtoken_t eStoreAs = GetStoreAsFromType(m_eType);
  14.668 +
  14.669 +	if (eStoreAs == STRING)
  14.670 +	{
  14.671 +		strcpy(pkv->szValue, m_szValue);
  14.672 +	}
  14.673 +	else if (eStoreAs == INTEGER)
  14.674 +	{
  14.675 +		itoa(m_nValue, pkv->szValue, 10);
  14.676 +	}
  14.677 +}
  14.678 +
  14.679 +
  14.680 +//-----------------------------------------------------------------------------
  14.681 +// Purpose: Returns the description string that corresponds to a value string
  14.682 +//			for a choices list.
  14.683 +// Input  : pszString - The choices value string.
  14.684 +// Output : Returns the description string.
  14.685 +//-----------------------------------------------------------------------------
  14.686 +const char *GDinputvariable::ItemStringForValue(const char *szValue)
  14.687 +{
  14.688 +	int nCount = m_Items.Count();
  14.689 +	for (int i = 0; i < nCount; i++)
  14.690 +	{
  14.691 +		if (!stricmp(m_Items[i].szValue, szValue))
  14.692 +		{
  14.693 +			return(m_Items[i].szCaption);
  14.694 +		}
  14.695 +	}
  14.696 +
  14.697 +	return(NULL);
  14.698 +}
  14.699 +
  14.700 +
  14.701 +//-----------------------------------------------------------------------------
  14.702 +// Purpose: Returns the value string that corresponds to a description string
  14.703 +//			for a choices list.
  14.704 +// Input  : pszString - The choices description string.
  14.705 +// Output : Returns the value string.
  14.706 +//-----------------------------------------------------------------------------
  14.707 +const char *GDinputvariable::ItemValueForString(const char *szString)
  14.708 +{
  14.709 +	int nCount = m_Items.Count();
  14.710 +	for (int i = 0; i < nCount; i++)
  14.711 +	{
  14.712 +		if (!strcmpi(m_Items[i].szCaption, szString))
  14.713 +		{
  14.714 +			return(m_Items[i].szValue);
  14.715 +		}
  14.716 +	}
  14.717 +
  14.718 +	return(NULL);
  14.719 +}
  14.720 +
  14.721 +
  14.722 +//-----------------------------------------------------------------------------
  14.723 +// Purpose: this function will let you iterate through the text names of the variable types
  14.724 +// Input  : eType - the type to get the text of
  14.725 +// Output : returns the textual name
  14.726 +//-----------------------------------------------------------------------------
  14.727 +const char *GDinputvariable::GetVarTypeName( GDIV_TYPE eType )
  14.728 +{
  14.729 +	return TypeMap[ eType ].pszName;
  14.730 +}
  14.731 +
  14.732 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/fgdlib/inputoutput.cpp	Mon Sep 02 11:39:10 2013 -0700
    15.3 @@ -0,0 +1,171 @@
    15.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
    15.5 +//
    15.6 +// Purpose: 
    15.7 +//
    15.8 +//=============================================================================
    15.9 +
   15.10 +
   15.11 +#include <tier0/dbg.h>
   15.12 +#include "fgdlib/InputOutput.h"
   15.13 +
   15.14 +// memdbgon must be the last include file in a .cpp file!!!
   15.15 +#include <tier0/memdbgon.h>
   15.16 +
   15.17 +
   15.18 +typedef struct
   15.19 +{
   15.20 +	InputOutputType_t eType;	// The enumeration of this type.
   15.21 +	char *pszName;				// The name of this type.
   15.22 +} TypeMap_t;
   15.23 +
   15.24 +
   15.25 +char *CClassInputOutputBase::g_pszEmpty = "";
   15.26 +
   15.27 +
   15.28 +//-----------------------------------------------------------------------------
   15.29 +// Maps type names to type enums for inputs and outputs.
   15.30 +//-----------------------------------------------------------------------------
   15.31 +static TypeMap_t TypeMap[] =
   15.32 +{
   15.33 +	{ iotVoid,		"void" },
   15.34 +	{ iotInt,		"integer" },
   15.35 +	{ iotBool,		"bool" },
   15.36 +	{ iotString,	"string" },
   15.37 +	{ iotFloat,		"float" },
   15.38 +	{ iotVector,	"vector" },
   15.39 +	{ iotEHandle,	"target_destination" },
   15.40 +	{ iotColor,		"color255" },
   15.41 +	{ iotEHandle,	"ehandle" }, // for backwards compatibility
   15.42 +};
   15.43 +
   15.44 +
   15.45 +//-----------------------------------------------------------------------------
   15.46 +// Purpose: 
   15.47 +//-----------------------------------------------------------------------------
   15.48 +CClassInputOutputBase::CClassInputOutputBase(void)
   15.49 +{
   15.50 +	m_eType = iotInvalid;
   15.51 +	m_pszDescription = NULL;
   15.52 +}
   15.53 +
   15.54 +
   15.55 +//-----------------------------------------------------------------------------
   15.56 +// Purpose: 
   15.57 +// Input  : pszName - 
   15.58 +//			eType - 
   15.59 +//-----------------------------------------------------------------------------
   15.60 +CClassInputOutputBase::CClassInputOutputBase(const char *pszName, InputOutputType_t eType)
   15.61 +{
   15.62 +	m_pszDescription = NULL;
   15.63 +}
   15.64 +
   15.65 +
   15.66 +//-----------------------------------------------------------------------------
   15.67 +// Purpose: Destructor.
   15.68 +//-----------------------------------------------------------------------------
   15.69 +CClassInputOutputBase::~CClassInputOutputBase(void)
   15.70 +{
   15.71 +	delete m_pszDescription;
   15.72 +	m_pszDescription = NULL;
   15.73 +}
   15.74 +
   15.75 +
   15.76 +//-----------------------------------------------------------------------------
   15.77 +// Purpose: Returns a string representing the type of this I/O, eg. "integer".
   15.78 +//-----------------------------------------------------------------------------
   15.79 +const char *CClassInputOutputBase::GetTypeText(void)
   15.80 +{
   15.81 +	for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
   15.82 +	{
   15.83 +		if (TypeMap[i].eType == m_eType)
   15.84 +		{
   15.85 +			return(TypeMap[i].pszName);
   15.86 +		}
   15.87 +	}
   15.88 +
   15.89 +	return("unknown");
   15.90 +}
   15.91 +
   15.92 +
   15.93 +//-----------------------------------------------------------------------------
   15.94 +// Purpose: 
   15.95 +// Input  : szType - 
   15.96 +// Output : InputOutputType_t
   15.97 +//-----------------------------------------------------------------------------
   15.98 +InputOutputType_t CClassInputOutputBase::SetType(const char *szType)
   15.99 +{
  15.100 +	for (int i = 0; i < sizeof(TypeMap) / sizeof(TypeMap[0]); i++)
  15.101 +	{
  15.102 +		if (!stricmp(TypeMap[i].pszName, szType))
  15.103 +		{
  15.104 +			m_eType = TypeMap[i].eType;
  15.105 +			return(m_eType);
  15.106 +		}
  15.107 +	}
  15.108 +
  15.109 +	return(iotInvalid);
  15.110 +}
  15.111 +
  15.112 +
  15.113 +//-----------------------------------------------------------------------------
  15.114 +// Purpose: Assignment operator.
  15.115 +//-----------------------------------------------------------------------------
  15.116 +CClassInputOutputBase &CClassInputOutputBase::operator =(CClassInputOutputBase &Other)
  15.117 +{
  15.118 +	strcpy(m_szName, Other.m_szName);
  15.119 +	m_eType = Other.m_eType;
  15.120 +
  15.121 +	//
  15.122 +	// Copy the description.
  15.123 +	//
  15.124 +	delete m_pszDescription;
  15.125 +	if (Other.m_pszDescription != NULL)
  15.126 +	{
  15.127 +		m_pszDescription = new char[strlen(Other.m_pszDescription) + 1];
  15.128 +		strcpy(m_pszDescription, Other.m_pszDescription);
  15.129 +	}
  15.130 +	else
  15.131 +	{
  15.132 +		m_pszDescription = NULL;
  15.133 +	}
  15.134 +
  15.135 +	return(*this);
  15.136 +}
  15.137 +
  15.138 +
  15.139 +//-----------------------------------------------------------------------------
  15.140 +// Purpose: 
  15.141 +//-----------------------------------------------------------------------------
  15.142 +CClassInput::CClassInput(void)
  15.143 +{
  15.144 +}
  15.145 +
  15.146 +
  15.147 +//-----------------------------------------------------------------------------
  15.148 +// Purpose: 
  15.149 +// Input  : pszName - 
  15.150 +//			eType - 
  15.151 +//-----------------------------------------------------------------------------
  15.152 +CClassInput::CClassInput(const char *pszName, InputOutputType_t eType)
  15.153 +	: CClassInputOutputBase(pszName, eType)
  15.154 +{
  15.155 +}
  15.156 +
  15.157 +
  15.158 +//-----------------------------------------------------------------------------
  15.159 +// Purpose: 
  15.160 +//-----------------------------------------------------------------------------
  15.161 +CClassOutput::CClassOutput(void)
  15.162 +{
  15.163 +}
  15.164 +
  15.165 +
  15.166 +//-----------------------------------------------------------------------------
  15.167 +// Purpose: 
  15.168 +// Input  : pszName - 
  15.169 +//			eType - 
  15.170 +//-----------------------------------------------------------------------------
  15.171 +CClassOutput::CClassOutput(const char *pszName, InputOutputType_t eType)
  15.172 +	: CClassInputOutputBase(pszName, eType)
  15.173 +{
  15.174 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/fgdlib/wckeyvalues.cpp	Mon Sep 02 11:39:10 2013 -0700
    16.3 @@ -0,0 +1,282 @@
    16.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
    16.5 +//
    16.6 +// Purpose: 
    16.7 +//
    16.8 +//=============================================================================
    16.9 +
   16.10 +#include "fgdlib/WCKeyValues.h"
   16.11 +
   16.12 +// memdbgon must be the last include file in a .cpp file!!!
   16.13 +#include <tier0/memdbgon.h>
   16.14 +
   16.15 +
   16.16 +//-----------------------------------------------------------------------------
   16.17 +// Purpose: Destructor.
   16.18 +//-----------------------------------------------------------------------------
   16.19 +MDkeyvalue::~MDkeyvalue(void)
   16.20 +{
   16.21 +}
   16.22 +
   16.23 +
   16.24 +//-----------------------------------------------------------------------------
   16.25 +// Purpose: Assignment operator.
   16.26 +//-----------------------------------------------------------------------------
   16.27 +MDkeyvalue &MDkeyvalue::operator =(const MDkeyvalue &other)
   16.28 +{
   16.29 +	V_strcpy_safe(szKey, other.szKey);
   16.30 +	V_strcpy_safe(szValue, other.szValue);
   16.31 +
   16.32 +	return(*this);
   16.33 +}
   16.34 +
   16.35 +//-----------------------------------------------------------------------------
   16.36 +//-----------------------------------------------------------------------------
   16.37 +void WCKVBase_Vector::RemoveKeyAt(int nIndex)
   16.38 +{
   16.39 +	Assert(nIndex >= 0);
   16.40 +	Assert(nIndex < (int)m_KeyValues.Count());
   16.41 +
   16.42 +	if ((nIndex >= 0) && (nIndex < (int)m_KeyValues.Count()))
   16.43 +	{
   16.44 +		m_KeyValues.Remove(nIndex);
   16.45 +	}
   16.46 +}
   16.47 +
   16.48 +//-----------------------------------------------------------------------------
   16.49 +// Purpose: Adds the key to the keyvalue array. Allows duplicate keys.
   16.50 +//
   16.51 +//			NOTE: This should only be used for keyvalue lists that do not require
   16.52 +//			unique key names! If you use this function then you should use GetCount
   16.53 +//			and GetKey/Value by index rather than GetValue by key name.
   16.54 +//-----------------------------------------------------------------------------
   16.55 +void WCKVBase_Vector::AddKeyValue(const char *pszKey, const char *pszValue)
   16.56 +{
   16.57 +	if (!pszKey || !pszValue)
   16.58 +	{
   16.59 +		return;
   16.60 +	}
   16.61 +
   16.62 +	char szTmpKey[KEYVALUE_MAX_KEY_LENGTH];
   16.63 +	char szTmpValue[KEYVALUE_MAX_VALUE_LENGTH];
   16.64 +
   16.65 +	V_strcpy_safe(szTmpKey, pszKey);
   16.66 +	V_strcpy_safe(szTmpValue, pszValue);
   16.67 +
   16.68 +	StripEdgeWhiteSpace(szTmpKey);
   16.69 +	StripEdgeWhiteSpace(szTmpValue);
   16.70 +
   16.71 +	//
   16.72 +	// Add the keyvalue to our list.
   16.73 +	//
   16.74 +	MDkeyvalue newkv;
   16.75 +	V_strcpy_safe(newkv.szKey, szTmpKey);
   16.76 +	V_strcpy_safe(newkv.szValue, szTmpValue);
   16.77 +	m_KeyValues.AddToTail(newkv);
   16.78 +}
   16.79 +
   16.80 +int WCKVBase_Vector::FindByKeyName( const char *pKeyName ) const
   16.81 +{
   16.82 +	for ( int i=0; i < m_KeyValues.Count(); i++ )
   16.83 +	{
   16.84 +		if ( V_stricmp( m_KeyValues[i].szKey, pKeyName ) == 0 )
   16.85 +			return i;
   16.86 +	}
   16.87 +	return GetInvalidIndex();
   16.88 +}
   16.89 +
   16.90 +void WCKVBase_Vector::InsertKeyValue( const MDkeyvalue &kv )
   16.91 +{
   16.92 +	m_KeyValues.AddToTail( kv );
   16.93 +}
   16.94 +
   16.95 +
   16.96 +//-----------------------------------------------------------------------------
   16.97 +//-----------------------------------------------------------------------------
   16.98 +void WCKVBase_Dict::RemoveKeyAt(int nIndex)
   16.99 +{
  16.100 +	m_KeyValues.RemoveAt(nIndex);
  16.101 +}
  16.102 +
  16.103 +
  16.104 +int WCKVBase_Dict::FindByKeyName( const char *pKeyName ) const
  16.105 +{
  16.106 +	return m_KeyValues.Find( pKeyName );
  16.107 +}
  16.108 +
  16.109 +void WCKVBase_Dict::InsertKeyValue( const MDkeyvalue &kv )
  16.110 +{
  16.111 +	m_KeyValues.Insert( kv.szKey, kv );
  16.112 +}
  16.113 +
  16.114 +
  16.115 +//-----------------------------------------------------------------------------
  16.116 +// Purpose: Constructor. Sets the initial size of the keyvalue array.
  16.117 +//-----------------------------------------------------------------------------
  16.118 +template<class Base>
  16.119 +WCKeyValuesT<Base>::WCKeyValuesT(void)
  16.120 +{
  16.121 +}
  16.122 +
  16.123 +
  16.124 +//-----------------------------------------------------------------------------
  16.125 +// Purpose: Destructor. Deletes the contents of this keyvalue array.
  16.126 +//-----------------------------------------------------------------------------
  16.127 +template<class Base>
  16.128 +WCKeyValuesT<Base>::~WCKeyValuesT(void)
  16.129 +{
  16.130 +	//int i = 0;
  16.131 +	//while (i < m_KeyValues.GetSize())
  16.132 +	//{
  16.133 +	//	delete m_KeyValues.GetAt(i++);
  16.134 +	//}
  16.135 +
  16.136 +	RemoveAll();
  16.137 +}
  16.138 +
  16.139 +
  16.140 +//-----------------------------------------------------------------------------
  16.141 +//-----------------------------------------------------------------------------
  16.142 +template<class Base>
  16.143 +const char *WCKeyValuesT<Base>::GetValue(const char *pszKey, int *piIndex) const
  16.144 +{
  16.145 +	int i = FindByKeyName( pszKey );
  16.146 +	if ( i == GetInvalidIndex() )
  16.147 +	{
  16.148 +		return NULL;
  16.149 +	}
  16.150 +	else
  16.151 +	{
  16.152 +		if(piIndex)
  16.153 +			piIndex[0] = i;
  16.154 +			
  16.155 +		return m_KeyValues[i].szValue;
  16.156 +	}
  16.157 +}
  16.158 +
  16.159 +
  16.160 +//-----------------------------------------------------------------------------
  16.161 +//-----------------------------------------------------------------------------
  16.162 +template<class Base>
  16.163 +void WCKeyValuesT<Base>::RemoveKey(const char *pszKey)
  16.164 +{
  16.165 +	SetValue(pszKey, (const char *)NULL);
  16.166 +}
  16.167 +
  16.168 +
  16.169 +//-----------------------------------------------------------------------------
  16.170 +//-----------------------------------------------------------------------------
  16.171 +template<class Base>
  16.172 +void WCKeyValuesT<Base>::SetValue(const char *pszKey, int iValue)
  16.173 +{
  16.174 +	char szValue[100];
  16.175 +	itoa(iValue, szValue, 10);
  16.176 +
  16.177 +	SetValue(pszKey, szValue);
  16.178 +}
  16.179 +
  16.180 +
  16.181 +//-----------------------------------------------------------------------------
  16.182 +// Purpose: Strips leading and trailing whitespace from the string.
  16.183 +// Input  : psz - 
  16.184 +//-----------------------------------------------------------------------------
  16.185 +void StripEdgeWhiteSpace(char *psz)
  16.186 +{
  16.187 +	if (!psz || !*psz)
  16.188 +		return;
  16.189 +
  16.190 +	char *pszBase = psz;
  16.191 +
  16.192 +	while (V_isspace(*psz))
  16.193 +	{
  16.194 +		psz++;
  16.195 +	}
  16.196 +
  16.197 +	int iLen = strlen(psz) - 1;
  16.198 +	
  16.199 +	if ( iLen >= 0 )
  16.200 +	{
  16.201 +		while (V_isspace(psz[iLen]))
  16.202 +		{
  16.203 +			psz[iLen--] = 0;
  16.204 +		}
  16.205 +	}
  16.206 +
  16.207 +	if (psz != pszBase)
  16.208 +	{
  16.209 +		memmove(pszBase, psz, iLen + 2);
  16.210 +	}
  16.211 +}
  16.212 +
  16.213 +
  16.214 +//-----------------------------------------------------------------------------
  16.215 +// Purpose: 
  16.216 +// Input  : pszKey - 
  16.217 +//			pszValue - 
  16.218 +//-----------------------------------------------------------------------------
  16.219 +template<class Base>
  16.220 +void WCKeyValuesT<Base>::SetValue(const char *pszKey, const char *pszValue)
  16.221 +{
  16.222 +	char szTmpKey[KEYVALUE_MAX_KEY_LENGTH];
  16.223 +	char szTmpValue[KEYVALUE_MAX_VALUE_LENGTH];
  16.224 +
  16.225 +	V_strcpy_safe(szTmpKey, pszKey);
  16.226 +
  16.227 +	if (pszValue != NULL)
  16.228 +	{
  16.229 +		V_strcpy_safe(szTmpValue, pszValue);
  16.230 +	}
  16.231 +	else
  16.232 +	{
  16.233 +		szTmpValue[0] = 0;
  16.234 +	}
  16.235 +
  16.236 +	StripEdgeWhiteSpace(szTmpKey);
  16.237 +	StripEdgeWhiteSpace(szTmpValue);
  16.238 +
  16.239 +	int i = FindByKeyName( szTmpKey );
  16.240 +	if ( i == GetInvalidIndex() )
  16.241 +	{
  16.242 +		if ( pszValue )
  16.243 +		{
  16.244 +			//
  16.245 +			// Add the keyvalue to our list.
  16.246 +			//
  16.247 +			MDkeyvalue newkv;
  16.248 +			Q_strncpy( newkv.szKey, szTmpKey, sizeof( newkv.szKey ) );
  16.249 +			Q_strncpy( newkv.szValue, szTmpValue, sizeof( newkv.szValue ) );
  16.250 +			InsertKeyValue( newkv );
  16.251 +		}
  16.252 +	}
  16.253 +	else
  16.254 +	{
  16.255 +		if (pszValue != NULL)
  16.256 +		{
  16.257 +			V_strncpy(m_KeyValues[i].szValue, szTmpValue, sizeof(m_KeyValues[i].szValue));
  16.258 +		}
  16.259 +		//
  16.260 +		// If we are setting to a NULL value, delete the key.
  16.261 +		//
  16.262 +		else
  16.263 +		{
  16.264 +			RemoveKeyAt( i );
  16.265 +		}
  16.266 +	}
  16.267 +}
  16.268 +
  16.269 +
  16.270 +//-----------------------------------------------------------------------------
  16.271 +// Purpose: 
  16.272 +//-----------------------------------------------------------------------------
  16.273 +template<class Base>
  16.274 +void WCKeyValuesT<Base>::RemoveAll(void)
  16.275 +{
  16.276 +	m_KeyValues.RemoveAll();
  16.277 +}
  16.278 +
  16.279 +
  16.280 +// Explicit instantiations.
  16.281 +template class WCKeyValuesT<WCKVBase_Dict>;
  16.282 +template class WCKeyValuesT<WCKVBase_Vector>;
  16.283 +
  16.284 +
  16.285 +
    17.1 --- a/game/client/c_baseentity.cpp	Tue Jul 30 15:10:15 2013 -0700
    17.2 +++ b/game/client/c_baseentity.cpp	Mon Sep 02 11:39:10 2013 -0700
    17.3 @@ -2462,27 +2462,36 @@
    17.4  void C_BaseEntity::ValidateModelIndex( void )
    17.5  {
    17.6  #ifdef TF_CLIENT_DLL
    17.7 -	if ( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_DEFAULT] > 0 ) 
    17.8 +	if ( m_nModelIndexOverrides[VISION_MODE_NONE] > 0 ) 
    17.9  	{
   17.10  		if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_HALLOWEEN ) )
   17.11  		{
   17.12 -			if ( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_HALLOWEEN] > 0 )
   17.13 +			if ( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] > 0 )
   17.14  			{
   17.15 -				SetModelByIndex( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_HALLOWEEN] );
   17.16 +				SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] );
   17.17  				return;
   17.18  			}
   17.19  		}
   17.20  		
   17.21  		if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_PYRO ) )
   17.22  		{
   17.23 -			if ( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_PYRO] > 0 )
   17.24 +			if ( m_nModelIndexOverrides[VISION_MODE_PYRO] > 0 )
   17.25  			{
   17.26 -				SetModelByIndex( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_PYRO] );
   17.27 +				SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_PYRO] );
   17.28  				return;
   17.29  			}
   17.30  		}
   17.31  
   17.32 -		SetModelByIndex( m_nModelIndexOverrides[MODEL_INDEX_OVERRIDE_DEFAULT] );		
   17.33 +		if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_ROME ) )
   17.34 +		{
   17.35 +			if ( m_nModelIndexOverrides[VISION_MODE_ROME] > 0 )
   17.36 +			{
   17.37 +				SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_ROME] );
   17.38 +				return;
   17.39 +			}
   17.40 +		}
   17.41 +
   17.42 +		SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_NONE] );		
   17.43  
   17.44  		return;
   17.45  	}
   17.46 @@ -3597,6 +3606,48 @@
   17.47  	}
   17.48  }
   17.49  
   17.50 +//-----------------------------------------------------------------------------
   17.51 +void C_BaseEntity::AddColoredStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, 
   17.52 +	bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal )
   17.53 +{
   17.54 +	if (doTrace)
   17.55 +	{
   17.56 +		enginetrace->ClipRayToEntity( ray, MASK_SHOT, this, &tr );
   17.57 +
   17.58 +		// Trace the ray against the entity
   17.59 +		if (tr.fraction == 1.0f)
   17.60 +			return;
   17.61 +
   17.62 +		// Set the trace index appropriately...
   17.63 +		tr.m_pEnt = this;
   17.64 +	}
   17.65 +
   17.66 +	// Exit out after doing the trace so any other effects that want to happen can happen.
   17.67 +	if ( !r_drawmodeldecals.GetBool() )
   17.68 +		return;
   17.69 +
   17.70 +	// Found the point, now lets apply the decals
   17.71 +	CreateModelInstance();
   17.72 +
   17.73 +	// FIXME: Pass in decal up?
   17.74 +	Vector up(0, 0, 1);
   17.75 +
   17.76 +	if (doTrace && (GetSolid() == SOLID_VPHYSICS) && !tr.startsolid && !tr.allsolid)
   17.77 +	{
   17.78 +		// Choose a more accurate normal direction
   17.79 +		// Also, since we have more accurate info, we can avoid pokethru
   17.80 +		Vector temp;
   17.81 +		VectorSubtract( tr.endpos, tr.plane.normal, temp );
   17.82 +		Ray_t betterRay;
   17.83 +		betterRay.Init( tr.endpos, temp );
   17.84 +		modelrender->AddColoredDecal( m_ModelInstance, betterRay, up, decalIndex, GetStudioBody(), cColor, true, maxLODToDecal );
   17.85 +	}
   17.86 +	else
   17.87 +	{
   17.88 +		modelrender->AddColoredDecal( m_ModelInstance, ray, up, decalIndex, GetStudioBody(), cColor, false, maxLODToDecal );
   17.89 +	}
   17.90 +}
   17.91 +
   17.92  
   17.93  //-----------------------------------------------------------------------------
   17.94  // This method works when we've got a brush model
   17.95 @@ -3648,6 +3699,56 @@
   17.96  }
   17.97  
   17.98  //-----------------------------------------------------------------------------
   17.99 +void C_BaseEntity::AddColoredDecal( const Vector& rayStart, const Vector& rayEnd,
  17.100 +	const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal )
  17.101 +{
  17.102 +	Ray_t ray;
  17.103 +	ray.Init( rayStart, rayEnd );
  17.104 +	
  17.105 +	// FIXME: Better bloat?
  17.106 +	// Bloat a little bit so we get the intersection
  17.107 +	ray.m_Delta *= 1.1f;
  17.108 +
  17.109 +	int modelType = modelinfo->GetModelType( model );
  17.110 +	if ( doTrace )
  17.111 +	{
  17.112 +		enginetrace->ClipRayToEntity( ray, MASK_SHOT, this, &tr );
  17.113 +		switch ( modelType )
  17.114 +		{
  17.115 +		case mod_studio:
  17.116 +			tr.m_pEnt = this;
  17.117 +			break;
  17.118 +		case mod_brush:
  17.119 +			if ( tr.fraction == 1.0f )
  17.120 +				return;		// Explicitly end
  17.121 +		default:
  17.122 +			// By default, no collision
  17.123 +			tr.fraction = 1.0f;
  17.124 +			break;
  17.125 +		}
  17.126 +	}
  17.127 +
  17.128 +	switch ( modelType )
  17.129 +	{
  17.130 +	case mod_studio:
  17.131 +		AddColoredStudioDecal( ray, hitbox, decalIndex, doTrace, tr, cColor, maxLODToDecal );
  17.132 +		break;
  17.133 +
  17.134 +	case mod_brush:
  17.135 +		{
  17.136 +			color32 cColor32 = { cColor.r(), cColor.g(), cColor.b(), cColor.a() };
  17.137 +			effects->DecalColorShoot( decalIndex, index, model, GetAbsOrigin(), GetAbsAngles(), decalCenter, 0, 0, cColor32 );
  17.138 +		}
  17.139 +		break;
  17.140 +
  17.141 +	default:
  17.142 +		// By default, no collision
  17.143 +		tr.fraction = 1.0f;
  17.144 +		break;
  17.145 +	}
  17.146 +}
  17.147 +
  17.148 +//-----------------------------------------------------------------------------
  17.149  // A method to remove all decals from an entity
  17.150  //-----------------------------------------------------------------------------
  17.151  void C_BaseEntity::RemoveAllDecals( void )
    18.1 --- a/game/client/c_baseentity.h	Tue Jul 30 15:10:15 2013 -0700
    18.2 +++ b/game/client/c_baseentity.h	Mon Sep 02 11:39:10 2013 -0700
    18.3 @@ -770,6 +770,10 @@
    18.4  	// A method to apply a decal to an entity
    18.5  	virtual void					AddDecal( const Vector& rayStart, const Vector& rayEnd,
    18.6  										const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
    18.7 +
    18.8 +	virtual void					AddColoredDecal( const Vector& rayStart, const Vector& rayEnd,
    18.9 +		const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
   18.10 +
   18.11  	// A method to remove all decals from an entity
   18.12  	void							RemoveAllDecals( void );
   18.13  
   18.14 @@ -1317,7 +1321,7 @@
   18.15  	short							m_nModelIndex;
   18.16  
   18.17  #ifdef TF_CLIENT_DLL
   18.18 -	int								m_nModelIndexOverrides[MAX_MODEL_INDEX_OVERRIDES];
   18.19 +	int								m_nModelIndexOverrides[MAX_VISION_MODES];
   18.20  #endif
   18.21  
   18.22  	char							m_takedamage;
   18.23 @@ -1464,6 +1468,7 @@
   18.24  
   18.25  	// methods related to decal adding
   18.26  	void AddStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
   18.27 +	void AddColoredStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, bool doTrace, trace_t& tr, Color cColor, int maxLODToDecal );
   18.28  	void AddBrushModelDecal( const Ray_t& ray, const Vector& decalCenter, int decalIndex, bool doTrace, trace_t& tr );
   18.29  
   18.30  	void ComputePackedOffsets( void );
    19.1 --- a/game/client/c_baseplayer.cpp	Tue Jul 30 15:10:15 2013 -0700
    19.2 +++ b/game/client/c_baseplayer.cpp	Mon Sep 02 11:39:10 2013 -0700
    19.3 @@ -2178,7 +2178,7 @@
    19.4  	if ( !filesystem->FileExists( fullsoundname ) )
    19.5  	{
    19.6  		char custname[ 512 ];
    19.7 -		Q_snprintf( custname, sizeof( custname ), "downloads/%s.dat", soundhex );
    19.8 +		Q_snprintf( custname, sizeof( custname ), "download/user_custom/%c%c/%s.dat", soundhex[0], soundhex[1], soundhex );
    19.9  		// it may have been downloaded but not copied under materials folder
   19.10  		if ( !filesystem->FileExists( custname ) )
   19.11  			return; // not downloaded yet
    20.1 --- a/game/client/cdll_client_int.cpp	Tue Jul 30 15:10:15 2013 -0700
    20.2 +++ b/game/client/cdll_client_int.cpp	Mon Sep 02 11:39:10 2013 -0700
    20.3 @@ -116,6 +116,7 @@
    20.4  #include "rtime.h"
    20.5  #include "tf_hud_disconnect_prompt.h"
    20.6  #include "../engine/audio/public/sound.h"
    20.7 +#include "tf_shared_content_manager.h"
    20.8  #endif
    20.9  #include "clientsteamcontext.h"
   20.10  #include "renamed_recvtable_compat.h"
   20.11 @@ -1018,6 +1019,7 @@
   20.12  	
   20.13  	#if defined( TF_CLIENT_DLL )
   20.14  	IGameSystem::Add( CustomTextureToolCacheGameSystem() );
   20.15 +	IGameSystem::Add( TFSharedContentManager() );
   20.16  	#endif
   20.17  
   20.18  #if defined( TF_CLIENT_DLL )
    21.1 --- a/game/client/client_base.vpc	Tue Jul 30 15:10:15 2013 -0700
    21.2 +++ b/game/client/client_base.vpc	Mon Sep 02 11:39:10 2013 -0700
    21.3 @@ -44,14 +44,18 @@
    21.4  
    21.5  $Configuration
    21.6  {
    21.7 +	$General
    21.8 +	{
    21.9 +			$OutputDirectory			".\$GAMENAME"		[$OSXALL]
   21.10 +	}
   21.11 +
   21.12  	$Compiler
   21.13  	{
   21.14  		$AdditionalIncludeDirectories	".\;$BASE;$SRCDIR\vgui2\include;$SRCDIR\vgui2\controls;$SRCDIR\game\shared;.\game_controls;$SRCDIR\thirdparty\sixensesdk\include"
   21.15  		$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" 
   21.16  		$PreprocessorDefinitions		"$BASE;ENABLE_CHROMEHTMLWINDOW;fopen=dont_use_fopen" [$WIN32]
   21.17  		$PreprocessorDefinitions		"$BASE;ENABLE_CHROMEHTMLWINDOW;" [$OSXALL]
   21.18 -		$PreprocessorDefinitions		"$BASE;ENABLE_CHROMEHTMLWINDOW;" [$LINUX]
   21.19 -		$PreprocessorDefinitions		"$BASE;USE_WEBM_FOR_REPLAY" [$LINUX]
   21.20 +		$PreprocessorDefinitions		"$BASE;ENABLE_CHROMEHTMLWINDOW;USE_WEBM_FOR_REPLAY;" [$LINUXALL]
   21.21  		$PreprocessorDefinitions		"$BASE;CURL_STATICLIB" [$WIN32 && $BUILD_REPLAY]
   21.22  		$Create/UsePrecompiledHeader	"Use Precompiled Header (/Yu)"
   21.23  		$Create/UsePCHThroughFile		"cbase.h"
   21.24 @@ -1232,55 +1236,7 @@
   21.25  		$File	"game_controls\IconPanel.h"
   21.26  	}
   21.27  	
   21.28 -	$Folder	"Link Libraries" [$WIN32]
   21.29 -	{
   21.30 -		$DynamicFile	"$SRCDIR\lib\public\bitmap.lib"
   21.31 -		$DynamicFile	"$SRCDIR\lib\public\choreoobjects.lib"
   21.32 -		$DynamicFile	"$SRCDIR\lib\public\dmxloader.lib"
   21.33 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
   21.34 -		$DynamicFile	"$SRCDIR\lib\public\matsys_controls.lib"
   21.35 -		$DynamicFile	"$SRCDIR\lib\public\particles.lib"
   21.36 -		$DynamicFile	"$SRCDIR\lib\public\tier1.lib"
   21.37 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
   21.38 -		$DynamicFile	"$SRCDIR\lib\public\tier3.lib"
   21.39 -		$DynamicFile	"$SRCDIR\lib\public\vgui_controls.lib"
   21.40 -		$DynamicFile	"$SRCDIR\lib\public\steam_api.lib"
   21.41 -		$DynamicFile	"$SRCDIR\lib\public\vtf.lib"
   21.42 -		$DynamicFile	"$SRCDIR\lib\win32\release\libcurl.lib"	[$BUILD_REPLAY]
   21.43 -	}
   21.44 -
   21.45 -	$Folder	"Link Libraries" [$X360]
   21.46 -	{
   21.47 -		$DynamicFile	"$SRCDIR\lib\public\bitmap_360.lib"
   21.48 -		$DynamicFile	"$SRCDIR\lib\public\choreoobjects_360.lib"
   21.49 -		$DynamicFile	"$SRCDIR\lib\public\dmxloader_360.lib"
   21.50 -		$DynamicFile	"$SRCDIR\lib\public\mathlib_360.lib"
   21.51 -		$DynamicFile	"$SRCDIR\lib\public\matsys_controls_360.lib"
   21.52 -		$DynamicFile	"$SRCDIR\lib\public\particles_360.lib"
   21.53 -		$DynamicFile	"$SRCDIR\lib\public\tier1_360.lib"
   21.54 -		$DynamicFile	"$SRCDIR\lib\public\tier2_360.lib"
   21.55 -		$DynamicFile	"$SRCDIR\lib\public\tier3_360.lib"
   21.56 -		$DynamicFile	"$SRCDIR\lib\public\vgui_controls_360.lib"
   21.57 -	}
   21.58 -	
   21.59 -	$Folder	"Link Libraries" [$POSIX && !$LINUX]
   21.60 -	{
   21.61 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\libcurl$_IMPLIB_EXT"	
   21.62 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\bitmap$_STATICLIB_EXT"
   21.63 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\choreoobjects$_STATICLIB_EXT"
   21.64 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\dmxloader$_STATICLIB_EXT"
   21.65 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\mathlib$_STATICLIB_EXT"
   21.66 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\matsys_controls$_STATICLIB_EXT"
   21.67 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\particles$_STATICLIB_EXT"
   21.68 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\tier1$_STATICLIB_EXT"
   21.69 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\tier2$_STATICLIB_EXT"
   21.70 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\tier3$_STATICLIB_EXT"
   21.71 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\vgui_controls$_STATICLIB_EXT"
   21.72 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_IMPLIB_EXT"
   21.73 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\vtf$_STATICLIB_EXT" 
   21.74 - 	}
   21.75 -
   21.76 -	$Folder	"Link Libraries" [$LINUX]
   21.77 +	$Folder	"Link Libraries"
   21.78  	{
   21.79  		$Lib		bitmap
   21.80  		$Lib		choreoobjects
   21.81 @@ -1292,12 +1248,20 @@
   21.82  		$Lib		tier2
   21.83  		$Lib		tier3
   21.84  		$Lib		vgui_controls
   21.85 -		$Lib		vtf 
   21.86 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_IMPLIB_EXT"
   21.87 -		$DynamicFile	"$SRCDIR/lib/linux32/libcurl$_STATICLIB_EXT" [$DEDICATED]
   21.88 -		$DynamicFile	"$SRCDIR/lib/linux32/libcurlssl$_STATICLIB_EXT" [!$DEDICATED]
   21.89 -		$DynamicFile	"$SRCDIR/lib/linux32/libssl$_STATICLIB_EXT" [!$DEDICATED]
   21.90 -		$DynamicFile	"$SRCDIR/lib/linux32/release/libcrypto$_STATICLIB_EXT" [!$DEDICATED]
   21.91 +		$Lib		vtf
   21.92 +		$ImpLib		steam_api
   21.93 +		
   21.94 +		$Lib $LIBCOMMON/libcrypto [$POSIX]
   21.95 +
   21.96 +		$ImpLib	"$LIBCOMMON\curl"	  [$OSXALL]
   21.97 +
   21.98 +		$Lib	"$LIBCOMMON\libcurl" [$WIN32]
   21.99 +		$Lib   "libz" [$WIN32]
  21.100 +
  21.101 +		$Libexternal	libz [$LINUXALL]
  21.102 +		$Libexternal "$LIBCOMMON/libcurl" [$LINUXALL]
  21.103 +		$Libexternal "$LIBCOMMON/libcurlssl" [$LINUXALL]
  21.104 +		$Libexternal "$LIBCOMMON/libssl" [$LINUXALL]
  21.105   	}
  21.106  
  21.107  }
    22.1 --- a/game/client/client_hl2mp.vpc	Tue Jul 30 15:10:15 2013 -0700
    22.2 +++ b/game/client/client_hl2mp.vpc	Mon Sep 02 11:39:10 2013 -0700
    22.3 @@ -10,9 +10,6 @@
    22.4  
    22.5  $Include "$SRCDIR\game\client\client_base.vpc"
    22.6  
    22.7 -$macro VSLIBDIR  "." [!$VS2010]
    22.8 -$macro VSLIBDIR  "VS2010" [$VS2010]
    22.9 -
   22.10  $Configuration
   22.11  {
   22.12  	$Compiler
   22.13 @@ -174,16 +171,4 @@
   22.14  			}
   22.15  		}
   22.16  	}
   22.17 -	$Folder "Libraries"
   22.18 -	{
   22.19 -		$File "$SRCDIR\lib\$PLATFORM\release\$VSLIBDIR\libprotobuf.lib" [$WINDOWS]
   22.20 -		{
   22.21 -			$Configuration "Debug" { $ExcludedFromBuild	"Yes" }
   22.22 -		}
   22.23 -		$File "$SRCDIR\lib\$PLATFORM\debug\$VSLIBDIR\libprotobuf.lib" [$WINDOWS]
   22.24 -		{
   22.25 -			$Configuration "Release" { $ExcludedFromBuild "Yes" }
   22.26 -		}
   22.27 -		$File "$SRCDIR\lib\$PLATFORM\release\libprotobuf.a"         [$POSIX]
   22.28 -	}
   22.29  }
    23.1 --- a/game/client/death.cpp	Tue Jul 30 15:10:15 2013 -0700
    23.2 +++ b/game/client/death.cpp	Mon Sep 02 11:39:10 2013 -0700
    23.3 @@ -289,7 +289,7 @@
    23.4  		if ( !strcmp( killedwith+2, "gauss" ) )
    23.5  			Q_strncpy( killedwith, "d_tau cannon", sizeof( killedwith ) );
    23.6  
    23.7 -		Msg( killedwith+2 ); // skip over the "d_" part
    23.8 +		Msg( "%s", killedwith+2 ); // skip over the "d_" part
    23.9  	}
   23.10  
   23.11  	Msg( "\n" );
    24.1 --- a/game/protobuf_include.vpc	Tue Jul 30 15:10:15 2013 -0700
    24.2 +++ b/game/protobuf_include.vpc	Mon Sep 02 11:39:10 2013 -0700
    24.3 @@ -6,25 +6,10 @@
    24.4  
    24.5  $MacroRequired "PLATFORM"
    24.6  
    24.7 -$macro VSLIBDIR  "." [!$VS2010]
    24.8 -$macro VSLIBDIR  "VS2010" [$VS2010]
    24.9 -
   24.10  $Project
   24.11  {
   24.12  	$Folder "Libraries"
   24.13  	{
   24.14 -		// Always use the release version of libprotobuf.lib because the debug
   24.15 -		// version uses iterator debugging, which is incompatible with the rest of
   24.16 -		// the Valve world.
   24.17 -		$File "$SRCDIR\lib\$PLATFORM\release\$VSLIBDIR\libprotobuf.lib" [$WINDOWS && $VS2010]
   24.18 -		$File "$SRCDIR\lib\$PLATFORM\release\$VSLIBDIR\libprotobuf.lib" [$WINDOWS && !$VS2010]
   24.19 -		{
   24.20 -			$Configuration "Debug" { $ExcludedFromBuild	"Yes" }
   24.21 -		}
   24.22 -		$File "$SRCDIR\lib\$PLATFORM\debug\$VSLIBDIR\libprotobuf.lib" [$WINDOWS && !$VS2010]
   24.23 -		{
   24.24 -			$Configuration "Release" { $ExcludedFromBuild "Yes" }
   24.25 -		}
   24.26 -		$File "$SRCDIR\lib\$PLATFORM\release\libprotobuf.a"         [$POSIX]
   24.27 +		$Libexternal libprotobuf
   24.28  	}
   24.29  }
    25.1 --- a/game/server/ai_behavior_lead.cpp	Tue Jul 30 15:10:15 2013 -0700
    25.2 +++ b/game/server/ai_behavior_lead.cpp	Mon Sep 02 11:39:10 2013 -0700
    25.3 @@ -3,7 +3,8 @@
    25.4  // Purpose:
    25.5  //
    25.6  //=============================================================================//
    25.7 -
    25.8 +#undef strncpy // we use std::string below that needs a good strncpy define
    25.9 +#undef sprintf // "
   25.10  #include "cbase.h"
   25.11  
   25.12  #include "ai_behavior_lead.h"
    26.1 --- a/game/server/ai_networkmanager.cpp	Tue Jul 30 15:10:15 2013 -0700
    26.2 +++ b/game/server/ai_networkmanager.cpp	Mon Sep 02 11:39:10 2013 -0700
    26.3 @@ -48,7 +48,7 @@
    26.4  		Q_vsnprintf( string, sizeof(string), pszFormat, argptr );
    26.5  		va_end( argptr );
    26.6  
    26.7 -		DevMsg( string );
    26.8 +		DevMsg( "%s", string );
    26.9  	}
   26.10  }
   26.11  
    27.1 --- a/game/server/ai_tacticalservices.cpp	Tue Jul 30 15:10:15 2013 -0700
    27.2 +++ b/game/server/ai_tacticalservices.cpp	Mon Sep 02 11:39:10 2013 -0700
    27.3 @@ -347,7 +347,7 @@
    27.4  
    27.5  	MARK_TASK_EXPENSIVE();
    27.6  
    27.7 -	DebugFindCover( g_AIDebugFindCoverNode, GetOuter()->EyePosition(), vThreatEyePos, 0, 255, 255 );
    27.8 +	DebugFindCover( NO_NODE, GetOuter()->EyePosition(), vThreatEyePos, 0, 255, 255 );
    27.9  
   27.10  	int iMyNode = GetPathfinder()->NearestNodeToPoint( vNearPos );
   27.11  
    28.1 --- a/game/server/baseentity.cpp	Tue Jul 30 15:10:15 2013 -0700
    28.2 +++ b/game/server/baseentity.cpp	Mon Sep 02 11:39:10 2013 -0700
    28.3 @@ -653,7 +653,7 @@
    28.4  void CBaseEntity::ClearModelIndexOverrides( void )
    28.5  {
    28.6  #ifdef TF_DLL
    28.7 -	for ( int index = 0 ; index < MAX_MODEL_INDEX_OVERRIDES ; index++ )
    28.8 +	for ( int index = 0 ; index < MAX_VISION_MODES ; index++ )
    28.9  	{
   28.10  		m_nModelIndexOverrides.Set( index, 0 );
   28.11  	}
   28.12 @@ -663,7 +663,7 @@
   28.13  void CBaseEntity::SetModelIndexOverride( int index, int nValue )
   28.14  {
   28.15  #ifdef TF_DLL
   28.16 -	if ( ( index >= MODEL_INDEX_OVERRIDE_DEFAULT ) && ( index < MAX_MODEL_INDEX_OVERRIDES ) )
   28.17 +	if ( ( index >= VISION_MODE_NONE ) && ( index < MAX_VISION_MODES ) )
   28.18  	{
   28.19  		if ( nValue != m_nModelIndexOverrides[index] )
   28.20  		{
   28.21 @@ -1950,7 +1950,7 @@
   28.22  	// DEFINE_FIELD( m_fDataObjectTypes, FIELD_INTEGER ),
   28.23  
   28.24  #ifdef TF_DLL
   28.25 -	DEFINE_ARRAY( m_nModelIndexOverrides, FIELD_INTEGER, MAX_MODEL_INDEX_OVERRIDES ),
   28.26 +	DEFINE_ARRAY( m_nModelIndexOverrides, FIELD_INTEGER, MAX_VISION_MODES ),
   28.27  #endif
   28.28  
   28.29  END_DATADESC()
   28.30 @@ -7302,6 +7302,30 @@
   28.31  {
   28.32  	MDLCACHE_CRITICAL_SECTION();
   28.33  
   28.34 +	CBasePlayer *pPlayer = UTIL_GetCommandClient();
   28.35 +	if (!pPlayer)
   28.36 +	{
   28.37 +		return;
   28.38 +	}
   28.39 +
   28.40 +	// Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire
   28.41 +	if ( !Q_stricmp( args[1], "point_servercommand" ) )
   28.42 +	{
   28.43 +		if ( engine->IsDedicatedServer() )
   28.44 +		{
   28.45 +			// We allow people with disabled autokick to do it, because they already have rcon.
   28.46 +			if ( pPlayer->IsAutoKickDisabled() == false )
   28.47 +				return;
   28.48 +		}
   28.49 +		else if ( gpGlobals->maxClients > 1 )
   28.50 +		{
   28.51 +			// On listen servers with more than 1 player, only allow the host to create point_servercommand.
   28.52 +			CBasePlayer *pHostPlayer = UTIL_GetListenServerHost();
   28.53 +			if ( pPlayer != pHostPlayer )
   28.54 +				return;
   28.55 +		}
   28.56 +	}
   28.57 +
   28.58  	bool allowPrecache = CBaseEntity::IsPrecacheAllowed();
   28.59  	CBaseEntity::SetAllowPrecache( true );
   28.60  
   28.61 @@ -7322,7 +7346,6 @@
   28.62  		DispatchSpawn(entity);
   28.63  
   28.64  		// Now attempt to drop into the world
   28.65 -		CBasePlayer* pPlayer = UTIL_GetCommandClient();
   28.66  		trace_t tr;
   28.67  		Vector forward;
   28.68  		pPlayer->EyeVectors( &forward );
    29.1 --- a/game/server/baseentity.h	Tue Jul 30 15:10:15 2013 -0700
    29.2 +++ b/game/server/baseentity.h	Mon Sep 02 11:39:10 2013 -0700
    29.3 @@ -792,7 +792,7 @@
    29.4  	CNetworkVar( short, m_nModelIndex );
    29.5  	
    29.6  #ifdef TF_DLL
    29.7 -	CNetworkArray( int, m_nModelIndexOverrides, MAX_MODEL_INDEX_OVERRIDES ); // used to override the base model index on the client if necessary
    29.8 +	CNetworkArray( int, m_nModelIndexOverrides, MAX_VISION_MODES ); // used to override the base model index on the client if necessary
    29.9  #endif
   29.10  
   29.11  	// was pev->rendercolor
    30.1 --- a/game/server/client.cpp	Tue Jul 30 15:10:15 2013 -0700
    30.2 +++ b/game/server/client.cpp	Mon Sep 02 11:39:10 2013 -0700
    30.3 @@ -798,6 +798,24 @@
    30.4  		Q_strncpy( item_to_give, args[1], sizeof( item_to_give ) );
    30.5  		Q_strlower( item_to_give );
    30.6  
    30.7 +		// Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire
    30.8 +		if ( !Q_stricmp( item_to_give, "point_servercommand" ) )
    30.9 +		{
   30.10 +			if ( engine->IsDedicatedServer() )
   30.11 +			{
   30.12 +				// We allow people with disabled autokick to do it, because they already have rcon.
   30.13 +				if ( pPlayer->IsAutoKickDisabled() == false )
   30.14 +					return;
   30.15 +			}
   30.16 +			else if ( gpGlobals->maxClients > 1 )
   30.17 +			{
   30.18 +				// On listen servers with more than 1 player, only allow the host to create point_servercommand.
   30.19 +				CBasePlayer *pHostPlayer = UTIL_GetListenServerHost();
   30.20 +				if ( pPlayer != pHostPlayer )
   30.21 +					return;
   30.22 +			}
   30.23 +		}
   30.24 +
   30.25  		// Dirty hack to avoid suit playing it's pickup sound
   30.26  		if ( !Q_stricmp( item_to_give, "item_suit" ) )
   30.27  		{
    31.1 --- a/game/server/doors.cpp	Tue Jul 30 15:10:15 2013 -0700
    31.2 +++ b/game/server/doors.cpp	Mon Sep 02 11:39:10 2013 -0700
    31.3 @@ -340,12 +340,11 @@
    31.4  #ifdef TF_DLL
    31.5  	if ( TFGameRules() && TFGameRules()->IsMultiplayer() )
    31.6  	{
    31.7 -		if ( !m_flBlockDamage )
    31.8 -		{
    31.9 -			// Never block doors in TF2 - to prevent various exploits.
   31.10 -			m_flBlockDamage = 10.f;
   31.11 -		}
   31.12 +		// Never block doors in TF2 - to prevent various exploits.
   31.13 +		m_bIgnoreNonPlayerEntsOnBlock = true;
   31.14  	}
   31.15 +#else
   31.16 +	m_bIgnoreNonPlayerEntsOnBlock = false;
   31.17  #endif // TF_DLL
   31.18  }
   31.19  
   31.20 @@ -1207,6 +1206,11 @@
   31.21  			pOther->TakeDamage( CTakeDamageInfo( this, this, m_flBlockDamage, DMG_CRUSH ) );
   31.22  		}
   31.23  	}
   31.24 +	// If set, ignore non-player ents that block us.  Mainly of use in multiplayer to prevent exploits.
   31.25 +	else if ( pOther && !pOther->IsPlayer() && m_bIgnoreNonPlayerEntsOnBlock )
   31.26 +	{
   31.27 +		return;
   31.28 +	}
   31.29  
   31.30  	// If we're set to force ourselves closed, keep going
   31.31  	if ( m_bForceClosed )
    32.1 --- a/game/server/doors.h	Tue Jul 30 15:10:15 2013 -0700
    32.2 +++ b/game/server/doors.h	Mon Sep 02 11:39:10 2013 -0700
    32.3 @@ -114,6 +114,7 @@
    32.4  	bool	m_bDoorGroup;
    32.5  	bool	m_bLocked;				// Whether the door is locked
    32.6  	bool	m_bIgnoreDebris;
    32.7 +	bool	m_bIgnoreNonPlayerEntsOnBlock;	// Non-player entities should never block.  This variable needs more letters.
    32.8  	
    32.9  	FuncDoorSpawnPos_t m_eSpawnPosition;
   32.10  
    33.1 --- a/game/server/episodic/npc_hunter.cpp	Tue Jul 30 15:10:15 2013 -0700
    33.2 +++ b/game/server/episodic/npc_hunter.cpp	Mon Sep 02 11:39:10 2013 -0700
    33.3 @@ -2199,7 +2199,7 @@
    33.4  		if ( m_flPupilDilateTime < gpGlobals->curtime )
    33.5  		{
    33.6   			CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
    33.7 - 			if ( pPlayer && !pPlayer->IsIlluminatedByFlashlight( this, NULL ) || !PlayerFlashlightOnMyEyes( pPlayer ) )
    33.8 + 			if ( ( pPlayer && !pPlayer->IsIlluminatedByFlashlight( this, NULL ) ) || !PlayerFlashlightOnMyEyes( pPlayer ) )
    33.9  			{
   33.10  				//Msg( "NOT SHINING FLASHLIGHT ON ME\n" );
   33.11  			
   33.12 @@ -6347,13 +6347,13 @@
   33.13  CBaseEntity *CNPC_Hunter::GetEnemyVehicle()
   33.14  {
   33.15  	if ( GetEnemy() == NULL )
   33.16 -		return false;
   33.17 +		return NULL;
   33.18  
   33.19  	CBaseCombatCharacter *pCCEnemy = GetEnemy()->MyCombatCharacterPointer();
   33.20  	if ( pCCEnemy != NULL )
   33.21  		return pCCEnemy->GetVehicleEntity();
   33.22  
   33.23 -	return false;
   33.24 +	return NULL;
   33.25  }
   33.26  
   33.27  
    34.1 --- a/game/server/hl2/npc_barnacle.cpp	Tue Jul 30 15:10:15 2013 -0700
    34.2 +++ b/game/server/hl2/npc_barnacle.cpp	Mon Sep 02 11:39:10 2013 -0700
    34.3 @@ -1810,7 +1810,10 @@
    34.4  
    34.5  #if HL2_EPISODIC
    34.6  		// digest poisonous things for just a moment before being killed by them (it looks wierd if it's instant)
    34.7 -		m_flDigestFinish = gpGlobals->curtime + m_bSwallowingPoison ? 0.48f : 10.0f;
    34.8 +		// Parentheses were probably intended around the ?: part of the expression, but putting them there now
    34.9 +		// would change the behavior which is undesirable, so parentheses were placed around the '+' to suppress
   34.10 +		// compiler warnings.
   34.11 +		m_flDigestFinish = ( gpGlobals->curtime + m_bSwallowingPoison ) ? 0.48f : 10.0f;
   34.12  #else
   34.13  		m_flDigestFinish = gpGlobals->curtime + 10.0;
   34.14  #endif
    35.1 --- a/game/server/hl2/npc_zombine.cpp	Tue Jul 30 15:10:15 2013 -0700
    35.2 +++ b/game/server/hl2/npc_zombine.cpp	Mon Sep 02 11:39:10 2013 -0700
    35.3 @@ -571,7 +571,7 @@
    35.4  				{
    35.5  					pNPC = ppAIs[i];
    35.6  
    35.7 -					if( pNPC->Classify() == CLASS_PLAYER_ALLY || pNPC->Classify() == CLASS_PLAYER_ALLY_VITAL && pNPC->FVisible(this) )
    35.8 +					if( pNPC->Classify() == CLASS_PLAYER_ALLY || ( pNPC->Classify() == CLASS_PLAYER_ALLY_VITAL && pNPC->FVisible(this) ) )
    35.9  					{
   35.10  						int priority;
   35.11  						Disposition_t disposition;
    36.1 --- a/game/server/player.h	Tue Jul 30 15:10:15 2013 -0700
    36.2 +++ b/game/server/player.h	Mon Sep 02 11:39:10 2013 -0700
    36.3 @@ -358,7 +358,7 @@
    36.4  
    36.5  	bool					IsHLTV( void ) const { return pl.hltv; }
    36.6  	bool					IsReplay( void ) const { return pl.replay; }
    36.7 -	virtual	bool			IsPlayer( void ) const { return true; }			// Spectators return TRUE for this, use IsObserver to seperate cases
    36.8 +	virtual	bool			IsPlayer( void ) const { return true; }			// Spectators return TRUE for this, use IsObserver to separate cases
    36.9  	virtual bool			IsNetClient( void ) const { return true; }		// Bots should return FALSE for this, they can't receive NET messages
   36.10  																			// Spectators should return TRUE for this
   36.11  
   36.12 @@ -1500,6 +1500,44 @@
   36.13  	return playerVector->Count();
   36.14  }
   36.15  
   36.16 +template < typename T >
   36.17 +int CollectHumanPlayers( CUtlVector< T * > *playerVector, int team = TEAM_ANY, bool isAlive = false, bool shouldAppend = false )
   36.18 +{
   36.19 +	if ( !shouldAppend )
   36.20 +	{
   36.21 +		playerVector->RemoveAll();
   36.22 +	}
   36.23 +
   36.24 +	for( int i=1; i<=gpGlobals->maxClients; ++i )
   36.25 +	{
   36.26 +		CBasePlayer *player = UTIL_PlayerByIndex( i );
   36.27 +
   36.28 +		if ( player == NULL )
   36.29 +			continue;
   36.30 +
   36.31 +		if ( FNullEnt( player->edict() ) )
   36.32 +			continue;
   36.33 +
   36.34 +		if ( !player->IsPlayer() )
   36.35 +			continue;
   36.36 +
   36.37 +		if ( player->IsBot() )
   36.38 +			continue;
   36.39 +
   36.40 +		if ( !player->IsConnected() )
   36.41 +			continue;
   36.42 +
   36.43 +		if ( team != TEAM_ANY && player->GetTeamNumber() != team )
   36.44 +			continue;
   36.45 +
   36.46 +		if ( isAlive && !player->IsAlive() )
   36.47 +			continue;
   36.48 +
   36.49 +		playerVector->AddToTail( assert_cast< T * >( player ) );
   36.50 +	}
   36.51 +
   36.52 +	return playerVector->Count();
   36.53 +}
   36.54  
   36.55  enum
   36.56  {
    37.1 --- a/game/server/props.cpp	Tue Jul 30 15:10:15 2013 -0700
    37.2 +++ b/game/server/props.cpp	Mon Sep 02 11:39:10 2013 -0700
    37.3 @@ -1937,6 +1937,18 @@
    37.4  	}
    37.5  
    37.6  	//m_debugOverlays |= OVERLAY_ABSBOX_BIT;
    37.7 +
    37.8 +#ifdef TF_DLL
    37.9 +	const char *pszModelName = modelinfo->GetModelName( GetModel() );
   37.10 +	if ( pszModelName && pszModelName[0] )
   37.11 +	{
   37.12 +		if ( FStrEq( pszModelName, "models/bots/boss_bot/carrier_parts.mdl" ) )
   37.13 +		{
   37.14 +			SetModelIndexOverride( VISION_MODE_NONE, modelinfo->GetModelIndex( pszModelName ) );
   37.15 +			SetModelIndexOverride( VISION_MODE_ROME, modelinfo->GetModelIndex( "models/bots/tw2/boss_bot/twcarrier_addon.mdl" ) );
   37.16 +		}
   37.17 +	}
   37.18 +#endif
   37.19  }
   37.20  
   37.21  //-----------------------------------------------------------------------------
    38.1 --- a/game/server/server_base.vpc	Tue Jul 30 15:10:15 2013 -0700
    38.2 +++ b/game/server/server_base.vpc	Mon Sep 02 11:39:10 2013 -0700
    38.3 @@ -44,6 +44,11 @@
    38.4  
    38.5  $Configuration
    38.6  {
    38.7 +	$General
    38.8 +	{
    38.9 +		$OutputDirectory		".\$GAMENAME"		[$OSXALL]
   38.10 +	}
   38.11 +	
   38.12  	$Compiler
   38.13  	{
   38.14  		$AdditionalIncludeDirectories	"$BASE;.\;$SRCDIR\game\shared;$SRCDIR\utils\common;$SRCDIR\game\shared\econ;$SRCDIR\game\server\NextBot"
   38.15 @@ -998,40 +1003,7 @@
   38.16  		$File	"toolframework_server.h"
   38.17  	}
   38.18  	
   38.19 -	
   38.20 -	$Folder	"Link Libraries" [$WIN32]
   38.21 -	{
   38.22 -		$DynamicFile	"$SRCDIR\lib\public\choreoobjects.lib"
   38.23 -		$DynamicFile	"$SRCDIR\lib\public\dmxloader.lib"
   38.24 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
   38.25 -		$DynamicFile	"$SRCDIR\lib\public\particles.lib"
   38.26 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
   38.27 -		$DynamicFile	"$SRCDIR\lib\public\tier3.lib"
   38.28 -		$DynamicFile	"$SRCDIR\lib\public\steam_api.lib"
   38.29 -	}
   38.30 -
   38.31 -	$Folder	"Link Libraries" [$X360]
   38.32 -	{
   38.33 -		$DynamicFile	"$SRCDIR\lib\public\choreoobjects_360.lib"
   38.34 -		$DynamicFile	"$SRCDIR\lib\public\dmxloader_360.lib"
   38.35 -		$DynamicFile	"$SRCDIR\lib\public\mathlib_360.lib"
   38.36 -		$DynamicFile	"$SRCDIR\lib\public\particles_360.lib"
   38.37 -		$DynamicFile	"$SRCDIR\lib\public\tier2_360.lib"
   38.38 -		$DynamicFile	"$SRCDIR\lib\public\tier3_360.lib"
   38.39 -	}
   38.40 -
   38.41 -	$Folder	"Link Libraries" [$POSIX && !$LINUX]
   38.42 -	{
   38.43 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\choreoobjects$_STATICLIB_EXT"
   38.44 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\dmxloader$_STATICLIB_EXT"
   38.45 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\mathlib$_STATICLIB_EXT"
   38.46 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\particles$_STATICLIB_EXT"
   38.47 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\tier2$_STATICLIB_EXT"
   38.48 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\tier3$_STATICLIB_EXT"
   38.49 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_IMPLIB_EXT"
   38.50 -	}
   38.51 -
   38.52 -	$Folder	"Link Libraries" [$LINUX]
   38.53 +	$Folder	"Link Libraries" 
   38.54  	{
   38.55  		$Lib	choreoobjects
   38.56  		$Lib	dmxloader
   38.57 @@ -1039,6 +1011,6 @@
   38.58  		$Lib	particles
   38.59  		$Lib	tier2
   38.60  		$Lib	tier3
   38.61 -		$DynamicFile		"$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXsteam_api$_EXTERNAL_IMPLIB_EXT"
   38.62 +		$ImpLibexternal steam_api
   38.63  	}
   38.64  }
    39.1 --- a/game/server/testfunctions.cpp	Tue Jul 30 15:10:15 2013 -0700
    39.2 +++ b/game/server/testfunctions.cpp	Mon Sep 02 11:39:10 2013 -0700
    39.3 @@ -16,6 +16,14 @@
    39.4  
    39.5  void Test_CreateEntity( const CCommand &args )
    39.6  {
    39.7 +	CBasePlayer *pPlayer = UTIL_GetCommandClient();
    39.8 +
    39.9 +	// Require a player entity or that the command was entered from the dedicated server console
   39.10 +	if ( !pPlayer && UTIL_GetCommandClientIndex() > 0 )
   39.11 +	{
   39.12 +		return;
   39.13 +	}
   39.14 +
   39.15  	if ( args.ArgC() < 2 )
   39.16  	{
   39.17  		Error( "Test_CreateEntity: requires entity classname argument." );
   39.18 @@ -23,6 +31,24 @@
   39.19  
   39.20  	const char *pClassName = args[ 1 ];
   39.21  
   39.22 +	// Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire
   39.23 +	if ( pPlayer && !Q_stricmp( pClassName, "point_servercommand" ) )
   39.24 +	{
   39.25 +		if ( engine->IsDedicatedServer() )
   39.26 +		{
   39.27 +			// We allow people with disabled autokick to do it, because they already have rcon.
   39.28 +			if ( pPlayer->IsAutoKickDisabled() == false )
   39.29 +				return;
   39.30 +		}
   39.31 +		else if ( gpGlobals->maxClients > 1 )
   39.32 +		{
   39.33 +			// On listen servers with more than 1 player, only allow the host to create point_servercommand.
   39.34 +			CBasePlayer *pHostPlayer = UTIL_GetListenServerHost();
   39.35 +			if ( pPlayer != pHostPlayer )
   39.36 +				return;
   39.37 +		}
   39.38 +	}
   39.39 +
   39.40  	if ( !CreateEntityByName( pClassName ) )
   39.41  	{
   39.42  		Error( "Test_CreateEntity( %s ) failed.", pClassName );
    40.1 --- a/game/server/util.cpp	Tue Jul 30 15:10:15 2013 -0700
    40.2 +++ b/game/server/util.cpp	Mon Sep 02 11:39:10 2013 -0700
    40.3 @@ -1892,7 +1892,8 @@
    40.4  			// Don't allow the PVS check to skip animation setup during spawning
    40.5  			pAnimating->SetBoneCacheFlags( BCF_IS_IN_SPAWN );
    40.6  			pEntity->Spawn();
    40.7 -			pAnimating->ClearBoneCacheFlags( BCF_IS_IN_SPAWN );
    40.8 +			if ( pEntSafe != NULL )
    40.9 +				pAnimating->ClearBoneCacheFlags( BCF_IS_IN_SPAWN );
   40.10  		}
   40.11  		mdlcache->SetAsyncLoad( MDLCACHE_ANIMBLOCK, bAsyncAnims );
   40.12  
    41.1 --- a/game/shared/GameStats.cpp	Tue Jul 30 15:10:15 2013 -0700
    41.2 +++ b/game/shared/GameStats.cpp	Mon Sep 02 11:39:10 2013 -0700
    41.3 @@ -3,10 +3,8 @@
    41.4  // Purpose: 
    41.5  //
    41.6  //=============================================================================
    41.7 -
    41.8  #include "cbase.h"
    41.9  
   41.10 -
   41.11  #include "igamesystem.h"
   41.12  #include "gamestats.h"
   41.13  #include "tier1/utlstring.h"
    42.1 --- a/game/shared/playernet_vars.h	Tue Jul 30 15:10:15 2013 -0700
    42.2 +++ b/game/shared/playernet_vars.h	Mon Sep 02 11:39:10 2013 -0700
    42.3 @@ -77,10 +77,10 @@
    42.4  	{
    42.5  		m_hCtrl.Set( NULL );
    42.6  		m_flTransitionTime = -1.0f;
    42.7 -		m_OldColor.r = m_OldColor.g = m_OldColor.g = m_OldColor.a = 0.0f;
    42.8 +		m_OldColor.r = m_OldColor.g = m_OldColor.b = m_OldColor.a = 0;
    42.9  		m_flOldStart = 0.0f;
   42.10  		m_flOldEnd = 0.0f;
   42.11 -		m_NewColor.r = m_NewColor.g = m_NewColor.g = m_NewColor.a = 0.0f;
   42.12 +		m_NewColor.r = m_NewColor.g = m_NewColor.b = m_NewColor.a = 0;
   42.13  		m_flNewStart = 0.0f;
   42.14  		m_flNewEnd = 0.0f;
   42.15  	}
    43.1 --- a/game/shared/shareddefs.h	Tue Jul 30 15:10:15 2013 -0700
    43.2 +++ b/game/shared/shareddefs.h	Mon Sep 02 11:39:10 2013 -0700
    43.3 @@ -919,14 +919,17 @@
    43.4  #define TF_VISION_FILTER_NONE			0
    43.5  #define TF_VISION_FILTER_PYRO			(1<<0)		// 1
    43.6  #define TF_VISION_FILTER_HALLOWEEN		(1<<1)		// 2
    43.7 +#define TF_VISION_FILTER_ROME			(1<<2)		// 4
    43.8  
    43.9 +// THIS ENUM SHOULD MATCH THE ORDER OF THE FLAGS ABOVE
   43.10  enum
   43.11  {
   43.12 -	MODEL_INDEX_OVERRIDE_DEFAULT = 0,
   43.13 -	MODEL_INDEX_OVERRIDE_PYRO,
   43.14 -	MODEL_INDEX_OVERRIDE_HALLOWEEN,
   43.15 +	VISION_MODE_NONE = 0,
   43.16 +	VISION_MODE_PYRO,
   43.17 +	VISION_MODE_HALLOWEEN,
   43.18 +	VISION_MODE_ROME,
   43.19  
   43.20 -	MAX_MODEL_INDEX_OVERRIDES
   43.21 +	MAX_VISION_MODES
   43.22  };
   43.23  #endif // TF_DLL || TF_CLIENT_DLL
   43.24  
    44.1 Binary file lib/common/libcurl.lib has changed
    45.1 Binary file lib/common/linux32/libcrypto.a has changed
    46.1 Binary file lib/common/linux32/libcurl.a has changed
    47.1 Binary file lib/common/linux32/libcurlssl.a has changed
    48.1 Binary file lib/common/linux32/libssl.a has changed
    49.1 Binary file lib/linux32/libcurl.a has changed
    50.1 Binary file lib/linux32/libcurlssl.a has changed
    51.1 Binary file lib/linux32/libssl.a has changed
    52.1 Binary file lib/linux32/libsteam_api.so has changed
    53.1 Binary file lib/linux32/release/libcrypto.a has changed
    54.1 Binary file lib/linux32/release/libprotobuf.a has changed
    55.1 Binary file lib/osx32/bitmap.a has changed
    56.1 Binary file lib/osx32/choreoobjects.a has changed
    57.1 Binary file lib/osx32/dmxloader.a has changed
    58.1 Binary file lib/osx32/libcurl.dylib has changed
    59.1 Binary file lib/osx32/libsteam_api.dylib has changed
    60.1 Binary file lib/osx32/libtier0.dylib has changed
    61.1 Binary file lib/osx32/libvstdlib.dylib has changed
    62.1 Binary file lib/osx32/matsys_controls.a has changed
    63.1 Binary file lib/osx32/particles.a has changed
    64.1 Binary file lib/osx32/release/libprotobuf.a has changed
    65.1 Binary file lib/osx32/shaderlib.a has changed
    66.1 Binary file lib/osx32/tier2.a has changed
    67.1 Binary file lib/osx32/tier3.a has changed
    68.1 Binary file lib/osx32/vtf.a has changed
    69.1 Binary file lib/public/appframework.lib has changed
    70.1 Binary file lib/public/bitmap.lib has changed
    71.1 Binary file lib/public/choreoobjects.lib has changed
    72.1 Binary file lib/public/dmxloader.lib has changed
    73.1 Binary file lib/public/fgdlib.lib has changed
    74.1 Binary file lib/public/libprotobuf.lib has changed
    75.1 Binary file lib/public/libz.lib has changed
    76.1 Binary file lib/public/linux32/bitmap.a has changed
    77.1 Binary file lib/public/linux32/choreoobjects.a has changed
    78.1 Binary file lib/public/linux32/dmxloader.a has changed
    79.1 Binary file lib/public/linux32/libprotobuf.a has changed
    80.1 Binary file lib/public/linux32/libsteam_api.so has changed
    81.1 Binary file lib/public/linux32/libtier0.so has changed
    82.1 Binary file lib/public/linux32/libvstdlib.so has changed
    83.1 Binary file lib/public/linux32/libz.a has changed
    84.1 Binary file lib/public/linux32/matsys_controls.a has changed
    85.1 Binary file lib/public/linux32/particles.a has changed
    86.1 Binary file lib/public/linux32/shaderlib.a has changed
    87.1 Binary file lib/public/linux32/tier2.a has changed
    88.1 Binary file lib/public/linux32/tier3.a has changed
    89.1 Binary file lib/public/linux32/vtf.a has changed
    90.1 Binary file lib/public/mathlib.lib has changed
    91.1 Binary file lib/public/matsys_controls.lib has changed
    92.1 Binary file lib/public/nvtristrip.lib has changed
    93.1 Binary file lib/public/osx32/bitmap.a has changed
    94.1 Binary file lib/public/osx32/choreoobjects.a has changed
    95.1 Binary file lib/public/osx32/dmxloader.a has changed
    96.1 Binary file lib/public/osx32/libprotobuf.a has changed
    97.1 Binary file lib/public/osx32/libsteam_api.dylib has changed
    98.1 Binary file lib/public/osx32/libtier0.dylib has changed
    99.1 Binary file lib/public/osx32/libvstdlib.dylib has changed
   100.1 Binary file lib/public/osx32/mathlib.a has changed
   101.1 Binary file lib/public/osx32/matsys_controls.a has changed
   102.1 Binary file lib/public/osx32/particles.a has changed
   103.1 Binary file lib/public/osx32/raytrace.a has changed
   104.1 Binary file lib/public/osx32/shaderlib.a has changed
   105.1 Binary file lib/public/osx32/tier1.a has changed
   106.1 Binary file lib/public/osx32/tier2.a has changed
   107.1 Binary file lib/public/osx32/tier3.a has changed
   108.1 Binary file lib/public/osx32/vgui_controls.a has changed
   109.1 Binary file lib/public/osx32/vtf.a has changed
   110.1 Binary file lib/public/particles.lib has changed
   111.1 Binary file lib/public/raytrace.lib has changed
   112.1 Binary file lib/public/shaderlib.lib has changed
   113.1 Binary file lib/public/tier0.lib has changed
   114.1 Binary file lib/public/tier1.lib has changed
   115.1 Binary file lib/public/tier2.lib has changed
   116.1 Binary file lib/public/tier3.lib has changed
   117.1 Binary file lib/public/vgui_controls.lib has changed
   118.1 Binary file lib/public/vmpi.lib has changed
   119.1 Binary file lib/public/vstdlib.lib has changed
   120.1 Binary file lib/public/vtf.lib has changed
   121.1 Binary file lib/win32/debug/vs2010/libprotobuf.lib has changed
   122.1 Binary file lib/win32/release/vs2010/libprotobuf.lib has changed
   123.1 --- a/materialsystem/stdshaders/game_shader_dx9_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   123.2 +++ b/materialsystem/stdshaders/game_shader_dx9_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   123.3 @@ -74,23 +74,9 @@
   123.4  	$Folder	"Link Libraries" [$WIN32]
   123.5  	{
   123.6  //		$File	"$SRCDIR\dx9sdk\lib\d3dx9.lib"		
   123.7 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
   123.8 -		$DynamicFile	"$SRCDIR\lib\public\shaderlib.lib"
   123.9  	}
  123.10  
  123.11 -	$Folder	"Link Libraries" [$X360]
  123.12 -	{
  123.13 -		$DynamicFile	"$SRCDIR\lib\public\mathlib_360.lib"	
  123.14 -		$DynamicFile	"$SRCDIR\lib\public\shaderlib_360.lib"
  123.15 -	}
  123.16 -
  123.17 -	$Folder "Link Libraries" [$POSIX&&!$LINUX]
  123.18 -	{
  123.19 -        $DynamicFile   "$SRCDIR\lib\$PLATFORM\mathlib$_STATICLIB_EXT"
  123.20 -        $DynamicFile   "$SRCDIR\lib\$PLATFORM\shaderlib$_STATICLIB_EXT"
  123.21 -    }
  123.22 -
  123.23 -	$Folder "Link Libraries" [$LINUX]
  123.24 +	$Folder "Link Libraries"
  123.25  	{
  123.26          $Lib	mathlib
  123.27          $Lib	shaderlib
   124.1 --- a/mathlib/mathlib.vpc	Tue Jul 30 15:10:15 2013 -0700
   124.2 +++ b/mathlib/mathlib.vpc	Mon Sep 02 11:39:10 2013 -0700
   124.3 @@ -5,8 +5,6 @@
   124.4  //-----------------------------------------------------------------------------
   124.5  
   124.6  $macro SRCDIR		".."
   124.7 -$Macro OUTLIBDIR	"$SRCDIR\lib\public" [!$LINUX]
   124.8 -
   124.9  $include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
  124.10  
  124.11  $Configuration
   125.1 --- a/public/XUnzip.cpp	Tue Jul 30 15:10:15 2013 -0700
   125.2 +++ b/public/XUnzip.cpp	Mon Sep 02 11:39:10 2013 -0700
   125.3 @@ -3232,10 +3232,12 @@
   125.4  
   125.5  	// we check the magic
   125.6  	if (err==UNZ_OK)
   125.7 +	{
   125.8  		if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
   125.9  			err=UNZ_ERRNO;
  125.10  		else if (uMagic!=0x02014b50)
  125.11  			err=UNZ_BADZIPFILE;
  125.12 +	}
  125.13  
  125.14  	if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
  125.15  		err=UNZ_ERRNO;
  125.16 @@ -3312,10 +3314,12 @@
  125.17  			uSizeRead = extraFieldBufferSize;
  125.18  
  125.19  		if (lSeek!=0)
  125.20 +		{
  125.21  			if (lufseek(s->file,lSeek,SEEK_CUR)==0)
  125.22  				lSeek=0;
  125.23  			else
  125.24  				err=UNZ_ERRNO;
  125.25 +		}
  125.26  		if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
  125.27  			if (lufread(extraField,(uInt)uSizeRead,1,s->file)!=1)
  125.28  				err=UNZ_ERRNO;
  125.29 @@ -3337,10 +3341,12 @@
  125.30  			uSizeRead = commentBufferSize;
  125.31  
  125.32  		if (lSeek!=0)
  125.33 +		{
  125.34  			if (lufseek(s->file,lSeek,SEEK_CUR)==0)
  125.35  				{} // unused lSeek=0;
  125.36  			else
  125.37  				err=UNZ_ERRNO;
  125.38 +		}
  125.39  		if ((file_info.size_file_comment>0) && (commentBufferSize>0))
  125.40  			if (lufread(szComment,(uInt)uSizeRead,1,s->file)!=1)
  125.41  				err=UNZ_ERRNO;
  125.42 @@ -3490,10 +3496,12 @@
  125.43  
  125.44  
  125.45  	if (err==UNZ_OK)
  125.46 +	{
  125.47  		if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
  125.48  			err=UNZ_ERRNO;
  125.49  		else if (uMagic!=0x04034b50)
  125.50  			err=UNZ_BADZIPFILE;
  125.51 +	}
  125.52  
  125.53  	if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
  125.54  		err=UNZ_ERRNO;
   126.1 --- a/public/bone_setup.cpp	Tue Jul 30 15:10:15 2013 -0700
   126.2 +++ b/public/bone_setup.cpp	Mon Sep 02 11:39:10 2013 -0700
   126.3 @@ -57,7 +57,9 @@
   126.4  		{
   126.5  			p = new T[MAXSTUDIOBONES];
   126.6  			if ( ((size_t)p) % TSLIST_NODE_ALIGNMENT != 0 )
   126.7 +			{
   126.8  				DebuggerBreak();
   126.9 +			}
  126.10  		}
  126.11  
  126.12  		return p;
   127.1 --- a/public/cdll_int.h	Tue Jul 30 15:10:15 2013 -0700
   127.2 +++ b/public/cdll_int.h	Mon Sep 02 11:39:10 2013 -0700
   127.3 @@ -566,6 +566,8 @@
   127.4  	virtual bool IsActiveApp() = 0;
   127.5  
   127.6  	virtual void DisconnectInternal() = 0;
   127.7 +
   127.8 +	virtual int GetInstancesRunningCount( ) = 0;
   127.9  };
  127.10  
  127.11  
   128.1 --- a/public/engine/IStaticPropMgr.h	Tue Jul 30 15:10:15 2013 -0700
   128.2 +++ b/public/engine/IStaticPropMgr.h	Mon Sep 02 11:39:10 2013 -0700
   128.3 @@ -63,7 +63,8 @@
   128.4  	// Adds decals to static props, returns point of decal in trace_t
   128.5  	virtual void	AddDecalToStaticProp( const Vector& rayStart, const Vector& rayEnd,
   128.6  		int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr ) = 0;
   128.7 -
   128.8 +	virtual void AddColorDecalToStaticProp( Vector const& rayStart, Vector const& rayEnd,
   128.9 +		int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr, bool bUseColor, Color cColor ) = 0;
  128.10  	// Adds/removes shadows from static props
  128.11  	virtual void	AddShadowToStaticProp( unsigned short shadowHandle, IClientRenderable* pRenderable ) = 0;
  128.12  	virtual void	RemoveAllShadowsFromStaticProp( IClientRenderable* pRenderable ) = 0;
   129.1 --- a/public/engine/ivmodelrender.h	Tue Jul 30 15:10:15 2013 -0700
   129.2 +++ b/public/engine/ivmodelrender.h	Mon Sep 02 11:39:10 2013 -0700
   129.3 @@ -138,6 +138,8 @@
   129.4  	// radius of the decal to create.
   129.5  	virtual void AddDecal( ModelInstanceHandle_t handle, Ray_t const& ray, 
   129.6  		Vector const& decalUp, int decalIndex, int body, bool noPokeThru = false, int maxLODToDecal = ADDDECAL_TO_ALL_LODS ) = 0;
   129.7 +	virtual void AddColoredDecal( ModelInstanceHandle_t handle, Ray_t const& ray, 
   129.8 +		Vector const& decalUp, int decalIndex, int body, Color cColor, bool noPokeThru = false, int maxLODToDecal = ADDDECAL_TO_ALL_LODS ) = 0;
   129.9  
  129.10  	// Removes all the decals on a model instance
  129.11  	virtual void RemoveAllDecals( ModelInstanceHandle_t handle ) = 0;
   130.1 --- a/public/game/server/pluginvariant.h	Tue Jul 30 15:10:15 2013 -0700
   130.2 +++ b/public/game/server/pluginvariant.h	Mon Sep 02 11:39:10 2013 -0700
   130.3 @@ -56,7 +56,7 @@
   130.4  	fieldtype_t FieldType( void ) { return fieldType; }
   130.5  
   130.6  	void SetBool( bool b ) { bVal = b; fieldType = FIELD_BOOLEAN; }
   130.7 -	void SetString( char *str ) { Q_snprintf(iszVal, 1024, str); fieldType = FIELD_STRING; }
   130.8 +	void SetString( char *str ) { Q_snprintf(iszVal, 1024, "%s", str); fieldType = FIELD_STRING; }
   130.9  	void SetInt( int val ) { iVal = val, fieldType = FIELD_INTEGER; }
  130.10  	void SetFloat( float val ) { flVal = val, fieldType = FIELD_FLOAT; }
  130.11  	void SetEdict( edict_t *val ) { eVal = val; fieldType = FIELD_EHANDLE; }
   131.1 --- a/public/inputsystem/iinputsystem.h	Tue Jul 30 15:10:15 2013 -0700
   131.2 +++ b/public/inputsystem/iinputsystem.h	Mon Sep 02 11:39:10 2013 -0700
   131.3 @@ -117,6 +117,13 @@
   131.4  
   131.5  	// read and clear accumulated raw input values
   131.6  	virtual bool GetRawMouseAccumulators( int& accumX, int& accumY ) = 0;
   131.7 +
   131.8 +	// tell the input system that we're not a game, we're console text mode.
   131.9 +	// this is used for dedicated servers to not initialize joystick system.
  131.10 +	// this needs to be called before CInputSystem::Init (e.g. in PreInit of
  131.11 +	// some system) if you want ot prevent the joystick system from ever
  131.12 +	// being initialized.
  131.13 +	virtual void SetConsoleTextMode( bool bConsoleTextMode ) = 0;
  131.14  };
  131.15  
  131.16  
   132.1 --- a/public/tier0/dbg.h	Tue Jul 30 15:10:15 2013 -0700
   132.2 +++ b/public/tier0/dbg.h	Mon Sep 02 11:39:10 2013 -0700
   132.3 @@ -253,9 +253,13 @@
   132.4  				if ( ret == SPEW_DEBUGGER)									\
   132.5  				{															\
   132.6  					if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
   132.7 +					{														\
   132.8  						DebuggerBreak();									\
   132.9 +					}														\
  132.10  					if ( _bFatal )											\
  132.11 +					{														\
  132.12  						_ExitOnFatalAssert( __TFILE__, __LINE__ );			\
  132.13 +					}														\
  132.14  				}															\
  132.15  			}																\
  132.16  		} while (0)
   133.1 --- a/public/tier0/platform.h	Tue Jul 30 15:10:15 2013 -0700
   133.2 +++ b/public/tier0/platform.h	Mon Sep 02 11:39:10 2013 -0700
   133.3 @@ -150,7 +150,6 @@
   133.4  
   133.5  #if defined(__x86_64__) || defined(_WIN64)
   133.6  	#define X64BITS
   133.7 -	#define PLATFORM_64BITS
   133.8  #endif // __x86_64__
   133.9  
  133.10  #if defined( _WIN32 )
  133.11 @@ -391,7 +390,7 @@
  133.12  	// On OSX, SIGTRAP doesn't really stop the thread cold when debugging.
  133.13  	// So if being debugged, use INT3 which is precise.
  133.14  #ifdef OSX
  133.15 -#define DebuggerBreak()  if ( Plat_IsInDebugSession() ) __asm ( "int $3" ); else { raise(SIGTRAP); }
  133.16 +#define DebuggerBreak()  if ( Plat_IsInDebugSession() ) { __asm ( "int $3" ); } else { raise(SIGTRAP); }
  133.17  #else
  133.18  #define DebuggerBreak()  raise(SIGTRAP)
  133.19  #endif
  133.20 @@ -662,6 +661,7 @@
  133.21  #pragma GCC diagnostic ignored "-Wconversion-null"			// passing NULL to non-pointer argument 1
  133.22  #pragma GCC diagnostic ignored "-Wnull-arithmetic"			// NULL used in arithmetic. Ie, vpanel == NULL where VPANEL is uint.
  133.23  #pragma GCC diagnostic ignored "-Wswitch-enum"				// enumeration values not handled in switch
  133.24 +#pragma GCC diagnostic ignored "-Wswitch"					// enumeration values not handled in switch
  133.25  #endif
  133.26  
  133.27  
   134.1 --- a/public/tier1/fmtstr.h	Tue Jul 30 15:10:15 2013 -0700
   134.2 +++ b/public/tier1/fmtstr.h	Mon Sep 02 11:39:10 2013 -0700
   134.3 @@ -18,6 +18,9 @@
   134.4  #if defined( _WIN32 )
   134.5  #pragma once
   134.6  #endif
   134.7 +#if defined(POSIX)
   134.8 +#pragma GCC visibility push(hidden)
   134.9 +#endif
  134.10  
  134.11  //=============================================================================
  134.12  
  134.13 @@ -28,7 +31,7 @@
  134.14  		int     result; \
  134.15  		va_list arg_ptr; \
  134.16  		bool bTruncated = false; \
  134.17 -		static int scAsserted = 0; \
  134.18 +		static unsigned int scAsserted = 0; \
  134.19  	\
  134.20  		va_start(arg_ptr, lastArg); \
  134.21  		result = Q_vsnprintfRet( (szBuf), nBufSize, (*(ppszFormat)), arg_ptr, &bTruncated ); \
  134.22 @@ -115,7 +118,7 @@
  134.23  		m_nLength = 0; 
  134.24  	}
  134.25  
  134.26 -	void AppendFormat( PRINTF_FORMAT_STRING const char *pchFormat, ... ) 
  134.27 +	void AppendFormat(PRINTF_FORMAT_STRING const char *pchFormat, ... ) FMTFUNCTION( 2, 3 )
  134.28  	{ 
  134.29  		char *pchEnd = m_szBuf + m_nLength; 
  134.30  		FmtStrVSNPrintf( pchEnd, SIZE_BUF - m_nLength, m_bQuietTruncation, &pchFormat, m_nLength, pchFormat ); 
  134.31 @@ -174,6 +177,10 @@
  134.32  }
  134.33  
  134.34  
  134.35 +#if defined(POSIX)
  134.36 +#pragma GCC visibility pop
  134.37 +#endif
  134.38 +
  134.39  //-----------------------------------------------------------------------------
  134.40  //
  134.41  // Purpose: Default-sized string formatter
   135.1 --- a/public/tier1/utlstring.h	Tue Jul 30 15:10:15 2013 -0700
   135.2 +++ b/public/tier1/utlstring.h	Mon Sep 02 11:39:10 2013 -0700
   135.3 @@ -16,7 +16,8 @@
   135.4  #include "limits.h"
   135.5  
   135.6  #if defined( OSX )
   135.7 -inline wchar_t *wcsdup(const wchar_t *pString)
   135.8 +#define wcsdup wcsdup_osx
   135.9 +inline wchar_t *wcsdup_osx(const wchar_t *pString)
  135.10  {
  135.11  	wchar_t *pMemory;
  135.12  
   136.1 --- a/public/vgui_controls/Panel.h	Tue Jul 30 15:10:15 2013 -0700
   136.2 +++ b/public/vgui_controls/Panel.h	Mon Sep 02 11:39:10 2013 -0700
   136.3 @@ -519,10 +519,10 @@
   136.4  	// [tj] Simple getters and setters to decide which corners to draw rounded
   136.5      unsigned char GetRoundedCorners() { return m_roundedCorners; }
   136.6  	void SetRoundedCorners (unsigned char cornerFlags) { m_roundedCorners = cornerFlags; }
   136.7 -	bool ShouldDrawTopLeftCornerRounded() { return m_roundedCorners & PANEL_ROUND_CORNER_TOP_LEFT; }
   136.8 -	bool ShouldDrawTopRightCornerRounded() { return m_roundedCorners & PANEL_ROUND_CORNER_TOP_RIGHT; }
   136.9 -	bool ShouldDrawBottomLeftCornerRounded() { return m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_LEFT; }
  136.10 -	bool ShouldDrawBottomRightCornerRounded() { return m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_RIGHT; }
  136.11 +	bool ShouldDrawTopLeftCornerRounded() { return ( m_roundedCorners & PANEL_ROUND_CORNER_TOP_LEFT ) != 0; }
  136.12 +	bool ShouldDrawTopRightCornerRounded() { return ( m_roundedCorners & PANEL_ROUND_CORNER_TOP_RIGHT ) != 0; }
  136.13 +	bool ShouldDrawBottomLeftCornerRounded() { return ( m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_LEFT ) != 0; }
  136.14 +	bool ShouldDrawBottomRightCornerRounded() { return ( m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_RIGHT ) != 0; }
  136.15  	 
  136.16  	//=============================================================================
  136.17  	// HPE_END
   137.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   137.2 +++ b/raytrace/raytrace.cpp	Mon Sep 02 11:39:10 2013 -0700
   137.3 @@ -0,0 +1,901 @@
   137.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
   137.5 +// $Id$
   137.6 +
   137.7 +#include "raytrace.h"
   137.8 +#include <filesystem_tools.h>
   137.9 +#include <cmdlib.h>
  137.10 +#include <stdio.h>
  137.11 +
  137.12 +static bool SameSign(float a, float b)
  137.13 +{
  137.14 +	int32 aa=*((int *) &a);
  137.15 +	int32 bb=*((int *) &b);
  137.16 +	return ((aa^bb)&0x80000000)==0;
  137.17 +}
  137.18 +
  137.19 +int FourRays::CalculateDirectionSignMask(void) const
  137.20 +{
  137.21 +	// this code treats the floats as integers since all it cares about is the sign bit and
  137.22 +	// floating point compares suck.
  137.23 +
  137.24 +	int ret;
  137.25 +	int ormask;
  137.26 +	int andmask;
  137.27 +	int32 const *treat_as_int=((int32 const *) (&direction));
  137.28 +
  137.29 +	ormask=andmask=*(treat_as_int++);
  137.30 +	ormask|=*treat_as_int;
  137.31 +	andmask&=*(treat_as_int++);
  137.32 +	ormask|=*(treat_as_int);
  137.33 +	andmask&=*(treat_as_int++);
  137.34 +	ormask|=*(treat_as_int);
  137.35 +	andmask&=*(treat_as_int++);
  137.36 +	if (ormask>=0)
  137.37 +		ret=0;
  137.38 +	else
  137.39 +	{
  137.40 +		if (andmask<0)
  137.41 +			ret=1;
  137.42 +		else return -1;
  137.43 +	}
  137.44 +	ormask=andmask=*(treat_as_int++);
  137.45 +	ormask|=*treat_as_int;
  137.46 +	andmask&=*(treat_as_int++);
  137.47 +	ormask|=*(treat_as_int);
  137.48 +	andmask&=*(treat_as_int++);
  137.49 +	ormask|=*(treat_as_int);
  137.50 +	andmask&=*(treat_as_int++);
  137.51 +	if (ormask<0)
  137.52 +	{
  137.53 +		if (andmask<0)
  137.54 +			ret|=2;
  137.55 +		else return -1;
  137.56 +	}
  137.57 +	ormask=andmask=*(treat_as_int++);
  137.58 +	ormask|=*treat_as_int;
  137.59 +	andmask&=*(treat_as_int++);
  137.60 +	ormask|=*(treat_as_int);
  137.61 +	andmask&=*(treat_as_int++);
  137.62 +	ormask|=*(treat_as_int);
  137.63 +	andmask&=*(treat_as_int++);
  137.64 +	if (ormask<0)
  137.65 +	{
  137.66 +		if (andmask<0)
  137.67 +			ret|=4;
  137.68 +		else return -1;
  137.69 +	}
  137.70 +	return ret;
  137.71 +}
  137.72 +
  137.73 +
  137.74 +
  137.75 +
  137.76 +void RayTracingEnvironment::MakeRoomForTriangles( int ntris )
  137.77 +{
  137.78 +	//OptimizedTriangleList.EnsureCapacity( ntris );
  137.79 +	if (! (Flags & RTE_FLAGS_DONT_STORE_TRIANGLE_COLORS))
  137.80 +		TriangleColors.EnsureCapacity( ntris );
  137.81 +}
  137.82 +
  137.83 +
  137.84 +void RayTracingEnvironment::AddTriangle(int32 id, const Vector &v1,
  137.85 +										const Vector &v2, const Vector &v3,
  137.86 +										const Vector &color)
  137.87 +{
  137.88 +	AddTriangle( id, v1, v2, v3, color, 0, 0 );
  137.89 +}
  137.90 +
  137.91 +void RayTracingEnvironment::AddTriangle(int32 id, const Vector &v1,
  137.92 +										const Vector &v2, const Vector &v3,
  137.93 +										const Vector &color, uint16 flags, int32 materialIndex)
  137.94 +{
  137.95 +	CacheOptimizedTriangle tmptri;
  137.96 +	tmptri.m_Data.m_GeometryData.m_nTriangleID = id;
  137.97 +	tmptri.Vertex( 0 ) = v1;
  137.98 +	tmptri.Vertex( 1 ) = v2;
  137.99 +	tmptri.Vertex( 2 ) = v3;
 137.100 +	tmptri.m_Data.m_GeometryData.m_nFlags = flags;
 137.101 +	OptimizedTriangleList.AddToTail(tmptri);
 137.102 +	if (! ( Flags & RTE_FLAGS_DONT_STORE_TRIANGLE_COLORS) )
 137.103 +		TriangleColors.AddToTail(color);
 137.104 +	if ( !( Flags & RTE_FLAGS_DONT_STORE_TRIANGLE_MATERIALS) )
 137.105 +		TriangleMaterials.AddToTail(materialIndex);
 137.106 +// 	printf("add triange from (%f %f %f),(%f %f %f),(%f %f %f) id %d\n",
 137.107 +// 		   XYZ(v1),XYZ(v2),XYZ(v3),id);
 137.108 +}
 137.109 +
 137.110 +void RayTracingEnvironment::AddQuad(
 137.111 +	int32 id, const Vector &v1, const Vector &v2, const Vector &v3,
 137.112 +	const Vector &v4,							// specify vertices in cw or ccw order
 137.113 +	const Vector &color)
 137.114 +{
 137.115 +	AddTriangle(id,v1,v2,v3,color);
 137.116 +	AddTriangle(id+1,v1,v3,v4,color);
 137.117 +}
 137.118 +
 137.119 +
 137.120 +void RayTracingEnvironment::AddAxisAlignedRectangularSolid(int id,Vector minc, Vector maxc,
 137.121 +														   const Vector &color)
 137.122 +{
 137.123 +
 137.124 +	// "far" face
 137.125 +	AddQuad(id,
 137.126 +			Vector(minc.x,maxc.y,maxc.z),
 137.127 +			Vector(maxc.x,maxc.y,maxc.z),Vector(maxc.x,minc.y,maxc.z),
 137.128 +			Vector(minc.x,minc.y,maxc.z),color);
 137.129 +	// "near" face
 137.130 +	AddQuad(id,
 137.131 +			Vector(minc.x,maxc.y,minc.z),
 137.132 +			Vector(maxc.x,maxc.y,minc.z),Vector(maxc.x,minc.y,minc.z),
 137.133 +			Vector(minc.x,minc.y,minc.z),color);
 137.134 +
 137.135 +	// "left" face
 137.136 +	AddQuad(id,
 137.137 +			Vector(minc.x,maxc.y,maxc.z),
 137.138 +			Vector(minc.x,maxc.y,minc.z),
 137.139 +			Vector(minc.x,minc.y,minc.z),
 137.140 +			Vector(minc.x,minc.y,maxc.z),color);
 137.141 +	// "right" face
 137.142 +	AddQuad(id,
 137.143 +			Vector(maxc.x,maxc.y,maxc.z),
 137.144 +			Vector(maxc.x,maxc.y,minc.z),
 137.145 +			Vector(maxc.x,minc.y,minc.z),
 137.146 +			Vector(maxc.x,minc.y,maxc.z),color);
 137.147 +	
 137.148 +	// "top" face
 137.149 +	AddQuad(id,
 137.150 +			Vector(minc.x,maxc.y,maxc.z),
 137.151 +			Vector(maxc.x,maxc.y,maxc.z),
 137.152 +			Vector(maxc.x,maxc.y,minc.z),
 137.153 +			Vector(minc.x,maxc.y,minc.z),color);
 137.154 +	// "bot" face
 137.155 +	AddQuad(id,
 137.156 +			Vector(minc.x,minc.y,maxc.z),
 137.157 +			Vector(maxc.x,minc.y,maxc.z),
 137.158 +			Vector(maxc.x,minc.y,minc.z),
 137.159 +			Vector(minc.x,minc.y,minc.z),color);
 137.160 +}
 137.161 +
 137.162 +
 137.163 +
 137.164 +static Vector GetEdgeEquation(Vector p1, Vector p2, int c1, int c2, Vector InsidePoint)
 137.165 +{
 137.166 +	float nx=p1[c2]-p2[c2];
 137.167 +	float ny=p2[c1]-p1[c1];
 137.168 +	float d=-(nx*p1[c1]+ny*p1[c2]);
 137.169 +// 	assert(fabs(nx*p1[c1]+ny*p1[c2]+d)<0.01);
 137.170 +// 	assert(fabs(nx*p2[c1]+ny*p2[c2]+d)<0.01);
 137.171 +
 137.172 +	// use the convention that negative is "outside"
 137.173 +	float trial_dist=InsidePoint[c1]*nx+InsidePoint[c2]*ny+d;
 137.174 +	if (trial_dist<0)
 137.175 +	{
 137.176 +		nx = -nx;
 137.177 +		ny = -ny;
 137.178 +		d = -d;
 137.179 +		trial_dist = -trial_dist;
 137.180 +	}
 137.181 +	nx /= trial_dist;										// scale so that it will be =1.0 at the oppositve vertex
 137.182 +	ny /= trial_dist;
 137.183 +	d /= trial_dist;
 137.184 +
 137.185 +	return Vector(nx,ny,d);
 137.186 +}
 137.187 +
 137.188 +void CacheOptimizedTriangle::ChangeIntoIntersectionFormat(void)
 137.189 +{
 137.190 +	// lose the vertices and use edge equations instead
 137.191 +
 137.192 +	// grab the whole original triangle to we don't overwrite it
 137.193 +	TriGeometryData_t srcTri = m_Data.m_GeometryData;
 137.194 +
 137.195 +	m_Data.m_IntersectData.m_nFlags = srcTri.m_nFlags;
 137.196 +	m_Data.m_IntersectData.m_nTriangleID = srcTri.m_nTriangleID;
 137.197 +
 137.198 +	Vector p1 = srcTri.Vertex( 0 );
 137.199 +	Vector p2 = srcTri.Vertex( 1 );
 137.200 +	Vector p3 = srcTri.Vertex( 2 );
 137.201 +
 137.202 +	Vector e1 = p2 - p1;
 137.203 +	Vector e2 = p3 - p1;
 137.204 +
 137.205 +	Vector N = e1.Cross( e2 );
 137.206 +	N.NormalizeInPlace();
 137.207 +	// now, determine which axis to drop
 137.208 +	int drop_axis = 0;
 137.209 +	for(int c=1 ; c<3 ; c++)
 137.210 +		if ( fabs(N[c]) > fabs( N[drop_axis] ) )
 137.211 +			drop_axis = c;
 137.212 +
 137.213 +	m_Data.m_IntersectData.m_flD = N.Dot( p1 );
 137.214 +	m_Data.m_IntersectData.m_flNx = N.x;
 137.215 +	m_Data.m_IntersectData.m_flNy = N.y;
 137.216 +	m_Data.m_IntersectData.m_flNz = N.z;
 137.217 +
 137.218 +	// decide which axes to keep
 137.219 +	int nCoordSelect0 = ( drop_axis + 1 ) % 3;
 137.220 +	int nCoordSelect1 = ( drop_axis + 2 ) % 3;
 137.221 +
 137.222 +	m_Data.m_IntersectData.m_nCoordSelect0 = nCoordSelect0;
 137.223 +	m_Data.m_IntersectData.m_nCoordSelect1 = nCoordSelect1;
 137.224 +
 137.225 +
 137.226 +	Vector edge1 = GetEdgeEquation( p1, p2, nCoordSelect0, nCoordSelect1, p3 );
 137.227 +	m_Data.m_IntersectData.m_ProjectedEdgeEquations[0] = edge1.x;
 137.228 +	m_Data.m_IntersectData.m_ProjectedEdgeEquations[1] = edge1.y;
 137.229 +	m_Data.m_IntersectData.m_ProjectedEdgeEquations[2] = edge1.z;
 137.230 +
 137.231 +	Vector edge2 = GetEdgeEquation( p2, p3, nCoordSelect0, nCoordSelect1, p1 );
 137.232 +	m_Data.m_IntersectData.m_ProjectedEdgeEquations[3] = edge2.x;
 137.233 +	m_Data.m_IntersectData.m_ProjectedEdgeEquations[4] = edge2.y;
 137.234 +	m_Data.m_IntersectData.m_ProjectedEdgeEquations[5] = edge2.z;
 137.235 +
 137.236 +
 137.237 +}
 137.238 +
 137.239 +int n_intersection_calculations=0;
 137.240 +
 137.241 +int CacheOptimizedTriangle::ClassifyAgainstAxisSplit(int split_plane, float split_value)
 137.242 +{
 137.243 +	// classify a triangle against an axis-aligned plane
 137.244 +	float minc=Vertex(0)[split_plane];
 137.245 +	float maxc=minc;
 137.246 +	for(int v=1;v<3;v++)
 137.247 +	{
 137.248 +		minc=min(minc,Vertex(v)[split_plane]);
 137.249 +		maxc=max(maxc,Vertex(v)[split_plane]);
 137.250 +	}
 137.251 +
 137.252 +	if (minc>=split_value)
 137.253 +		return PLANECHECK_POSITIVE;
 137.254 +	if (maxc<=split_value)
 137.255 +		return PLANECHECK_NEGATIVE;
 137.256 +	if (minc==maxc)
 137.257 +		return PLANECHECK_POSITIVE;
 137.258 +	return PLANECHECK_STRADDLING;
 137.259 +}
 137.260 +
 137.261 +#define MAILBOX_HASH_SIZE 256
 137.262 +#define MAX_TREE_DEPTH 21
 137.263 +#define MAX_NODE_STACK_LEN (40*MAX_TREE_DEPTH)
 137.264 +
 137.265 +struct NodeToVisit {
 137.266 +	CacheOptimizedKDNode const *node;
 137.267 +	fltx4 TMin;
 137.268 +	fltx4 TMax;
 137.269 +};
 137.270 +
 137.271 +
 137.272 +static fltx4 FourEpsilons={1.0e-10,1.0e-10,1.0e-10,1.0e-10};
 137.273 +static fltx4 FourZeros={1.0e-10,1.0e-10,1.0e-10,1.0e-10};
 137.274 +static fltx4 FourNegativeEpsilons={-1.0e-10,-1.0e-10,-1.0e-10,-1.0e-10};
 137.275 +
 137.276 +static float BoxSurfaceArea(Vector const &boxmin, Vector const &boxmax)
 137.277 +{
 137.278 +	Vector boxdim=boxmax-boxmin;
 137.279 +	return 2.0*((boxdim[0]*boxdim[2])+(boxdim[0]*boxdim[1])+(boxdim[1]*boxdim[2]));
 137.280 +}
 137.281 +
 137.282 +void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 TMax,
 137.283 +									   RayTracingResult *rslt_out,
 137.284 +									   int32 skip_id, ITransparentTriangleCallback *pCallback)
 137.285 +{
 137.286 +	int msk=rays.CalculateDirectionSignMask();
 137.287 +	if (msk!=-1)
 137.288 +		Trace4Rays(rays,TMin,TMax,msk,rslt_out,skip_id, pCallback);
 137.289 +	else
 137.290 +	{
 137.291 +		// sucky case - can't trace 4 rays at once. in the worst case, need to trace all 4
 137.292 +		// separately, but usually we will still get 2x, Since our tracer only does 4 at a
 137.293 +		// time, we will have to cover up the undesired rays with the desired ray
 137.294 +
 137.295 +		//!! speed!! there is room for some sse-ization here
 137.296 +		FourRays tmprays;
 137.297 +		tmprays.origin=rays.origin;
 137.298 +
 137.299 +		uint8 need_trace[4]={1,1,1,1};
 137.300 +		for(int try_trace=0;try_trace<4;try_trace++)
 137.301 +		{
 137.302 +			if (need_trace[try_trace])
 137.303 +			{
 137.304 +				need_trace[try_trace]=2;			// going to trace it
 137.305 +				// replicate the ray being traced into all 4 rays
 137.306 +				tmprays.direction.x=ReplicateX4(rays.direction.X(try_trace));
 137.307 +				tmprays.direction.y=ReplicateX4(rays.direction.Y(try_trace));
 137.308 +				tmprays.direction.z=ReplicateX4(rays.direction.Z(try_trace));
 137.309 +				// now, see if any of the other remaining rays can be handled at the same time.
 137.310 +				for(int try2=try_trace+1;try2<4;try2++)
 137.311 +					if (need_trace[try2])
 137.312 +					{
 137.313 +						if (
 137.314 +							SameSign(rays.direction.X(try2),
 137.315 +									 rays.direction.X(try_trace)) &&
 137.316 +							SameSign(rays.direction.Y(try2),
 137.317 +									 rays.direction.Y(try_trace)) &&
 137.318 +							SameSign(rays.direction.Z(try2),
 137.319 +									 rays.direction.Z(try_trace)))
 137.320 +						{
 137.321 +							need_trace[try2]=2;
 137.322 +							tmprays.direction.X(try2) = rays.direction.X(try2);
 137.323 +							tmprays.direction.Y(try2) = rays.direction.Y(try2);
 137.324 +							tmprays.direction.Z(try2) = rays.direction.Z(try2);
 137.325 +						}
 137.326 +					}
 137.327 +				// ok, now trace between 1 and 3 rays, and output the results
 137.328 +				RayTracingResult tmpresults;
 137.329 +				msk=tmprays.CalculateDirectionSignMask();
 137.330 +				assert(msk!=-1);
 137.331 +				Trace4Rays(tmprays,TMin,TMax,msk,&tmpresults,skip_id, pCallback);
 137.332 +				// now, move results to proper place
 137.333 +				for(int i=0;i<4;i++)
 137.334 +					if (need_trace[i]==2)
 137.335 +					{
 137.336 +						need_trace[i]=0;
 137.337 +						rslt_out->HitIds[i]=tmpresults.HitIds[i];
 137.338 +						SubFloat(rslt_out->HitDistance, i) = SubFloat(tmpresults.HitDistance, i);
 137.339 +						rslt_out->surface_normal.X(i) = tmpresults.surface_normal.X(i);
 137.340 +						rslt_out->surface_normal.Y(i) = tmpresults.surface_normal.Y(i);
 137.341 +						rslt_out->surface_normal.Z(i) = tmpresults.surface_normal.Z(i);
 137.342 +					}
 137.343 +				
 137.344 +			}
 137.345 +		}
 137.346 +	}
 137.347 +}
 137.348 +
 137.349 +
 137.350 +void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 TMax,
 137.351 +									   int DirectionSignMask, RayTracingResult *rslt_out,
 137.352 +									   int32 skip_id, ITransparentTriangleCallback *pCallback)
 137.353 +{
 137.354 +	rays.Check();
 137.355 +
 137.356 +	memset(rslt_out->HitIds,0xff,sizeof(rslt_out->HitIds));
 137.357 +
 137.358 +	rslt_out->HitDistance=ReplicateX4(1.0e23);
 137.359 +
 137.360 +	rslt_out->surface_normal.DuplicateVector(Vector(0.,0.,0.));
 137.361 +	FourVectors OneOverRayDir=rays.direction;
 137.362 +	OneOverRayDir.MakeReciprocalSaturate();
 137.363 +	
 137.364 +	// now, clip rays against bounding box
 137.365 +	for(int c=0;c<3;c++)
 137.366 +	{
 137.367 +		fltx4 isect_min_t=
 137.368 +			MulSIMD(SubSIMD(ReplicateX4(m_MinBound[c]),rays.origin[c]),OneOverRayDir[c]);
 137.369 +		fltx4 isect_max_t=
 137.370 +			MulSIMD(SubSIMD(ReplicateX4(m_MaxBound[c]),rays.origin[c]),OneOverRayDir[c]);
 137.371 +		TMin=MaxSIMD(TMin,MinSIMD(isect_min_t,isect_max_t));
 137.372 +		TMax=MinSIMD(TMax,MaxSIMD(isect_min_t,isect_max_t));
 137.373 +	}
 137.374 +	fltx4 active=CmpLeSIMD(TMin,TMax);					// mask of which rays are active
 137.375 +	if (! IsAnyNegative(active) )
 137.376 +		return;												// missed bounding box
 137.377 +
 137.378 +	int32 mailboxids[MAILBOX_HASH_SIZE];					// used to avoid redundant triangle tests
 137.379 +	memset(mailboxids,0xff,sizeof(mailboxids));				// !!speed!! keep around?
 137.380 +
 137.381 +	int front_idx[3],back_idx[3];							// based on ray direction, whether to
 137.382 +															// visit left or right node first
 137.383 +
 137.384 +	if (DirectionSignMask & 1)
 137.385 +	{
 137.386 +		back_idx[0]=0;
 137.387 +		front_idx[0]=1;
 137.388 +	}
 137.389 +		else
 137.390 +	{
 137.391 +		back_idx[0]=1;
 137.392 +		front_idx[0]=0;
 137.393 +	}
 137.394 +	if (DirectionSignMask & 2)
 137.395 +	{
 137.396 +		back_idx[1]=0;
 137.397 +		front_idx[1]=1;
 137.398 +	}
 137.399 +	else
 137.400 +	{
 137.401 +		back_idx[1]=1;
 137.402 +		front_idx[1]=0;
 137.403 +	}
 137.404 +	if (DirectionSignMask & 4)
 137.405 +	{
 137.406 +		back_idx[2]=0;
 137.407 +		front_idx[2]=1;
 137.408 +	}
 137.409 +	else
 137.410 +	{
 137.411 +		back_idx[2]=1;
 137.412 +		front_idx[2]=0;
 137.413 +	}
 137.414 +		
 137.415 +	NodeToVisit NodeQueue[MAX_NODE_STACK_LEN];
 137.416 +	CacheOptimizedKDNode const *CurNode=&(OptimizedKDTree[0]);
 137.417 +	NodeToVisit *stack_ptr=&NodeQueue[MAX_NODE_STACK_LEN];
 137.418 +	while(1)
 137.419 +	{
 137.420 +		while (CurNode->NodeType() != KDNODE_STATE_LEAF)		// traverse until next leaf
 137.421 +		{	   
 137.422 +			int split_plane_number=CurNode->NodeType();
 137.423 +			CacheOptimizedKDNode const *FrontChild=&(OptimizedKDTree[CurNode->LeftChild()]);
 137.424 +			
 137.425 +			fltx4 dist_to_sep_plane=						// dist=(split-org)/dir
 137.426 +				MulSIMD(
 137.427 +					SubSIMD(ReplicateX4(CurNode->SplittingPlaneValue),
 137.428 +							   rays.origin[split_plane_number]),OneOverRayDir[split_plane_number]);
 137.429 +			fltx4 active=CmpLeSIMD(TMin,TMax);			// mask of which rays are active
 137.430 +
 137.431 +			// now, decide how to traverse children. can either do front,back, or do front and push
 137.432 +			// back.
 137.433 +			fltx4 hits_front=AndSIMD(active,CmpGeSIMD(dist_to_sep_plane,TMin));
 137.434 +			if (! IsAnyNegative(hits_front))
 137.435 +			{
 137.436 +				// missed the front. only traverse back
 137.437 +				//printf("only visit back %d\n",CurNode->LeftChild()+back_idx[split_plane_number]);
 137.438 +				CurNode=FrontChild+back_idx[split_plane_number];
 137.439 +				TMin=MaxSIMD(TMin, dist_to_sep_plane);
 137.440 +
 137.441 +			}
 137.442 +			else
 137.443 +			{
 137.444 +				fltx4 hits_back=AndSIMD(active,CmpLeSIMD(dist_to_sep_plane,TMax));
 137.445 +				if (! IsAnyNegative(hits_back) )
 137.446 +				{
 137.447 +					// missed the back - only need to traverse front node
 137.448 +					//printf("only visit front %d\n",CurNode->LeftChild()+front_idx[split_plane_number]);
 137.449 +					CurNode=FrontChild+front_idx[split_plane_number];
 137.450 +					TMax=MinSIMD(TMax, dist_to_sep_plane);
 137.451 +				}
 137.452 +				else
 137.453 +				{
 137.454 +					// at least some rays hit both nodes.
 137.455 +					// must push far, traverse near
 137.456 + 					//printf("visit %d,%d\n",CurNode->LeftChild()+front_idx[split_plane_number],
 137.457 + 					//	   CurNode->LeftChild()+back_idx[split_plane_number]);
 137.458 +					assert(stack_ptr>NodeQueue);
 137.459 +					--stack_ptr;
 137.460 +					stack_ptr->node=FrontChild+back_idx[split_plane_number];
 137.461 +					stack_ptr->TMin=MaxSIMD(TMin,dist_to_sep_plane);
 137.462 +					stack_ptr->TMax=TMax;
 137.463 +					CurNode=FrontChild+front_idx[split_plane_number];
 137.464 +					TMax=MinSIMD(TMax,dist_to_sep_plane);
 137.465 +				}
 137.466 +			}
 137.467 +		}
 137.468 +		// hit a leaf! must do intersection check
 137.469 +		int ntris=CurNode->NumberOfTrianglesInLeaf();
 137.470 +		if (ntris)
 137.471 +		{
 137.472 +			int32 const *tlist=&(TriangleIndexList[CurNode->TriangleIndexStart()]);
 137.473 +			do
 137.474 +			{
 137.475 +				int tnum=*(tlist++);
 137.476 +				//printf("try tri %d\n",tnum);
 137.477 +				// check mailbox
 137.478 +				int mbox_slot=tnum & (MAILBOX_HASH_SIZE-1);
 137.479 +				TriIntersectData_t const *tri = &( OptimizedTriangleList[tnum].m_Data.m_IntersectData );
 137.480 +				if ( ( mailboxids[mbox_slot] != tnum ) && ( tri->m_nTriangleID != skip_id ) )
 137.481 +				{
 137.482 +					n_intersection_calculations++;
 137.483 +					mailboxids[mbox_slot] = tnum;
 137.484 +					// compute plane intersection
 137.485 +
 137.486 +
 137.487 +					FourVectors N;
 137.488 +					N.x = ReplicateX4( tri->m_flNx );
 137.489 +					N.y = ReplicateX4( tri->m_flNy );
 137.490 +					N.z = ReplicateX4( tri->m_flNz );
 137.491 +
 137.492 +					fltx4 DDotN = rays.direction * N;
 137.493 +					// mask off zero or near zero (ray parallel to surface)
 137.494 +					fltx4 did_hit = OrSIMD( CmpGtSIMD( DDotN,FourEpsilons ),
 137.495 +											CmpLtSIMD( DDotN, FourNegativeEpsilons ) );
 137.496 +
 137.497 +					fltx4 numerator=SubSIMD( ReplicateX4( tri->m_flD ), rays.origin * N );
 137.498 +
 137.499 +					fltx4 isect_t=DivSIMD( numerator,DDotN );
 137.500 +					// now, we have the distance to the plane. lets update our mask
 137.501 +					did_hit = AndSIMD( did_hit, CmpGtSIMD( isect_t, FourZeros ) );
 137.502 +					//did_hit=AndSIMD(did_hit,CmpLtSIMD(isect_t,TMax));
 137.503 +					did_hit = AndSIMD( did_hit, CmpLtSIMD( isect_t, rslt_out->HitDistance ) );
 137.504 +
 137.505 +					if ( ! IsAnyNegative( did_hit ) )
 137.506 +						continue;
 137.507 +
 137.508 +					// now, check 3 edges
 137.509 +					fltx4 hitc1 = AddSIMD( rays.origin[tri->m_nCoordSelect0],
 137.510 +										MulSIMD( isect_t, rays.direction[ tri->m_nCoordSelect0] ) );
 137.511 +					fltx4 hitc2 = AddSIMD( rays.origin[tri->m_nCoordSelect1],
 137.512 +										   MulSIMD( isect_t, rays.direction[tri->m_nCoordSelect1] ) );
 137.513 +					
 137.514 +					// do barycentric coordinate check
 137.515 +					fltx4 B0 = MulSIMD( ReplicateX4( tri->m_ProjectedEdgeEquations[0] ), hitc1 );
 137.516 +
 137.517 +					B0 = AddSIMD(
 137.518 +						B0,
 137.519 +						MulSIMD( ReplicateX4( tri->m_ProjectedEdgeEquations[1] ), hitc2 ) );
 137.520 +					B0 = AddSIMD(
 137.521 +						B0, ReplicateX4( tri->m_ProjectedEdgeEquations[2] ) );
 137.522 +
 137.523 +					did_hit = AndSIMD( did_hit, CmpGeSIMD( B0, FourZeros ) );
 137.524 +
 137.525 +					fltx4 B1 = MulSIMD( ReplicateX4( tri->m_ProjectedEdgeEquations[3] ), hitc1 );
 137.526 +					B1 = AddSIMD(
 137.527 +						B1,
 137.528 +						MulSIMD( ReplicateX4( tri->m_ProjectedEdgeEquations[4]), hitc2 ) );
 137.529 +
 137.530 +					B1 = AddSIMD(
 137.531 +						B1, ReplicateX4( tri->m_ProjectedEdgeEquations[5] ) );
 137.532 +					
 137.533 +					did_hit = AndSIMD( did_hit, CmpGeSIMD( B1, FourZeros ) );
 137.534 +
 137.535 +					fltx4 B2 = AddSIMD( B1, B0 );
 137.536 +					did_hit = AndSIMD( did_hit, CmpLeSIMD( B2, Four_Ones ) );
 137.537 +
 137.538 +					if ( ! IsAnyNegative( did_hit ) )
 137.539 +						continue;
 137.540 +
 137.541 +					// if the triangle is transparent
 137.542 +					if ( tri->m_nFlags & FCACHETRI_TRANSPARENT )
 137.543 +					{
 137.544 +						if ( pCallback )
 137.545 +						{
 137.546 +							// assuming a triangle indexed as v0, v1, v2
 137.547 +							// the projected edge equations are set up such that the vert opposite the first
 137.548 +							// equation is v2, and the vert opposite the second equation is v0
 137.549 +							// Therefore we pass them back in 1, 2, 0 order
 137.550 +							// Also B2 is currently B1 + B0 and needs to be 1 - (B1+B0) in order to be a real
 137.551 +							// barycentric coordinate.  Compute that now and pass it to the callback
 137.552 +							fltx4 b2 = SubSIMD( Four_Ones, B2 );
 137.553 +							if ( pCallback->VisitTriangle_ShouldContinue( *tri, rays, &did_hit, &B1, &b2, &B0, tnum ) )
 137.554 +							{
 137.555 +								did_hit = Four_Zeros;
 137.556 +							}
 137.557 +						}
 137.558 +					}
 137.559 +					// now, set the hit_id and closest_hit fields for any enabled rays
 137.560 +					fltx4 replicated_n = ReplicateIX4(tnum);
 137.561 +					StoreAlignedSIMD((float *) rslt_out->HitIds,
 137.562 +								 OrSIMD(AndSIMD(replicated_n,did_hit),
 137.563 +										   AndNotSIMD(did_hit,LoadAlignedSIMD(
 137.564 +															 (float *) rslt_out->HitIds))));
 137.565 +					rslt_out->HitDistance=OrSIMD(AndSIMD(isect_t,did_hit),
 137.566 +									 AndNotSIMD(did_hit,rslt_out->HitDistance));
 137.567 +
 137.568 +					rslt_out->surface_normal.x=OrSIMD(
 137.569 +						AndSIMD(N.x,did_hit),
 137.570 +						AndNotSIMD(did_hit,rslt_out->surface_normal.x));
 137.571 +					rslt_out->surface_normal.y=OrSIMD(
 137.572 +						AndSIMD(N.y,did_hit),
 137.573 +						AndNotSIMD(did_hit,rslt_out->surface_normal.y));
 137.574 +					rslt_out->surface_normal.z=OrSIMD(
 137.575 +						AndSIMD(N.z,did_hit),
 137.576 +						AndNotSIMD(did_hit,rslt_out->surface_normal.z));
 137.577 +					
 137.578 +				}
 137.579 +			} while (--ntris);
 137.580 +			// now, check if all rays have terminated
 137.581 +			fltx4 raydone=CmpLeSIMD(TMax,rslt_out->HitDistance);
 137.582 +			if (! IsAnyNegative(raydone))
 137.583 +			{
 137.584 +				return;
 137.585 +			}
 137.586 +		}
 137.587 +		
 137.588 + 		if (stack_ptr==&NodeQueue[MAX_NODE_STACK_LEN])
 137.589 +		{
 137.590 +			return;
 137.591 +		}
 137.592 +		// pop stack!
 137.593 +		CurNode=stack_ptr->node;
 137.594 +		TMin=stack_ptr->TMin;
 137.595 +		TMax=stack_ptr->TMax;
 137.596 +		stack_ptr++;
 137.597 +	}
 137.598 +}
 137.599 +
 137.600 +
 137.601 +int RayTracingEnvironment::MakeLeafNode(int first_tri, int last_tri)
 137.602 +{
 137.603 +	CacheOptimizedKDNode ret;
 137.604 +	ret.Children=KDNODE_STATE_LEAF+(TriangleIndexList.Count()<<2);
 137.605 +	ret.SetNumberOfTrianglesInLeafNode(1+(last_tri-first_tri));
 137.606 +	for(int tnum=first_tri;tnum<=last_tri;tnum++)
 137.607 +		TriangleIndexList.AddToTail(tnum);
 137.608 +	OptimizedKDTree.AddToTail(ret);
 137.609 +	return OptimizedKDTree.Count()-1;
 137.610 +}
 137.611 +
 137.612 +
 137.613 +void RayTracingEnvironment::CalculateTriangleListBounds(int32 const *tris,int ntris,
 137.614 +														Vector &minout, Vector &maxout)
 137.615 +{
 137.616 +	minout = Vector( 1.0e23, 1.0e23, 1.0e23);
 137.617 +	maxout = Vector( -1.0e23, -1.0e23, -1.0e23);
 137.618 +	for(int i=0; i<ntris; i++)
 137.619 +	{
 137.620 +		CacheOptimizedTriangle const &tri=OptimizedTriangleList[tris[i]];
 137.621 +		for(int v=0; v<3; v++)
 137.622 +			for(int c=0; c<3; c++)
 137.623 +			{
 137.624 +				minout[c]=min(minout[c],tri.Vertex(v)[c]);
 137.625 +							  maxout[c]=max(maxout[c],tri.Vertex(v)[c]);
 137.626 +			}
 137.627 +	}
 137.628 +}
 137.629 +
 137.630 +
 137.631 +// Both the "quick" and regular kd tree building algorithms here use the "surface area heuristic":
 137.632 +// the relative probability of hitting the "left" subvolume (Vl) from a split is equal to that
 137.633 +// subvolume's surface area divided by its parent's surface area (Vp) : P(Vl | V)=SA(Vl)/SA(Vp).
 137.634 +// The same holds for the right subvolume, Vp. Nl is the number of triangles in the left volume,
 137.635 +// and Nr in the right volume. if Ct is the cost of traversing one tree node, and Ci is the cost of
 137.636 +// intersection with the primitive, than the cost of splitting is estimated as:
 137.637 +//
 137.638 +//    Ct+Ci*((SA(Vl)/SA(V))*Nl+(SA(Vr)/SA(V)*Nr)).
 137.639 +// and the cost of not splitting is
 137.640 +//    Ci*N
 137.641 +//
 137.642 +//  This both provides a metric to minimize when computing how and where to split, and also a
 137.643 +//  termination criterion.
 137.644 +//
 137.645 +// the "quick" method just splits down the middle, while the slow method splits at the best
 137.646 +// discontinuity of the cost formula. The quick method splits along the longest axis ; the 
 137.647 +// regular algorithm tries all 3 to find which one results in the minimum cost
 137.648 +// 
 137.649 +// both methods use the additional optimization of "growing" empty nodes - if the split results in
 137.650 +// one side being devoid of triangles, the empty side is "grown" as much as possible.
 137.651 +//
 137.652 +
 137.653 +#define COST_OF_TRAVERSAL 75								// approximate #operations
 137.654 +#define COST_OF_INTERSECTION 167							// approximate #operations
 137.655 +
 137.656 +
 137.657 +float RayTracingEnvironment::CalculateCostsOfSplit(
 137.658 +	int split_plane,int32 const *tri_list,int ntris,
 137.659 +	Vector MinBound,Vector MaxBound, float &split_value,
 137.660 +	int &nleft, int &nright, int &nboth)
 137.661 +{
 137.662 +	// determine the costs of splitting on a given axis, and label triangles with respect to
 137.663 +	// that axis by storing the value in coordselect0. It will also return the number of
 137.664 +	// tris in the left, right, and nboth groups, in order to facilitate memory
 137.665 +	nleft=nboth=nright=0;
 137.666 +	
 137.667 +	// now, label each triangle. Since we have not converted the triangles into
 137.668 +	// intersection fromat yet, we can use the CoordSelect0 field of each as a temp.
 137.669 +	nleft=0;
 137.670 +	nright=0;
 137.671 +	nboth=0;
 137.672 +	float min_coord=1.0e23,max_coord=-1.0e23;
 137.673 +
 137.674 +	for(int t=0;t<ntris;t++)
 137.675 +	{
 137.676 +		CacheOptimizedTriangle &tri=OptimizedTriangleList[tri_list[t]];
 137.677 +		// determine max and min coordinate values for later optimization
 137.678 +		for(int v=0;v<3;v++)
 137.679 +		{
 137.680 +			min_coord = min( min_coord, tri.Vertex(v)[split_plane] );
 137.681 +			max_coord = max( max_coord, tri.Vertex(v)[split_plane] );
 137.682 +		}
 137.683 +		switch(tri.ClassifyAgainstAxisSplit(split_plane,split_value))
 137.684 +		{
 137.685 +			case PLANECHECK_NEGATIVE:
 137.686 +				nleft++;
 137.687 +				tri.m_Data.m_GeometryData.m_nTmpData0 = PLANECHECK_NEGATIVE;
 137.688 +				break;
 137.689 +
 137.690 +			case PLANECHECK_POSITIVE:
 137.691 +				nright++;
 137.692 +				tri.m_Data.m_GeometryData.m_nTmpData0 = PLANECHECK_POSITIVE;
 137.693 +				break;
 137.694 +
 137.695 +			case PLANECHECK_STRADDLING:
 137.696 +				nboth++;
 137.697 +				tri.m_Data.m_GeometryData.m_nTmpData0 = PLANECHECK_STRADDLING;
 137.698 +				break;
 137.699 +		}
 137.700 +	}
 137.701 +	// now, if the split resulted in one half being empty, "grow" the empty half
 137.702 +	if (nleft && (nboth==0) && (nright==0))
 137.703 +		split_value=max_coord;
 137.704 +	if (nright && (nboth==0) && (nleft==0))
 137.705 +		split_value=min_coord;
 137.706 +
 137.707 +	// now, perform surface area/cost check to determine whether this split was worth it
 137.708 +	Vector LeftMins=MinBound;
 137.709 +	Vector LeftMaxes=MaxBound;
 137.710 +	Vector RightMins=MinBound;
 137.711 +	Vector RightMaxes=MaxBound;
 137.712 +	LeftMaxes[split_plane]=split_value;
 137.713 +	RightMins[split_plane]=split_value;
 137.714 +	float SA_L=BoxSurfaceArea(LeftMins,LeftMaxes);
 137.715 +	float SA_R=BoxSurfaceArea(RightMins,RightMaxes);
 137.716 +	float ISA=1.0/BoxSurfaceArea(MinBound,MaxBound);
 137.717 +	float cost_of_split=COST_OF_TRAVERSAL+COST_OF_INTERSECTION*(nboth+
 137.718 +		(SA_L*ISA*(nleft))+(SA_R*ISA*(nright)));
 137.719 +	return cost_of_split;
 137.720 +}
 137.721 +
 137.722 +
 137.723 +#define NEVER_SPLIT 0
 137.724 +
 137.725 +void RayTracingEnvironment::RefineNode(int node_number,int32 const *tri_list,int ntris,
 137.726 +									   Vector MinBound,Vector MaxBound, int depth)
 137.727 +{
 137.728 +	if (ntris<3)											// never split empty lists
 137.729 +	{
 137.730 +		// no point in continuing
 137.731 +		OptimizedKDTree[node_number].Children=KDNODE_STATE_LEAF+(TriangleIndexList.Count()<<2);
 137.732 +		OptimizedKDTree[node_number].SetNumberOfTrianglesInLeafNode(ntris);
 137.733 +
 137.734 +#ifdef DEBUG_RAYTRACE
 137.735 +		OptimizedKDTree[node_number].vecMins = MinBound;
 137.736 +		OptimizedKDTree[node_number].vecMaxs = MaxBound;
 137.737 +#endif
 137.738 +
 137.739 +		for(int t=0;t<ntris;t++)
 137.740 +			TriangleIndexList.AddToTail(tri_list[t]);
 137.741 +		return;
 137.742 +	}
 137.743 +
 137.744 +	float best_cost=1.0e23;
 137.745 +	int best_nleft=0,best_nright=0,best_nboth=0;
 137.746 +	float best_splitvalue=0;
 137.747 +	int split_plane=0;
 137.748 +
 137.749 +	int tri_skip=1+(ntris/10);								// don't try all trinagles as split
 137.750 +															// points when there are a lot of them
 137.751 +	for(int axis=0;axis<3;axis++)
 137.752 +	{
 137.753 +		for(int ts=-1;ts<ntris;ts+=tri_skip)
 137.754 +		{
 137.755 +			for(int tv=0;tv<3;tv++)
 137.756 +			{
 137.757 +				int trial_nleft,trial_nright,trial_nboth;
 137.758 +				float trial_splitvalue;
 137.759 +				if (ts==-1)
 137.760 +					trial_splitvalue=0.5*(MinBound[axis]+MaxBound[axis]);
 137.761 +				else
 137.762 +				{
 137.763 +					// else, split at the triangle vertex if possible
 137.764 +					CacheOptimizedTriangle &tri=OptimizedTriangleList[tri_list[ts]];
 137.765 +					trial_splitvalue = tri.Vertex(tv)[axis];
 137.766 +					if ((trial_splitvalue>MaxBound[axis]) || (trial_splitvalue<MinBound[axis]))
 137.767 +						continue;							// don't try this vertex - not inside
 137.768 +					
 137.769 +				}
 137.770 +//				printf("ts=%d tv=%d tp=%f\n",ts,tv,trial_splitvalue);
 137.771 +				float trial_cost=
 137.772 +					CalculateCostsOfSplit(axis,tri_list,ntris,MinBound,MaxBound,trial_splitvalue,
 137.773 +										  trial_nleft,trial_nright, trial_nboth);
 137.774 +// 				printf("try %d cost=%f nl=%d nr=%d nb=%d sp=%f\n",axis,trial_cost,trial_nleft,trial_nright, trial_nboth,
 137.775 +// 					   trial_splitvalue);
 137.776 +				if (trial_cost<best_cost)
 137.777 +				{
 137.778 +					split_plane=axis;
 137.779 +					best_cost=trial_cost;
 137.780 +					best_nleft=trial_nleft;
 137.781 +					best_nright=trial_nright;
 137.782 +					best_nboth=trial_nboth;
 137.783 +					best_splitvalue=trial_splitvalue;
 137.784 +					// save away the axis classification of each triangle
 137.785 +					for(int t=0 ; t < ntris; t++)
 137.786 +					{
 137.787 +						CacheOptimizedTriangle &tri=OptimizedTriangleList[tri_list[t]];
 137.788 +						tri.m_Data.m_GeometryData.m_nTmpData1 = tri.m_Data.m_GeometryData.m_nTmpData0;
 137.789 +					}
 137.790 +				}
 137.791 +				if (ts==-1)
 137.792 +					break;
 137.793 +			}
 137.794 +		}
 137.795 +
 137.796 +	}
 137.797 +	float cost_of_no_split=COST_OF_INTERSECTION*ntris;
 137.798 +	if ( (cost_of_no_split<=best_cost) || NEVER_SPLIT || (depth>MAX_TREE_DEPTH))
 137.799 +	{
 137.800 +		// no benefit to splitting. just make this a leaf node
 137.801 +		OptimizedKDTree[node_number].Children=KDNODE_STATE_LEAF+(TriangleIndexList.Count()<<2);
 137.802 +		OptimizedKDTree[node_number].SetNumberOfTrianglesInLeafNode(ntris);
 137.803 +#ifdef DEBUG_RAYTRACE
 137.804 +		OptimizedKDTree[node_number].vecMins = MinBound;
 137.805 +		OptimizedKDTree[node_number].vecMaxs = MaxBound;
 137.806 +#endif
 137.807 +		for(int t=0;t<ntris;t++)
 137.808 +			TriangleIndexList.AddToTail(tri_list[t]);
 137.809 +	}
 137.810 +	else
 137.811 +	{
 137.812 +// 		printf("best split was %d at %f (mid=%f,n=%d, sk=%d)\n",split_plane,best_splitvalue,
 137.813 +// 			   0.5*(MinBound[split_plane]+MaxBound[split_plane]),ntris,tri_skip);
 137.814 +		// its worth splitting!
 137.815 +		// we will achieve the splitting without sorting by using a selection algorithm.
 137.816 +		int32 *new_triangle_list;
 137.817 +		new_triangle_list=new int32[ntris];
 137.818 +
 137.819 +		// now, perform surface area/cost check to determine whether this split was worth it
 137.820 +		Vector LeftMins=MinBound;
 137.821 +		Vector LeftMaxes=MaxBound;
 137.822 +		Vector RightMins=MinBound;
 137.823 +		Vector RightMaxes=MaxBound;
 137.824 +		LeftMaxes[split_plane]=best_splitvalue;
 137.825 +		RightMins[split_plane]=best_splitvalue;
 137.826 +		
 137.827 +		int n_left_output=0;
 137.828 +		int n_both_output=0;
 137.829 +		int n_right_output=0;
 137.830 +		for(int t=0;t<ntris;t++)
 137.831 +		{
 137.832 +			CacheOptimizedTriangle &tri=OptimizedTriangleList[tri_list[t]];
 137.833 +			switch( tri.m_Data.m_GeometryData.m_nTmpData1 )
 137.834 +			{
 137.835 +				case PLANECHECK_NEGATIVE:
 137.836 +//					printf("%d goes left\n",t);
 137.837 +					new_triangle_list[n_left_output++]=tri_list[t];
 137.838 +					break;
 137.839 +				case PLANECHECK_POSITIVE:
 137.840 +					n_right_output++;
 137.841 +//					printf("%d goes right\n",t);
 137.842 +					new_triangle_list[ntris-n_right_output]=tri_list[t];
 137.843 +					break;
 137.844 +				case PLANECHECK_STRADDLING:
 137.845 +//					printf("%d goes both\n",t);
 137.846 +					new_triangle_list[best_nleft+n_both_output]=tri_list[t];
 137.847 +					n_both_output++;
 137.848 +					break;
 137.849 +
 137.850 +					
 137.851 +			}
 137.852 +		}
 137.853 +		int left_child=OptimizedKDTree.Count();
 137.854 +		int right_child=left_child+1;
 137.855 +// 		printf("node %d split on axis %d at %f, nl=%d nr=%d nb=%d lc=%d rc=%d\n",node_number,
 137.856 +// 			   split_plane,best_splitvalue,best_nleft,best_nright,best_nboth,
 137.857 +// 			   left_child,right_child);
 137.858 +		OptimizedKDTree[node_number].Children=split_plane+(left_child<<2);
 137.859 +		OptimizedKDTree[node_number].SplittingPlaneValue=best_splitvalue;
 137.860 +#ifdef DEBUG_RAYTRACE
 137.861 +		OptimizedKDTree[node_number].vecMins = MinBound;
 137.862 +		OptimizedKDTree[node_number].vecMaxs = MaxBound;
 137.863 +#endif
 137.864 +		CacheOptimizedKDNode newnode;
 137.865 +		OptimizedKDTree.AddToTail(newnode);
 137.866 +		OptimizedKDTree.AddToTail(newnode);
 137.867 +		// now, recurse!
 137.868 +		if ( (ntris<20) && ((best_nleft==0) || (best_nright==0)) )
 137.869 +			depth+=100;
 137.870 +		RefineNode(left_child,new_triangle_list,best_nleft+best_nboth,LeftMins,LeftMaxes,depth+1);
 137.871 +		RefineNode(right_child,new_triangle_list+best_nleft,best_nright+best_nboth,
 137.872 +				   RightMins,RightMaxes,depth+1);
 137.873 +		delete[] new_triangle_list;
 137.874 +	}	
 137.875 +}
 137.876 +
 137.877 +
 137.878 +void RayTracingEnvironment::SetupAccelerationStructure(void)
 137.879 +{
 137.880 +	CacheOptimizedKDNode root;
 137.881 +	OptimizedKDTree.AddToTail(root);
 137.882 +	int32 *root_triangle_list=new int32[OptimizedTriangleList.Count()];
 137.883 +	for(int t=0;t<OptimizedTriangleList.Count();t++)
 137.884 +		root_triangle_list[t]=t;
 137.885 +	CalculateTriangleListBounds(root_triangle_list,OptimizedTriangleList.Count(),m_MinBound,
 137.886 +								m_MaxBound);
 137.887 +	RefineNode(0,root_triangle_list,OptimizedTriangleList.Count(),m_MinBound,m_MaxBound,0);
 137.888 +	delete[] root_triangle_list;
 137.889 +
 137.890 +	// now, convert all triangles to "intersection format"
 137.891 +	for(int i=0;i<OptimizedTriangleList.Count();i++)
 137.892 +		OptimizedTriangleList[i].ChangeIntoIntersectionFormat();
 137.893 +}
 137.894 +
 137.895 +
 137.896 +
 137.897 +void RayTracingEnvironment::AddInfinitePointLight(Vector position, Vector intensity)
 137.898 +{
 137.899 +	LightDesc_t mylight(position,intensity);
 137.900 +	LightList.AddToTail(mylight);
 137.901 +	
 137.902 +}
 137.903 +
 137.904 +
   138.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.2 +++ b/raytrace/raytrace.vpc	Mon Sep 02 11:39:10 2013 -0700
   138.3 @@ -0,0 +1,26 @@
   138.4 +//-----------------------------------------------------------------------------
   138.5 +//	RAYTRACE.VPC
   138.6 +//
   138.7 +//	Project Script
   138.8 +//-----------------------------------------------------------------------------
   138.9 +
  138.10 +$Macro SRCDIR		".."
  138.11 +$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
  138.12 +
  138.13 +$Configuration
  138.14 +{
  138.15 +	$Compiler
  138.16 +	{
  138.17 +		$AdditionalIncludeDirectories		"$BASE,$SRCDIR\utils\common"
  138.18 +	}
  138.19 +}
  138.20 +
  138.21 +$Project "Raytrace"
  138.22 +{
  138.23 +	$Folder	"Source Files"
  138.24 +	{
  138.25 +		$File	"raytrace.cpp"
  138.26 +		$File	"trace2.cpp"
  138.27 +		$File	"trace3.cpp"
  138.28 +	}
  138.29 +}
   139.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.2 +++ b/raytrace/trace2.cpp	Mon Sep 02 11:39:10 2013 -0700
   139.3 @@ -0,0 +1,376 @@
   139.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
   139.5 +// $Id$
   139.6 +#include "raytrace.h"
   139.7 +#include <mathlib/halton.h>
   139.8 +
   139.9 +static uint32 MapDistanceToPixel(float t)
  139.10 +{
  139.11 +	if (t<0) return 0xffff0000;
  139.12 +	if (t>100) return 0xff000000;
  139.13 +	int a=t*1000; a&=0xff;
  139.14 +	int b=t*10; b &=0xff;
  139.15 +	int c=t*.01; c &=0xff;
  139.16 +	return 0xff000000+(a<<16)+(b<<8)+c;
  139.17 +}
  139.18 +
  139.19 +#define IGAMMA (1.0/2.2)
  139.20 +
  139.21 +#define MAGIC_NUMBER (1<<23)
  139.22 +
  139.23 +static fltx4 Four_MagicNumbers={ MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER };
  139.24 +static ALIGN16 int32 Four_255s[4]= {0xff,0xff,0xff,0xff};
  139.25 +#define PIXMASK ( * ( reinterpret_cast< fltx4 *>( &Four_255s ) ) )
  139.26 +
  139.27 +void MapLinearIntensities(FourVectors const &intens,uint32 *p1, uint32 *p2, uint32 *p3, uint32 *p4)
  139.28 +{
  139.29 +	// convert four pixels worth of sse-style rgb into argb lwords
  139.30 +	// NOTE the _mm_empty macro is voodoo. do not mess with this routine casually - simply throwing
  139.31 +	// anything that ends up generating a fpu stack references in here would be bad news.
  139.32 +	static fltx4 pixscale={255.0,255.0,255.0,255.0};
  139.33 +	fltx4 r,g,b;
  139.34 +	r=MinSIMD(pixscale,MulSIMD(pixscale,PowSIMD(intens.x,IGAMMA)));
  139.35 +	g=MinSIMD(pixscale,MulSIMD(pixscale,PowSIMD(intens.y,IGAMMA)));
  139.36 +	b=MinSIMD(pixscale,MulSIMD(pixscale,PowSIMD(intens.z,IGAMMA)));
  139.37 +	// now, convert to integer
  139.38 +	r=AndSIMD( AddSIMD( r, Four_MagicNumbers ), PIXMASK );
  139.39 +	g=AndSIMD( AddSIMD( g, Four_MagicNumbers ), PIXMASK );
  139.40 +	b=AndSIMD( AddSIMD( b, Four_MagicNumbers ), PIXMASK );
  139.41 +
  139.42 +	*(p1)=(SubInt(r, 0))|(SubInt(g, 0)<<8)|(SubInt(b, 0)<<16);
  139.43 +	*(p2)=(SubInt(r, 1))|(SubInt(g, 1)<<8)|(SubInt(b, 1)<<16);
  139.44 +	*(p3)=(SubInt(r, 2))|(SubInt(g, 2)<<8)|(SubInt(b, 2)<<16);
  139.45 +	*(p4)=(SubInt(r, 3))|(SubInt(g, 3)<<8)|(SubInt(b, 3)<<16);
  139.46 +}
  139.47 +
  139.48 +static ALIGN16 int32 signmask[4]={0x80000000,0x80000000,0x80000000,0x80000000};
  139.49 +static ALIGN16 int32 all_ones[4]={-1,-1,-1,-1};
  139.50 +static fltx4 all_zeros={0,0,0,0};
  139.51 +static fltx4 TraceLimit={1.0e20,1.0e20,1.0e20,1.0e20};
  139.52 +
  139.53 +void RayTracingEnvironment::RenderScene(
  139.54 +	int width, int height,								   // width and height of desired rendering
  139.55 +	int stride,											 // actual width in pixels of target buffer
  139.56 +	uint32 *output_buffer,									// pointer to destination 
  139.57 +	Vector CameraOrigin,									// eye position
  139.58 +	Vector ULCorner,										// word space coordinates of upper left
  139.59 +															// monitor corner
  139.60 +	Vector URCorner,										// top right corner
  139.61 +	Vector LLCorner,										// lower left
  139.62 +	Vector LRCorner,										// lower right
  139.63 +	RayTraceLightingMode_t lmode)
  139.64 +{
  139.65 +	// first, compute deltas
  139.66 +	Vector dxvector=URCorner;
  139.67 +	dxvector-=ULCorner;
  139.68 +	dxvector*=(1.0/width);
  139.69 +	Vector dxvectortimes2=dxvector;
  139.70 +	dxvectortimes2+=dxvector;
  139.71 +
  139.72 +	Vector dyvector=LLCorner;
  139.73 +	dyvector-=ULCorner;
  139.74 +	dyvector*=(1.0/height);
  139.75 +
  139.76 +
  139.77 +	// block_offsets-relative offsets for eahc of the 4 pixels in the block, in sse format
  139.78 +	FourVectors block_offsets;
  139.79 +	block_offsets.LoadAndSwizzle(Vector(0,0,0),dxvector,dyvector,dxvector+dyvector);
  139.80 +	
  139.81 +	FourRays myrays;
  139.82 +	myrays.origin.DuplicateVector(CameraOrigin);
  139.83 +	
  139.84 +	// tmprays is used fo rthe case when we cannot trace 4 rays at once.
  139.85 +	FourRays tmprays;
  139.86 +	tmprays.origin.DuplicateVector(CameraOrigin);
  139.87 +
  139.88 +	// now, we will ray trace pixels. we will do the rays in a 2x2 pattern
  139.89 +	for(int y=0;y<height;y+=2)
  139.90 +	{
  139.91 +		Vector SLoc=dyvector;
  139.92 +		SLoc*=((float) y);
  139.93 +		SLoc+=ULCorner;
  139.94 +		uint32 *dest=output_buffer+y*stride;
  139.95 +		for(int x=0;x<width;x+=2)
  139.96 +		{
  139.97 +			myrays.direction.DuplicateVector(SLoc);
  139.98 +			myrays.direction+=block_offsets;
  139.99 +			myrays.direction.VectorNormalize();
 139.100 +			
 139.101 +			RayTracingResult rslt;
 139.102 +			Trace4Rays(myrays,all_zeros,TraceLimit, &rslt);
 139.103 +			if ((rslt.HitIds[0]==-1) && (rslt.HitIds[1]==-1) && 
 139.104 +				(rslt.HitIds[2]==-1) && (rslt.HitIds[3]==-1))
 139.105 +				MapLinearIntensities(BackgroundColor,dest,dest+1,dest+stride,dest+stride+1);
 139.106 +			else
 139.107 +			{
 139.108 +				// make sure normal points back towards ray origin
 139.109 +				fltx4 ndoti=rslt.surface_normal*myrays.direction;
 139.110 +				fltx4 bad_dirs=AndSIMD(CmpGtSIMD(ndoti,Four_Zeros),
 139.111 +										   LoadAlignedSIMD((float *) signmask));
 139.112 +
 139.113 +				// flip signs of all "wrong" normals
 139.114 +				rslt.surface_normal.x=XorSIMD(bad_dirs,rslt.surface_normal.x);
 139.115 +				rslt.surface_normal.y=XorSIMD(bad_dirs,rslt.surface_normal.y);
 139.116 +				rslt.surface_normal.z=XorSIMD(bad_dirs,rslt.surface_normal.z);
 139.117 +
 139.118 +				FourVectors intens;
 139.119 +				intens.DuplicateVector(Vector(0,0,0));
 139.120 +				// set up colors
 139.121 +				FourVectors surf_colors;
 139.122 +				surf_colors.DuplicateVector(Vector(0,0,0));
 139.123 +				for(int i=0;i<4;i++)
 139.124 +				{
 139.125 +					if (rslt.HitIds[i]>=0)
 139.126 +					{
 139.127 +						surf_colors.X(i)=TriangleColors[rslt.HitIds[i]].x;
 139.128 +						surf_colors.Y(i)=TriangleColors[rslt.HitIds[i]].y;
 139.129 +						surf_colors.Z(i)=TriangleColors[rslt.HitIds[i]].z;
 139.130 +					}
 139.131 +
 139.132 +				}
 139.133 +				FourVectors surface_pos=myrays.direction;
 139.134 +				surface_pos*=rslt.HitDistance;
 139.135 +				surface_pos+=myrays.origin;
 139.136 +				
 139.137 +				switch(lmode)
 139.138 +				{
 139.139 +					case DIRECT_LIGHTING:
 139.140 +					{
 139.141 +						// light all points
 139.142 +						for(int l=0;l<LightList.Count();l++)
 139.143 +						{
 139.144 +							LightList[l].ComputeLightAtPoints(surface_pos,rslt.surface_normal,
 139.145 +															  intens);
 139.146 +						}
 139.147 +					}
 139.148 +					break;
 139.149 +
 139.150 +					case DIRECT_LIGHTING_WITH_SHADOWS:
 139.151 +					{
 139.152 +						// light all points
 139.153 +						for(int l=0;l<LightList.Count();l++)
 139.154 +						{
 139.155 +							FourVectors ldir;
 139.156 +							ldir.DuplicateVector(LightList[l].m_Position);
 139.157 +							ldir-=surface_pos;
 139.158 +							fltx4 MaxT=ldir.length();
 139.159 +							ldir.VectorNormalizeFast();
 139.160 +							// now, compute shadow flag
 139.161 +							FourRays myrays;
 139.162 +							myrays.origin=surface_pos;
 139.163 +							FourVectors epsilon=ldir;
 139.164 +							epsilon*=0.01;
 139.165 +							myrays.origin+=epsilon;
 139.166 +							myrays.direction=ldir;
 139.167 +							RayTracingResult shadowtest;
 139.168 +							Trace4Rays(myrays,Four_Zeros,MaxT, &shadowtest);
 139.169 +							fltx4 unshadowed=CmpGtSIMD(shadowtest.HitDistance,MaxT);
 139.170 +							if (! (IsAllZeros(unshadowed)))
 139.171 +							{
 139.172 +								FourVectors tmp;
 139.173 +								tmp.DuplicateVector(Vector(0,0,0));
 139.174 +								LightList[l].ComputeLightAtPoints(surface_pos,rslt.surface_normal,
 139.175 +																  tmp);
 139.176 +								intens.x=AddSIMD(intens.x,AndSIMD(tmp.x,unshadowed));
 139.177 +								intens.y=AddSIMD(intens.y,AndSIMD(tmp.y,unshadowed));
 139.178 +								intens.z=AddSIMD(intens.z,AndSIMD(tmp.z,unshadowed));
 139.179 +							}
 139.180 +						}
 139.181 +					}
 139.182 +					break;
 139.183 +				}
 139.184 +				// now, mask off non-hitting pixels
 139.185 +				intens.VProduct(surf_colors);
 139.186 +				fltx4 no_hit_mask=CmpGtSIMD(rslt.HitDistance,TraceLimit);
 139.187 +				
 139.188 +				intens.x=OrSIMD(AndSIMD(BackgroundColor.x,no_hit_mask),
 139.189 +								   AndNotSIMD(no_hit_mask,intens.x));
 139.190 +				intens.y=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
 139.191 +								   AndNotSIMD(no_hit_mask,intens.y));
 139.192 +				intens.z=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
 139.193 +								   AndNotSIMD(no_hit_mask,intens.z));
 139.194 +
 139.195 +				MapLinearIntensities(intens,dest,dest+1,dest+stride,dest+stride+1);
 139.196 +			}
 139.197 +			dest+=2;
 139.198 +			SLoc+=dxvectortimes2;
 139.199 +		}
 139.200 +	}
 139.201 +}
 139.202 +
 139.203 +
 139.204 +
 139.205 +
 139.206 +#define SQ(x) ((x)*(x))
 139.207 +
 139.208 +void RayTracingEnvironment::ComputeVirtualLightSources(void)
 139.209 +{
 139.210 +	int start_pos=0;
 139.211 +	for(int b=0;b<3;b++)
 139.212 +	{
 139.213 +		int nl=LightList.Count();
 139.214 +		int where_to_start=start_pos;
 139.215 +		start_pos=nl;
 139.216 +		for(int l=where_to_start;l<nl;l++)
 139.217 +		{
 139.218 +			DirectionalSampler_t sample_generator;
 139.219 +			int n_desired=1*LightList[l].m_Color.Length();
 139.220 +			if (LightList[l].m_Type==MATERIAL_LIGHT_SPOT)
 139.221 +				n_desired*=LightList[l].m_Phi/2;
 139.222 +			for(int try1=0;try1<n_desired;try1++)
 139.223 +			{
 139.224 +				LightDesc_t const &li=LightList[l];
 139.225 +				FourRays myrays;
 139.226 +				myrays.origin.DuplicateVector(li.m_Position);
 139.227 +				RayTracingResult rslt;
 139.228 +				Vector trial_dir=sample_generator.NextValue();
 139.229 +				if (li.IsDirectionWithinLightCone(trial_dir))
 139.230 +				{
 139.231 +					myrays.direction.DuplicateVector(trial_dir);
 139.232 +					Trace4Rays(myrays,all_zeros,ReplicateX4(1000.0), &rslt);
 139.233 +					if ((rslt.HitIds[0]!=-1))
 139.234 +					{
 139.235 +						// make sure normal points back towards ray origin
 139.236 +						fltx4 ndoti=rslt.surface_normal*myrays.direction;
 139.237 +						fltx4 bad_dirs=AndSIMD(CmpGtSIMD(ndoti,Four_Zeros),
 139.238 +												   LoadAlignedSIMD((float *) signmask));
 139.239 +						
 139.240 +						// flip signs of all "wrong" normals
 139.241 +						rslt.surface_normal.x=XorSIMD(bad_dirs,rslt.surface_normal.x);
 139.242 +						rslt.surface_normal.y=XorSIMD(bad_dirs,rslt.surface_normal.y);
 139.243 +						rslt.surface_normal.z=XorSIMD(bad_dirs,rslt.surface_normal.z);
 139.244 +
 139.245 +						// a hit! let's make a virtual light source
 139.246 +
 139.247 +						// treat the virtual light as a disk with its center at the hit position
 139.248 +						// and its radius scaled by the amount of the solid angle this probe
 139.249 +						// represents.
 139.250 +						float area_of_virtual_light=
 139.251 +							4.0*M_PI*SQ( SubFloat( rslt.HitDistance, 0 ) )*(1.0/n_desired);
 139.252 +
 139.253 +						FourVectors intens;
 139.254 +						intens.DuplicateVector(Vector(0,0,0));
 139.255 +
 139.256 +						FourVectors surface_pos=myrays.direction;
 139.257 +						surface_pos*=rslt.HitDistance;
 139.258 +						surface_pos+=myrays.origin;
 139.259 +						FourVectors delta=rslt.surface_normal;
 139.260 +						delta*=0.1;
 139.261 +						surface_pos+=delta;
 139.262 +						LightList[l].ComputeLightAtPoints(surface_pos,rslt.surface_normal,
 139.263 +														  intens);
 139.264 +						FourVectors surf_colors;
 139.265 +						surf_colors.DuplicateVector(TriangleColors[rslt.HitIds[0]]);
 139.266 +						intens*=surf_colors;
 139.267 +						// see if significant
 139.268 +						LightDesc_t l1;
 139.269 +						l1.m_Type=MATERIAL_LIGHT_SPOT;
 139.270 +						l1.m_Position=Vector(surface_pos.X(0),surface_pos.Y(0),surface_pos.Z(0));
 139.271 +						l1.m_Direction=Vector(rslt.surface_normal.X(0),rslt.surface_normal.Y(0),
 139.272 +											  rslt.surface_normal.Z(0));
 139.273 +						l1.m_Color=Vector(intens.X(0),intens.Y(0),intens.Z(0));
 139.274 +						if (l1.m_Color.Length()>0)
 139.275 +						{
 139.276 +							l1.m_Color*=area_of_virtual_light/M_PI;
 139.277 +							l1.m_Range=0.0;
 139.278 +							l1.m_Falloff=1.0;
 139.279 +							l1.m_Attenuation0=1.0;
 139.280 +							l1.m_Attenuation1=0.0;
 139.281 +							l1.m_Attenuation2=1.0;			// intens falls off as 1/r^2
 139.282 +							l1.m_Theta=0;
 139.283 +							l1.m_Phi=M_PI;
 139.284 +							l1.RecalculateDerivedValues();
 139.285 +							LightList.AddToTail(l1);
 139.286 +						}
 139.287 +					}
 139.288 +				}
 139.289 +			}
 139.290 +		}
 139.291 +	}
 139.292 +}
 139.293 +
 139.294 +
 139.295 +
 139.296 +static unsigned int GetSignMask(Vector const &v)
 139.297 +{
 139.298 +	unsigned int ret=0;
 139.299 +	if (v.x<0.0)
 139.300 +		ret++;
 139.301 +	if (v.y<0)
 139.302 +		ret+=2;
 139.303 +	if (v.z<0)
 139.304 +		ret+=4;
 139.305 +	return ret;
 139.306 +}
 139.307 +
 139.308 +
 139.309 +inline void RayTracingEnvironment::FlushStreamEntry(RayStream &s,int msk)
 139.310 +{
 139.311 +	assert(msk>=0);
 139.312 +	assert(msk<8);
 139.313 +	fltx4 tmax=s.PendingRays[msk].direction.length();
 139.314 +	fltx4 scl=ReciprocalSaturateSIMD(tmax);
 139.315 +	s.PendingRays[msk].direction*=scl;					// normalize
 139.316 +	RayTracingResult tmpresult;
 139.317 +	Trace4Rays(s.PendingRays[msk],Four_Zeros,tmax,msk,&tmpresult);
 139.318 +	// now, write out results
 139.319 +	for(int r=0;r<4;r++)
 139.320 +	{
 139.321 +		RayTracingSingleResult *out=s.PendingStreamOutputs[msk][r];
 139.322 +		out->ray_length=SubFloat( tmax, r );
 139.323 +		out->surface_normal.x=tmpresult.surface_normal.X(r);
 139.324 +		out->surface_normal.y=tmpresult.surface_normal.Y(r);
 139.325 +		out->surface_normal.z=tmpresult.surface_normal.Z(r);
 139.326 +		out->HitID=tmpresult.HitIds[r];
 139.327 +		out->HitDistance=SubFloat( tmpresult.HitDistance, r );
 139.328 +	}
 139.329 +	s.n_in_stream[msk]=0;
 139.330 +}
 139.331 +
 139.332 +void RayTracingEnvironment::AddToRayStream(RayStream &s,
 139.333 +										   Vector const &start,Vector const &end,
 139.334 +										   RayTracingSingleResult *rslt_out)
 139.335 +{
 139.336 +	Vector delta=end;
 139.337 +	delta-=start;
 139.338 +	int msk=GetSignMask(delta);
 139.339 +	assert(msk>=0);
 139.340 +	assert(msk<8);
 139.341 +	int pos=s.n_in_stream[msk];
 139.342 +	assert(pos<4);
 139.343 +	s.PendingRays[msk].origin.X(pos)=start.x;
 139.344 +	s.PendingRays[msk].origin.Y(pos)=start.y;
 139.345 +	s.PendingRays[msk].origin.Z(pos)=start.z;
 139.346 +	s.PendingRays[msk].direction.X(pos)=delta.x;
 139.347 +	s.PendingRays[msk].direction.Y(pos)=delta.y;
 139.348 +	s.PendingRays[msk].direction.Z(pos)=delta.z;
 139.349 +	s.PendingStreamOutputs[msk][pos]=rslt_out;
 139.350 +	if (pos==3)
 139.351 +	{
 139.352 +		FlushStreamEntry(s,msk);
 139.353 +	}
 139.354 +	else
 139.355 +		s.n_in_stream[msk]++;
 139.356 +}
 139.357 +
 139.358 +void RayTracingEnvironment::FinishRayStream(RayStream &s)
 139.359 +{
 139.360 +	for(int msk=0;msk<8;msk++)
 139.361 +	{
 139.362 +		int cnt=s.n_in_stream[msk];
 139.363 +		if (cnt)
 139.364 +		{
 139.365 +			// fill in unfilled entries with dups of first
 139.366 +			for(int c=cnt;c<4;c++)
 139.367 +			{
 139.368 +				s.PendingRays[msk].origin.X(c) = s.PendingRays[msk].origin.X(0);
 139.369 +				s.PendingRays[msk].origin.Y(c) = s.PendingRays[msk].origin.Y(0);
 139.370 +				s.PendingRays[msk].origin.Z(c) = s.PendingRays[msk].origin.Z(0);
 139.371 +				s.PendingRays[msk].direction.X(c) = s.PendingRays[msk].direction.X(0);
 139.372 +				s.PendingRays[msk].direction.Y(c) = s.PendingRays[msk].direction.Y(0);
 139.373 +				s.PendingRays[msk].direction.Z(c) = s.PendingRays[msk].direction.Z(0);
 139.374 +				s.PendingStreamOutputs[msk][c]=s.PendingStreamOutputs[msk][0];
 139.375 +			}
 139.376 +			FlushStreamEntry(s,msk);
 139.377 +		}
 139.378 +	}
 139.379 +}
   140.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.2 +++ b/raytrace/trace3.cpp	Mon Sep 02 11:39:10 2013 -0700
   140.3 @@ -0,0 +1,127 @@
   140.4 +//========= Copyright Valve Corporation, All rights reserved. ============//
   140.5 +
   140.6 +#include "raytrace.h"
   140.7 +#include <bspfile.h>
   140.8 +#include "bsplib.h"
   140.9 +
  140.10 +static Vector VertCoord(dface_t const &f, int vnum)
  140.11 +{
  140.12 +	int eIndex = dsurfedges[f.firstedge+vnum];
  140.13 +	int point;
  140.14 +	if( eIndex < 0 )
  140.15 +	{
  140.16 +		point = dedges[-eIndex].v[1];
  140.17 +	}
  140.18 +	else
  140.19 +	{
  140.20 +		point = dedges[eIndex].v[0];
  140.21 +	}
  140.22 +	dvertex_t *v=dvertexes+point;
  140.23 +	return Vector(v->point[0],v->point[1],v->point[2]);
  140.24 +
  140.25 +}
  140.26 +
  140.27 +Vector colors[]={
  140.28 +	Vector(0.5,0.5,1),
  140.29 +	Vector(0.5,1,0.5),
  140.30 +	Vector(0.5,1,1),
  140.31 +	Vector(1,0.5,0.5),
  140.32 +	Vector(1,0.5,1),
  140.33 +	Vector(1,1,1)};
  140.34 +
  140.35 +void RayTracingEnvironment::AddBSPFace(int id,dface_t const &face)
  140.36 +{
  140.37 +	if (face.dispinfo!=-1)									// displacements must be dealt with elsewhere
  140.38 +		return;
  140.39 +	texinfo_t *tx =(face.texinfo>=0)?&(texinfo[face.texinfo]):0;
  140.40 +// 	if (tx && (tx->flags & (SURF_SKY|SURF_NODRAW)))
  140.41 +// 		return;
  140.42 +	if (tx)
  140.43 +	{
  140.44 +		printf("id %d flags=%x\n",id,tx->flags);
  140.45 +	}
  140.46 +	printf("side: ");
  140.47 +	for(int v=0;v<face.numedges;v++)
  140.48 +	{
  140.49 +		printf("(%f %f %f) ",XYZ(VertCoord(face,v)));
  140.50 +	}
  140.51 +	printf("\n");
  140.52 +	int ntris=face.numedges-2;
  140.53 +	for(int tri=0;tri<ntris;tri++)
  140.54 +	{
  140.55 +		
  140.56 +		AddTriangle(id,VertCoord(face,0),VertCoord(face,(tri+1)%face.numedges),
  140.57 +					VertCoord(face,(tri+2)%face.numedges),Vector(1,1,1)); //colors[id % NELEMS(colors)]);
  140.58 +	}
  140.59 +}
  140.60 +
  140.61 +void RayTracingEnvironment::InitializeFromLoadedBSP(void)
  140.62 +{
  140.63 +// 	CUtlVector<uint8> PlanesToSkip;
  140.64 +// 	SidesToSkip.EnsureCapacity(numplanes);
  140.65 +// 	for(int s=0;s<numplanes;s++)
  140.66 +// 		SidesToSkip.AddToTail(0);
  140.67 +// 	for(int b=0;b<numbrushes;b++)
  140.68 +// 		if ((dbrushes[b].contents & MASK_OPAQUE)==0)
  140.69 +// 		{
  140.70 +// 			// transparent brush - mark all its sides as "do not process"
  140.71 +// 			for(int s=0;s<dbrushes[b].numsides;s++)
  140.72 +// 			{
  140.73 +// 				PlanesToSkip[s+dbrushes[b].firstside]=1;
  140.74 +// 			}
  140.75 +
  140.76 +// 		}
  140.77 +// 	// now, add all origfaces, omitting those whose sides are the ones we marked previously
  140.78 +// 	for(int c=0;c<numorigfaces;c++)
  140.79 +// 	{
  140.80 +// 		dface_t const &f=dorigfaces[c];
  140.81 +// 		if (SidesToSkip[f.AddBSPFace(c,dorigfaces[c]);
  140.82 +// 	}
  140.83 +	
  140.84 +
  140.85 +
  140.86 +// 	// ugly - I want to traverse all the faces. but there is no way to get from a face back to it's
  140.87 +// 	// original brush, and I need to get back to the face to the contents field of the brush.  So I
  140.88 +// 	// will create a temporary mapping from a "side" to its brush. I can get from the face to it
  140.89 +// 	// side, which can get me back to its brush.
  140.90 +	
  140.91 +// 	CUtlVector<uint8> OrigFaceVisited;
  140.92 +// 	OrigFaceVisited.EnsureCapacity(numorigfaces);
  140.93 +// 	int n_added=0;
  140.94 +
  140.95 +// 	for(int i=0;i<numorigfaces;i++)
  140.96 +// 		OrigFaceVisited.AddToTail(0);
  140.97 +
  140.98 +// 	for(int l=0;l<numleafs;l++)
  140.99 +// 	{
 140.100 +// 		dleaf_t const &lf=dleafs[l];
 140.101 +// //		if (lf.contents & MASK_OPAQUE)
 140.102 +// 		{
 140.103 +// 			for(int f=0;f<lf.numleaffaces;f++);
 140.104 +// 			{
 140.105 +// 				dface_t const &face=dfaces[f+lf.firstleafface];
 140.106 +// 				if (OrigFaceVisited[face.origFace]==0)
 140.107 +// 				{
 140.108 +// 					dface_t const &oface=dorigfaces[face.origFace];
 140.109 +// 					OrigFaceVisited[face.origFace]=1;
 140.110 +// 					n_added++;
 140.111 +// 					AddBSPFace(face.origFace,oface);
 140.112 +// 				}
 140.113 +// 			}
 140.114 +// 		}
 140.115 +// 	}
 140.116 +// 	printf("added %d of %d\n",n_added,numorigfaces);
 140.117 +// 	for(int c=0;c<numorigfaces;c++)
 140.118 +// 	{
 140.119 +// 		dface_t const &f=dorigfaces[c];
 140.120 +// 		AddBSPFace(c,dorigfaces[c]);
 140.121 +// 	}
 140.122 +	for(int c=0;c<numfaces;c++)
 140.123 +	{
 140.124 +//		dface_t const &f=dfaces[c];
 140.125 +		AddBSPFace(c,dorigfaces[c]);
 140.126 +	}
 140.127 +
 140.128 +//	AddTriangle(1234,Vector(51,145,-700),Vector(71,165,-700),Vector(51,165,-700),colors[5]);
 140.129 +}
 140.130 +
   141.1 --- a/tier0/tier0_exclude.vpc	Tue Jul 30 15:10:15 2013 -0700
   141.2 +++ b/tier0/tier0_exclude.vpc	Mon Sep 02 11:39:10 2013 -0700
   141.3 @@ -1,5 +1,5 @@
   141.4  //-----------------------------------------------------------------------------
   141.5 -//	tier0_s_exclude.vpc
   141.6 +//	tier0_exclude.vpc
   141.7  //
   141.8  //	Project Script
   141.9  //-----------------------------------------------------------------------------
  141.10 @@ -8,8 +8,7 @@
  141.11  {
  141.12  	$Folder	"Link Libraries"
  141.13  	{
  141.14 -		-$File "$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXtier0$_IMPLIB_EXT" [!$WINDOWS]
  141.15 -		-$File "$SRCDIR\lib\public\$_IMPLIB_PREFIXtier0$_IMPLIB_EXT" [$WINDOWS]
  141.16 +		-$Lib "$LIBPUBLIC\tier0"
  141.17  	}
  141.18  	$Folder	"Source Files"
  141.19  	{
   142.1 --- a/tier1/bitbuf.cpp	Tue Jul 30 15:10:15 2013 -0700
   142.2 +++ b/tier1/bitbuf.cpp	Mon Sep 02 11:39:10 2013 -0700
   142.3 @@ -877,7 +877,7 @@
   142.4  void bf_read::ReadBits(void *pOutData, int nBits)
   142.5  {
   142.6  #if defined( BB_PROFILING )
   142.7 -	VPROF( "bf_write::ReadBits" );
   142.8 +	VPROF( "bf_read::ReadBits" );
   142.9  #endif
  142.10  
  142.11  	unsigned char *pOut = (unsigned char*)pOutData;
  142.12 @@ -1083,7 +1083,7 @@
  142.13  float bf_read::ReadBitCoord (void)
  142.14  {
  142.15  #if defined( BB_PROFILING )
  142.16 -	VPROF( "bf_write::ReadBitCoord" );
  142.17 +	VPROF( "bf_read::ReadBitCoord" );
  142.18  #endif
  142.19  	int		intval=0,fractval=0,signbit=0;
  142.20  	float	value = 0.0;
  142.21 @@ -1126,7 +1126,7 @@
  142.22  float bf_read::ReadBitCoordMP( bool bIntegral, bool bLowPrecision )
  142.23  {
  142.24  #if defined( BB_PROFILING )
  142.25 -	VPROF( "bf_write::ReadBitCoordMP" );
  142.26 +	VPROF( "bf_read::ReadBitCoordMP" );
  142.27  #endif
  142.28  	// BitCoordMP float encoding: inbounds bit, integer bit, sign bit, optional int bits, float bits
  142.29  	// BitCoordMP integer encoding: inbounds bit, integer bit, optional sign bit, optional int bits.
  142.30 @@ -1212,7 +1212,7 @@
  142.31  unsigned int bf_read::ReadBitCoordBits (void)
  142.32  {
  142.33  #if defined( BB_PROFILING )
  142.34 -	VPROF( "bf_write::ReadBitCoordBits" );
  142.35 +	VPROF( "bf_read::ReadBitCoordBits" );
  142.36  #endif
  142.37  
  142.38  	unsigned int flags = ReadUBitLong(2);
  142.39 @@ -1231,7 +1231,7 @@
  142.40  unsigned int bf_read::ReadBitCoordMPBits( bool bIntegral, bool bLowPrecision )
  142.41  {
  142.42  #if defined( BB_PROFILING )
  142.43 -	VPROF( "bf_write::ReadBitCoordMPBits" );
  142.44 +	VPROF( "bf_read::ReadBitCoordMPBits" );
  142.45  #endif
  142.46  
  142.47  	unsigned int flags = ReadUBitLong(2);
   143.1 --- a/tier1/strtools.cpp	Tue Jul 30 15:10:15 2013 -0700
   143.2 +++ b/tier1/strtools.cpp	Mon Sep 02 11:39:10 2013 -0700
   143.3 @@ -1491,14 +1491,34 @@
   143.4  #elif defined(POSIX)
   143.5  	iconv_t conv_t = iconv_open( "UTF-8", "UCS-2LE" );
   143.6  	size_t cchResult = -1;
   143.7 -	size_t nLenUnicde = cubDestSizeInBytes;
   143.8 -	size_t nMaxUTF8 = cubDestSizeInBytes;
   143.9 +
  143.10 +	// pUCS2 will be null-terminated so use that to work out the input
  143.11 +	// buffer size. Note that we shouldn't assume iconv will stop when it
  143.12 +	// finds a zero, and nLenUnicde should be given in bytes, so we multiply
  143.13 +	// it by sizeof( ucs2 ) at the end.
  143.14 +	size_t nLenUnicde = 0;
  143.15 +	while ( pUCS2[nLenUnicde] )
  143.16 +	{
  143.17 +		++nLenUnicde;
  143.18 +	}
  143.19 +	nLenUnicde *= sizeof( ucs2 );
  143.20 +
  143.21 +	// Calculate number of bytes we want iconv to write, leaving space
  143.22 +	// for the null-terminator
  143.23 +	size_t nMaxUTF8 = cubDestSizeInBytes - 1;
  143.24  	char *pIn = (char *)pUCS2;
  143.25  	char *pOut = (char *)pUTF8;
  143.26  	if ( conv_t > 0 )
  143.27  	{
  143.28  		cchResult = 0;
  143.29 +		const size_t nBytesToWrite = nMaxUTF8;
  143.30  		cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUTF8 );
  143.31 +
  143.32 +		// Calculate how many bytes were actually written and use that to
  143.33 +		// null-terminate our output string.
  143.34 +		const size_t nBytesWritten = nBytesToWrite - nMaxUTF8;
  143.35 +		pUTF8[nBytesWritten] = 0;
  143.36 +
  143.37  		iconv_close( conv_t );
  143.38  		if ( (int)cchResult < 0 )
  143.39  			cchResult = 0;
   144.1 --- a/tier1/tier1.vpc	Tue Jul 30 15:10:15 2013 -0700
   144.2 +++ b/tier1/tier1.vpc	Mon Sep 02 11:39:10 2013 -0700
   144.3 @@ -5,11 +5,8 @@
   144.4  //-----------------------------------------------------------------------------
   144.5  
   144.6  $macro SRCDIR		".."
   144.7 -
   144.8 -$macro OUTLIBDIR    "$SRCDIR\lib\public" [!$LINUX && !$OSXALL]
   144.9   
  144.10  $include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
  144.11 -$include "$SRCDIR\vstdlib\vstdlib_exclude.vpc" [$OSXALL]
  144.12  
  144.13  $Configuration
  144.14  {
   145.1 --- a/utils/captioncompiler/captioncompiler.vpc	Tue Jul 30 15:10:15 2013 -0700
   145.2 +++ b/utils/captioncompiler/captioncompiler.vpc	Mon Sep 02 11:39:10 2013 -0700
   145.3 @@ -7,7 +7,7 @@
   145.4  $Macro SRCDIR		"..\.."
   145.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   145.6  
   145.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   145.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   145.9  
  145.10  $Configuration
  145.11  {
  145.12 @@ -52,9 +52,9 @@
  145.13  
  145.14  	$Folder "Link Libraries"
  145.15  	{
  145.16 -		$DynamicFile	"$SRCDIR\lib\public\appframework.lib"
  145.17 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  145.18 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  145.19 -		$DynamicFile	"$SRCDIR\lib\public\tier3.lib"
  145.20 +		$Lib appframework
  145.21 +		$Lib mathlib
  145.22 +		$Lib tier2
  145.23 +		$Lib tier3
  145.24  	}
  145.25  }
   146.1 --- a/utils/glview/glview.vpc	Tue Jul 30 15:10:15 2013 -0700
   146.2 +++ b/utils/glview/glview.vpc	Mon Sep 02 11:39:10 2013 -0700
   146.3 @@ -7,7 +7,7 @@
   146.4  $Macro SRCDIR		"..\.."
   146.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   146.6  
   146.7 -$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
   146.8 +$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
   146.9  
  146.10  $Configuration
  146.11  {
  146.12 @@ -49,7 +49,7 @@
  146.13  
  146.14  	$Folder	"Link Libraries"
  146.15  	{
  146.16 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  146.17 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  146.18 +		$Lib mathlib
  146.19 +		$Lib tier2
  146.20  	}
  146.21  }
   147.1 --- a/utils/height2normal/height2normal.vpc	Tue Jul 30 15:10:15 2013 -0700
   147.2 +++ b/utils/height2normal/height2normal.vpc	Mon Sep 02 11:39:10 2013 -0700
   147.3 @@ -7,7 +7,7 @@
   147.4  $Macro SRCDIR		"..\.."
   147.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   147.6  
   147.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   147.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   147.9  
  147.10  $Configuration
  147.11  {
  147.12 @@ -34,8 +34,8 @@
  147.13  
  147.14  	$Folder	"Link Libraries"
  147.15  	{
  147.16 -		$DynamicFile	"$SRCDIR\lib\public\bitmap.lib"
  147.17 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  147.18 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  147.19 +		$Lib bitmap
  147.20 +		$Lib mathlib
  147.21 +		$Lib tier2
  147.22  	}
  147.23  }
   148.1 --- a/utils/motionmapper/motionmapper.vpc	Tue Jul 30 15:10:15 2013 -0700
   148.2 +++ b/utils/motionmapper/motionmapper.vpc	Mon Sep 02 11:39:10 2013 -0700
   148.3 @@ -7,7 +7,7 @@
   148.4  $Macro SRCDIR		"..\.."
   148.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   148.6  
   148.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   148.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   148.9  
  148.10  $Configuration
  148.11  {
  148.12 @@ -81,8 +81,8 @@
  148.13  
  148.14  	$Folder	"Link Libraries"
  148.15  	{
  148.16 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  148.17 -		$DynamicFile	"$SRCDIR\lib\public\nvtristrip.lib"
  148.18 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  148.19 +		$Lib mathlib
  148.20 +		$Lib nvtristrip
  148.21 +		$Lib tier2
  148.22  	}
  148.23  }
   149.1 --- a/utils/phonemeextractor/phonemeextractor.vpc	Tue Jul 30 15:10:15 2013 -0700
   149.2 +++ b/utils/phonemeextractor/phonemeextractor.vpc	Mon Sep 02 11:39:10 2013 -0700
   149.3 @@ -7,7 +7,7 @@
   149.4  $Macro SRCDIR		"..\.."
   149.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin\phonemeextractors"
   149.6  
   149.7 -$Include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc"
   149.8 +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
   149.9  
  149.10  $Configuration
  149.11  {
  149.12 @@ -77,7 +77,7 @@
  149.13  	
  149.14  	$Folder	"Link Libraries"
  149.15  	{
  149.16 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  149.17 +		$Lib mathlib
  149.18  		$DynamicFile	"..\sapi51\lib\i386\sapi.lib"
  149.19  	}
  149.20  }
   150.1 --- a/utils/phonemeextractor/phonemeextractor_ims.vpc	Tue Jul 30 15:10:15 2013 -0700
   150.2 +++ b/utils/phonemeextractor/phonemeextractor_ims.vpc	Mon Sep 02 11:39:10 2013 -0700
   150.3 @@ -7,7 +7,7 @@
   150.4  $Macro SRCDIR		"..\.."
   150.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin\phonemeextractors"
   150.6  
   150.7 -$Include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc"
   150.8 +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
   150.9  
  150.10  $Configuration
  150.11  {
  150.12 @@ -92,7 +92,7 @@
  150.13  	
  150.14  	$Folder	"Link Libraries"
  150.15  	{
  150.16 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  150.17 +		$Lib mathlib
  150.18  		$File	"..\sapi51\lib\i386\sapi.lib"
  150.19  	}
  150.20  }
   151.1 --- a/utils/qc_eyes/qc_eyes.vpc	Tue Jul 30 15:10:15 2013 -0700
   151.2 +++ b/utils/qc_eyes/qc_eyes.vpc	Mon Sep 02 11:39:10 2013 -0700
   151.3 @@ -7,7 +7,7 @@
   151.4  $Macro SRCDIR		"..\.."
   151.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   151.6  
   151.7 -$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
   151.8 +$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
   151.9  
  151.10  $Configuration
  151.11  {
   152.1 --- a/utils/serverplugin_sample/serverplugin_empty.vpc	Tue Jul 30 15:10:15 2013 -0700
   152.2 +++ b/utils/serverplugin_sample/serverplugin_empty.vpc	Mon Sep 02 11:39:10 2013 -0700
   152.3 @@ -56,11 +56,7 @@
   152.4  
   152.5  	$Folder	"Link Libraries"
   152.6  	{
   152.7 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib" [$WIN32]
   152.8 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib" [$WIN32]
   152.9 -		$DynamicFile	"$SRCDIR\lib\public\$PLATFORM\mathlib$_STATICLIB_EXT" [$LINUX]
  152.10 -		$DynamicFile	"$SRCDIR\lib\public\$PLATFORM\tier2$_STATICLIB_EXT" [$LINUX]
  152.11 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\mathlib$_STATICLIB_EXT" [$OSXALL]
  152.12 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\tier2$_STATICLIB_EXT" [$OSXALL]
  152.13 +		$Lib mathlib
  152.14 +		$Lib tier2
  152.15  	}
  152.16  }
   153.1 --- a/utils/tgadiff/tgadiff.vpc	Tue Jul 30 15:10:15 2013 -0700
   153.2 +++ b/utils/tgadiff/tgadiff.vpc	Mon Sep 02 11:39:10 2013 -0700
   153.3 @@ -7,7 +7,7 @@
   153.4  $Macro SRCDIR		"..\.."
   153.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   153.6  
   153.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   153.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   153.9  
  153.10  $Project "Tgadiff"
  153.11  {
  153.12 @@ -18,8 +18,8 @@
  153.13  
  153.14  	$Folder	"Link Libraries"
  153.15  	{
  153.16 -		$DynamicFile	"$SRCDIR\lib\public\bitmap.lib"
  153.17 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  153.18 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  153.19 +		$Lib bitmap
  153.20 +		$Lib mathlib
  153.21 +		$Lib tier2
  153.22  	}
  153.23  }
   154.1 --- a/utils/vbsp/vbsp.vpc	Tue Jul 30 15:10:15 2013 -0700
   154.2 +++ b/utils/vbsp/vbsp.vpc	Mon Sep 02 11:39:10 2013 -0700
   154.3 @@ -7,7 +7,7 @@
   154.4  $Macro SRCDIR		"..\.."
   154.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   154.6  
   154.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   154.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   154.9  
  154.10  $Configuration
  154.11  {
  154.12 @@ -173,11 +173,11 @@
  154.13  
  154.14  	$Folder	"Link Libraries"
  154.15  	{
  154.16 -		$DynamicFile	"$SRCDIR\lib\public\bitmap.lib"
  154.17 -		$DynamicFile	"$SRCDIR\lib\public\fgdlib.lib"
  154.18 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  154.19 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  154.20 -		$DynamicFile	"$SRCDIR\lib\public\vtf.lib"
  154.21 +		$Lib bitmap
  154.22 +		$Lib fgdlib
  154.23 +		$Lib mathlib
  154.24 +		$Lib tier2
  154.25 +		$Lib vtf
  154.26  	}
  154.27  
  154.28  	$File	"notes.txt"
   155.1 --- a/utils/vice/vice.vpc	Tue Jul 30 15:10:15 2013 -0700
   155.2 +++ b/utils/vice/vice.vpc	Mon Sep 02 11:39:10 2013 -0700
   155.3 @@ -7,7 +7,7 @@
   155.4  $Macro SRCDIR		"..\.."
   155.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   155.6  
   155.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   155.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   155.9  
  155.10  $Configuration
  155.11  {
  155.12 @@ -35,7 +35,7 @@
  155.13  
  155.14  	$Folder	"Link Libraries"
  155.15  	{
  155.16 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  155.17 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  155.18 +		$Lib tier2
  155.19 +		$Lib mathlib
  155.20  	}
  155.21  }
   156.1 --- a/utils/vrad/vrad_dll.vpc	Tue Jul 30 15:10:15 2013 -0700
   156.2 +++ b/utils/vrad/vrad_dll.vpc	Mon Sep 02 11:39:10 2013 -0700
   156.3 @@ -7,7 +7,7 @@
   156.4  $Macro SRCDIR		"..\.."
   156.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   156.6  
   156.7 -$Include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc"
   156.8 +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
   156.9  
  156.10  $Configuration
  156.11  {
  156.12 @@ -213,12 +213,12 @@
  156.13  
  156.14  	$Folder	"Link Libraries"
  156.15  	{
  156.16 -		$DynamicFile	"$SRCDIR\lib\public\bitmap.lib"
  156.17 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  156.18 -		$DynamicFile	"$SRCDIR\lib\public\raytrace.lib"
  156.19 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  156.20 -		$DynamicFile	"$SRCDIR\lib\public\vmpi.lib"
  156.21 -		$DynamicFile	"$SRCDIR\lib\public\vtf.lib"
  156.22 +		$Lib bitmap
  156.23 +		$Lib mathlib
  156.24 +		$Lib raytrace
  156.25 +		$Lib tier2
  156.26 +		$Lib vmpi
  156.27 +		$Lib vtf
  156.28  	}
  156.29  
  156.30  	$File	"notes.txt"
   157.1 --- a/utils/vrad_launcher/vrad_launcher.vpc	Tue Jul 30 15:10:15 2013 -0700
   157.2 +++ b/utils/vrad_launcher/vrad_launcher.vpc	Mon Sep 02 11:39:10 2013 -0700
   157.3 @@ -8,7 +8,7 @@
   157.4  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   157.5  $Macro OUTBINNAME	"vrad"
   157.6  
   157.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   157.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   157.9  
  157.10  $Configuration
  157.11  {
   158.1 --- a/utils/vtf2tga/vtf2tga.vpc	Tue Jul 30 15:10:15 2013 -0700
   158.2 +++ b/utils/vtf2tga/vtf2tga.vpc	Mon Sep 02 11:39:10 2013 -0700
   158.3 @@ -7,7 +7,7 @@
   158.4  $Macro SRCDIR		"..\.."
   158.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   158.6  
   158.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   158.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   158.9  
  158.10  $Project "Vtf2tga"
  158.11  {
  158.12 @@ -39,9 +39,9 @@
  158.13  
  158.14  	$Folder	"Link Libraries"
  158.15  	{
  158.16 -		$DynamicFile	"$SRCDIR\lib\public\bitmap.lib"
  158.17 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  158.18 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  158.19 -		$DynamicFile	"$SRCDIR\lib\public\vtf.lib"
  158.20 +		$Lib bitmap
  158.21 +		$Lib mathlib
  158.22 +		$Lib tier2
  158.23 +		$Lib vtf
  158.24  	}
  158.25  }
   159.1 --- a/utils/vtfdiff/vtfdiff.vpc	Tue Jul 30 15:10:15 2013 -0700
   159.2 +++ b/utils/vtfdiff/vtfdiff.vpc	Mon Sep 02 11:39:10 2013 -0700
   159.3 @@ -7,7 +7,7 @@
   159.4  $Macro SRCDIR		"..\.."
   159.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   159.6  
   159.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   159.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   159.9  
  159.10  $Project "Vtfdiff"
  159.11  {
  159.12 @@ -18,9 +18,9 @@
  159.13  
  159.14  	$Folder	"Link Libraries"
  159.15  	{
  159.16 -		$DynamicFile	"$SRCDIR\lib\public\bitmap.lib"
  159.17 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  159.18 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  159.19 -		$DynamicFile	"$SRCDIR\lib\public\vtf.lib"
  159.20 +		$Lib bitmap
  159.21 +		$Lib mathlib
  159.22 +		$Lib tier2
  159.23 +		$Lib vtf
  159.24  	}
  159.25  }
   160.1 --- a/utils/vvis/vvis_dll.vpc	Tue Jul 30 15:10:15 2013 -0700
   160.2 +++ b/utils/vvis/vvis_dll.vpc	Mon Sep 02 11:39:10 2013 -0700
   160.3 @@ -7,7 +7,7 @@
   160.4  $Macro SRCDIR		"..\.."
   160.5  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   160.6  
   160.7 -$Include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc"
   160.8 +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
   160.9  
  160.10  $Configuration
  160.11  {
  160.12 @@ -94,8 +94,8 @@
  160.13  
  160.14  	$Folder	"Link Libraries"
  160.15  	{
  160.16 -		$DynamicFile	"$SRCDIR\lib\public\mathlib.lib"
  160.17 -		$DynamicFile	"$SRCDIR\lib\public\tier2.lib"
  160.18 -		$DynamicFile	"$SRCDIR\lib\public\vmpi.lib"
  160.19 +		$Lib mathlib
  160.20 +		$Lib tier2
  160.21 +		$Lib vmpi
  160.22  	}
  160.23  }
   161.1 --- a/utils/vvis_launcher/vvis_launcher.vpc	Tue Jul 30 15:10:15 2013 -0700
   161.2 +++ b/utils/vvis_launcher/vvis_launcher.vpc	Mon Sep 02 11:39:10 2013 -0700
   161.3 @@ -8,7 +8,7 @@
   161.4  $Macro OUTBINDIR	"$SRCDIR\..\game\bin"
   161.5  $Macro OUTBINNAME	"vvis"
   161.6  
   161.7 -$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
   161.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
   161.9  
  161.10  $Configuration
  161.11  {
   162.1 --- a/vgui2/vgui_controls/TextEntry.cpp	Tue Jul 30 15:10:15 2013 -0700
   162.2 +++ b/vgui2/vgui_controls/TextEntry.cpp	Mon Sep 02 11:39:10 2013 -0700
   162.3 @@ -3355,7 +3355,7 @@
   162.4  			buf.AddToTail(m_TextStream[i]);
   162.5  		}
   162.6  		buf.AddToTail('\0');
   162.7 -		system()->SetClipboardText(buf.Base(), x1 - x0);
   162.8 +		system()->SetClipboardText(buf.Base(), buf.Count());
   162.9  	}
  162.10  	
  162.11  	// have to request focus if we used the menu
   163.1 --- a/vgui2/vgui_controls/vgui_controls.vpc	Tue Jul 30 15:10:15 2013 -0700
   163.2 +++ b/vgui2/vgui_controls/vgui_controls.vpc	Mon Sep 02 11:39:10 2013 -0700
   163.3 @@ -7,7 +7,6 @@
   163.4  $macro SRCDIR		"..\.."
   163.5  $Macro GENERATED_PROTO_DIR	"generated_proto"
   163.6  $macro PROTOBUF_LITE 0
   163.7 -$Macro OUTLIBDIR	"$SRCDIR\lib\public"	[!$LINUX]
   163.8  
   163.9  $include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
  163.10  $include "$SRCDIR\vpc_scripts\protobuf_builder.vpc"
   164.1 --- a/vpc_scripts/definitions/win32_2010.def	Tue Jul 30 15:10:15 2013 -0700
   164.2 +++ b/vpc_scripts/definitions/win32_2010.def	Mon Sep 02 11:39:10 2013 -0700
   164.3 @@ -232,7 +232,12 @@
   164.4  		{
   164.5  			"type"	"ignore"
   164.6  		}
   164.7 -				
   164.8 +		
   164.9 +		"$AdditionalLibraryDirectories"
  164.10 +		{
  164.11 +			"type"	"ignore"
  164.12 +		}
  164.13 +		
  164.14  		// General
  164.15  		"$AdditionalIncludeDirectories"
  164.16  		{
   165.1 --- a/vpc_scripts/groups.vgc	Tue Jul 30 15:10:15 2013 -0700
   165.2 +++ b/vpc_scripts/groups.vgc	Mon Sep 02 11:39:10 2013 -0700
   165.3 @@ -18,6 +18,7 @@
   165.4  {
   165.5  	"client"
   165.6  	"mathlib"
   165.7 +	"raytrace"
   165.8  	"server"
   165.9  	"tier1"
  165.10  	"vgui_controls"
  165.11 @@ -32,12 +33,14 @@
  165.12  {
  165.13  	"captioncompiler"
  165.14  	"client"
  165.15 +	"fgdlib"
  165.16  	"game_shader_dx9"
  165.17  	"glview"
  165.18  	"height2normal"
  165.19  	"mathlib"
  165.20  	"motionmapper"
  165.21  	"phonemeextractor"
  165.22 +	"raytrace"
  165.23  	"qc_eyes"
  165.24  	"server"
  165.25  	"serverplugin_empty"
   166.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.2 +++ b/vpc_scripts/platform_dirs.vpc	Mon Sep 02 11:39:10 2013 -0700
   166.3 @@ -0,0 +1,5 @@
   166.4 +$Macro PLATSUBDIR	"\."	[$WIN32]
   166.5 +$Macro PLATSUBDIR	"\x64"	[$WIN64]
   166.6 +$Macro PLATSUBDIR	"\."	[$X360]
   166.7 +$Macro PLATSUBDIR	"\linux32" [$LINUX32]
   166.8 +$Macro PLATSUBDIR	"\osx32" [$OSX32]
   167.1 --- a/vpc_scripts/projects.vgc	Tue Jul 30 15:10:15 2013 -0700
   167.2 +++ b/vpc_scripts/projects.vgc	Mon Sep 02 11:39:10 2013 -0700
   167.3 @@ -19,6 +19,11 @@
   167.4  	"game\client\client_hl2mp.vpc"		[($WIN32||$POSIX) && $HL2MP]
   167.5  }
   167.6  
   167.7 +$Project "fgdlib"
   167.8 +{
   167.9 +	"fgdlib\fgdlib.vpc" [$WIN32]
  167.10 +}
  167.11 +
  167.12  $Project "game_shader_dx9"
  167.13  {
  167.14  	"materialsystem\stdshaders\game_shader_dx9_hl2mp.vpc" [$HL2MP]
  167.15 @@ -54,6 +59,11 @@
  167.16  	"utils\phonemeextractor\phonemeextractor.vpc" [$WIN32]
  167.17  }
  167.18  
  167.19 +$Project "raytrace"
  167.20 +{
  167.21 +	"raytrace\raytrace.vpc" [$WIN32||$X360||$POSIX]
  167.22 +}
  167.23 +
  167.24  $Project "qc_eyes"
  167.25  {
  167.26  	"utils\qc_eyes\qc_eyes.vpc" [$WIN32]
   168.1 --- a/vpc_scripts/protobuf_builder.vpc	Tue Jul 30 15:10:15 2013 -0700
   168.2 +++ b/vpc_scripts/protobuf_builder.vpc	Mon Sep 02 11:39:10 2013 -0700
   168.3 @@ -9,7 +9,7 @@
   168.4  	$CommandLine	"mkdir $GENERATED_PROTO_DIR 2> /dev/null;"  \
   168.5  					"$SRCDIR/devtools/bin/osx32/protoc --proto_path=$SRCDIR\thirdparty\protobuf-2.3.0\src --proto_path=$(InputDir) --proto_path=$SRCDIR\gcsdk --cpp_out=$GENERATED_PROTO_DIR $(InputPath)" [$OSXALL]
   168.6  	$CommandLine	"mkdir $GENERATED_PROTO_DIR 2> /dev/null;"  \
   168.7 -					"$SRCDIR/gcsdk/bin/linux/protoc --proto_path=$SRCDIR\thirdparty\protobuf-2.3.0\src --proto_path=$(InputDir) --proto_path=$SRCDIR\gcsdk --cpp_out=$GENERATED_PROTO_DIR $(InputPath)" [$LINUX]
   168.8 +					"$SRCDIR/gcsdk/bin/linux/protoc --proto_path=$SRCDIR\thirdparty\protobuf-2.3.0\src --proto_path=$(InputDir) --proto_path=$SRCDIR\gcsdk --cpp_out=$GENERATED_PROTO_DIR $(InputPath)" [$LINUXALL]
   168.9  	$Outputs		"$GENERATED_PROTO_DIR\$(InputName).pb.cc;$GENERATED_PROTO_DIR\$(InputName).pb.h"
  168.10  }
  168.11  
   169.1 --- a/vpc_scripts/source_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   169.2 +++ b/vpc_scripts/source_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   169.3 @@ -15,3 +15,32 @@
   169.4  // rel/tf_beta branch:
   169.5  //$Conditional TF_BETA	"1"
   169.6  
   169.7 +$Configuration "Debug"
   169.8 +{
   169.9 +	$Compiler
  169.10 +	{
  169.11 +		// Pass on appropriate branch define to preprocessor
  169.12 +		$PreprocessorDefinitions		"VPC"
  169.13 +		$PreprocessorDefinitions		"$BASE;STAGING_ONLY" [$STAGING_ONLY]
  169.14 +		$PreprocessorDefinitions		"$BASE;TF_BETA" [$TF_BETA]
  169.15 +		$PreprocessorDefinitions		"$BASE;RAD_TELEMETRY_DISABLED" [$SOURCESDK]
  169.16 +// Need to revisit the code to make things run with the _RETAIL preprocessor definition
  169.17 +// This line was added in the previous check-in, but had previously not been defined in this branch
  169.18 +//		$PreprocessorDefinitions		"$BASE;_RETAIL"		[$RETAIL]
  169.19 +	}
  169.20 +}
  169.21 +
  169.22 +$Configuration "Release"
  169.23 +{
  169.24 +	$Compiler
  169.25 +	{
  169.26 +		// Pass on appropriate branch define to preprocessor
  169.27 +		$PreprocessorDefinitions		"VPC"
  169.28 +		$PreprocessorDefinitions		"$BASE;STAGING_ONLY" [$STAGING_ONLY]
  169.29 +		$PreprocessorDefinitions		"$BASE;TF_BETA" [$TF_BETA]
  169.30 +		$PreprocessorDefinitions		"$BASE;RAD_TELEMETRY_DISABLED" [$SOURCESDK]
  169.31 +// Need to revisit the code to make things run with the _RETAIL preprocessor definition
  169.32 +// This line was added in the previous check-in, but had previously not been defined in this branch
  169.33 +//		$PreprocessorDefinitions		"$BASE;_RETAIL"		[$RETAIL]
  169.34 +	}
  169.35 +}
   170.1 --- a/vpc_scripts/source_dll_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   170.2 +++ b/vpc_scripts/source_dll_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   170.3 @@ -1,20 +1,25 @@
   170.4 -//-----------------------------------------------------------------------------
   170.5 -//	source_dll_base.VPC
   170.6 -//
   170.7 -//	Project Script
   170.8 -//-----------------------------------------------------------------------------
   170.9 -
  170.10 +$MacroRequired		"OUTDLLEXT" "$_DLL_EXT"
  170.11 +$Include "$SRCDIR\vpc_scripts\platform_dirs.vpc"
  170.12  $include "$SRCDIR\vpc_scripts\source_base.vpc"
  170.13  
  170.14 -$Macro PLATSUBDIR	"\linux32" [$LINUX32]
  170.15 -$Macro PLATSUBDIR	"\osx32" [$OSX32]
  170.16 -$Macro OUTBINDIR	"$OUTBINDIR" [$LINUX32]
  170.17 -$Macro LIBPUBLIC	"$SRCDIR\lib\public$PLATSUBDIR" [$LINUX32]
  170.18 -$Macro LIBCOMMON	"$SRCDIR\lib\common$PLATSUBDIR" [$LINUX32]
  170.19 -
  170.20 -$include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc"	[$WINDOWS]
  170.21 -$include "$SRCDIR\vpc_scripts\source_dll_x360_base.vpc"	[$X360]
  170.22 -$include "$SRCDIR\vpc_scripts\source_dll_posix_base.vpc"	[$OSXALL]
  170.23 -$Include "$SRCDIR\vpc_scripts\source_dll_linux_base.vpc"	[$LINUX]
  170.24 +$include "$SRCDIR\vpc_scripts\source_dll_posix_base.vpc"	[$POSIX]
  170.25 +$Include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc"	[( $WIN32 || $WIN64 ) && !$POSIX]
  170.26 +$Include "$SRCDIR\vpc_scripts\source_dll_x360_base.vpc"		[$X360]
  170.27 +$Include "$SRCDIR\vpc_scripts\source_ppu_prx_ps3_base.vpc"	[$PS3]
  170.28  $Include "$SRCDIR\vpc_scripts\source_video_base.vpc"
  170.29  
  170.30 +$Configuration
  170.31 +{
  170.32 +	$General	[$VS2010]
  170.33 +	{
  170.34 +		$TargetExtension	"$OUTDLLEXT"
  170.35 +	}
  170.36 +
  170.37 +	$Compiler
  170.38 +	{
  170.39 +		$PreprocessorDefinitions			"$BASE;DEV_BUILD"						[!$PUBLISH]
  170.40 +		$PreprocessorDefinitions			"$BASE;_PROFILE"						[$PROFILE && !$RETAIL]
  170.41 +		$PreprocessorDefinitions			"$BASE;RETAIL_ASSERTS"					[$RETAIL && $RETAILASSERTS]
  170.42 +		$PreprocessorDefinitions			"$BASE;FRAME_POINTER_OMISSION_DISABLED"	[$NOFPO || $VS2010]
  170.43 +	}
  170.44 +}
   171.1 --- a/vpc_scripts/source_dll_linux_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   171.2 +++ b/vpc_scripts/source_dll_linux_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   171.3 @@ -2,9 +2,8 @@
   171.4  $Include "$SRCDIR\vpc_scripts\version.vpc"
   171.5  $Include "$SRCDIR\vpc_scripts\source_linux_base_project.vpc"
   171.6  
   171.7 -
   171.8  $MacroRequired	 "OUTBINNAME"	"$PROJECTNAME"
   171.9 -
  171.10 +$MacroRequired	 "OUTBINDIR"	"$SRCDIR\..\game\bin"
  171.11  
  171.12  // General configuration info.
  171.13  $Configuration
  171.14 @@ -12,7 +11,7 @@
  171.15  	$General
  171.16  	{
  171.17  		$ConfigurationType				"Dynamic Library (.dll)"
  171.18 -		$OutputFile						"$(OBJ_DIR)/$OUTBINNAME$_DLL_EXT"
  171.19 +		$OutputFile					"$(OBJ_DIR)/$OUTBINNAME$_DLL_EXT"
  171.20  		$GameOutputFile					"$OUTBINDIR/$OUTBINNAME$_DLL_EXT"
  171.21  	}
  171.22  
  171.23 @@ -22,3 +21,25 @@
  171.24  	}
  171.25  }
  171.26  
  171.27 +// Skeleton Project - All derived projects get this as a starting base
  171.28 +$Project
  171.29 +{
  171.30 +	$Folder	"Source Files"
  171.31 +	{
  171.32 +		$File	"$SRCDIR\public\tier0\memoverride.cpp"
  171.33 +		{
  171.34 +			$Configuration
  171.35 +			{
  171.36 +				$Compiler
  171.37 +				{
  171.38 +					$Create/UsePrecompiledHeader	"Not Using Precompiled Headers"
  171.39 +				}
  171.40 +			}
  171.41 +		}
  171.42 +	}
  171.43 +
  171.44 +	$Folder "Resources"
  171.45 +	{
  171.46 +		$File	"$ROOTSCRIPT"
  171.47 +	}
  171.48 +}
   172.1 --- a/vpc_scripts/source_dll_posix_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   172.2 +++ b/vpc_scripts/source_dll_posix_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   172.3 @@ -13,12 +13,17 @@
   172.4  	$General
   172.5  	{
   172.6  		$ConfigurationType				"Dynamic Library (.dll)"
   172.7 -		$GameOutputFile					"$OUTBINDIR/$OUTBINNAME$_DLL_EXT"
   172.8 +		$GameOutputFile					"$OUTBINDIR/$OUTBINNAME$OUTDLLEXT"
   172.9 +	}
  172.10 +
  172.11 +	$Compiler
  172.12 +	{
  172.13 +		$PreprocessorDefinitions		"$BASE;DLLNAME=$OUTBINNAME"
  172.14  	}
  172.15  
  172.16  	$Linker
  172.17  	{
  172.18 -		$OutputFile					"$(OBJ_DIR)/$OUTBINNAME$_DLL_EXT"
  172.19 +		$OutputFile					"$(OBJ_DIR)/$OUTBINNAME$OUTDLLEXT"
  172.20  	}
  172.21  }
  172.22  
   173.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.2 +++ b/vpc_scripts/source_dll_qt_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   173.3 @@ -0,0 +1,44 @@
   173.4 +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
   173.5 +//
   173.6 +//==================================================================================================
   173.7 +
   173.8 +$Macro	QT_ROOT	"$SRCDIR\thirdparty\lgpl\qt"
   173.9 +
  173.10 +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
  173.11 +$Include "$SRCDIR\vpc_scripts\qt_base.vpc"
  173.12 +
  173.13 +$Configuration
  173.14 +{
  173.15 +	$Compiler
  173.16 +	{
  173.17 +		$AdditionalIncludeDirectories		"$BASE;.\;$SRCDIR\game\shared;$QT_ROOT\include;.\$QT_TARGET_SUBDIR"
  173.18 +		$PreprocessorDefinitions			"$BASE;QT_LARGEFILE_SUPPORT;QT_DLL;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT"
  173.19 +		$DisableSpecificWarnings			"4127;4512;$BASE"
  173.20 +
  173.21 +		// Causes a bunch of bogus compiler warnings for now; let's disable it
  173.22 +		$Detect64bitPortabilityIssues	"No"
  173.23 +	}
  173.24 +}
  173.25 +
  173.26 +$Configuration "Release"
  173.27 +{
  173.28 +	$Compiler
  173.29 +	{
  173.30 +		$PreprocessorDefinitions			"$BASE;QT_NO_DEBUG"
  173.31 +	}
  173.32 +}
  173.33 +
  173.34 +$Project
  173.35 +{
  173.36 +	$Folder "Link Libraries" [$QTDEBUG]
  173.37 +	{
  173.38 +		$Lib								"$QT_ROOT\lib\qtcored4"
  173.39 +		$Lib								"$QT_ROOT\lib\qtguid4"
  173.40 +	}
  173.41 +	
  173.42 +	$Folder "Link Libraries" [!$QTDEBUG]
  173.43 +	{
  173.44 +		$Lib								"$QT_ROOT\lib\qtcore4"
  173.45 +		$Lib								"$QT_ROOT\lib\qtgui4"
  173.46 +	}
  173.47 +}
   174.1 --- a/vpc_scripts/source_dll_win32_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   174.2 +++ b/vpc_scripts/source_dll_win32_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   174.3 @@ -6,26 +6,13 @@
   174.4  
   174.5  $Include "$SRCDIR\vpc_scripts\version.vpc"
   174.6  
   174.7 -$Macro NOAPPENDPLATSUBDIR "1" [!$WIN64]
   174.8 -
   174.9 -$MacroRequired				"PLATSUBDIR"
  174.10  $MacroRequired				"SRCDIR"
  174.11  $MacroRequired				"OUTBINNAME"	"$PROJECTNAME"
  174.12  $MacroRequired				"OUTBINDIR"
  174.13 -
  174.14 -// These are convenient for adjusting directory paths based on platform
  174.15 -// but they must be used without absolute consistency to avoid dependency
  174.16 -// problems. It appears that if VPC compares $LIBPUBLIC to $SRCDIR\lib\public
  174.17 -// it will decide that they are not equal, even if the *value* of $LIBPUBLIC
  174.18 -// is $SRCDIR\lib\public. These macros can safely be used in copy commands
  174.19 -// and other areas that VPC doesn't use for dependency tracking.
  174.20 -$Macro LIBPUBLIC	"$SRCDIR\lib\public"
  174.21 -$Macro LIBCOMMON	"$SRCDIR\lib\common"
  174.22 -
  174.23 -// Fix up directories for targets like win64
  174.24 -$Macro OUTBINDIR	"$OUTBINDIR$PLATSUBDIR" [!$NOAPPENDPLATSUBDIR && !$NOMODIFYOUTBINDIR]
  174.25 -$Macro LIBPUBLIC	"$LIBPUBLIC$PLATSUBDIR" [!$NOAPPENDPLATSUBDIR]
  174.26 -$Macro LIBCOMMON	"$LIBCOMMON$PLATSUBDIR" [!$NOAPPENDPLATSUBDIR]
  174.27 +		
  174.28 +$Macro OUTBINDIR	"$OUTBINDIR$PLATSUBDIR"
  174.29 +$Macro LIBPUBLIC	"$SRCDIR\lib\public$PLATSUBDIR"
  174.30 +$Macro LIBCOMMON	"$SRCDIR\lib\common$PLATSUBDIR"
  174.31  
  174.32  $Include "$SRCDIR\vpc_scripts\loadaddress.vpc"
  174.33  $Include "$SRCDIR\vpc_scripts\source_dll_win32_debug.vpc"
  174.34 @@ -34,75 +21,71 @@
  174.35  
  174.36  $IgnoreRedundancyWarning	"ON"
  174.37  
  174.38 -$Linux
  174.39 -{
  174.40 -	-$File	"$SRCDIR\lib\public\tier0.lib"
  174.41 -	$file   "$SRCDIR\linux\tier0_i686.so"
  174.42 -
  174.43 -	-$File	"$SRCDIR\lib\public\vstdlib.lib"	[!$WIN64]
  174.44 -	-$File	"$SRCDIR\lib\public\$PLATFORM\vstdlib.lib"	[$WIN64]
  174.45 -	$file	"$SRCDIR\linux\vstdlib_i686.so"
  174.46 -}
  174.47 -
  174.48  // Common Configuration
  174.49  $Configuration
  174.50  {
  174.51 -	$General [$VS2010]
  174.52 +	$General	[$VS2010]
  174.53  	{
  174.54 -		$TargetName		"$OUTBINNAME"
  174.55 +		$TargetName	"$OUTBINNAME"
  174.56  	}
  174.57  
  174.58 +	$Compiler
  174.59 +	{
  174.60 +		$PreprocessorDefinitions			"$BASE;PLATFORM_64BITS;WIN64;_WIN64;COMPILER_MSVC64" [$WIN64]
  174.61 +		$PreprocessorDefinitions			"$BASE;COMPILER_MSVC32" [$WIN32]		
  174.62 +		$PreprocessorDefinitions			"$BASE;COMPILER_MSVC;_DLL_EXT=$_DLL_EXT"
  174.63 +		$PreprocessorDefinitions			"$BASE;DLLNAME=$OUTBINNAME"		
  174.64 +	}
  174.65 +
  174.66 +	$Compiler [$WIN32]
  174.67 +	{
  174.68 +		$EnableEnhancedInstructionSet	"Streaming SIMD Extensions 2 (/arch:SSE2)"
  174.69 +	}
  174.70 +	
  174.71 +	$Linker
  174.72 +	{
  174.73 +		$AdditionalDependencies				"$BASE shell32.lib user32.lib advapi32.lib gdi32.lib comdlg32.lib ole32.lib" [$WIN32||$WIN64]
  174.74 +		$TargetMachine						"MachineX86 (/MACHINE:X86)"	[$WIN32]
  174.75 +		$TargetMachine						"MachineX64 (/MACHINE:X64)"	[$WIN64]
  174.76 +		// Suppress this pointless warning using the undocumented /ignore linker switch
  174.77 +		// schemalib.lib(schemaclassinfo.obj) : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library
  174.78 +		$AdditionalOptions					"$BASE /ignore:4221"
  174.79 +	}
  174.80 +	
  174.81  	$PreBuildEvent
  174.82  	{
  174.83  		$CommandLine		"if EXIST $OUTBINDIR\$(TargetFileName) for /f $QUOTEdelims=$QUOTE %%A in ('attrib $QUOTE$OUTBINDIR\$(TargetFileName)$QUOTE') do set valveTmpIsReadOnly=$QUOTE%%A$QUOTE" "\n" \
  174.84  							"set valveTmpIsReadOnlyLetter=%valveTmpIsReadOnly:~6,1%" "\n" \
  174.85  							"if $QUOTE%valveTmpIsReadOnlyLetter%$QUOTE==$QUOTER$QUOTE del /q $QUOTE$(TargetDir)$QUOTE$(TargetFileName)" "\n" \
  174.86 -							"$CRCCHECK" [!$SOURCESDK]
  174.87 +							"$CRCCHECK" "\n"
  174.88  	}
  174.89  
  174.90  	$PostBuildEvent [!$ANALYZE]
  174.91  	{
  174.92  		$CommandLine		"if not exist $QUOTE$OUTBINDIR$QUOTE mkdir $QUOTE$OUTBINDIR$QUOTE" "\n" 
  174.93  		$CommandLine		"$BASE" "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $QUOTE$OUTBINDIR\$(TargetFileName)$QUOTE $SRCDIR" "\n" [!$SOURCESDK]
  174.94 -		$CommandLine		"$BASE" "copy $QUOTE$(TargetDir)$QUOTE$(TargetFileName) $QUOTE$OUTBINDIR\$(TargetFileName)$QUOTE" "\n" \
  174.95 +		$CommandLine		"$BASE" "copy $QUOTE$(TargetDir)$(TargetFileName)$QUOTE $QUOTE$OUTBINDIR\$(TargetFileName)$QUOTE" "\n" \
  174.96  							"if ERRORLEVEL 1 goto BuildEventFailed" "\n" \
  174.97 -							"if exist $QUOTE$(TargetDir)$QUOTE$(TargetName).map copy $QUOTE$(TargetDir)$QUOTE$(TargetName).map $OUTBINDIR\$(TargetName).map" "\n" 
  174.98 -		$CommandLine		"$BASE" "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\$(TargetName).pdb $SRCDIR" "\n" [!$SOURCESDK]
  174.99 -		$CommandLine		"$BASE" "copy $QUOTE$(TargetDir)$QUOTE$(TargetName).pdb $OUTBINDIR\$(TargetName).pdb" "\n" \
 174.100 +							"if exist $QUOTE$(TargetDir)$(TargetName).map$QUOTE copy $QUOTE$(TargetDir)$(TargetName).map$QUOTE $OUTBINDIR\$(TargetName).map" "\n" 
 174.101 +		$CommandLine		"$BASE" "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $QUOTE$OUTBINDIR\$(TargetName).pdb$QUOTE $SRCDIR" "\n"  [!$SOURCESDK] 
 174.102 +		$CommandLine		"$BASE" "copy $QUOTE$(TargetDir)$(TargetName).pdb$QUOTE $OUTBINDIR\$(TargetName).pdb" "\n" \
 174.103  							"if ERRORLEVEL 1 goto BuildEventFailed" "\n" \
 174.104  							"goto BuildEventOK" "\n" \
 174.105  							":BuildEventFailed" "\n" \
 174.106  							"echo *** ERROR! PostBuildStep FAILED for $(ProjectName)! EXE or DLL is probably running. ***" "\n" \
 174.107 -							"del /q $QUOTE$(TargetDir)$QUOTE$(TargetFileName)" "\n" \
 174.108 +							"del /q $QUOTE$(TargetDir)$(TargetFileName)$QUOTE" "\n" \
 174.109  							"exit 1" "\n" \
 174.110 -							":BuildEventOK" "\n"
 174.111 +							":BuildEventOK" "\n" 
 174.112  
 174.113  		$CommandLine		"$BASE" "\n" \
 174.114 -							"call $SRCDIR\devtools\bin\vsign.bat -sign $OUTBINDIR\$(TargetFileName)" "\n" [$RETAIL && !$SOURCESDK]
 174.115 +							"call $SRCDIR\devtools\bin\vsign.bat -sign $OUTBINDIR\$(TargetFileName)" "\n" [$RETAIL && $PUBLISH]
 174.116  
 174.117  		$CommandLine		"$BASE" "\n" \
 174.118 -							"call $SRCDIR\devtools\bin\vsign.bat -signvalve $OUTBINDIR\$(TargetFileName)" "\n" [!$RETAIL && !$SOURCESDK]
 174.119 +							"call $SRCDIR\devtools\bin\vsign.bat -signvalve $OUTBINDIR\$(TargetFileName)" "\n" [!$RETAIL && !$PUBLISH && !$SOURCESDK]
 174.120  
 174.121  		$Description		"Publishing to $OUTBINDIR"
 174.122  		$ExcludedFromBuild	"No"
 174.123  	}
 174.124 -
 174.125 -	$Linker
 174.126 -	{
 174.127 -		// Suppress this warning using the undocumented /ignore linker switch
 174.128 -		// schemalib.lib(schemaclassinfo.obj) : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library
 174.129 -		$AdditionalOptions					"$BASE /ignore:4221"
 174.130 -		$AdditionalDependencies	"%(AdditionalDependencies)" [$VS2010]
 174.131 -		$TargetMachine						"MachineX86 (/MACHINE:X86)"	[$WIN32]
 174.132 -		$TargetMachine						"MachineX64 (/MACHINE:X64)"	[$WIN64]
 174.133 -
 174.134 -		// This option is from the devil.  Basically, it causes the link inputs
 174.135 -		// to vary depending on what is in the solution.  This is anathema
 174.136 -		// to the way that we use projects and solutions here at Valve.
 174.137 -		// It also exposes a bug in VS2005 causing files to be recompiled/linked
 174.138 -		// even if nothing changed.
 174.139 -		$LinkLibraryDependencies	"false"
 174.140 -	}
 174.141  }
 174.142  
 174.143  // Skeleton Project - All derived projects get this as a starting base
 174.144 @@ -120,23 +103,6 @@
 174.145  				}
 174.146  			}
 174.147  		}
 174.148 -
 174.149 -		// Implement __imp__EncodePointer and __imp__DecodePointer so that we can run on XP SP1
 174.150 -		// when building with VS 2010.
 174.151 -		$File	"$SRCDIR\public\tier0\pointeroverride.asm" [$WIN32 && $VS2010]
 174.152 -		{
 174.153 -			$Configuration
 174.154 -			{	
 174.155 -				$CustomBuildStep
 174.156 -				{
 174.157 -					// General
 174.158 -					$CommandLine				"$QUOTE$(VCInstallDir)bin\ml.exe$QUOTE /safeseh /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE"
 174.159 -					$Description				"Compiling pointeroverride.asm"
 174.160 -					$Outputs					"$(IntDir)\$(InputName).obj"
 174.161 -				}		
 174.162 -			}
 174.163 -		}
 174.164 -
 174.165  		$File	"$SRCDIR\common\debug_dll_check.cpp"	[!$SOURCESDK]	
 174.166  		{
 174.167  			$Configuration
 174.168 @@ -146,18 +112,14 @@
 174.169  					$Create/UsePrecompiledHeader	"Not Using Precompiled Headers"
 174.170  				}
 174.171  			}
 174.172 -		}		
 174.173 +		}
 174.174  	}
 174.175  
 174.176  	$Folder	"Link Libraries"
 174.177  	{
 174.178 -		$DynamicFile	"$SRCDIR\lib\public\tier0.lib"		[!$WIN64]
 174.179 -		$DynamicFile	"$SRCDIR\lib\public\tier1.lib"		[!$WIN64]
 174.180 -		$DynamicFile	"$SRCDIR\lib\public\vstdlib.lib"	[!$WIN64]
 174.181 -
 174.182 -		$DynamicFile	"$SRCDIR\lib\public\$PLATFORM\tier0.lib" 		[$WIN64]
 174.183 -		$DynamicFile	"$SRCDIR\lib\public\$PLATFORM\tier1.lib" 		[$WIN64]
 174.184 -		$DynamicFile	"$SRCDIR\lib\public\$PLATFORM\vstdlib.lib" 		[$WIN64]
 174.185 +		$Implib	"$LIBPUBLIC\tier0"
 174.186 +		$Lib	"$LIBPUBLIC\tier1"
 174.187 +		$Implib	"$LIBPUBLIC\vstdlib"
 174.188  	}
 174.189  }
 174.190  
   175.1 --- a/vpc_scripts/source_dll_win32_debug.vpc	Tue Jul 30 15:10:15 2013 -0700
   175.2 +++ b/vpc_scripts/source_dll_win32_debug.vpc	Mon Sep 02 11:39:10 2013 -0700
   175.3 @@ -6,18 +6,26 @@
   175.4  
   175.5  $IgnoreRedundancyWarning	"ON"
   175.6  
   175.7 -$MacroRequired				"PLATSUBDIR"
   175.8  $MacroRequired				"SRCDIR"
   175.9  $MacroRequired				"OUTBINNAME"
  175.10  $MacroRequired				"OUTBINDIR"
  175.11 +$MacroRequired				"LIBPUBLIC"
  175.12 +$MacroRequired				"LIBCOMMON"
  175.13 +$MacroRequired				"PLATSUBDIR"
  175.14 +$MacroRequired				"OUTDLLEXT"
  175.15 +$MacroRequiredAllowEmpty	"GAMENAME"
  175.16 +$MacroRequiredAllowEmpty	"INTERMEDIATESUBDIR"
  175.17 +$MacroRequiredAllowEmpty	"_UNITYSUBDIR"
  175.18 +$Macro						"_SUBDIRSUFFIX"		"$INTERMEDIATESUBDIR$GAMENAME$PLATSUBDIR$_UNITYSUBDIR"
  175.19  
  175.20  $Configuration "Debug"
  175.21  {
  175.22  	$General	
  175.23  	{
  175.24  		// General
  175.25 -		$OutputDirectory					".\Debug$PLATSUBDIR"
  175.26 -		$IntermediateDirectory				".\Debug$PLATSUBDIR"
  175.27 +		$OutputDirectory					".\Debug$_SUBDIRSUFFIX"
  175.28 +		$IntermediateDirectory				".\Debug$_SUBDIRSUFFIX"
  175.29 +
  175.30  		$ExtensionsToDeleteOnClean
  175.31  		$BuildLogFile
  175.32  		$InheritedProjectPropertySheets
  175.33 @@ -49,11 +57,10 @@
  175.34  		// General
  175.35  		$AdditionalIncludeDirectories		"$SRCDIR\common;$SRCDIR\public;$SRCDIR\public\tier0;$SRCDIR\public\tier1"
  175.36  		$Resolve#UsingReferences
  175.37 -		$DebugInformationFormat				"Program Database for Edit & Continue (/ZI)" [!$EANDCDISABLED && !$WIN64]
  175.38 -		$DebugInformationFormat				"Program Database (/Zi)"                     [$EANDCDISABLED || $WIN64]
  175.39 +		$DebugInformationFormat				"Program Database for Edit & Continue (/ZI)" [$WIN32]
  175.40 +		$DebugInformationFormat				"Program Database (/Zi)" [$WIN64]
  175.41  		$SuppressStartupBanner		
  175.42  		$WarningLevel						"Level 4 (/W4)"
  175.43 -		$Detect64bitPortabilityIssues		"Yes (/Wp64)"
  175.44  		$TreatWarningsAsErrors
  175.45  		$UseUNICODEResponseFiles
  175.46  
  175.47 @@ -67,19 +74,14 @@
  175.48  		$WholeProgramOptimization
  175.49  
  175.50  		// Preprocessor
  175.51 -		$PreprocessorDefinitions			"_HAS_ITERATOR_DEBUGGING=0;WIN32;_WIN32;_DEBUG;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;DLLNAME=$OUTBINNAME"
  175.52 -		$PreprocessorDefinitions			"$BASE;RAD_TELEMETRY_DISABLED" [$SOURCESDK]
  175.53 +		$PreprocessorDefinitions			"$BASE;_HAS_ITERATOR_DEBUGGING=0;WIN32;_WIN32;_DEBUG;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
  175.54  		$IgnoreStandardIncludePath
  175.55  		$GeneratePreprocessedFile
  175.56  		$KeepComments
  175.57  
  175.58  		// Code Generation
  175.59  		$EnableStringPooling				"Yes (/GF)"
  175.60 -		// EnableMinimalRebuild is incompatible with /MP (multi-processor builds)
  175.61 -		// and it also makes it hard to iterate on warnings because the compiler
  175.62 -		// detects that there is no reason to recompile when you request it.
  175.63 -		// It should always be off? It should definitely be off for /analyze builds.
  175.64 -		//$EnableMinimalRebuild				"Yes (/Gm)" [!$ANALYZE]
  175.65 +		$EnableMinimalRebuild				
  175.66  		$EnableC++Exceptions				"No"
  175.67  		$SmallerTypeCheck
  175.68  		$BasicRuntimeChecks					"Default"
  175.69 @@ -88,7 +90,6 @@
  175.70  		$BufferSecurityCheck				"Yes"
  175.71  		$EnableFunctionLevelLinking
  175.72  		$EnableEnhancedInstructionSet
  175.73 -		$EnableEnhancedInstructionSet			"Streaming SIMD Extensions (/arch:SSE)" [$WIN32]
  175.74  		$FloatingPointModel					"Fast (/fp:fast)"
  175.75  		$EnableFloatingPointExceptions
  175.76  
  175.77 @@ -127,18 +128,18 @@
  175.78  		$ShowIncludes
  175.79  		$UndefinePreprocessorDefinitions
  175.80  		$UndefineAllPreprocessorDefinitions
  175.81 -		$UseFullPaths
  175.82 +		$UseFullPaths						"Yes (/FC)"
  175.83  		$OmitDefaultLibraryNames
  175.84  		$ErrorReporting						"Prompt Immediately (/errorReport:prompt)"
  175.85  
  175.86 -		// Command Line 
  175.87 -		$AdditionalOptions					"$BASE /MP"
  175.88 +		// Command Line (L4D adding /MP)
  175.89 +		$AdditionalOptions					"/MP /Zm200"
  175.90  	}
  175.91  
  175.92  	$Linker
  175.93  	{
  175.94  		// General
  175.95 -		$OutputFile							"$(OutDir)/$OUTBINNAME.dll"
  175.96 +		$OutputFile							"$(OutDir)/$OUTBINNAME$OUTDLLEXT"
  175.97  		$ShowProgress						"Not Set"
  175.98  		$Version
  175.99  		$EnableIncrementalLinking			"Yes (/INCREMENTAL)"
 175.100 @@ -166,13 +167,12 @@
 175.101  		$ManifestFile
 175.102  		$AdditionalManifestDependencies
 175.103  		$AllowIsolation
 175.104 +		//$UACExecutionLevel				[$VS2010]
 175.105  
 175.106  		// Debugging
 175.107  		$GenerateDebugInfo					"Yes (/DEBUG)"
 175.108  		$GenerateProgramDatabaseFile		"$(IntDir)/$(TargetName).pdb"
 175.109  		$StripPrivateSymbols
 175.110 -		$GenerateMapFile					"No"
 175.111 -		$MapFileName						"$(IntDir)/$(TargetName).map"
 175.112  		$MapExports
 175.113  		$DebuggableAssembly
 175.114  
 175.115 @@ -188,6 +188,9 @@
 175.116  		$SwapRunFromNetwork
 175.117  		$Driver
 175.118  
 175.119 +		// DYNAMICBASE/ASLR in debug builds is annoying and not helpful.
 175.120 +		$RandomizedBaseAddress				"false"
 175.121 +
 175.122  		// Optimization
 175.123  		$References
 175.124  		$EnableCOMDATFolding
 175.125 @@ -213,6 +216,7 @@
 175.126  		$DelayLoadedDLL
 175.127  		$ImportLibrary
 175.128  		$MergeSections
 175.129 +		$TargetMachine					
 175.130  		$Profile
 175.131  		$CLRThreadAttribute
 175.132  		$CLRImageType
 175.133 @@ -226,12 +230,6 @@
 175.134  		$AdditionalOptions						
 175.135  	}
 175.136  
 175.137 -	$Linker [$VS2010]
 175.138 -	{
 175.139 -		// SAFE_SEH should always be disabled on debug builds.
 175.140 -		$ImageHasSafeExceptionHandlers		"false"
 175.141 -	}
 175.142 -
 175.143  	$ManifestTool
 175.144  	{
 175.145  		// General
 175.146 @@ -285,7 +283,7 @@
 175.147  	$Resources
 175.148  	{
 175.149  		// General
 175.150 -		$PreprocessorDefinitions			"_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
 175.151 +		$PreprocessorDefinitions			"$BASE;_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
 175.152  		$Culture							"English (United States) (0x409)"
 175.153  		$AdditionalIncludeDirectories
 175.154  		$IgnoreStandardIncludePath
   176.1 --- a/vpc_scripts/source_dll_win32_release.vpc	Tue Jul 30 15:10:15 2013 -0700
   176.2 +++ b/vpc_scripts/source_dll_win32_release.vpc	Mon Sep 02 11:39:10 2013 -0700
   176.3 @@ -6,18 +6,34 @@
   176.4  
   176.5  $IgnoreRedundancyWarning	"ON"
   176.6  
   176.7 -$MacroRequired				"PLATSUBDIR"
   176.8 +// Disable frame pointer omission to allow fast stack walking, necessary for
   176.9 +// good ETW profiling.
  176.10 +$Macro  NOFPO  "1"
  176.11 +
  176.12  $MacroRequired				"SRCDIR"
  176.13  $MacroRequired				"OUTBINNAME"
  176.14  $MacroRequired				"OUTBINDIR"
  176.15 +$MacroRequired				"LIBPUBLIC"
  176.16 +$MacroRequired				"LIBCOMMON"
  176.17 +$MacroRequired				"PLATSUBDIR"
  176.18 +$MacroRequired				"OUTDLLEXT"
  176.19 +$MacroRequiredAllowEmpty	"GAMENAME"
  176.20 +$MacroRequiredAllowEmpty	"INTERMEDIATESUBDIR"
  176.21 +$MacroRequiredAllowEmpty	"_UNITYSUBDIR"
  176.22 +$Macro						"_SUBDIRSUFFIX"		"$INTERMEDIATESUBDIR$GAMENAME$PLATSUBDIR$_UNITYSUBDIR"
  176.23  
  176.24  $Configuration "Release"
  176.25  {
  176.26  	$General	
  176.27  	{
  176.28  		// General
  176.29 -		$OutputDirectory					".\Release$PLATSUBDIR"
  176.30 -		$IntermediateDirectory				".\Release$PLATSUBDIR"
  176.31 +		$OutputDirectory				".\Release$_SUBDIRSUFFIX"	[!$RETAIL && !$PROFILE]
  176.32 +		$IntermediateDirectory			".\Release$_SUBDIRSUFFIX"	[!$RETAIL && !$PROFILE]
  176.33 +		$OutputDirectory				".\Retail$_SUBDIRSUFFIX"	[$RETAIL]
  176.34 +		$IntermediateDirectory			".\Retail$_SUBDIRSUFFIX"	[$RETAIL]
  176.35 +		$OutputDirectory				".\Profile$_SUBDIRSUFFIX"	[!$RETAIL && $PROFILE]
  176.36 +		$IntermediateDirectory			".\Profile$_SUBDIRSUFFIX"	[!$RETAIL && $PROFILE]
  176.37 +
  176.38  		$ExtensionsToDeleteOnClean
  176.39  		$BuildLogFile
  176.40  		$InheritedProjectPropertySheets
  176.41 @@ -29,7 +45,7 @@
  176.42  		$MinimizeCRTUseInATL
  176.43  		$CharacterSet						"Use Multi-Byte Character Set"
  176.44  		$CommonLanguageRuntimeSupport
  176.45 -		$WholeProgramOptimization
  176.46 +		$WholeProgramOptimization			"Use Link Time Code Generation" [$LTCG]
  176.47  	}
  176.48  
  176.49  	$Debugging
  176.50 @@ -52,7 +68,6 @@
  176.51  		$DebugInformationFormat				"Program Database (/Zi)"
  176.52  		$SuppressStartupBanner
  176.53  		$WarningLevel						"Level 4 (/W4)"
  176.54 -		$Detect64bitPortabilityIssues		"Yes (/Wp64)"
  176.55  		$TreatWarningsAsErrors
  176.56  		$UseUNICODEResponseFiles
  176.57  
  176.58 @@ -66,10 +81,8 @@
  176.59  		$WholeProgramOptimization
  176.60  
  176.61  		// Preprocessor
  176.62 -		$PreprocessorDefinitions			"WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;DLLNAME=$OUTBINNAME"
  176.63 -		// Enable asserts in release builds if /define:releaseasserts is specified on the VPC command line.
  176.64 -		$PreprocessorDefinitions			"$BASE;RELEASEASSERTS" [$RELEASEASSERTS]
  176.65 -		$PreprocessorDefinitions			"$BASE;RAD_TELEMETRY_DISABLED" [$SOURCESDK]
  176.66 +		$PreprocessorDefinitions			"$BASE;WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
  176.67 +		$PreprocessorDefinitions			"$BASE;RELEASE_ASSERTS" [$RELEASEASSERTS]
  176.68  		$IgnoreStandardIncludePath
  176.69  		$GeneratePreprocessedFile
  176.70  		$KeepComments
  176.71 @@ -82,11 +95,10 @@
  176.72  		$BasicRuntimeChecks
  176.73  		$RuntimeLibrary						"Multi-threaded (/MT)"
  176.74  		$StructMemberAlignment
  176.75 -		$BufferSecurityCheck				"Yes"	[$STAGING_ONLY]
  176.76 -		$BufferSecurityCheck				"No"	[!$STAGING_ONLY]
  176.77 +		$BufferSecurityCheck                "No"	[$RETAIL]
  176.78 +		$BufferSecurityCheck                "Yes"	[!$RETAIL]
  176.79  		$EnableFunctionLevelLinking			"Yes (/Gy)"
  176.80  		$EnableEnhancedInstructionSet
  176.81 -		$EnableEnhancedInstructionSet			"Streaming SIMD Extensions (/arch:SSE)" [$WIN32]
  176.82  		$FloatingPointModel					"Fast (/fp:fast)"
  176.83  		$EnableFloatingPointExceptions
  176.84  
  176.85 @@ -125,20 +137,21 @@
  176.86  		$ShowIncludes
  176.87  		$UndefinePreprocessorDefinitions
  176.88  		$UndefineAllPreprocessorDefinitions
  176.89 -		$UseFullPaths
  176.90 +		$UseFullPaths						"Yes (/FC)"
  176.91  		$OmitDefaultLibraryNames
  176.92  		$ErrorReporting						"Prompt Immediately (/errorReport:prompt)"
  176.93  
  176.94 -		// Command Line 
  176.95 -		$AdditionalOptions					"$BASE /MP"
  176.96 +		// Command Line (L4D adding /MP)
  176.97 +		$AdditionalOptions					"/MP /Zm200"
  176.98  		// Enable extra debugging information.
  176.99 -		$AdditionalOptions					"$BASE /d2Zi+"
 176.100 +		$AdditionalOptions					"$BASE /d2Zi+"  [$VS2010]
 176.101 +		$AdditionalOptions					"$BASE /Oy-"	[$NOFPO]
 176.102  	}
 176.103  
 176.104  	$Linker
 176.105  	{
 176.106  		// General
 176.107 -		$OutputFile							"$(OutDir)/$OUTBINNAME.dll"
 176.108 +		$OutputFile							"$(OutDir)/$OUTBINNAME$OUTDLLEXT"
 176.109  		$ShowProgress						"Not Set"
 176.110  		$Version
 176.111  		$EnableIncrementalLinking			"No (/INCREMENTAL:NO)"
 176.112 @@ -166,13 +179,12 @@
 176.113  		$ManifestFile
 176.114  		$AdditionalManifestDependencies
 176.115  		$AllowIsolation
 176.116 +		//$UACExecutionLevel
 176.117  
 176.118  		// Debugging
 176.119  		$GenerateDebugInfo					"Yes (/DEBUG)"
 176.120  		$GenerateProgramDatabaseFile		"$(IntDir)/$(TargetName).pdb"
 176.121  		$StripPrivateSymbols
 176.122 -		$GenerateMapFile					"No"
 176.123 -		$MapFileName						"$(IntDir)/$(TargetName).map"
 176.124  		$MapExports
 176.125  		$DebuggableAssembly
 176.126  
 176.127 @@ -188,9 +200,22 @@
 176.128  		$SwapRunFromNetwork
 176.129  		$Driver
 176.130  
 176.131 +		// RandomizeBaseAddress (/DYNAMICBASE, /ASLR) is a hugely important security setting.
 176.132 +		// However it can cause confusion during development and can make tracking down certain
 176.133 +		// bugs tricky by making code/stack/heap addresses change between runs. Enable for retail,
 176.134 +		// but disable for development builds.
 176.135 +		$RandomizedBaseAddress				"true" [$RETAIL]
 176.136 +		$RandomizedBaseAddress				"false" [!$RETAIL]
 176.137 +
 176.138  		// Optimization
 176.139  		$References							"Eliminate Unreferenced Data (/OPT:REF)"
 176.140 -		$EnableCOMDATFolding				"Remove Redundant COMDATs (/OPT:ICF)"
 176.141 +		// COMDAT folding can be very confusing when debugging and profiling because it can
 176.142 +		// cause execution to go through nonsensical functions (that happen to be binary
 176.143 +		// equivalent to the logical function). The performance benefit is small enough that
 176.144 +		// it is not worth enabling in the development builds. It should be enabled on retail
 176.145 +		// builds.
 176.146 +		$EnableCOMDATFolding				"Remove Redundant COMDATs (/OPT:ICF)" [$RETAIL]
 176.147 +		$EnableCOMDATFolding				"No (/OPT:NOICF)" [!$RETAIL]
 176.148  		$OptimizeForWindows98
 176.149  		$FunctionOrder
 176.150  		$ProfileGuidedDatabase
 176.151 @@ -208,12 +233,13 @@
 176.152  		$NoEntryPoint
 176.153  		$SetChecksum
 176.154  		$BaseAddress						"$LOADADDRESS_DEVELOPMENT"
 176.155 -		$BaseAddress						"$LOADADDRESS_RETAIL" [$RETAIL]
 176.156 +		//$BaseAddress						"$LOADADDRESS_RETAIL" [$RETAIL]
 176.157  		$FixedBaseAddress
 176.158  		$TurnOffAssemblyGeneration
 176.159  		$DelayLoadedDLL
 176.160  		$ImportLibrary
 176.161  		$MergeSections
 176.162 +		$TargetMachine					
 176.163  		$Profile
 176.164  		$CLRThreadAttribute
 176.165  		$CLRImageType
 176.166 @@ -224,7 +250,7 @@
 176.167  		$CLRUnmanagedCodeCheck
 176.168  
 176.169  		// Command Line
 176.170 -		$AdditionalOptions					"$BASE /DYNAMICBASE"		
 176.171 +		$AdditionalOptions						
 176.172  	}
 176.173  
 176.174  	$ManifestTool
 176.175 @@ -280,7 +306,7 @@
 176.176  	$Resources
 176.177  	{
 176.178  		// General
 176.179 -		$PreprocessorDefinitions			"NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
 176.180 +		$PreprocessorDefinitions			"$BASE;NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
 176.181  		$Culture							"English (United States) (0x409)"
 176.182  		$AdditionalIncludeDirectories
 176.183  		$IgnoreStandardIncludePath
 176.184 @@ -320,4 +346,4 @@
 176.185  		$Outputs
 176.186  		$AdditionalDependencies
 176.187  	}
 176.188 -}
 176.189 \ No newline at end of file
 176.190 +}
   177.1 --- a/vpc_scripts/source_exe_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   177.2 +++ b/vpc_scripts/source_exe_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   177.3 @@ -1,13 +1,20 @@
   177.4 -//-----------------------------------------------------------------------------
   177.5 -//	source_exe_base.VPC
   177.6 -//
   177.7 -//	Project Script
   177.8 -//-----------------------------------------------------------------------------
   177.9 -
  177.10 +$Include "$SRCDIR\vpc_scripts\platform_dirs.vpc"
  177.11  $include "$SRCDIR\vpc_scripts\source_base.vpc"
  177.12  
  177.13 -$include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"	[$WINDOWS]
  177.14 -$Include "$SRCDIR\vpc_scripts\source_exe_linux_base.vpc"	[$LINUX]
  177.15 -$include "$SRCDIR\vpc_scripts\source_exe_posix_base.vpc"	[$POSIX && !$LINUX]
  177.16 -$include "$SRCDIR\vpc_scripts\source_xex_x360_base.vpc"		[$X360]
  177.17 +$Include "$SRCDIR\vpc_scripts\source_exe_posix_base.vpc"		[$POSIX]
  177.18 +$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc" 	[$WIN32 || $WIN64]
  177.19 +$Include "$SRCDIR\vpc_scripts\source_xex_x360_base.vpc"			[$X360]
  177.20 +$Include "$SRCDIR\vpc_scripts\source_ppu_elf_ps3_base.vpc"		[$PS3]
  177.21 +
  177.22  $Include "$SRCDIR\vpc_scripts\source_video_base.vpc"
  177.23 +
  177.24 +$Configuration
  177.25 +{
  177.26 +	$Compiler
  177.27 +	{
  177.28 +		$PreprocessorDefinitions			"$BASE;DEV_BUILD"						[!$PUBLISH]
  177.29 +		$PreprocessorDefinitions			"$BASE;_PROFILE"						[$PROFILE && !$RETAIL]
  177.30 +		$PreprocessorDefinitions			"$BASE;RETAIL_ASSERTS"					[$RETAIL && $RETAILASSERTS]
  177.31 +		$PreprocessorDefinitions			"$BASE;FRAME_POINTER_OMISSION_DISABLED"	[$NOFPO || $VS2010]
  177.32 +	}
  177.33 +}
  177.34 \ No newline at end of file
   178.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.2 +++ b/vpc_scripts/source_exe_con_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   178.3 @@ -0,0 +1,18 @@
   178.4 +$Include "$SRCDIR\vpc_scripts\platform_dirs.vpc"
   178.5 +$include "$SRCDIR\vpc_scripts\source_base.vpc"
   178.6 +
   178.7 +
   178.8 +$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc" [$WINDOWS]
   178.9 +$Include "$SRCDIR\vpc_scripts\source_exe_posix_base.vpc" [$POSIX]
  178.10 +$Include "$SRCDIR\vpc_scripts\source_xex_x360_base.vpc"	[$X360]
  178.11 +
  178.12 +$Configuration
  178.13 +{
  178.14 +	$Compiler
  178.15 +	{
  178.16 +		$PreprocessorDefinitions			"$BASE;DEV_BUILD"						[!$PUBLISH]
  178.17 +		$PreprocessorDefinitions			"$BASE;_PROFILE"						[$PROFILE && !$RETAIL]
  178.18 +		$PreprocessorDefinitions			"$BASE;RETAIL_ASSERTS"					[$RETAIL && $RETAILASSERTS]
  178.19 +		$PreprocessorDefinitions			"$BASE;FRAME_POINTER_OMISSION_DISABLED"	[$NOFPO || $VS2010]
  178.20 +	}
  178.21 +}
   179.1 --- a/vpc_scripts/source_exe_con_win32_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   179.2 +++ b/vpc_scripts/source_exe_con_win32_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   179.3 @@ -7,6 +7,8 @@
   179.4  $IgnoreRedundancyWarning	"ON"
   179.5  $MacroRequired				"SRCDIR"
   179.6  $MacroRequired				"OUTBINDIR"
   179.7 +$MacroRequired				"PLATSUBDIR"
   179.8 +
   179.9  
  179.10  $Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
  179.11  
   180.1 --- a/vpc_scripts/source_exe_posix_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   180.2 +++ b/vpc_scripts/source_exe_posix_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   180.3 @@ -5,10 +5,11 @@
   180.4  //-----------------------------------------------------------------------------
   180.5  
   180.6  $Include "$SRCDIR\vpc_scripts\version.vpc"
   180.7 -$Include "$SRCDIR\vpc_scripts\source_posix_base.vpc"
   180.8  
   180.9  $MacroRequired				"SRCDIR"
  180.10  $MacroRequired				"OUTBINNAME"	"$PROJECTNAME"
  180.11 +$Macro IS_LIB_PROJECT		"1"
  180.12 +$Include "$SRCDIR\vpc_scripts\source_posix_base.vpc"
  180.13  
  180.14  $Include "$SRCDIR\vpc_scripts\loadaddress.vpc"
  180.15  
  180.16 @@ -22,9 +23,21 @@
  180.17  		$ConfigurationType				"Application (.exe)"
  180.18  	}
  180.19  
  180.20 +	$Compiler
  180.21 +	{
  180.22 +		$PreprocessorDefinitions		"$BASE;EXENAME=$OUTBINNAME"
  180.23 +	}
  180.24 +
  180.25  	$Linker
  180.26  	{
  180.27 -			$OutputFile								"$SRCDIR/../game/$OUTBINNAME"
  180.28 +		$OutputFile						"$SRCDIR/../game/$OUTBINNAME"
  180.29 +
  180.30 +		// In order to get the Valve standard allocator memory alignment (16-byte
  180.31 +		// alignment for objects that are a multiple of 16 bytes) we use tcmalloc.
  180.32 +		// Using -l will ask the linker to use it, but if there are no references
  180.33 +		// to malloc/free then it may not actually use it. Wrapping the flag in the
  180.34 +		// as-needed controls forces it to be pulled in (from libtcmalloc_minimal.so).
  180.35 +		$GCC_ExtraLinkerFlags			"-Wl,--no-as-needed -ltcmalloc_minimal -Wl,--as-needed" [$LINUXALL&&!$DEDICATED]
  180.36  	}
  180.37  }
  180.38  
  180.39 @@ -49,16 +62,10 @@
  180.40  	{
  180.41  		$File	"$ROOTSCRIPT"
  180.42  	}
  180.43 -	
  180.44 -	
  180.45 -	$Folder	"Link Libraries"
  180.46 +
  180.47 +	$Folder	"Link Libraries" [$LINUXALL&&!$DEDICATED]
  180.48  	{
  180.49 -		$ImpLib tier0	[$LINUXALL]
  180.50 -		$Lib	tier1	[$LINUXALL]
  180.51 -		$ImpLib vstdlib	[$LINUXALL]
  180.52 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXtier0$_IMPLIB_EXT"	[!$LINUXALL]
  180.53 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\tier1$_STATICLIB_EXT"				[!$LINUXALL]
  180.54 -		$DynamicFile	"$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIXvstdlib$_IMPLIB_EXT"	[!$LINUXALL]
  180.55 +		$File	"$SRCDIR/thirdparty/gperftools-2.0/.libs/libtcmalloc_minimal.so"
  180.56  	}
  180.57  }
  180.58  
   181.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   181.2 +++ b/vpc_scripts/source_exe_qt_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   181.3 @@ -0,0 +1,5 @@
   181.4 +// call up either the posix or win32 vpc file based upon target platform
   181.5 +
   181.6 +//$Include "$SRCDIR\vpc_scripts\source_exe_qt_linux_base.vpc"		[$POSIX]
   181.7 +$Include "$SRCDIR\vpc_scripts\source_exe_qt_win32_base.vpc" 	[$WIN32 || $WIN64]
   181.8 +		 
   181.9 \ No newline at end of file
   182.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.2 +++ b/vpc_scripts/source_exe_qt_con_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   182.3 @@ -0,0 +1,16 @@
   182.4 +// base file for a console app with qt. win32 only for now. CG: I'm not 100% sure this is the right definition,
   182.5 +// but I'm moving the logic here so it doesn't end up pasted into every such app.
   182.6 +
   182.7 +$Include "$SRCDIR\vpc_scripts\source_exe_qt_win32_base.vpc"
   182.8 +
   182.9 +$Configuration
  182.10 +{
  182.11 +	$Linker
  182.12 +	{
  182.13 +		$SubSystem		"Console (/SUBSYSTEM:CONSOLE)"
  182.14 +	}
  182.15 +	$Compiler
  182.16 +	{
  182.17 +		$AdditionalIncludeDirectories		"$BASE,..\common"
  182.18 +	}
  182.19 +}
   183.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.2 +++ b/vpc_scripts/source_exe_qt_win32_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   183.3 @@ -0,0 +1,48 @@
   183.4 +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
   183.5 +//
   183.6 +//==================================================================================================
   183.7 +
   183.8 +$Macro	QT_ROOT	"$SRCDIR\thirdparty\lgpl\qt"
   183.9 +
  183.10 +$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
  183.11 +$Include "$SRCDIR\vpc_scripts\qt_base.vpc"
  183.12 +
  183.13 +$Configuration
  183.14 +{
  183.15 +	$Compiler
  183.16 +	{
  183.17 +		$AdditionalIncludeDirectories		"$BASE;.\;$SRCDIR\game\shared;$QT_ROOT\include;.\$QT_TARGET_SUBDIR"
  183.18 +		$PreprocessorDefinitions			"$BASE;UNICODE;QT_LARGEFILE_SUPPORT;QT_DLL;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT"
  183.19 +		$PreprocessorDefinitions			"$BASE;QT_NO_DEBUG" [!$QTDEBUG]
  183.20 +		$DisableSpecificWarnings			"4127;4512;$BASE"
  183.21 +	}
  183.22 +}
  183.23 +
  183.24 +$Configuration
  183.25 +{
  183.26 +	$Linker
  183.27 +	{
  183.28 +		// Link tier0 first because Qt needs our allocators during static object initization!
  183.29 +		$AdditionalDependencies				"$BASE $LIBPUBLIC\tier0.lib"
  183.30 +		$GenerateManifest					"Yes"
  183.31 +		$AdditionalOptions					"$BASE $QUOTE/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'$QUOTE"
  183.32 +	}
  183.33 +}
  183.34 +
  183.35 +$Project
  183.36 +{
  183.37 +	$Folder "Link Libraries" [$QTDEBUG]
  183.38 +	{
  183.39 +		$Lib								"$QT_ROOT\lib\qtmaind"
  183.40 +		$Lib								"$QT_ROOT\lib\qtcored4"
  183.41 +		$Lib								"$QT_ROOT\lib\qtguid4"
  183.42 +	}
  183.43 +	
  183.44 +	$Folder "Link Libraries" [!$QTDEBUG]
  183.45 +	{
  183.46 +		$Lib								"$QT_ROOT\lib\qtmain"
  183.47 +		$Lib								"$QT_ROOT\lib\qtcore4"
  183.48 +		$Lib								"$QT_ROOT\lib\qtgui4"
  183.49 +	}
  183.50 +}
  183.51 +
   184.1 --- a/vpc_scripts/source_exe_win_win32_base.vpc	Tue Jul 30 15:10:15 2013 -0700
   184.2 +++ b/vpc_scripts/source_exe_win_win32_base.vpc	Mon Sep 02 11:39:10 2013 -0700
   184.3 @@ -6,59 +6,71 @@
   184.4  
   184.5  $Include "$SRCDIR\vpc_scripts\version.vpc"
   184.6  
   184.7 -$Macro NOAPPENDPLATSUBDIR "1" [!$WIN64]
   184.8 -
   184.9 -$MacroRequired				"PLATSUBDIR"
  184.10  $MacroRequired				"SRCDIR"
  184.11  $MacroRequired				"OUTBINNAME"	"$PROJECTNAME"
  184.12  $MacroRequired				"OUTBINDIR"
  184.13  
  184.14 -// These are convenient for adjusting directory paths based on platform
  184.15 -// but they must be used without absolute consistency to avoid dependency
  184.16 -// problems. It appears that if VPC compares $LIBPUBLIC to $SRCDIR\lib\public
  184.17 -// it will decide that they are not equal, even if the *value* of $LIBPUBLIC
  184.18 -// is $SRCDIR\lib\public. These macros can safely be used in copy commands
  184.19 -// and other areas that VPC doesn't use for dependency tracking.
  184.20 -$Macro LIBPUBLIC	"$SRCDIR\lib\public"
  184.21 -$Macro LIBCOMMON	"$SRCDIR\lib\common"
  184.22 +$Macro OUTBINDIR	"$OUTBINDIR$PLATSUBDIR"
  184.23 +$Macro LIBPUBLIC	"$SRCDIR\lib\public$PLATSUBDIR"
  184.24 +$Macro LIBCOMMON	"$SRCDIR\lib\common$PLATSUBDIR"
  184.25  
  184.26  $Include "$SRCDIR\vpc_scripts\loadaddress.vpc"
  184.27  $Include "$SRCDIR\vpc_scripts\source_exe_win_win32_debug.vpc"
  184.28  $Include "$SRCDIR\vpc_scripts\source_exe_win_win32_release.vpc"
  184.29  $Include "$SRCDIR\vpc_scripts\source_win32_base.vpc"
  184.30  
  184.31 -// Fix up directories for targets like win64
  184.32 -$Macro OUTBINDIR	"$OUTBINDIR$PLATSUBDIR" [!$NOAPPENDPLATSUBDIR]
  184.33 -$Macro LIBPUBLIC	"$LIBPUBLIC$PLATSUBDIR" [!$NOAPPENDPLATSUBDIR]
  184.34 -$Macro LIBCOMMON	"$LIBCOMMON$PLATSUBDIR" [!$NOAPPENDPLATSUBDIR]
  184.35 -
  184.36  $IgnoreRedundancyWarning	"ON"
  184.37  
  184.38  // Common Configuration
  184.39  $Configuration
  184.40  {
  184.41 -	$General [$VS2010]
  184.42 +	$General	[$VS2010]
  184.43  	{
  184.44 -		$TargetName		"$OUTBINNAME"