mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2024-12-23 01:59:43 +08:00
Imported more changes from sdk2013.
This commit is contained in:
parent
9b952c8845
commit
80466261f6
@ -102,7 +102,7 @@ void CChoreoScene::choreoprintf( int level, const char *fmt, ... )
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( string );
|
||||
printf( "%s", string );
|
||||
}
|
||||
|
||||
Msg( "%s", string );
|
||||
|
Binary file not shown.
@ -35,7 +35,7 @@ else
|
||||
CC = /usr/bin/gcc
|
||||
CPLUS = /usr/bin/g++
|
||||
CLINK = /usr/bin/gcc
|
||||
CPP_LIB = $(SRCDS_DIR)/bin/libstdc++.so.6 $(SRCDS_DIR)/bin/libgcc_s.so.1
|
||||
CPP_LIB = #$(SRCDS_DIR)/bin/libstdc++.so.6 $(SRCDS_DIR)/bin/libgcc_s.so.1
|
||||
endif
|
||||
|
||||
# put any compiler flags you want passed here
|
||||
@ -57,6 +57,16 @@ DEBUG = false
|
||||
#############################################################################
|
||||
# Things below here shouldn't need to be altered
|
||||
#############################################################################
|
||||
IS_CLANG := $(shell $(CPP) --version | head -1 | grep clang > /dev/null && echo "1" || echo "0")
|
||||
|
||||
ifeq "$(IS_CLANG)" "1"
|
||||
CPP_MAJOR := $(shell $(CPP) --version | grep clang | sed "s/.*version \([0-9]\)*\.[0-9]*.*/\1/")
|
||||
CPP_MINOR := $(shell $(CPP) --version | grep clang | sed "s/.*version [0-9]*\.\([0-9]\)*.*/\1/")
|
||||
else
|
||||
CPP_MAJOR := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
||||
CPP_MINOR := $(shell $(CPP) -dumpversion >&1 | cut -b3)
|
||||
endif
|
||||
|
||||
MAKE = make
|
||||
AR = "ar rvs"
|
||||
|
||||
@ -77,28 +87,38 @@ endif
|
||||
|
||||
# the CPU target for the build, must be i486 for now
|
||||
ARCH = i486
|
||||
ARCH_CFLAGS = -mtune=i686 -march=pentium3 -mmmx -m32
|
||||
ARCH_CFLAGS = -mtune=i686 -march=pentium3 -mmmx -msse -msse2 -m32
|
||||
|
||||
ifeq "$(OS)" "Darwin"
|
||||
DEFINES = -D_OSX -DOSX
|
||||
DEFINES = -D_OSX -DOSX -D_DLL_EXT=.dylib
|
||||
ARCH_CFLAGS += -mmacosx-version-min=10.5
|
||||
SHLIBEXT = dylib
|
||||
SHLIBLDFLAGS = -dynamiclib -mmacosx-version-min=10.5
|
||||
SHLIBSUFFIX =
|
||||
else
|
||||
DEFINES = -D_LINUX -DLINUX
|
||||
DEFINES = -D_LINUX -DLINUX -D_DLL_EXT=.so
|
||||
SHLIBEXT = so
|
||||
SHLIBLDFLAGS = -shared -Wl,-Map,$@_map.txt -Wl
|
||||
SHLIBLDFLAGS = -shared -Wl,-Map,$@_map.txt
|
||||
SHLIBSUFFIX = _srv
|
||||
endif
|
||||
|
||||
DEFINES +=-DVPROF_LEVEL=1 -DSWDS -D_finite=finite -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp \
|
||||
-Dstrnicmp=strncasecmp -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp
|
||||
-Dstrnicmp=strncasecmp -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -DPOSIX -DGNUC -DCOMPILER_GCC -DNO_MALLOC_OVERRIDE
|
||||
UNDEF = -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE
|
||||
|
||||
BASE_CFLAGS = -fno-strict-aliasing -Wall -Wsign-compare -Werror -Wno-conversion -Wno-overloaded-virtual -Wno-non-virtual-dtor -Wno-invalid-offsetof \
|
||||
-Wno-delete-non-virtual-dtor
|
||||
-Wno-unknown-pragmas -Wno-unused
|
||||
SHLIBCFLAGS = -fPIC
|
||||
|
||||
# Clang >= 3 || GCC >= 4.7
|
||||
ifeq "$(shell expr $(IS_CLANG) \& $(CPP_MAJOR) \>= 3 \| $(CPP_MAJOR) \>= 4 \& $(CPP_MINOR) \>= 7)" "1"
|
||||
BASE_CFLAGS += -Wno-delete-non-virtual-dtor -Wno-narrowing
|
||||
endif
|
||||
|
||||
ifeq "$(shell expr $(IS_CLANG) \= 0 \& $(CPP_MAJOR) \>= 6)" "1"
|
||||
BASE_CFLAGS += -Wno-nonnull-compare
|
||||
endif
|
||||
|
||||
# Flags passed to the c compiler
|
||||
CFLAGS = $(DEFINES) $(ARCH_CFLAGS) -O3 $(BASE_CFLAGS)
|
||||
ifdef USER_CFLAGS
|
||||
|
@ -513,12 +513,14 @@ public:
|
||||
case DC_AGE_DISCARD:
|
||||
case DC_FLUSH_DISCARD:
|
||||
case DC_REMOVED:
|
||||
STORAGE_TYPE *p = (STORAGE_TYPE *)notification.clientId;
|
||||
p->DestroyResource();
|
||||
{
|
||||
STORAGE_TYPE *p = (STORAGE_TYPE *)notification.clientId;
|
||||
p->DestroyResource();
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return CDefaultDataCacheClient::HandleCacheNotification( notification );
|
||||
}
|
||||
|
||||
return CDefaultDataCacheClient::HandleCacheNotification( notification );
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "tier0/platform.h"
|
||||
#include "appframework/IAppSystem.h"
|
||||
|
||||
class CFunctor;
|
||||
|
||||
enum LoaderError_t
|
||||
{
|
||||
LOADERERROR_NONE = 0,
|
||||
@ -30,6 +32,8 @@ enum LoaderPriority_t
|
||||
|
||||
typedef void ( *QueuedLoaderCallback_t )( void *pContext, void *pContext2, const void *pData, int nSize, LoaderError_t loaderError );
|
||||
|
||||
typedef void ( *DynamicResourceCallback_t )( const char *pFilename, void *pContext, void *pContext2 );
|
||||
|
||||
struct LoaderJob_t
|
||||
{
|
||||
LoaderJob_t()
|
||||
@ -106,7 +110,7 @@ public:
|
||||
#define LOADER_DETAIL_LATECOMPLETIONS (1<<2)
|
||||
#define LOADER_DETAIL_PURGES (1<<3)
|
||||
|
||||
#define QUEUEDLOADER_INTERFACE_VERSION "QueuedLoaderVersion001"
|
||||
#define QUEUEDLOADER_INTERFACE_VERSION "QueuedLoaderVersion004"
|
||||
abstract_class IQueuedLoader : public IAppSystem
|
||||
{
|
||||
public:
|
||||
@ -122,6 +126,11 @@ public:
|
||||
// injects a resource into the map's reslist, rejected if not understood
|
||||
virtual void AddMapResource( const char *pFilename ) = 0;
|
||||
|
||||
// dynamically load a map resource
|
||||
virtual void DynamicLoadMapResource( const char *pFilename, DynamicResourceCallback_t pCallback, void *pContext, void *pContext2 ) = 0;
|
||||
virtual void QueueDynamicLoadFunctor( CFunctor* pFunctor ) = 0;
|
||||
virtual bool CompleteDynamicLoad() = 0;
|
||||
|
||||
// callback is asynchronous
|
||||
virtual bool ClaimAnonymousJob( const char *pFilename, QueuedLoaderCallback_t pCallback, void *pContext, void *pContext2 = NULL ) = 0;
|
||||
// provides data if loaded, caller owns data
|
||||
@ -134,6 +143,8 @@ public:
|
||||
// callers can expect that jobs are not immediately started when batching
|
||||
virtual bool IsBatching() const = 0;
|
||||
|
||||
virtual bool IsDynamic() const = 0;
|
||||
|
||||
// callers can conditionalize operational spew
|
||||
virtual int GetSpewDetail() const = 0;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@ -6,21 +6,24 @@
|
||||
|
||||
#undef PROTECTED_THINGS_ENABLE
|
||||
#undef PROTECT_FILEIO_FUNCTIONS
|
||||
#ifndef POSIX
|
||||
#undef fopen
|
||||
#endif
|
||||
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#elif defined( _LINUX ) || defined( __APPLE__ )
|
||||
#elif defined( POSIX )
|
||||
#include <unistd.h>
|
||||
#define _putenv putenv
|
||||
#define _chdir chdir
|
||||
#define _access access
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include "tier1/strtools.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "KeyValues.h"
|
||||
@ -83,7 +86,7 @@ public:
|
||||
if ( pValue )
|
||||
{
|
||||
m_bExisted = true;
|
||||
m_OriginalValue.SetSize( strlen( pValue ) + 1 );
|
||||
m_OriginalValue.SetSize( Q_strlen( pValue ) + 1 );
|
||||
memcpy( m_OriginalValue.Base(), pValue, m_OriginalValue.Count() );
|
||||
}
|
||||
else
|
||||
@ -144,16 +147,24 @@ public:
|
||||
Q_vsnprintf( valueString, sizeof( valueString ), pValue, marker );
|
||||
va_end( marker );
|
||||
|
||||
#ifdef WIN32
|
||||
char str[4096];
|
||||
Q_snprintf( str, sizeof( str ), "%s=%s", m_pVarName, valueString );
|
||||
_putenv( str );
|
||||
#else
|
||||
setenv( m_pVarName, valueString, 1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClearValue()
|
||||
{
|
||||
#ifdef WIN32
|
||||
char str[512];
|
||||
Q_snprintf( str, sizeof( str ), "%s=", m_pVarName );
|
||||
_putenv( str );
|
||||
#else
|
||||
setenv( m_pVarName, "", 1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
@ -213,6 +224,7 @@ CFSSearchPathsInit::CFSSearchPathsInit()
|
||||
m_pDirectoryName = NULL;
|
||||
m_pLanguage = NULL;
|
||||
m_ModPath[0] = 0;
|
||||
m_bMountHDContent = m_bLowViolence = false;
|
||||
}
|
||||
|
||||
|
||||
@ -248,47 +260,6 @@ const char *FileSystem_GetLastErrorString()
|
||||
}
|
||||
|
||||
|
||||
void AddLanguageGameDir( IFileSystem *pFileSystem, const char *pLocation, const char *pLanguage )
|
||||
{
|
||||
if ( IsX360() )
|
||||
{
|
||||
// 360 does not use this path for localization
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined( SWDS )
|
||||
char temp[MAX_PATH];
|
||||
Q_snprintf( temp, sizeof(temp), "%s_%s", pLocation, pLanguage );
|
||||
pFileSystem->AddSearchPath( temp, "GAME", PATH_ADD_TO_TAIL );
|
||||
|
||||
if ( !pFileSystem->IsSteam() )
|
||||
{
|
||||
// also look in "..\localization\<folder>" if not running Steam
|
||||
char baseDir[MAX_PATH];
|
||||
char *tempPtr = NULL, *gameDir = NULL;
|
||||
|
||||
Q_strncpy( baseDir, pLocation, sizeof(baseDir) );
|
||||
tempPtr = Q_strstr( baseDir, "\\game\\" );
|
||||
|
||||
if ( tempPtr )
|
||||
{
|
||||
gameDir = tempPtr + Q_strlen( "\\game\\" );
|
||||
*tempPtr = 0;
|
||||
Q_snprintf( temp, sizeof(temp), "%s%clocalization%c%s_%s", baseDir, CORRECT_PATH_SEPARATOR, CORRECT_PATH_SEPARATOR, gameDir, pLanguage );
|
||||
pFileSystem->AddSearchPath( temp, "GAME", PATH_ADD_TO_TAIL );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void AddGameBinDir( IFileSystem *pFileSystem, const char *pLocation )
|
||||
{
|
||||
char temp[MAX_PATH];
|
||||
Q_snprintf( temp, sizeof(temp), "%s%cbin", pLocation, CORRECT_PATH_SEPARATOR );
|
||||
pFileSystem->AddSearchPath( temp, "GAMEBIN", PATH_ADD_TO_TAIL );
|
||||
}
|
||||
|
||||
KeyValues* ReadKeyValuesFile( const char *pFilename )
|
||||
{
|
||||
// Read in the gameinfo.txt file and null-terminate it.
|
||||
@ -376,7 +347,8 @@ bool FileSystem_GetExecutableDir( char *exedir, int exeDirLen )
|
||||
Q_StrRight( exedir, 4, ext, sizeof( ext ) );
|
||||
if ( ext[0] != CORRECT_PATH_SEPARATOR || Q_stricmp( ext+1, "bin" ) != 0 )
|
||||
{
|
||||
Q_strncat( exedir, "\\bin", exeDirLen, COPY_ALL_CHARACTERS );
|
||||
Q_strncat( exedir, CORRECT_PATH_SEPARATOR_S, exeDirLen, COPY_ALL_CHARACTERS );
|
||||
Q_strncat( exedir, "bin", exeDirLen, COPY_ALL_CHARACTERS );
|
||||
Q_FixSlashes( exedir );
|
||||
}
|
||||
|
||||
@ -489,124 +461,73 @@ FSReturnCode_t LoadGameInfoFile(
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
// checks the registry for the low violence setting
|
||||
// Check "HKEY_CURRENT_USER\Software\Valve\Source\Settings" and "User Token 2" or "User Token 3"
|
||||
bool IsLowViolenceBuild( void )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
HKEY hKey;
|
||||
char szValue[64];
|
||||
unsigned long len = sizeof(szValue) - 1;
|
||||
bool retVal = false;
|
||||
|
||||
if ( IsPC() && RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Valve\\Source\\Settings", NULL, KEY_READ, &hKey) == ERROR_SUCCESS )
|
||||
{
|
||||
// User Token 2
|
||||
if ( RegQueryValueEx( hKey, "User Token 2", NULL, NULL, (unsigned char*)szValue, &len ) == ERROR_SUCCESS )
|
||||
{
|
||||
if ( Q_strlen( szValue ) > 0 )
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !retVal )
|
||||
{
|
||||
// reset "len" for the next check
|
||||
len = sizeof(szValue) - 1;
|
||||
|
||||
// User Token 3
|
||||
if ( RegQueryValueEx( hKey, "User Token 3", NULL, NULL, (unsigned char*)szValue, &len ) == ERROR_SUCCESS )
|
||||
{
|
||||
if ( Q_strlen( szValue ) > 0 )
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
#elif _LINUX
|
||||
return false;
|
||||
#else
|
||||
#error "Fix me"
|
||||
#endif
|
||||
}
|
||||
|
||||
static void FileSystem_AddLoadedSearchPath(
|
||||
CFSSearchPathsInit &initInfo,
|
||||
const char *pPathID,
|
||||
bool *bFirstGamePath,
|
||||
const char *pBaseDir,
|
||||
const char *pLocation,
|
||||
const char *fullLocationPath,
|
||||
bool bLowViolence )
|
||||
{
|
||||
char fullLocationPath[MAX_PATH];
|
||||
Q_MakeAbsolutePath( fullLocationPath, sizeof( fullLocationPath ), pLocation, pBaseDir );
|
||||
|
||||
// Now resolve any ./'s.
|
||||
V_FixSlashes( fullLocationPath );
|
||||
if ( !V_RemoveDotSlashes( fullLocationPath ) )
|
||||
Error( "FileSystem_AddLoadedSearchPath - Can't resolve pathname for '%s'", fullLocationPath );
|
||||
|
||||
// Add language, mod, and gamebin search paths automatically.
|
||||
if ( Q_stricmp( pPathID, "game" ) == 0 )
|
||||
// Check for mounting LV game content in LV builds only
|
||||
if ( V_stricmp( pPathID, "game_lv" ) == 0 )
|
||||
{
|
||||
// add the low violence path
|
||||
if ( bLowViolence )
|
||||
{
|
||||
char szPath[MAX_PATH];
|
||||
Q_snprintf( szPath, sizeof(szPath), "%s_lv", fullLocationPath );
|
||||
initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL );
|
||||
}
|
||||
|
||||
// add the language path
|
||||
if ( initInfo.m_pLanguage )
|
||||
{
|
||||
AddLanguageGameDir( initInfo.m_pFileSystem, fullLocationPath, initInfo.m_pLanguage );
|
||||
}
|
||||
|
||||
// Not in LV build, don't mount
|
||||
if ( !initInfo.m_bLowViolence )
|
||||
return;
|
||||
|
||||
// Mount, as a game path
|
||||
pPathID = "game";
|
||||
}
|
||||
|
||||
// Check for mounting HD game content if enabled
|
||||
if ( V_stricmp( pPathID, "game_hd" ) == 0 )
|
||||
{
|
||||
|
||||
// Not in LV build, don't mount
|
||||
if ( !initInfo.m_bMountHDContent )
|
||||
return;
|
||||
|
||||
// Mount, as a game path
|
||||
pPathID = "game";
|
||||
}
|
||||
|
||||
|
||||
// Special processing for ordinary game folders
|
||||
if ( V_stristr( fullLocationPath, ".vpk" ) == NULL && Q_stricmp( pPathID, "game" ) == 0 )
|
||||
{
|
||||
if ( CommandLine()->FindParm( "-tempcontent" ) != 0 )
|
||||
{
|
||||
char szPath[MAX_PATH];
|
||||
Q_snprintf( szPath, sizeof(szPath), "%s_tempcontent", fullLocationPath );
|
||||
initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL );
|
||||
}
|
||||
}
|
||||
|
||||
// mark the first "game" dir as the "MOD" dir
|
||||
if ( *bFirstGamePath )
|
||||
{
|
||||
*bFirstGamePath = false;
|
||||
initInfo.m_pFileSystem->AddSearchPath( fullLocationPath, "MOD", PATH_ADD_TO_TAIL );
|
||||
Q_strncpy( initInfo.m_ModPath, fullLocationPath, sizeof( initInfo.m_ModPath ) );
|
||||
}
|
||||
|
||||
// add the game bin
|
||||
AddGameBinDir( initInfo.m_pFileSystem, fullLocationPath );
|
||||
if ( initInfo.m_pLanguage &&
|
||||
Q_stricmp( initInfo.m_pLanguage, "english" ) &&
|
||||
V_strstr( fullLocationPath, "_english" ) != NULL )
|
||||
{
|
||||
char szPath[MAX_PATH];
|
||||
char szLangString[MAX_PATH];
|
||||
|
||||
// Need to add a language version of this path first
|
||||
|
||||
Q_snprintf( szLangString, sizeof(szLangString), "_%s", initInfo.m_pLanguage);
|
||||
V_StrSubst( fullLocationPath, "_english", szLangString, szPath, sizeof( szPath ), true );
|
||||
initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL );
|
||||
}
|
||||
|
||||
initInfo.m_pFileSystem->AddSearchPath( fullLocationPath, pPathID, PATH_ADD_TO_TAIL );
|
||||
}
|
||||
|
||||
|
||||
bool FileSystem_IsHldsUpdateToolDedicatedServer()
|
||||
static int SortStricmp( char * const * sz1, char * const * sz2 )
|
||||
{
|
||||
// To determine this, we see if the directory our executable was launched from is "orangebox".
|
||||
// We only are under "orangebox" if we're run from hldsupdatetool.
|
||||
char baseDir[MAX_PATH];
|
||||
if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) )
|
||||
return false;
|
||||
|
||||
V_FixSlashes( baseDir );
|
||||
V_StripTrailingSlash( baseDir );
|
||||
const char *pLastDir = V_UnqualifiedFileName( baseDir );
|
||||
return ( pLastDir && V_stricmp( pLastDir, "orangebox" ) == 0 );
|
||||
return V_stricmp( *sz1, *sz2 );
|
||||
}
|
||||
|
||||
|
||||
FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo )
|
||||
{
|
||||
if ( !initInfo.m_pFileSystem || !initInfo.m_pDirectoryName )
|
||||
@ -622,23 +543,41 @@ FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo )
|
||||
if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) )
|
||||
return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." );
|
||||
|
||||
initInfo.m_ModPath[0] = 0;
|
||||
// The MOD directory is always the one that contains gameinfo.txt
|
||||
Q_strncpy( initInfo.m_ModPath, initInfo.m_pDirectoryName, sizeof( initInfo.m_ModPath ) );
|
||||
|
||||
#define GAMEINFOPATH_TOKEN "|gameinfo_path|"
|
||||
#define BASESOURCEPATHS_TOKEN "|all_source_engine_paths|"
|
||||
|
||||
bool bLowViolence = IsLowViolenceBuild();
|
||||
bool bFirstGamePath = true;
|
||||
|
||||
const char *pszExtraSearchPath = CommandLine()->ParmValue( "-insert_search_path" );
|
||||
if ( pszExtraSearchPath )
|
||||
{
|
||||
CUtlStringList vecPaths;
|
||||
V_SplitString( pszExtraSearchPath, ",", vecPaths );
|
||||
FOR_EACH_VEC( vecPaths, idxExtraPath )
|
||||
{
|
||||
char szAbsSearchPath[MAX_PATH];
|
||||
Q_StripPrecedingAndTrailingWhitespace( vecPaths[ idxExtraPath ] );
|
||||
V_MakeAbsolutePath( szAbsSearchPath, sizeof( szAbsSearchPath ), vecPaths[ idxExtraPath ], baseDir );
|
||||
V_FixSlashes( szAbsSearchPath );
|
||||
if ( !V_RemoveDotSlashes( szAbsSearchPath ) )
|
||||
Error( "Bad -insert_search_path - Can't resolve pathname for '%s'", szAbsSearchPath );
|
||||
V_StripTrailingSlash( szAbsSearchPath );
|
||||
FileSystem_AddLoadedSearchPath( initInfo, "GAME", szAbsSearchPath, false );
|
||||
FileSystem_AddLoadedSearchPath( initInfo, "MOD", szAbsSearchPath, false );
|
||||
}
|
||||
}
|
||||
|
||||
bool bLowViolence = initInfo.m_bLowViolence;
|
||||
for ( KeyValues *pCur=pSearchPaths->GetFirstValue(); pCur; pCur=pCur->GetNextValue() )
|
||||
{
|
||||
const char *pPathID = pCur->GetName();
|
||||
const char *pLocation = pCur->GetString();
|
||||
|
||||
const char *pszBaseDir = baseDir;
|
||||
|
||||
if ( Q_stristr( pLocation, GAMEINFOPATH_TOKEN ) == pLocation )
|
||||
{
|
||||
pLocation += strlen( GAMEINFOPATH_TOKEN );
|
||||
FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, initInfo.m_pDirectoryName, pLocation, bLowViolence );
|
||||
pszBaseDir = initInfo.m_pDirectoryName;
|
||||
}
|
||||
else if ( Q_stristr( pLocation, BASESOURCEPATHS_TOKEN ) == pLocation )
|
||||
{
|
||||
@ -650,26 +589,117 @@ FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo )
|
||||
// We need a special identifier in the gameinfo.txt here because the base hl2 folder exists in different places.
|
||||
// In the case of a game or a Steam-launched dedicated server, all the necessary prior engine content is mapped in with the Steam depots,
|
||||
// so we can just use the path as-is.
|
||||
|
||||
// In the case of an hldsupdatetool dedicated server, the base hl2 folder is "..\..\hl2" (since we're up in the 'orangebox' folder).
|
||||
|
||||
pLocation += strlen( BASESOURCEPATHS_TOKEN );
|
||||
}
|
||||
|
||||
// Add the Orange-box path (which also will include whatever the depots mapped in as well if we're
|
||||
// running a Steam-launched app).
|
||||
FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, baseDir, pLocation, bLowViolence );
|
||||
CUtlStringList vecFullLocationPaths;
|
||||
char szAbsSearchPath[MAX_PATH];
|
||||
V_MakeAbsolutePath( szAbsSearchPath, sizeof( szAbsSearchPath ), pLocation, pszBaseDir );
|
||||
|
||||
if ( FileSystem_IsHldsUpdateToolDedicatedServer() )
|
||||
{
|
||||
// If we're using the hldsupdatetool dedicated server, then go up a directory to get the ep1-era files too.
|
||||
char ep1EraPath[MAX_PATH];
|
||||
V_snprintf( ep1EraPath, sizeof( ep1EraPath ), "..%c%s", CORRECT_PATH_SEPARATOR, pLocation );
|
||||
FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, baseDir, ep1EraPath, bLowViolence );
|
||||
}
|
||||
// Now resolve any ./'s.
|
||||
V_FixSlashes( szAbsSearchPath );
|
||||
if ( !V_RemoveDotSlashes( szAbsSearchPath ) )
|
||||
Error( "FileSystem_AddLoadedSearchPath - Can't resolve pathname for '%s'", szAbsSearchPath );
|
||||
V_StripTrailingSlash( szAbsSearchPath );
|
||||
|
||||
// Don't bother doing any wildcard expansion unless it has wildcards. This avoids the weird
|
||||
// thing with xxx_dir.vpk files being referred to simply as xxx.vpk.
|
||||
if ( V_stristr( pLocation, "?") == NULL && V_stristr( pLocation, "*") == NULL )
|
||||
{
|
||||
vecFullLocationPaths.CopyAndAddToTail( szAbsSearchPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, baseDir, pLocation, bLowViolence );
|
||||
FileFindHandle_t findHandle = 0;
|
||||
const char *pszFoundShortName = initInfo.m_pFileSystem->FindFirst( szAbsSearchPath, &findHandle );
|
||||
if ( pszFoundShortName )
|
||||
{
|
||||
do
|
||||
{
|
||||
|
||||
// We only know how to mount VPK's and directories
|
||||
if ( pszFoundShortName[0] != '.' && ( initInfo.m_pFileSystem->FindIsDirectory( findHandle ) || V_stristr( pszFoundShortName, ".vpk" ) ) )
|
||||
{
|
||||
char szAbsName[MAX_PATH];
|
||||
V_ExtractFilePath( szAbsSearchPath, szAbsName, sizeof( szAbsName ) );
|
||||
V_AppendSlash( szAbsName, sizeof(szAbsName) );
|
||||
V_strcat_safe( szAbsName, pszFoundShortName );
|
||||
|
||||
vecFullLocationPaths.CopyAndAddToTail( szAbsName );
|
||||
|
||||
// Check for a common mistake
|
||||
if (
|
||||
!V_stricmp( pszFoundShortName, "materials" )
|
||||
|| !V_stricmp( pszFoundShortName, "maps" )
|
||||
|| !V_stricmp( pszFoundShortName, "resource" )
|
||||
|| !V_stricmp( pszFoundShortName, "scripts" )
|
||||
|| !V_stricmp( pszFoundShortName, "sound" )
|
||||
|| !V_stricmp( pszFoundShortName, "models" ) )
|
||||
{
|
||||
|
||||
char szReadme[MAX_PATH];
|
||||
V_ExtractFilePath( szAbsSearchPath, szReadme, sizeof( szReadme ) );
|
||||
V_AppendSlash( szReadme, sizeof(szReadme) );
|
||||
V_strcat_safe( szReadme, "readme.txt" );
|
||||
|
||||
Error(
|
||||
"Tried to add %s as a search path.\n"
|
||||
"\nThis is probably not what you intended.\n"
|
||||
"\nCheck %s for more info\n",
|
||||
szAbsName, szReadme );
|
||||
}
|
||||
|
||||
}
|
||||
pszFoundShortName = initInfo.m_pFileSystem->FindNext( findHandle );
|
||||
} while ( pszFoundShortName );
|
||||
initInfo.m_pFileSystem->FindClose( findHandle );
|
||||
}
|
||||
|
||||
// Sort alphabetically. Also note that this will put
|
||||
// all the xxx_000.vpk packs just before the corresponding
|
||||
// xxx_dir.vpk
|
||||
vecFullLocationPaths.Sort( SortStricmp );
|
||||
|
||||
// Now for any _dir.vpk files, remove the _nnn.vpk ones.
|
||||
int idx = vecFullLocationPaths.Count()-1;
|
||||
while ( idx > 0 )
|
||||
{
|
||||
char szTemp[ MAX_PATH ];
|
||||
V_strcpy_safe( szTemp, vecFullLocationPaths[ idx ] );
|
||||
--idx;
|
||||
|
||||
char *szDirVpk = V_stristr( szTemp, "_dir.vpk" );
|
||||
if ( szDirVpk != NULL )
|
||||
{
|
||||
*szDirVpk = '\0';
|
||||
while ( idx >= 0 )
|
||||
{
|
||||
char *pszPath = vecFullLocationPaths[ idx ];
|
||||
if ( V_stristr( pszPath, szTemp ) != pszPath )
|
||||
break;
|
||||
delete pszPath;
|
||||
vecFullLocationPaths.Remove( idx );
|
||||
--idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse Path ID list
|
||||
CUtlStringList vecPathIDs;
|
||||
V_SplitString( pCur->GetName(), "+", vecPathIDs );
|
||||
FOR_EACH_VEC( vecPathIDs, idxPathID )
|
||||
{
|
||||
Q_StripPrecedingAndTrailingWhitespace( vecPathIDs[ idxPathID ] );
|
||||
}
|
||||
|
||||
// Mount them.
|
||||
FOR_EACH_VEC( vecFullLocationPaths, idxLocation )
|
||||
{
|
||||
FOR_EACH_VEC( vecPathIDs, idxPathID )
|
||||
{
|
||||
FileSystem_AddLoadedSearchPath( initInfo, vecPathIDs[ idxPathID ], vecFullLocationPaths[ idxLocation ], bLowViolence );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -679,15 +709,13 @@ FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo )
|
||||
// when people forget to specify a search path.
|
||||
initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "executable_path", true );
|
||||
initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "gamebin", true );
|
||||
initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "download", true );
|
||||
initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "mod", true );
|
||||
if ( initInfo.m_ModPath[0] != 0 )
|
||||
{
|
||||
// Add the write path last.
|
||||
initInfo.m_pFileSystem->AddSearchPath( initInfo.m_ModPath, "DEFAULT_WRITE_PATH", PATH_ADD_TO_TAIL );
|
||||
}
|
||||
initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "game_write", true );
|
||||
initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "mod_write", true );
|
||||
|
||||
#ifdef _DEBUG
|
||||
initInfo.m_pFileSystem->PrintSearchPaths();
|
||||
// initInfo.m_pFileSystem->PrintSearchPaths();
|
||||
#endif
|
||||
|
||||
return FS_OK;
|
||||
@ -954,60 +982,6 @@ bool DoesPathExistAlready( const char *pPathEnvVar, const char *pTestPath )
|
||||
}
|
||||
}
|
||||
|
||||
FSReturnCode_t SetSteamInstallPath( char *steamInstallPath, int steamInstallPathLen, CSteamEnvVars &steamEnvVars, bool bErrorsAsWarnings )
|
||||
{
|
||||
if ( IsConsole() )
|
||||
{
|
||||
// consoles don't use steam
|
||||
return FS_MISSING_STEAM_DLL;
|
||||
}
|
||||
|
||||
// Start at our bin directory and move up until we find a directory with steam.dll in it.
|
||||
char executablePath[MAX_PATH];
|
||||
if ( !FileSystem_GetExecutableDir( executablePath, sizeof( executablePath ) ) )
|
||||
{
|
||||
if ( bErrorsAsWarnings )
|
||||
{
|
||||
Warning( "SetSteamInstallPath: FileSystem_GetExecutableDir failed.\n" );
|
||||
return FS_INVALID_PARAMETERS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." );
|
||||
}
|
||||
}
|
||||
|
||||
Q_strncpy( steamInstallPath, executablePath, steamInstallPathLen );
|
||||
while ( 1 )
|
||||
{
|
||||
// Ignore steamapp.cfg here in case they're debugging. We still need to know the real steam path so we can find their username.
|
||||
// find
|
||||
if ( DoesFileExistIn( steamInstallPath, "steam.dll" ) && !DoesFileExistIn( steamInstallPath, "steamapp.cfg" ) )
|
||||
break;
|
||||
|
||||
if ( !Q_StripLastDir( steamInstallPath, steamInstallPathLen ) )
|
||||
{
|
||||
if ( bErrorsAsWarnings )
|
||||
{
|
||||
Warning( "Can't find steam.dll relative to executable path: %s.\n", executablePath );
|
||||
return FS_MISSING_STEAM_DLL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SetupFileSystemError( false, FS_MISSING_STEAM_DLL, "Can't find steam.dll relative to executable path: %s.", executablePath );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also, add the install path to their PATH environment variable, so filesystem_steam.dll can get to steam.dll.
|
||||
char szPath[ 8192 ];
|
||||
steamEnvVars.m_Path.GetValue( szPath, sizeof( szPath ) );
|
||||
if ( !DoesPathExistAlready( szPath, steamInstallPath ) )
|
||||
{
|
||||
steamEnvVars.m_Path.SetValue( "%s;%s", szPath, steamInstallPath );
|
||||
}
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
FSReturnCode_t GetSteamCfgPath( char *steamCfgPath, int steamCfgPathLen )
|
||||
{
|
||||
@ -1087,53 +1061,6 @@ void SetSteamUserPassphrase( KeyValues *pSteamInfo, CSteamEnvVars &steamEnvVars
|
||||
}
|
||||
}
|
||||
|
||||
void SetSteamAppId( KeyValues *pFileSystemInfo, const char *pGameInfoDirectory, CSteamEnvVars &steamEnvVars )
|
||||
{
|
||||
// SteamAppId is in gameinfo.txt->FileSystem->FileSystemInfo_Steam->SteamAppId.
|
||||
int iAppId = pFileSystemInfo->GetInt( "SteamAppId", -1 );
|
||||
if ( iAppId == -1 )
|
||||
Error( "Missing SteamAppId in %s\\%s.", pGameInfoDirectory, GAMEINFO_FILENAME );
|
||||
|
||||
steamEnvVars.m_SteamAppId.SetValue( "%d", iAppId );
|
||||
}
|
||||
|
||||
FSReturnCode_t SetupSteamStartupEnvironment( KeyValues *pFileSystemInfo, const char *pGameInfoDirectory, CSteamEnvVars &steamEnvVars )
|
||||
{
|
||||
// Ok, we're going to run Steam. See if they have SteamInfo.txt. If not, we'll try to deduce what we can.
|
||||
char steamInfoFile[MAX_PATH];
|
||||
Q_strncpy( steamInfoFile, pGameInfoDirectory, sizeof( steamInfoFile ) );
|
||||
Q_AppendSlash( steamInfoFile, sizeof( steamInfoFile ) );
|
||||
Q_strncat( steamInfoFile, "steaminfo.txt", sizeof( steamInfoFile ), COPY_ALL_CHARACTERS );
|
||||
KeyValues *pSteamInfo = ReadKeyValuesFile( steamInfoFile );
|
||||
|
||||
char steamInstallPath[MAX_PATH];
|
||||
FSReturnCode_t ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, false );
|
||||
if ( ret != FS_OK )
|
||||
return ret;
|
||||
|
||||
SetSteamAppUser( pSteamInfo, steamInstallPath, steamEnvVars );
|
||||
SetSteamUserPassphrase( pSteamInfo, steamEnvVars );
|
||||
SetSteamAppId( pFileSystemInfo, pGameInfoDirectory, steamEnvVars );
|
||||
|
||||
if ( pSteamInfo )
|
||||
pSteamInfo->deleteThis();
|
||||
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
FSReturnCode_t GetSteamExtraAppId( const char *pDirectoryName, int *nExtraAppId )
|
||||
{
|
||||
// Now, load gameinfo.txt (to make sure it's there)
|
||||
KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths;
|
||||
FSReturnCode_t ret = LoadGameInfoFile( pDirectoryName, pMainFile, pFileSystemInfo, pSearchPaths );
|
||||
if ( ret != FS_OK )
|
||||
return ret;
|
||||
|
||||
*nExtraAppId = pFileSystemInfo->GetInt( "ToolsAppId", -1 );
|
||||
pMainFile->deleteThis();
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
FSReturnCode_t FileSystem_SetBasePaths( IFileSystem *pFileSystem )
|
||||
{
|
||||
pFileSystem->RemoveSearchPaths( "EXECUTABLE_PATH" );
|
||||
@ -1143,6 +1070,12 @@ FSReturnCode_t FileSystem_SetBasePaths( IFileSystem *pFileSystem )
|
||||
return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." );
|
||||
|
||||
pFileSystem->AddSearchPath( executablePath, "EXECUTABLE_PATH" );
|
||||
|
||||
if ( !FileSystem_GetBaseDir( executablePath, sizeof( executablePath ) ) )
|
||||
return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." );
|
||||
|
||||
pFileSystem->AddSearchPath( executablePath, "BASE_PATH" );
|
||||
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
@ -1158,41 +1091,31 @@ FSReturnCode_t FileSystem_GetFileSystemDLLName( char *pFileSystemDLL, int nMaxLe
|
||||
char executablePath[MAX_PATH];
|
||||
if ( !FileSystem_GetExecutableDir( executablePath, sizeof( executablePath ) ) )
|
||||
return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." );
|
||||
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
// If filesystem_stdio.dll is missing or -steam is specified, then load filesystem_steam.dll.
|
||||
// There are two command line parameters for Steam:
|
||||
// 1) -steam (runs Steam in remote filesystem mode; requires Steam backend)
|
||||
// 2) -steamlocal (runs Steam in local filesystem mode (all content off HDD)
|
||||
Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_stdio.dll", executablePath, CORRECT_PATH_SEPARATOR );
|
||||
if ( CommandLine()->FindParm( "-steam" ) || CommandLine()->FindParm( "-steamlocal" ) || _access( pFileSystemDLL, 0 ) != 0 )
|
||||
{
|
||||
Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_steam.dll", executablePath, CORRECT_PATH_SEPARATOR );
|
||||
bSteam = true;
|
||||
}
|
||||
#elif defined( _X360 )
|
||||
Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_stdio.dll", executablePath, CORRECT_PATH_SEPARATOR );
|
||||
#elif defined( _LINUX )
|
||||
Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_i486.so", executablePath, CORRECT_PATH_SEPARATOR );
|
||||
#else
|
||||
#error "define a filesystem dll name"
|
||||
#endif
|
||||
|
||||
// Assume we'll use local files
|
||||
Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_stdio" DLL_EXT_STRING, executablePath, CORRECT_PATH_SEPARATOR );
|
||||
|
||||
#if !defined( _X360 )
|
||||
|
||||
// Use filsystem_steam if it exists?
|
||||
#if defined( OSX ) || defined( LINUX )
|
||||
struct stat statBuf;
|
||||
#endif
|
||||
if (
|
||||
#if defined( OSX ) || defined( LINUX )
|
||||
stat( pFileSystemDLL, &statBuf ) != 0
|
||||
#else
|
||||
_access( pFileSystemDLL, 0 ) != 0
|
||||
#endif
|
||||
) {
|
||||
Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_steam" DLL_EXT_STRING, executablePath, CORRECT_PATH_SEPARATOR );
|
||||
bSteam = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the steam.dll install path in our PATH env var (so you can then just
|
||||
// LoadLibrary() on filesystem_steam.dll without having to copy steam.dll anywhere special )
|
||||
//-----------------------------------------------------------------------------
|
||||
FSReturnCode_t FileSystem_SetupSteamInstallPath()
|
||||
{
|
||||
CSteamEnvVars steamEnvVars;
|
||||
char steamInstallPath[MAX_PATH];
|
||||
FSReturnCode_t ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, true );
|
||||
steamEnvVars.m_Path.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward.
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the steam environment + gets back the gameinfo.txt path
|
||||
@ -1205,45 +1128,13 @@ FSReturnCode_t FileSystem_SetupSteamEnvironment( CFSSteamSetupInfo &fsInfo )
|
||||
return ret;
|
||||
|
||||
// This is so that processes spawned by this application will have the same VPROJECT
|
||||
#ifdef WIN32
|
||||
char pEnvBuf[MAX_PATH+32];
|
||||
Q_snprintf( pEnvBuf, sizeof(pEnvBuf), "%s=%s", GAMEDIR_TOKEN, fsInfo.m_GameInfoPath );
|
||||
_putenv( pEnvBuf );
|
||||
|
||||
CSteamEnvVars steamEnvVars;
|
||||
if ( fsInfo.m_bSteam )
|
||||
{
|
||||
if ( fsInfo.m_bToolsMode )
|
||||
{
|
||||
// Now, load gameinfo.txt (to make sure it's there)
|
||||
KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths;
|
||||
ret = LoadGameInfoFile( fsInfo.m_GameInfoPath, pMainFile, pFileSystemInfo, pSearchPaths );
|
||||
if ( ret != FS_OK )
|
||||
return ret;
|
||||
|
||||
// If filesystem_stdio.dll is missing or -steam is specified, then load filesystem_steam.dll.
|
||||
// There are two command line parameters for Steam:
|
||||
// 1) -steam (runs Steam in remote filesystem mode; requires Steam backend)
|
||||
// 2) -steamlocal (runs Steam in local filesystem mode (all content off HDD)
|
||||
|
||||
// Setup all the environment variables related to Steam so filesystem_steam.dll knows how to initialize Steam.
|
||||
ret = SetupSteamStartupEnvironment( pFileSystemInfo, fsInfo.m_GameInfoPath, steamEnvVars );
|
||||
if ( ret != FS_OK )
|
||||
return ret;
|
||||
|
||||
steamEnvVars.m_SteamAppId.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward.
|
||||
|
||||
// We're done with main file
|
||||
pMainFile->deleteThis();
|
||||
}
|
||||
else if ( fsInfo.m_bSetSteamDLLPath )
|
||||
{
|
||||
// This is used by the engine to automatically set the path to their steam.dll when running the engine,
|
||||
// so they can debug it without having to copy steam.dll up into their hl2.exe folder.
|
||||
char steamInstallPath[MAX_PATH];
|
||||
ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, true );
|
||||
steamEnvVars.m_Path.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward.
|
||||
}
|
||||
}
|
||||
#else
|
||||
setenv( GAMEDIR_TOKEN, fsInfo.m_GameInfoPath, 1 );
|
||||
#endif
|
||||
|
||||
return FS_OK;
|
||||
}
|
||||
@ -1287,33 +1178,33 @@ FSReturnCode_t FileSystem_MountContent( CFSMountContentInfo &mountContentInfo )
|
||||
// This part is Steam-only.
|
||||
if ( mountContentInfo.m_pFileSystem->IsSteam() )
|
||||
{
|
||||
// Find out the "extra app id". This is for tools, which want to mount a base app's filesystem
|
||||
// like HL2, then mount the SDK content (tools materials and models, etc) in addition.
|
||||
int nExtraAppId = -1;
|
||||
if ( mountContentInfo.m_bToolsMode )
|
||||
{
|
||||
FSReturnCode_t ret = GetSteamExtraAppId( mountContentInfo.m_pDirectoryName, &nExtraAppId );
|
||||
if ( ret != FS_OK )
|
||||
return ret;
|
||||
}
|
||||
return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "Should not be using filesystem_steam anymore!" );
|
||||
|
||||
// Set our working directory temporarily so Steam can remember it.
|
||||
// This is what Steam strips off absolute filenames like c:\program files\valve\steam\steamapps\username\sourcesdk
|
||||
// to get to the relative part of the path.
|
||||
char baseDir[MAX_PATH], oldWorkingDir[MAX_PATH];
|
||||
if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) )
|
||||
return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." );
|
||||
|
||||
Q_getwd( oldWorkingDir, sizeof( oldWorkingDir ) );
|
||||
_chdir( baseDir );
|
||||
|
||||
// Filesystem_tools needs to add dependencies in here beforehand.
|
||||
FilesystemMountRetval_t retVal = mountContentInfo.m_pFileSystem->MountSteamContent( nExtraAppId );
|
||||
|
||||
_chdir( oldWorkingDir );
|
||||
|
||||
if ( retVal != FILESYSTEM_MOUNT_OK )
|
||||
return SetupFileSystemError( true, FS_UNABLE_TO_INIT, "Unable to mount Steam content in the file system" );
|
||||
// // Find out the "extra app id". This is for tools, which want to mount a base app's filesystem
|
||||
// // like HL2, then mount the SDK content (tools materials and models, etc) in addition.
|
||||
// int nExtraAppId = -1;
|
||||
// if ( mountContentInfo.m_bToolsMode )
|
||||
// {
|
||||
// // !FIXME! Here we need to mount the tools content (VPK's) in some way...?
|
||||
// }
|
||||
//
|
||||
// // Set our working directory temporarily so Steam can remember it.
|
||||
// // This is what Steam strips off absolute filenames like c:\program files\valve\steam\steamapps\username\sourcesdk
|
||||
// // to get to the relative part of the path.
|
||||
// char baseDir[MAX_PATH], oldWorkingDir[MAX_PATH];
|
||||
// if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) )
|
||||
// return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." );
|
||||
//
|
||||
// Q_getwd( oldWorkingDir, sizeof( oldWorkingDir ) );
|
||||
// _chdir( baseDir );
|
||||
//
|
||||
// // Filesystem_tools needs to add dependencies in here beforehand.
|
||||
// FilesystemMountRetval_t retVal = mountContentInfo.m_pFileSystem->MountSteamContent( nExtraAppId );
|
||||
//
|
||||
// _chdir( oldWorkingDir );
|
||||
//
|
||||
// if ( retVal != FILESYSTEM_MOUNT_OK )
|
||||
// return SetupFileSystemError( true, FS_UNABLE_TO_INIT, "Unable to mount Steam content in the file system" );
|
||||
}
|
||||
|
||||
return FileSystem_SetBasePaths( mountContentInfo.m_pFileSystem );
|
||||
@ -1342,17 +1233,9 @@ void FileSystem_ClearSteamEnvVars()
|
||||
void FileSystem_AddSearchPath_Platform( IFileSystem *pFileSystem, const char *szGameInfoPath )
|
||||
{
|
||||
char platform[MAX_PATH];
|
||||
if ( pFileSystem->IsSteam() )
|
||||
{
|
||||
// Steam doesn't support relative paths
|
||||
Q_strncpy( platform, "platform", MAX_PATH );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( platform, szGameInfoPath, MAX_PATH );
|
||||
Q_StripTrailingSlash( platform );
|
||||
Q_strncat( platform, "/../platform", MAX_PATH, MAX_PATH );
|
||||
}
|
||||
Q_strncpy( platform, szGameInfoPath, MAX_PATH );
|
||||
Q_StripTrailingSlash( platform );
|
||||
Q_strncat( platform, "/../platform", MAX_PATH, MAX_PATH );
|
||||
|
||||
pFileSystem->AddSearchPath( platform, "PLATFORM" );
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@ -148,14 +148,17 @@ public:
|
||||
// This specifies the directory where gameinfo.txt is. This must be set.
|
||||
const char *m_pDirectoryName;
|
||||
|
||||
// If this is set, then it will add a search path with _<language> appended to the pathname
|
||||
// for each search path with a path ID of "game".
|
||||
// If this is set, then any search paths with a _english will be replaced with _m_pLanguage and added before the
|
||||
// _english path
|
||||
// (default: null)
|
||||
const char *m_pLanguage;
|
||||
|
||||
// This is the filesystem FileSystem_LoadSearchPaths is talking to.
|
||||
IFileSystem *m_pFileSystem;
|
||||
|
||||
bool m_bMountHDContent;
|
||||
bool m_bLowViolence;
|
||||
|
||||
// Outputs.
|
||||
public:
|
||||
// This is the location of the first search path called "game", which also becomes your "mod" search path.
|
||||
@ -206,11 +209,6 @@ void FileSystem_ClearSteamEnvVars();
|
||||
// Find the steam.cfg above you for optional stuff
|
||||
FSReturnCode_t GetSteamCfgPath( char *steamCfgPath, int steamCfgPathLen );
|
||||
|
||||
// Setup the Steam.dll path without needing all the extra gameinfo stuff first
|
||||
// used by the CSteamApplication::Create() code to LoadModule() on the filesystem
|
||||
// before the underlying apps know specific details about the environment to load
|
||||
FSReturnCode_t FileSystem_SetupSteamInstallPath();
|
||||
|
||||
// Returns the last error.
|
||||
const char *FileSystem_GetLastErrorString();
|
||||
|
||||
|
@ -19,6 +19,12 @@
|
||||
#endif
|
||||
|
||||
|
||||
// This is a trick to get the DLL extension off the -D option on the command line.
|
||||
#define DLLExtTokenPaste(x) #x
|
||||
#define DLLExtTokenPaste2(x) DLLExtTokenPaste(x)
|
||||
#define DLL_EXT_STRING DLLExtTokenPaste2( _DLL_EXT )
|
||||
|
||||
|
||||
#include "protected_things.h"
|
||||
|
||||
// There's a different version of this file in the xbox codeline
|
||||
|
@ -337,6 +337,9 @@ typedef void * HINSTANCE;
|
||||
#define ALIGN128 DECL_ALIGN(128)
|
||||
|
||||
|
||||
// Pull in the /analyze code annotations.
|
||||
#include "annotations.h"
|
||||
|
||||
// Linux had a few areas where it didn't construct objects in the same order that Windows does.
|
||||
// So when CVProfile::CVProfile() would access g_pMemAlloc, it would crash because the allocator wasn't initalized yet.
|
||||
#if defined(_LINUX) || defined(__APPLE__)
|
||||
|
@ -179,12 +179,18 @@ extern CreateInterfaceFn Sys_GetFactory( CSysModule *pModule );
|
||||
extern CreateInterfaceFn Sys_GetFactory( const char *pModuleName );
|
||||
extern CreateInterfaceFn Sys_GetFactoryThis( void );
|
||||
|
||||
enum Sys_Flags
|
||||
{
|
||||
SYS_NOFLAGS = 0x00,
|
||||
SYS_NOLOAD = 0x01 // no loading, no ref-counting, only returns handle if lib is loaded.
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Load & Unload should be called in exactly one place for each module
|
||||
// The factory for that module should be passed on to dependent components for
|
||||
// proper versioning.
|
||||
//-----------------------------------------------------------------------------
|
||||
extern CSysModule *Sys_LoadModule( const char *pModuleName );
|
||||
extern CSysModule *Sys_LoadModule( const char *pModuleName, Sys_Flags flags = SYS_NOFLAGS );
|
||||
extern void Sys_UnloadModule( CSysModule *pModule );
|
||||
|
||||
// This is a helper function to load a module, get its factory, and get a specific interface.
|
||||
|
@ -1,4 +1,4 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@ -107,14 +107,14 @@ template < typename T >
|
||||
class CArrayAutoPtr : public CPlainAutoPtr < T > // Warning: no polymorphic destructor (delete on base class will be a mistake)
|
||||
{
|
||||
public:
|
||||
explicit CArrayAutoPtr( T *p = NULL ) { Attach( p ); }
|
||||
~CArrayAutoPtr( void ) { Delete(); }
|
||||
explicit CArrayAutoPtr( T *p = NULL ) { this->Attach( p ); }
|
||||
~CArrayAutoPtr( void ) { this->Delete(); }
|
||||
|
||||
public:
|
||||
void Delete( void ) { delete [] Detach(); }
|
||||
void Delete( void ) { delete [] CPlainAutoPtr < T >::Detach(); }
|
||||
|
||||
public:
|
||||
T & operator [] ( int k ) const { return Get()[ k ]; }
|
||||
T & operator [] ( int k ) const { return CPlainAutoPtr < T >::Get()[ k ]; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <ctype.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
@ -137,13 +138,24 @@ void V_normalizeFloatString( char* pFloat );
|
||||
// pDest[maxLen-1] is always NULL terminated if pSrc's length is >= maxLen.
|
||||
//
|
||||
// This means the last parameter can usually be a sizeof() of a string.
|
||||
void V_strncpy( char *pDest, const char *pSrc, int maxLen );
|
||||
void V_strncpy( OUT_Z_CAP(maxLenInChars) char *pDest, const char *pSrc, int maxLenInChars );
|
||||
|
||||
// Ultimate safe strcpy function, for arrays only -- buffer size is inferred by the compiler
|
||||
template <size_t maxLenInChars> void V_strcpy_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pSrc )
|
||||
{
|
||||
V_strncpy( pDest, pSrc, (int)maxLenInChars );
|
||||
}
|
||||
|
||||
int V_snprintf( char *pDest, int destLen, const char *pFormat, ... );
|
||||
void V_wcsncpy( wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes );
|
||||
int V_snwprintf( wchar_t *pDest, int destLen, const wchar_t *pFormat, ... );
|
||||
|
||||
#define COPY_ALL_CHARACTERS -1
|
||||
char *V_strncat(char *, const char *, size_t destBufferSize, int max_chars_to_copy=COPY_ALL_CHARACTERS );
|
||||
char *V_strncat( INOUT_Z_CAP(cchDest) char *pDest, const char *pSrc, size_t cchDest, int max_chars_to_copy=COPY_ALL_CHARACTERS );
|
||||
template <size_t cchDest> char *V_strcat_safe( INOUT_Z_ARRAY char (&pDest)[cchDest], const char *pSrc, int nMaxCharsToCopy=COPY_ALL_CHARACTERS )
|
||||
{
|
||||
return V_strncat( pDest, pSrc, (int)cchDest, nMaxCharsToCopy );
|
||||
}
|
||||
char *V_strnlwr(char *, size_t);
|
||||
|
||||
|
||||
@ -169,16 +181,20 @@ typedef char * va_list;
|
||||
|
||||
#endif // _VA_LIST_DEFINED
|
||||
|
||||
#elif defined(_LINUX) || defined(__APPLE__)
|
||||
#elif POSIX
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define CORRECT_PATH_SEPARATOR '\\'
|
||||
#define CORRECT_PATH_SEPARATOR_S "\\"
|
||||
#define INCORRECT_PATH_SEPARATOR '/'
|
||||
#elif defined(_LINUX) || defined(__APPLE__)
|
||||
#define INCORRECT_PATH_SEPARATOR_S "/"
|
||||
#elif POSIX
|
||||
#define CORRECT_PATH_SEPARATOR '/'
|
||||
#define CORRECT_PATH_SEPARATOR_S "/"
|
||||
#define INCORRECT_PATH_SEPARATOR '\\'
|
||||
#define INCORRECT_PATH_SEPARATOR_S "\\"
|
||||
#endif
|
||||
|
||||
int V_vsnprintf( char *pDest, int maxLen, const char *pFormat, va_list params );
|
||||
@ -193,6 +209,16 @@ char *V_pretifynum( int64 value );
|
||||
int V_UTF8ToUnicode( const char *pUTF8, wchar_t *pwchDest, int cubDestSizeInBytes );
|
||||
int V_UnicodeToUTF8( const wchar_t *pUnicode, char *pUTF8, int cubDestSizeInBytes );
|
||||
|
||||
|
||||
// strips leading and trailing whitespace; returns true if any characters were removed. UTF-8 and UTF-16 versions.
|
||||
bool Q_StripPrecedingAndTrailingWhitespace( char *pch );
|
||||
bool Q_StripPrecedingAndTrailingWhitespaceW( wchar_t *pwch );
|
||||
|
||||
// strips leading and trailing whitespace, also taking "aggressive" characters
|
||||
// like punctuation spaces, non-breaking spaces, composing characters, and so on
|
||||
bool Q_AggressiveStripPrecedingAndTrailingWhitespace( char *pch );
|
||||
bool Q_AggressiveStripPrecedingAndTrailingWhitespaceW( wchar_t *pwch );
|
||||
bool Q_RemoveAllEvilCharacters( char *pch );
|
||||
// Functions for converting hexidecimal character strings back into binary data etc.
|
||||
//
|
||||
// e.g.,
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "tier0/dbg.h"
|
||||
#include <string.h>
|
||||
#include "tier0/platform.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
#include "tier0/memalloc.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
|
@ -790,5 +790,68 @@ void CUtlVector<T, A>::Validate( CValidator &validator, char *pchName )
|
||||
}
|
||||
#endif // DBGFLAG_VALIDATE
|
||||
|
||||
// A vector class for storing pointers, so that the elements pointed to by the pointers are deleted
|
||||
// on exit.
|
||||
template<class T> class CUtlVectorAutoPurge : public CUtlVector< T, CUtlMemory< T, int> >
|
||||
{
|
||||
public:
|
||||
~CUtlVectorAutoPurge( void )
|
||||
{
|
||||
this->PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// easy string list class with dynamically allocated strings. For use with V_SplitString, etc.
|
||||
// Frees the dynamic strings in destructor.
|
||||
class CUtlStringList : public CUtlVectorAutoPurge< char *>
|
||||
{
|
||||
public:
|
||||
void CopyAndAddToTail( char const *pString ) // clone the string and add to the end
|
||||
{
|
||||
char *pNewStr = new char[1 + strlen( pString )];
|
||||
V_strcpy( pNewStr, pString );
|
||||
AddToTail( pNewStr );
|
||||
}
|
||||
|
||||
static int __cdecl SortFunc( char * const * sz1, char * const * sz2 )
|
||||
{
|
||||
return strcmp( *sz1, *sz2 );
|
||||
}
|
||||
|
||||
inline void PurgeAndDeleteElements()
|
||||
{
|
||||
for( int i=0; i < m_Size; i++ )
|
||||
{
|
||||
delete [] Element(i);
|
||||
}
|
||||
Purge();
|
||||
}
|
||||
|
||||
~CUtlStringList( void )
|
||||
{
|
||||
this->PurgeAndDeleteElements();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// <Sergiy> placing it here a few days before Cert to minimize disruption to the rest of codebase
|
||||
class CSplitString: public CUtlVector<char*, CUtlMemory<char*, int> >
|
||||
{
|
||||
public:
|
||||
CSplitString(const char *pString, const char *pSeparator);
|
||||
CSplitString(const char *pString, const char **pSeparators, int nSeparators);
|
||||
~CSplitString();
|
||||
//
|
||||
// NOTE: If you want to make Construct() public and implement Purge() here, you'll have to free m_szBuffer there
|
||||
//
|
||||
private:
|
||||
void Construct(const char *pString, const char **pSeparators, int nSeparators);
|
||||
void PurgeAndDeleteElements();
|
||||
private:
|
||||
char *m_szBuffer; // a copy of original string, with '\0' instead of separators
|
||||
};
|
||||
|
||||
|
||||
#endif // CCVECTOR_H
|
||||
|
@ -229,12 +229,12 @@ class CKeyValuesGrowableStringTable
|
||||
public:
|
||||
// Constructor
|
||||
CKeyValuesGrowableStringTable() :
|
||||
m_hashLookup( 2048, 0, 0, m_Functor, m_Functor ),
|
||||
#ifdef PLATFORM_64BITS
|
||||
m_vecStrings( 0, 4 * 512 * 1024 )
|
||||
#else
|
||||
m_vecStrings( 0, 512 * 1024 )
|
||||
#endif
|
||||
, m_hashLookup( 2048, 0, 0, m_Functor, m_Functor )
|
||||
{
|
||||
m_vecStrings.AddToTail( '\0' );
|
||||
}
|
||||
@ -1465,14 +1465,14 @@ const wchar_t *KeyValues::GetWString( const char *keyName, const wchar_t *defaul
|
||||
bool KeyValues::GetBool( const char *keyName, bool defaultValue, bool* optGotDefault )
|
||||
{
|
||||
if ( FindKey( keyName ) )
|
||||
{
|
||||
if ( optGotDefault )
|
||||
(*optGotDefault) = false;
|
||||
{
|
||||
if ( optGotDefault )
|
||||
(*optGotDefault) = false;
|
||||
return 0 != GetInt( keyName, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( optGotDefault )
|
||||
(*optGotDefault) = true;
|
||||
if ( optGotDefault )
|
||||
(*optGotDefault) = true;
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
@ -3054,4 +3054,4 @@ bool CKeyValuesDumpContextAsDevMsg::KvWriteText( char const *szText )
|
||||
Msg( "%s", szText );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -137,12 +137,12 @@ unsigned FASTCALL HashStringCaselessConventional( const char *pszKey )
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned FASTCALL HashInt( const int n )
|
||||
{
|
||||
register unsigned even, odd;
|
||||
unsigned even, odd;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
@ -154,16 +154,16 @@ unsigned FASTCALL HashInt( const int n )
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned FASTCALL Hash4( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
const uint32 * p = (const uint32 *) pKey;
|
||||
unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
@ -176,16 +176,16 @@ unsigned FASTCALL Hash4( const void *pKey )
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned FASTCALL Hash8( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
const uint32 * p = (const uint32 *) pKey;
|
||||
unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
@ -204,16 +204,16 @@ unsigned FASTCALL Hash8( const void *pKey )
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned FASTCALL Hash12( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
const uint32 * p = (const uint32 *) pKey;
|
||||
unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
@ -238,16 +238,16 @@ unsigned FASTCALL Hash12( const void *pKey )
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned FASTCALL Hash16( const void *pKey )
|
||||
{
|
||||
register const uint32 * p = (const uint32 *) pKey;
|
||||
register unsigned even,
|
||||
odd,
|
||||
n;
|
||||
const uint32 * p = (const uint32 *) pKey;
|
||||
unsigned even,
|
||||
odd,
|
||||
n;
|
||||
n = *p;
|
||||
even = g_nRandomValues[n & 0xff];
|
||||
odd = g_nRandomValues[((n >> 8) & 0xff)];
|
||||
|
||||
even = g_nRandomValues[odd ^ (n >> 24)];
|
||||
odd = g_nRandomValues[even ^ (n >> 16) & 0xff];
|
||||
odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)];
|
||||
even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)];
|
||||
odd = g_nRandomValues[even ^ (n & 0xff)];
|
||||
|
||||
|
@ -142,53 +142,59 @@ struct ThreadedLoadLibaryContext_t
|
||||
#ifdef _WIN32
|
||||
|
||||
// wraps LoadLibraryEx() since 360 doesn't support that
|
||||
static HMODULE InternalLoadLibrary( const char *pName )
|
||||
static HMODULE InternalLoadLibrary( const char *pName, Sys_Flags flags )
|
||||
{
|
||||
#if defined(_X360)
|
||||
return LoadLibrary( pName );
|
||||
#else
|
||||
return LoadLibraryEx( pName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
|
||||
if ( flags & SYS_NOLOAD )
|
||||
return GetModuleHandle( pName );
|
||||
else
|
||||
return LoadLibraryEx( pName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
|
||||
#endif
|
||||
}
|
||||
unsigned ThreadedLoadLibraryFunc( void *pParam )
|
||||
{
|
||||
ThreadedLoadLibaryContext_t *pContext = (ThreadedLoadLibaryContext_t*)pParam;
|
||||
pContext->m_hLibrary = InternalLoadLibrary(pContext->m_pLibraryName);
|
||||
pContext->m_hLibrary = InternalLoadLibrary( pContext->m_pLibraryName, SYS_NOFLAGS );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
HMODULE Sys_LoadLibrary( const char *pLibraryName )
|
||||
#endif // _WIN32
|
||||
|
||||
HMODULE Sys_LoadLibrary( const char *pLibraryName, Sys_Flags flags )
|
||||
{
|
||||
char str[1024];
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
const char *pModuleExtension = ".dll";
|
||||
const char *pModuleAddition = pModuleExtension;
|
||||
#elif defined( _X360 )
|
||||
const char *pModuleExtension = "_360.dll";
|
||||
const char *pModuleAddition = pModuleExtension;
|
||||
#elif defined( _LINUX )
|
||||
const char *pModuleExtension = ".so";
|
||||
const char *pModuleAddition = "_i486.so"; // if an extension is on the filename assume the i486 binary set
|
||||
#elif defined( __APPLE__ )
|
||||
const char *pModuleExtension = ".dylib";
|
||||
const char *pModuleAddition = ".dylib";
|
||||
#endif
|
||||
char str[ 1024 ];
|
||||
// Note: DLL_EXT_STRING can be "_srv.so" or "_360.dll". So be careful
|
||||
// when using the V_*Extension* routines...
|
||||
const char *pDllStringExtension = V_GetFileExtension( DLL_EXT_STRING );
|
||||
const char *pModuleExtension = pDllStringExtension ? ( pDllStringExtension - 1 ) : DLL_EXT_STRING;
|
||||
|
||||
Q_strncpy( str, pLibraryName, sizeof(str) );
|
||||
if ( !Q_stristr( str, pModuleExtension ) )
|
||||
|
||||
if ( IsX360() )
|
||||
{
|
||||
if ( IsX360() )
|
||||
// old, probably busted, behavior for xbox
|
||||
if ( !Q_stristr( str, pModuleExtension ) )
|
||||
{
|
||||
Q_StripExtension( str, str, sizeof(str) );
|
||||
V_SetExtension( str, pModuleExtension, sizeof(str) );
|
||||
}
|
||||
Q_strncat( str, pModuleAddition, sizeof(str) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// always force the final extension to be .dll
|
||||
V_SetExtension( str, pModuleExtension, sizeof(str) );
|
||||
}
|
||||
|
||||
Q_FixSlashes( str );
|
||||
|
||||
#ifdef _WIN32
|
||||
ThreadedLoadLibraryFunc_t threadFunc = GetThreadedLoadLibraryFunc();
|
||||
if ( !threadFunc )
|
||||
return InternalLoadLibrary( str );
|
||||
return InternalLoadLibrary( str, flags );
|
||||
|
||||
// We shouldn't be passing noload while threaded.
|
||||
Assert( !( flags & SYS_NOLOAD ) );
|
||||
|
||||
ThreadedLoadLibaryContext_t context;
|
||||
context.m_pLibraryName = str;
|
||||
@ -209,28 +215,33 @@ HMODULE Sys_LoadLibrary( const char *pLibraryName )
|
||||
ReleaseThreadHandle( h );
|
||||
return context.m_hLibrary;
|
||||
|
||||
#elif defined _LINUX || defined __APPLE__
|
||||
HMODULE ret = dlopen( str, RTLD_NOW );
|
||||
if ( ! ret )
|
||||
#elif POSIX
|
||||
int dlopen_mode = RTLD_NOW;
|
||||
|
||||
if ( flags & SYS_NOLOAD )
|
||||
dlopen_mode |= RTLD_NOLOAD;
|
||||
|
||||
HMODULE ret = ( HMODULE )dlopen( str, dlopen_mode );
|
||||
if ( !ret && !( flags & SYS_NOLOAD ) )
|
||||
{
|
||||
const char *pError = dlerror();
|
||||
if ( pError && ( strstr( pError, "No such file" ) == 0 ) )
|
||||
if ( pError && ( strstr( pError, "No such file" ) == 0 ) && ( strstr( pError, "image not found" ) == 0 ) )
|
||||
{
|
||||
Msg( " failed to dlopen %s error=%s\n", str, pError );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
static bool s_bRunningWithDebugModules = false;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Loads a DLL/component from disk and returns a handle to it
|
||||
// Input : *pModuleName - filename of the component
|
||||
// Output : opaque handle to the module (hides system dependency)
|
||||
//-----------------------------------------------------------------------------
|
||||
CSysModule *Sys_LoadModule( const char *pModuleName )
|
||||
CSysModule *Sys_LoadModule( const char *pModuleName, Sys_Flags flags /* = SYS_NOFLAGS (0) */ )
|
||||
{
|
||||
// If using the Steam filesystem, either the DLL must be a minimum footprint
|
||||
// file in the depot (MFP) or a filesystem GetLocalCopy() call must be made
|
||||
@ -247,7 +258,7 @@ CSysModule *Sys_LoadModule( const char *pModuleName )
|
||||
int i = CommandLine()->FindParm( "-basedir" );
|
||||
if ( i )
|
||||
{
|
||||
strcpy( szCwd, CommandLine()->GetParm( i+1 ) );
|
||||
V_strcpy_safe( szCwd, CommandLine()->GetParm( i + 1 ) );
|
||||
}
|
||||
}
|
||||
if (szCwd[strlen(szCwd) - 1] == '/' || szCwd[strlen(szCwd) - 1] == '\\' )
|
||||
@ -256,7 +267,8 @@ CSysModule *Sys_LoadModule( const char *pModuleName )
|
||||
}
|
||||
|
||||
char szAbsoluteModuleName[1024];
|
||||
if ( strstr( pModuleName, "bin/") == pModuleName )
|
||||
size_t cCwd = strlen( szCwd );
|
||||
if ( strstr( pModuleName, "bin/") == pModuleName || ( szCwd[ cCwd - 1 ] == 'n' && szCwd[ cCwd - 2 ] == 'i' && szCwd[ cCwd - 3 ] == 'b' ) )
|
||||
{
|
||||
// don't make bin/bin path
|
||||
Q_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/%s", szCwd, pModuleName );
|
||||
@ -265,13 +277,13 @@ CSysModule *Sys_LoadModule( const char *pModuleName )
|
||||
{
|
||||
Q_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/bin/%s", szCwd, pModuleName );
|
||||
}
|
||||
hDLL = Sys_LoadLibrary( szAbsoluteModuleName );
|
||||
hDLL = Sys_LoadLibrary( szAbsoluteModuleName, flags );
|
||||
}
|
||||
|
||||
if ( !hDLL )
|
||||
{
|
||||
// full path failed, let LoadLibrary() try to search the PATH now
|
||||
hDLL = Sys_LoadLibrary( pModuleName );
|
||||
hDLL = Sys_LoadLibrary( pModuleName, flags );
|
||||
#if defined( _DEBUG )
|
||||
if ( !hDLL )
|
||||
{
|
||||
@ -293,28 +305,69 @@ CSysModule *Sys_LoadModule( const char *pModuleName )
|
||||
|
||||
LocalFree( (HLOCAL)lpMsgBuf );
|
||||
#elif defined( _X360 )
|
||||
Msg( "Failed to load %s:\n", pModuleName );
|
||||
DWORD error = GetLastError();
|
||||
Msg( "Error(%d) - Failed to load %s:\n", error, pModuleName );
|
||||
#else
|
||||
Error( "Failed to load %s: %s\n", pModuleName, dlerror() );
|
||||
Msg( "Failed to load %s: %s\n", pModuleName, dlerror() );
|
||||
#endif // _WIN32
|
||||
}
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
#if !defined(LINUX)
|
||||
// If running in the debugger, assume debug binaries are okay, otherwise they must run with -allowdebug
|
||||
if ( !IsX360() && hDLL &&
|
||||
!CommandLine()->FindParm( "-allowdebug" ) &&
|
||||
!Sys_IsDebuggerPresent() )
|
||||
if ( Sys_GetProcAddress( hDLL, "BuiltDebug" ) )
|
||||
{
|
||||
if ( Sys_GetProcAddress( hDLL, "BuiltDebug" ) )
|
||||
if ( !IsX360() && hDLL &&
|
||||
!CommandLine()->FindParm( "-allowdebug" ) &&
|
||||
!Sys_IsDebuggerPresent() )
|
||||
{
|
||||
Error( "Module %s is a debug build\n", pModuleName );
|
||||
}
|
||||
|
||||
DevWarning( "Module %s is a debug build\n", pModuleName );
|
||||
|
||||
if ( !s_bRunningWithDebugModules )
|
||||
{
|
||||
s_bRunningWithDebugModules = true;
|
||||
|
||||
#if 0 //def IS_WINDOWS_PC
|
||||
char chMemoryName[ MAX_PATH ];
|
||||
DebugKernelMemoryObjectName( chMemoryName );
|
||||
|
||||
(void) CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, chMemoryName );
|
||||
// Created a shared memory kernel object specific to process id
|
||||
// Existence of this object indicates that we have debug modules loaded
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<CSysModule *>(hDLL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Determine if any debug modules were loaded
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Sys_RunningWithDebugModules()
|
||||
{
|
||||
if ( !s_bRunningWithDebugModules )
|
||||
{
|
||||
#if 0 //def IS_WINDOWS_PC
|
||||
char chMemoryName[ MAX_PATH ];
|
||||
DebugKernelMemoryObjectName( chMemoryName );
|
||||
|
||||
HANDLE hObject = OpenFileMapping( FILE_MAP_READ, FALSE, chMemoryName );
|
||||
if ( hObject && hObject != INVALID_HANDLE_VALUE )
|
||||
{
|
||||
CloseHandle( hObject );
|
||||
s_bRunningWithDebugModules = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return s_bRunningWithDebugModules;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Unloads a DLL/component from
|
||||
|
@ -992,9 +992,240 @@ char *V_pretifynum( int64 value )
|
||||
return out;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if a wide character is a "mean" space; that is,
|
||||
// if it is technically a space or punctuation, but causes disruptive
|
||||
// behavior when used in names, web pages, chat windows, etc.
|
||||
//
|
||||
// characters in this set are removed from the beginning and/or end of strings
|
||||
// by Q_AggressiveStripPrecedingAndTrailingWhitespaceW()
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_IsMeanSpaceW( wchar_t wch )
|
||||
{
|
||||
bool bIsMean = false;
|
||||
|
||||
switch ( wch )
|
||||
{
|
||||
case L'\x0082': // BREAK PERMITTED HERE
|
||||
case L'\x0083': // NO BREAK PERMITTED HERE
|
||||
case L'\x00A0': // NO-BREAK SPACE
|
||||
case L'\x034F': // COMBINING GRAPHEME JOINER
|
||||
case L'\x2000': // EN QUAD
|
||||
case L'\x2001': // EM QUAD
|
||||
case L'\x2002': // EN SPACE
|
||||
case L'\x2003': // EM SPACE
|
||||
case L'\x2004': // THICK SPACE
|
||||
case L'\x2005': // MID SPACE
|
||||
case L'\x2006': // SIX SPACE
|
||||
case L'\x2007': // figure space
|
||||
case L'\x2008': // PUNCTUATION SPACE
|
||||
case L'\x2009': // THIN SPACE
|
||||
case L'\x200A': // HAIR SPACE
|
||||
case L'\x200B': // ZERO-WIDTH SPACE
|
||||
case L'\x200C': // ZERO-WIDTH NON-JOINER
|
||||
case L'\x200D': // ZERO WIDTH JOINER
|
||||
case L'\x200E': // LEFT-TO-RIGHT MARK
|
||||
case L'\x2028': // LINE SEPARATOR
|
||||
case L'\x2029': // PARAGRAPH SEPARATOR
|
||||
case L'\x202F': // NARROW NO-BREAK SPACE
|
||||
case L'\x2060': // word joiner
|
||||
case L'\xFEFF': // ZERO-WIDTH NO BREAK SPACE
|
||||
case L'\xFFFC': // OBJECT REPLACEMENT CHARACTER
|
||||
bIsMean = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return bIsMean;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Converts a UTF8 string into a unicode string
|
||||
// Purpose: strips trailing whitespace; returns pointer inside string just past
|
||||
// any leading whitespace.
|
||||
//
|
||||
// bAggresive = true causes this function to also check for "mean" spaces,
|
||||
// which we don't want in persona names or chat strings as they're disruptive
|
||||
// to the user experience.
|
||||
//-----------------------------------------------------------------------------
|
||||
static wchar_t *StripWhitespaceWorker( int cchLength, wchar_t *pwch, bool *pbStrippedWhitespace, bool bAggressive )
|
||||
{
|
||||
// walk backwards from the end of the string, killing any whitespace
|
||||
*pbStrippedWhitespace = false;
|
||||
|
||||
wchar_t *pwchEnd = pwch + cchLength;
|
||||
while ( --pwchEnd >= pwch )
|
||||
{
|
||||
if ( !iswspace( *pwchEnd ) && ( !bAggressive || !Q_IsMeanSpaceW( *pwchEnd ) ) )
|
||||
break;
|
||||
|
||||
*pwchEnd = 0;
|
||||
*pbStrippedWhitespace = true;
|
||||
}
|
||||
|
||||
// walk forward in the string
|
||||
while ( pwch < pwchEnd )
|
||||
{
|
||||
if ( !iswspace( *pwch ) )
|
||||
break;
|
||||
|
||||
*pbStrippedWhitespace = true;
|
||||
pwch++;
|
||||
}
|
||||
|
||||
return pwch;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Strips all evil characters (ie. zero-width no-break space)
|
||||
// from a string.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_RemoveAllEvilCharacters( char *pch )
|
||||
{
|
||||
// convert to unicode
|
||||
int cch = Q_strlen( pch );
|
||||
int cubDest = (cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwch = (wchar_t *)stackalloc( cubDest );
|
||||
int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ) / sizeof( wchar_t );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
|
||||
// Walk through and skip over evil characters
|
||||
int nWalk = 0;
|
||||
for( int i=0; i<cwch; ++i )
|
||||
{
|
||||
if( !Q_IsMeanSpaceW( pwch[i] ) )
|
||||
{
|
||||
pwch[nWalk] = pwch[i];
|
||||
++nWalk;
|
||||
}
|
||||
else
|
||||
{
|
||||
bStrippedWhitespace = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Null terminate
|
||||
pwch[nWalk-1] = L'\0';
|
||||
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_UnicodeToUTF8( pwch, pch, cch );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_StripPrecedingAndTrailingWhitespaceW( wchar_t *pwch )
|
||||
{
|
||||
int cch = Q_wcslen( pwch );
|
||||
|
||||
// Early out and don't convert if we don't have any chars or leading/trailing ws.
|
||||
if ( ( cch < 1 ) || ( !iswspace( pwch[ 0 ] ) && !iswspace( pwch[ cch - 1 ] ) ) )
|
||||
return false;
|
||||
|
||||
// duplicate on stack
|
||||
int cubDest = ( cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwchT = (wchar_t *)stackalloc( cubDest );
|
||||
Q_wcsncpy( pwchT, pwch, cubDest );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwchT = StripWhitespaceWorker( cch, pwch, &bStrippedWhitespace, false /* not aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_wcsncpy( pwch, pwchT, cubDest );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace,
|
||||
// and also strips punctuation and formatting characters with "clear"
|
||||
// representations.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_AggressiveStripPrecedingAndTrailingWhitespaceW( wchar_t *pwch )
|
||||
{
|
||||
// duplicate on stack
|
||||
int cch = Q_wcslen( pwch );
|
||||
int cubDest = ( cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwchT = (wchar_t *)stackalloc( cubDest );
|
||||
Q_wcsncpy( pwchT, pwch, cubDest );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwchT = StripWhitespaceWorker( cch, pwch, &bStrippedWhitespace, true /* is aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_wcsncpy( pwch, pwchT, cubDest );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_StripPrecedingAndTrailingWhitespace( char *pch )
|
||||
{
|
||||
int cch = Q_strlen( pch );
|
||||
|
||||
// Early out and don't convert if we don't have any chars or leading/trailing ws.
|
||||
if ( ( cch < 1 ) || ( !isspace( (unsigned char)pch[ 0 ] ) && !isspace( (unsigned char)pch[ cch - 1 ] ) ) )
|
||||
return false;
|
||||
|
||||
// convert to unicode
|
||||
int cubDest = (cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwch = (wchar_t *)stackalloc( cubDest );
|
||||
int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ) / sizeof( wchar_t );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwch = StripWhitespaceWorker( cwch-1, pwch, &bStrippedWhitespace, false /* not aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_UnicodeToUTF8( pwch, pch, cch );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_AggressiveStripPrecedingAndTrailingWhitespace( char *pch )
|
||||
{
|
||||
// convert to unicode
|
||||
int cch = Q_strlen( pch );
|
||||
int cubDest = (cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwch = (wchar_t *)stackalloc( cubDest );
|
||||
int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ) / sizeof( wchar_t );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwch = StripWhitespaceWorker( cwch-1, pwch, &bStrippedWhitespace, true /* is aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_UnicodeToUTF8( pwch, pch, cch );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Converts a ucs2 string to a unicode (wchar_t) one, no-op on win32
|
||||
//-----------------------------------------------------------------------------
|
||||
int V_UTF8ToUnicode( const char *pUTF8, wchar_t *pwchDest, int cubDestSizeInBytes )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user