2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-12-01 16:41:45 +00:00
Copyright ( C ) 2012 Robert Beckebans
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# include "../idlib/precompiled.h"
# pragma hdrstop
# include "Unzip.h"
# include "Zip.h"
# ifdef WIN32
2012-11-28 15:47:07 +00:00
# include <io.h> // for _read
2012-11-26 18:58:24 +00:00
# else
2012-11-28 15:47:07 +00:00
# if !__MACH__ && __MWERKS__
# include <types.h>
# include <stat.h>
2012-11-26 18:58:24 +00:00
# else
2012-11-28 15:47:07 +00:00
# include <sys/types.h>
# include <sys/stat.h>
# endif
# include <unistd.h>
2012-11-26 18:58:24 +00:00
# endif
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
DOOM FILESYSTEM
2012-11-28 15:47:07 +00:00
All of Doom ' s data access is through a hierarchical file system , but the contents of
2012-11-26 18:58:24 +00:00
the file system can be transparently merged from several sources .
A " relativePath " is a reference to game file data , which must include a terminating zero .
" .. " , " \\ " , and " : " are explicitly illegal in qpaths to prevent any references
outside the Doom directory system .
The " base path " is the path to the directory holding all the game directories and
usually the executable . It defaults to the current directory , but can be overridden
with " +set fs_basepath c: \ doom " on the command line . The base path cannot be modified
at all after startup .
The " save path " is the path to the directory where game files will be saved . It defaults
to the base path , but can be overridden with a " +set fs_savepath c: \ doom " on the
command line . Any files that are created during the game ( demos , screenshots , etc . ) will
be created reletive to the save path .
If a user runs the game directly from a CD , the base path would be on the CD . This
should still function correctly , but all file writes will fail ( harmlessly ) .
The " base game " is the directory under the paths where data comes from by default , and
can be either " base " or " demo " .
The " current game " may be the same as the base game , or it may be the name of another
directory under the paths that should be searched for files before looking in the base
game . The game directory is set with " +set fs_game myaddon " on the command line . This is
the basis for addons .
No other directories outside of the base game and current game will ever be referenced by
filesystem functions .
Because we will have updated executables freely available online , there is no point to
trying to restrict demo / oem versions of the game with code changes . Demo / oem versions
should be exactly the same executables as release versions , but with different data that
automatically restricts where game media can come from to prevent add - ons from working .
If the " fs_copyfiles " cvar is set to 1 , then every time a file is sourced from the base
path , it will be copied over to the save path . This is a development aid to help build
test releases and to copy working sets of files .
The relative path " sound/newstuff/test.wav " would be searched for in the following places :
for save path , base path :
for current game , base game :
search directory
search zip files
downloaded files , to be written to save path + current game ' s directory
The filesystem can be safely shutdown and reinitialized with different
basedir / cddir / game combinations , but all other subsystems that rely on it
( sound , video ) must also be forced to restart .
" additional mod path search " :
fs_game_base can be used to set an additional search path
in search order , fs_game , fs_game_base , BASEGAME
for instance to base a mod of D3 + D3XP assets , fs_game mymod , fs_game_base d3xp
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# define MAX_ZIPPED_FILE_NAME 2048
# define FILE_HASH_SIZE 1024
2012-11-28 15:47:07 +00:00
struct searchpath_t
{
2012-11-26 18:58:24 +00:00
idStr path ; // c:\doom
idStr gamedir ; // base
} ;
// search flags when opening a file
# define FSFLAG_SEARCH_DIRS ( 1 << 0 )
# define FSFLAG_RETURN_FILE_MEM ( 1 << 1 )
2012-11-28 15:47:07 +00:00
class idFileSystemLocal : public idFileSystem
{
2012-11-26 18:58:24 +00:00
public :
2012-11-28 15:47:07 +00:00
idFileSystemLocal ( ) ;
2012-11-26 18:58:24 +00:00
virtual void Init ( ) ;
virtual void Restart ( ) ;
virtual void Shutdown ( bool reloading ) ;
virtual bool IsInitialized ( ) const ;
2012-11-28 15:47:07 +00:00
virtual idFileList * ListFiles ( const char * relativePath , const char * extension , bool sort = false , bool fullRelativePath = false , const char * gamedir = NULL ) ;
virtual idFileList * ListFilesTree ( const char * relativePath , const char * extension , bool sort = false , const char * gamedir = NULL ) ;
virtual void FreeFileList ( idFileList * fileList ) ;
virtual const char * OSPathToRelativePath ( const char * OSPath ) ;
virtual const char * RelativePathToOSPath ( const char * relativePath , const char * basePath ) ;
virtual const char * BuildOSPath ( const char * base , const char * game , const char * relativePath ) ;
virtual const char * BuildOSPath ( const char * base , const char * relativePath ) ;
virtual void CreateOSPath ( const char * OSPath ) ;
virtual int ReadFile ( const char * relativePath , void * * buffer , ID_TIME_T * timestamp ) ;
virtual void FreeFile ( void * buffer ) ;
virtual int WriteFile ( const char * relativePath , const void * buffer , int size , const char * basePath = " fs_savepath " ) ;
virtual void RemoveFile ( const char * relativePath ) ;
virtual bool RemoveDir ( const char * relativePath ) ;
virtual bool RenameFile ( const char * relativePath , const char * newName , const char * basePath = " fs_savepath " ) ;
virtual idFile * OpenFileReadFlags ( const char * relativePath , int searchFlags , bool allowCopyFiles = true , const char * gamedir = NULL ) ;
virtual idFile * OpenFileRead ( const char * relativePath , bool allowCopyFiles = true , const char * gamedir = NULL ) ;
virtual idFile * OpenFileReadMemory ( const char * relativePath , bool allowCopyFiles = true , const char * gamedir = NULL ) ;
virtual idFile * OpenFileWrite ( const char * relativePath , const char * basePath = " fs_savepath " ) ;
virtual idFile * OpenFileAppend ( const char * relativePath , bool sync = false , const char * basePath = " fs_basepath " ) ;
virtual idFile * OpenFileByMode ( const char * relativePath , fsMode_t mode ) ;
virtual idFile * OpenExplicitFileRead ( const char * OSPath ) ;
virtual idFile * OpenExplicitFileWrite ( const char * OSPath ) ;
virtual idFile_Cached * OpenExplicitPakFile ( const char * OSPath ) ;
virtual void CloseFile ( idFile * f ) ;
virtual void FindDLL ( const char * basename , char dllPath [ MAX_OSPATH ] ) ;
virtual void CopyFile ( const char * fromOSPath , const char * toOSPath ) ;
virtual findFile_t FindFile ( const char * path ) ;
virtual bool FilenameCompare ( const char * s1 , const char * s2 ) const ;
virtual int GetFileLength ( const char * relativePath ) ;
virtual sysFolder_t IsFolder ( const char * relativePath , const char * basePath = " fs_basepath " ) ;
2012-11-26 18:58:24 +00:00
// resource tracking
virtual void EnableBackgroundCache ( bool enable ) ;
2012-11-28 15:47:07 +00:00
virtual void BeginLevelLoad ( const char * name , char * _blockBuffer , int _blockBufferSize ) ;
2012-11-26 18:58:24 +00:00
virtual void EndLevelLoad ( ) ;
2012-11-28 15:47:07 +00:00
virtual bool InProductionMode ( )
{
return ( resourceFiles . Num ( ) > 0 ) | ( com_productionMode . GetInteger ( ) ! = 0 ) ;
}
virtual bool UsingResourceFiles ( )
{
return resourceFiles . Num ( ) > 0 ;
}
virtual void UnloadMapResources ( const char * name ) ;
virtual void UnloadResourceContainer ( const char * name ) ;
idFile * GetResourceContainer ( int idx )
{
if ( idx > = 0 & & idx < resourceFiles . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return resourceFiles [ idx ] - > resourceFile ;
}
return NULL ;
}
2012-11-28 15:47:07 +00:00
virtual void StartPreload ( const idStrList & _preload ) ;
2012-11-26 18:58:24 +00:00
virtual void StopPreload ( ) ;
2012-11-28 15:47:07 +00:00
idFile * GetResourceFile ( const char * fileName , bool memFile ) ;
bool GetResourceCacheEntry ( const char * fileName , idResourceCacheEntry & rc ) ;
virtual int ReadFromBGL ( idFile * _resourceFile , void * _buffer , int _offset , int _len ) ;
virtual bool IsBinaryModel ( const idStr & resName ) const ;
virtual bool IsSoundSample ( const idStr & resName ) const ;
virtual void FreeResourceBuffer ( )
{
resourceBufferAvailable = resourceBufferSize ;
}
virtual void AddImagePreload ( const char * resName , int _filter , int _repeat , int _usage , int _cube )
{
2012-11-26 18:58:24 +00:00
preloadList . AddImage ( resName , _filter , _repeat , _usage , _cube ) ;
}
2012-11-28 15:47:07 +00:00
virtual void AddSamplePreload ( const char * resName )
{
2012-11-26 18:58:24 +00:00
preloadList . AddSample ( resName ) ;
}
2012-11-28 15:47:07 +00:00
virtual void AddModelPreload ( const char * resName )
{
2012-11-26 18:58:24 +00:00
preloadList . AddModel ( resName ) ;
}
2012-11-28 15:47:07 +00:00
virtual void AddAnimPreload ( const char * resName )
{
2012-11-26 18:58:24 +00:00
preloadList . AddAnim ( resName ) ;
}
2012-11-28 15:47:07 +00:00
virtual void AddCollisionPreload ( const char * resName )
{
2012-11-26 18:58:24 +00:00
preloadList . AddCollisionModel ( resName ) ;
}
2012-11-28 15:47:07 +00:00
virtual void AddParticlePreload ( const char * resName )
{
2012-11-26 18:58:24 +00:00
preloadList . AddParticle ( resName ) ;
}
2012-11-28 15:47:07 +00:00
static void Dir_f ( const idCmdArgs & args ) ;
static void DirTree_f ( const idCmdArgs & args ) ;
static void Path_f ( const idCmdArgs & args ) ;
static void TouchFile_f ( const idCmdArgs & args ) ;
static void TouchFileList_f ( const idCmdArgs & args ) ;
static void BuildGame_f ( const idCmdArgs & args ) ;
2012-11-26 18:58:24 +00:00
//static void FileStats_f( const idCmdArgs &args );
2012-11-28 15:47:07 +00:00
static void WriteResourceFile_f ( const idCmdArgs & args ) ;
static void ExtractResourceFile_f ( const idCmdArgs & args ) ;
static void UpdateResourceFile_f ( const idCmdArgs & args ) ;
static void GenerateResourceCRCs_f ( const idCmdArgs & args ) ;
static void CreateCRCsForResourceFileList ( const idFileList & list ) ;
2012-11-26 18:58:24 +00:00
void BuildOrderedStartupContainer ( ) ;
private :
idList < searchpath_t > searchPaths ;
int loadCount ; // total files read
int loadStack ; // total files in memory
idStr gameFolder ; // this will be a single name without separators
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
static idCVar fs_debug ;
static idCVar fs_debugResources ;
static idCVar fs_copyfiles ;
static idCVar fs_buildResources ;
static idCVar fs_game ;
static idCVar fs_game_base ;
static idCVar fs_enableBGL ;
static idCVar fs_debugBGL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr manifestName ;
idStrList fileManifest ;
idPreloadManifest preloadList ;
2012-11-28 15:47:07 +00:00
idList < idResourceContainer * > resourceFiles ;
byte * resourceBufferPtr ;
2012-11-26 18:58:24 +00:00
int resourceBufferSize ;
int resourceBufferAvailable ;
int numFilesOpenedAsCached ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
private :
// .resource file creation
void ClearResourcePacks ( ) ;
void WriteResourcePacks ( ) ;
2012-11-28 15:47:07 +00:00
void AddRenderProgs ( idStrList & files ) ;
void AddFonts ( idStrList & files ) ;
void ReplaceSeparators ( idStr & path , char sep = PATHSEPARATOR_CHAR ) ;
int ListOSFiles ( const char * directory , const char * extension , idStrList & list ) ;
idFileHandle OpenOSFile ( const char * name , fsMode_t mode ) ;
2012-11-26 18:58:24 +00:00
void CloseOSFile ( idFileHandle o ) ;
int DirectFileLength ( idFileHandle o ) ;
2012-11-28 15:47:07 +00:00
void CopyFile ( idFile * src , const char * toOSPath ) ;
int AddUnique ( const char * name , idStrList & list , idHashIndex & hashIndex ) const ;
void GetExtensionList ( const char * extension , idStrList & extensionList ) const ;
int GetFileList ( const char * relativePath , const idStrList & extensions , idStrList & list , idHashIndex & hashIndex , bool fullRelativePath , const char * gamedir = NULL ) ;
int GetFileListTree ( const char * relativePath , const idStrList & extensions , idStrList & list , idHashIndex & hashIndex , const char * gamedir = NULL ) ;
void AddGameDirectory ( const char * path , const char * dir ) ;
int AddResourceFile ( const char * resourceFileName ) ;
void RemoveMapResourceFile ( const char * resourceFileName ) ;
void RemoveResourceFileByIndex ( const int & idx ) ;
void RemoveResourceFile ( const char * resourceFileName ) ;
int FindResourceFile ( const char * resourceFileName ) ;
void SetupGameDirectories ( const char * gameName ) ;
2012-11-26 18:58:24 +00:00
void Startup ( ) ;
void InitPrecache ( ) ;
void ReOpenCacheFiles ( ) ;
} ;
2012-11-28 15:47:07 +00:00
idCVar idFileSystemLocal : : fs_debug ( " fs_debug " , " 0 " , CVAR_SYSTEM | CVAR_INTEGER , " " , 0 , 2 , idCmdSystem : : ArgCompletion_Integer < 0 , 2 > ) ;
2012-11-26 18:58:24 +00:00
idCVar idFileSystemLocal : : fs_debugResources ( " fs_debugResources " , " 0 " , CVAR_SYSTEM | CVAR_BOOL , " " ) ;
idCVar idFileSystemLocal : : fs_enableBGL ( " fs_enableBGL " , " 0 " , CVAR_SYSTEM | CVAR_BOOL , " " ) ;
idCVar idFileSystemLocal : : fs_debugBGL ( " fs_debugBGL " , " 0 " , CVAR_SYSTEM | CVAR_BOOL , " " ) ;
idCVar idFileSystemLocal : : fs_copyfiles ( " fs_copyfiles " , " 0 " , CVAR_SYSTEM | CVAR_INIT | CVAR_BOOL , " Copy every file touched to fs_savepath " ) ;
idCVar idFileSystemLocal : : fs_buildResources ( " fs_buildresources " , " 0 " , CVAR_SYSTEM | CVAR_BOOL | CVAR_INIT , " Copy every file touched to a resource file " ) ;
idCVar idFileSystemLocal : : fs_game ( " fs_game " , " " , CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO , " mod path " ) ;
idCVar idFileSystemLocal : : fs_game_base ( " fs_game_base " , " " , CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO , " alternate mod path, searched after the main fs_game path, before the basedir " ) ;
idCVar fs_basepath ( " fs_basepath " , " " , CVAR_SYSTEM | CVAR_INIT , " " ) ;
idCVar fs_savepath ( " fs_savepath " , " " , CVAR_SYSTEM | CVAR_INIT , " " ) ;
idCVar fs_resourceLoadPriority ( " fs_resourceLoadPriority " , " 1 " , CVAR_SYSTEM , " if 1, open requests will be honored from resource files first; if 0, the resource files are checked after normal search paths " ) ;
idCVar fs_enableBackgroundCaching ( " fs_enableBackgroundCaching " , " 1 " , CVAR_SYSTEM , " if 1 allow the 360 to precache game files in the background " ) ;
idFileSystemLocal fileSystemLocal ;
2012-11-28 15:47:07 +00:00
idFileSystem * fileSystem = & fileSystemLocal ;
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : ReadFromBGL
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : ReadFromBGL ( idFile * _resourceFile , void * _buffer , int _offset , int _len )
{
if ( _resourceFile - > Tell ( ) ! = _offset )
{
2012-11-26 18:58:24 +00:00
_resourceFile - > Seek ( _offset , FS_SEEK_SET ) ;
}
return _resourceFile - > Read ( _buffer , _len ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : StartPreload
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : StartPreload ( const idStrList & _preload )
{
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : StopPreload
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : StopPreload ( )
{
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : idFileSystemLocal
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFileSystemLocal : : idFileSystemLocal ( )
{
2012-11-26 18:58:24 +00:00
loadCount = 0 ;
loadStack = 0 ;
resourceBufferPtr = NULL ;
resourceBufferSize = 0 ;
resourceBufferAvailable = 0 ;
numFilesOpenedAsCached = 0 ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : FilenameCompare
Ignore case and separator char distinctions
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idFileSystemLocal : : FilenameCompare ( const char * s1 , const char * s2 ) const
{
2012-11-26 18:58:24 +00:00
int c1 , c2 ;
2012-11-28 15:47:07 +00:00
do
{
2012-11-26 18:58:24 +00:00
c1 = * s1 + + ;
c2 = * s2 + + ;
2012-11-28 15:47:07 +00:00
if ( c1 > = ' a ' & & c1 < = ' z ' )
{
c1 - = ( ' a ' - ' A ' ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
if ( c2 > = ' a ' & & c2 < = ' z ' )
{
c2 - = ( ' a ' - ' A ' ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
if ( c1 = = ' \\ ' | | c1 = = ' : ' )
{
2012-11-26 18:58:24 +00:00
c1 = ' / ' ;
}
2012-11-28 15:47:07 +00:00
if ( c2 = = ' \\ ' | | c2 = = ' : ' )
{
2012-11-26 18:58:24 +00:00
c2 = ' / ' ;
}
2012-11-28 15:47:07 +00:00
if ( c1 ! = c2 )
{
2012-11-26 18:58:24 +00:00
return true ; // strings not equal
}
2012-11-28 15:47:07 +00:00
}
while ( c1 ) ;
2012-11-26 18:58:24 +00:00
return false ; // strings are equal
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : GetFileLength
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : GetFileLength ( const char * relativePath )
{
idFile * f ;
2012-11-26 18:58:24 +00:00
int len ;
2012-11-28 15:47:07 +00:00
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
idLib : : FatalError ( " Filesystem call made without initialization " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! relativePath | | ! relativePath [ 0 ] )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " idFileSystemLocal::GetFileLength with empty name " ) ;
return - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( resourceFiles . Num ( ) > 0 )
{
2012-11-26 18:58:24 +00:00
idResourceCacheEntry rc ;
2012-11-28 15:47:07 +00:00
if ( GetResourceCacheEntry ( relativePath , rc ) )
{
2012-11-26 18:58:24 +00:00
return rc . length ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// look for it in the filesystem or pack files
f = OpenFileRead ( relativePath , false ) ;
2012-11-28 15:47:07 +00:00
if ( f = = NULL )
{
2012-11-26 18:58:24 +00:00
return - 1 ;
}
2012-11-28 15:47:07 +00:00
len = ( int ) f - > Length ( ) ;
2012-11-26 18:58:24 +00:00
delete f ;
return len ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : OpenOSFile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFileHandle idFileSystemLocal : : OpenOSFile ( const char * fileName , fsMode_t mode )
{
2012-11-26 18:58:24 +00:00
idFileHandle fp ;
2012-11-28 15:47:07 +00:00
2012-12-06 23:09:53 +00:00
// RB begin
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
DWORD dwAccess = 0 ;
DWORD dwShare = 0 ;
DWORD dwCreate = 0 ;
DWORD dwFlags = 0 ;
2012-11-28 15:47:07 +00:00
if ( mode = = FS_WRITE )
{
2012-11-26 18:58:24 +00:00
dwAccess = GENERIC_READ | GENERIC_WRITE ;
dwShare = FILE_SHARE_READ ;
dwCreate = CREATE_ALWAYS ;
dwFlags = FILE_ATTRIBUTE_NORMAL ;
2012-11-28 15:47:07 +00:00
}
else if ( mode = = FS_READ )
{
2012-11-26 18:58:24 +00:00
dwAccess = GENERIC_READ ;
dwShare = FILE_SHARE_READ ;
dwCreate = OPEN_EXISTING ;
dwFlags = FILE_ATTRIBUTE_NORMAL ;
2012-11-28 15:47:07 +00:00
}
else if ( mode = = FS_APPEND )
{
2012-11-26 18:58:24 +00:00
dwAccess = GENERIC_READ | GENERIC_WRITE ;
dwShare = FILE_SHARE_READ ;
dwCreate = OPEN_ALWAYS ;
dwFlags = FILE_ATTRIBUTE_NORMAL ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
fp = CreateFile ( fileName , dwAccess , dwShare , NULL , dwCreate , dwFlags , NULL ) ;
2012-11-28 15:47:07 +00:00
if ( fp = = INVALID_HANDLE_VALUE )
{
2012-11-26 18:58:24 +00:00
return NULL ;
2012-11-28 15:47:07 +00:00
}
2012-12-06 23:09:53 +00:00
# else
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
# ifndef __MWERKS__
# ifndef WIN32
// some systems will let you fopen a directory
struct stat buf ;
if ( stat ( fileName , & buf ) ! = - 1 & & ! S_ISREG ( buf . st_mode ) )
{
return NULL ;
}
# endif
# endif
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
if ( mode = = FS_WRITE )
{
fp = fopen ( fileName , " wb " ) ;
}
else if ( mode = = FS_READ )
{
fp = fopen ( fileName , " rb " ) ;
}
else if ( mode = = FS_APPEND )
{
fp = fopen ( fileName , " ab " ) ;
}
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
if ( ! fp ) //&& fs_caseSensitiveOS.GetBool() )
{
// RB: really any proper OS other than Windows should have a case sensitive filesystem
idStr fpath , entry ;
idStrList list ;
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
fpath = fileName ;
fpath . StripFilename ( ) ;
fpath . StripTrailing ( PATHSEPARATOR_CHAR ) ;
if ( ListOSFiles ( fpath , NULL , list ) = = - 1 )
{
return NULL ;
}
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
for ( int i = 0 ; i < list . Num ( ) ; i + + )
{
entry = fpath + PATHSEPARATOR_CHAR + list [ i ] ;
if ( ! entry . Icmp ( fileName ) )
{
if ( mode = = FS_WRITE )
{
fp = fopen ( entry , " wb " ) ;
}
else if ( mode = = FS_READ )
{
fp = fopen ( entry , " rb " ) ;
}
else if ( mode = = FS_APPEND )
{
fp = fopen ( entry , " ab " ) ;
}
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
if ( fp )
{
if ( fs_debug . GetInteger ( ) )
{
common - > Printf ( " idFileSystemLocal::OpenFileRead: changed %s to %s \n " , fileName , entry . c_str ( ) ) ;
}
break ;
}
else
{
// not supposed to happen if ListOSFiles is doing it's job correctly
common - > Warning ( " idFileSystemLocal::OpenFileRead: fs_caseSensitiveOS 1 could not open %s " , entry . c_str ( ) ) ;
}
}
}
}
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
# endif
// RB end
2012-12-08 17:20:13 +00:00
2012-11-26 18:58:24 +00:00
return fp ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : CloseOSFile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : CloseOSFile ( idFileHandle o )
{
2012-12-06 23:09:53 +00:00
// RB begin
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
: : CloseHandle ( o ) ;
2012-12-06 23:09:53 +00:00
# else
fclose ( o ) ;
# endif
// RB end
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : DirectFileLength
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : DirectFileLength ( idFileHandle o )
{
2012-12-06 23:09:53 +00:00
// RB begin
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
return GetFileSize ( o , NULL ) ;
2012-12-06 23:09:53 +00:00
# else
int pos ;
int end ;
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
pos = ftell ( o ) ;
fseek ( o , 0 , SEEK_END ) ;
end = ftell ( o ) ;
fseek ( o , pos , SEEK_SET ) ;
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
return end ;
# endif
// RB end
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = =
idFileSystemLocal : : CreateOSPath
Creates any directories needed to store the given filename
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : CreateOSPath ( const char * OSPath )
{
char * ofs ;
2012-11-26 18:58:24 +00:00
// make absolutely sure that it can't back up the path
// FIXME: what about c: ?
2012-11-28 15:47:07 +00:00
if ( strstr ( OSPath , " .. " ) | | strstr ( OSPath , " :: " ) )
{
# ifdef _DEBUG
2012-11-26 18:58:24 +00:00
common - > DPrintf ( " refusing to create relative path \" %s \" \n " , OSPath ) ;
# endif
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > path ( OSPath ) ;
2012-12-11 23:36:07 +00:00
// RB begin
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
path . SlashesToBackSlashes ( ) ;
2012-12-11 23:36:07 +00:00
# endif
// RB end
2012-11-28 15:47:07 +00:00
for ( ofs = & path [ 1 ] ; * ofs ; ofs + + )
{
if ( * ofs = = PATHSEPARATOR_CHAR )
{
2012-11-26 18:58:24 +00:00
// create the directory
* ofs = 0 ;
Sys_Mkdir ( path ) ;
* ofs = PATHSEPARATOR_CHAR ;
}
}
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : EnableBackgroundCache
= = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : EnableBackgroundCache ( bool enable )
{
if ( ! fs_enableBackgroundCaching . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : BeginLevelLoad
= = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : BeginLevelLoad ( const char * name , char * _blockBuffer , int _blockBufferSize )
{
if ( name = = NULL | | * name = = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
resourceBufferPtr = ( byte * ) _blockBuffer ;
resourceBufferAvailable = _blockBufferSize ;
resourceBufferSize = _blockBufferSize ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
manifestName = name ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileManifest . Clear ( ) ;
preloadList . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
EnableBackgroundCache ( false ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ReOpenCacheFiles ( ) ;
manifestName . StripPath ( ) ;
2012-11-28 15:47:07 +00:00
if ( resourceFiles . Num ( ) > 0 )
{
2012-11-26 18:58:24 +00:00
AddResourceFile ( va ( " %s.resources " , manifestName . c_str ( ) ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : UnloadResourceContainer
2012-11-28 15:47:07 +00:00
= = = = = = = = = = = = = = = = =
2012-11-26 18:58:24 +00:00
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : UnloadResourceContainer ( const char * name )
{
if ( name = = NULL | | * name = = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
return ;
}
RemoveResourceFile ( va ( " %s.resources " , name ) ) ;
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : UnloadMapResources
2012-11-28 15:47:07 +00:00
= = = = = = = = = = = = = = = = =
2012-11-26 18:58:24 +00:00
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : UnloadMapResources ( const char * name )
{
if ( name = = NULL | | * name = = ' \0 ' | | idStr : : Icmp ( " _startup " , name ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( resourceFiles . Num ( ) > 0 )
{
2012-11-26 18:58:24 +00:00
RemoveMapResourceFile ( va ( " %s.resources " , name ) ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : EndLevelLoad
2012-11-28 15:47:07 +00:00
= = = = = = = = = = = = = = = = =
2012-11-26 18:58:24 +00:00
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : EndLevelLoad ( )
{
if ( fs_buildResources . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
int saveCopyFiles = fs_copyfiles . GetInteger ( ) ;
fs_copyfiles . SetInteger ( 0 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr manifestFileName = manifestName ;
manifestFileName . StripPath ( ) ;
manifestFileName . SetFileExtension ( " manifest " ) ;
manifestFileName . Insert ( " maps/ " , 0 ) ;
2012-11-28 15:47:07 +00:00
idFile * outFile = fileSystem - > OpenFileWrite ( manifestFileName ) ;
if ( outFile ! = NULL )
{
2012-11-26 18:58:24 +00:00
int num = fileManifest . Num ( ) ;
outFile - > WriteBig ( num ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
outFile - > WriteString ( fileManifest [ i ] ) ;
}
delete outFile ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > preloadName = manifestName ;
preloadName . Insert ( " maps/ " , 0 ) ;
preloadName + = " .preload " ;
2012-11-28 15:47:07 +00:00
idFile * fileOut = fileSystem - > OpenFileWrite ( preloadName , " fs_savepath " ) ;
2012-11-26 18:58:24 +00:00
preloadList . WriteManifestToFile ( fileOut ) ;
delete fileOut ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fs_copyfiles . SetInteger ( saveCopyFiles ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
EnableBackgroundCache ( true ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
resourceBufferPtr = NULL ;
resourceBufferAvailable = 0 ;
resourceBufferSize = 0 ;
}
2012-11-28 15:47:07 +00:00
bool FileExistsInAllManifests ( const char * filename , idList < idFileManifest > & manifests )
{
for ( int i = 0 ; i < manifests . Num ( ) ; i + + )
{
if ( strstr ( manifests [ i ] . GetManifestName ( ) , " _startup " ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( strstr ( manifests [ i ] . GetManifestName ( ) , " _pc " ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( manifests [ i ] . FindFile ( filename ) = = - 1 )
{
2012-11-26 18:58:24 +00:00
return false ;
}
}
return true ;
}
2012-11-28 15:47:07 +00:00
bool FileExistsInAllPreloadManifests ( const char * filename , idList < idPreloadManifest > & manifests )
{
for ( int i = 0 ; i < manifests . Num ( ) ; i + + )
{
if ( strstr ( manifests [ i ] . GetManifestName ( ) , " _startup " ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( manifests [ i ] . FindResource ( filename ) = = - 1 )
{
2012-11-26 18:58:24 +00:00
return false ;
}
}
return true ;
}
2012-11-28 15:47:07 +00:00
void RemoveFileFromAllManifests ( const char * filename , idList < idFileManifest > & manifests )
{
for ( int i = 0 ; i < manifests . Num ( ) ; i + + )
{
if ( strstr ( manifests [ i ] . GetManifestName ( ) , " _startup " ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( strstr ( manifests [ i ] . GetManifestName ( ) , " _pc " ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
continue ;
}
manifests [ i ] . RemoveAll ( filename ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : AddPerPlatformResources
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : AddRenderProgs ( idStrList & files )
{
2012-11-26 18:58:24 +00:00
idStrList work ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// grab all the renderprogs
idStr path = RelativePathToOSPath ( " renderprogs/cgb " , " fs_basepath " ) ;
ListOSFiles ( path , " *.cgb " , work ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < work . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
files . Append ( idStr ( " renderprogs/cgb/ " ) + work [ i ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
path = RelativePathToOSPath ( " renderprogs/hlsl " , " fs_basepath " ) ;
ListOSFiles ( path , " *.v360 " , work ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < work . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
files . Append ( idStr ( " renderprogs/hlsl/ " ) + work [ i ] ) ;
}
ListOSFiles ( path , " *.p360 " , work ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < work . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
files . Append ( idStr ( " renderprogs/hlsl/ " ) + work [ i ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
path = RelativePathToOSPath ( " renderprogs/gl " , " fs_basepath " ) ;
ListOSFiles ( path , " *.* " , work ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < work . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
files . Append ( idStr ( " renderprogs/gl/ " ) + work [ i ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : AddSoundResources
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : AddFonts ( idStrList & files )
{
2012-11-26 18:58:24 +00:00
// temp fix for getting idaudio files in
2012-11-28 15:47:07 +00:00
idFileList * fl = ListFilesTree ( " generated/images/newfonts " , " *.bimage " , false ) ;
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
files . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " newfonts " , " *.dat " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
files . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
}
2012-11-28 15:47:07 +00:00
const char * excludeExtensions [ ] =
{
2012-11-26 18:58:24 +00:00
" .idxma " , " .idmsf " , " .idwav " , " .xma " , " .msf " , " .wav " , " .resource "
} ;
const int numExcludeExtensions = sizeof ( excludeExtensions ) / sizeof ( excludeExtensions [ 0 ] ) ;
2012-11-28 15:47:07 +00:00
bool IsExcludedFile ( const idStr & resName )
{
for ( int k = 0 ; k < numExcludeExtensions ; k + + )
{
if ( resName . Find ( excludeExtensions [ k ] , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
return true ;
}
}
return false ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : IsBinaryModel
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idFileSystemLocal : : IsBinaryModel ( const idStr & resName ) const
{
2012-11-26 18:58:24 +00:00
idStrStatic < 32 > ext ;
resName . ExtractFileExtension ( ext ) ;
2012-11-28 15:47:07 +00:00
if ( ( ext . Icmp ( " base " ) = = 0 ) | | ( ext . Icmp ( " blwo " ) = = 0 ) | | ( ext . Icmp ( " bflt " ) = = 0 ) | | ( ext . Icmp ( " bma " ) = = 0 ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
return false ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : IsSoundSample
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idFileSystemLocal : : IsSoundSample ( const idStr & resName ) const
{
2012-11-26 18:58:24 +00:00
idStrStatic < 32 > ext ;
resName . ExtractFileExtension ( ext ) ;
2012-11-28 15:47:07 +00:00
if ( ( ext . Icmp ( " idxma " ) = = 0 ) | | ( ext . Icmp ( " idwav " ) = = 0 ) | | ( ext . Icmp ( " idmsf " ) = = 0 ) | | ( ext . Icmp ( " xma " ) = = 0 ) | | ( ext . Icmp ( " wav " ) = = 0 ) | | ( ext . Icmp ( " msf " ) = = 0 ) | | ( ext . Icmp ( " msadpcm " ) = = 0 ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
return false ;
}
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : BuildOrderedStartupContainer ( )
{
2012-11-26 18:58:24 +00:00
idStrList orderedFiles ( 1024 ) ;
2012-11-28 15:47:07 +00:00
idFileList * fl = ListFilesTree ( " materials " , " *.mtr " , true ) ;
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " renderprogs " , " *.v360 " , true ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " renderprogs " , " *.p360 " , true ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " renderprogs " , " *.cgb " , true ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " renderprogs/gl " , " *.* " , true ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " skins " , " *.skin " , true ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " sound " , " *.sndshd " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " def " , " *.def " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " fx " , " *.fx " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " particles " , " *.prt " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl = ListFilesTree ( " af " , " *.af " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
fl = ListFilesTree ( " newpdas " , " *.pda " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
orderedFiles . Append ( " script/doom_main.script " ) ;
orderedFiles . Append ( " script/doom_defs.script " ) ;
orderedFiles . Append ( " script/doom_defs.script " ) ;
orderedFiles . Append ( " script/doom_events.script " ) ;
orderedFiles . Append ( " script/doom_util.script " ) ;
orderedFiles . Append ( " script/weapon_base.script " ) ;
orderedFiles . Append ( " script/ai_base.script " ) ;
orderedFiles . Append ( " script/weapon_fists.script " ) ;
orderedFiles . Append ( " script/weapon_pistol.script " ) ;
orderedFiles . Append ( " script/weapon_shotgun.script " ) ;
orderedFiles . Append ( " script/weapon_machinegun.script " ) ;
orderedFiles . Append ( " script/weapon_chaingun.script " ) ;
orderedFiles . Append ( " script/weapon_handgrenade.script " ) ;
orderedFiles . Append ( " script/weapon_plasmagun.script " ) ;
orderedFiles . Append ( " script/weapon_rocketlauncher.script " ) ;
orderedFiles . Append ( " script/weapon_bfg.script " ) ;
orderedFiles . Append ( " script/weapon_soulcube.script " ) ;
orderedFiles . Append ( " script/weapon_chainsaw.script " ) ;
orderedFiles . Append ( " script/weapon_flashlight.script " ) ;
orderedFiles . Append ( " script/weapon_pda.script " ) ;
orderedFiles . Append ( " script/ai_monster_base.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie_base.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_archvile.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_cherub.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_hellknight.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_imp.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_maggot.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_mancubus.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_pinky.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_revenant.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_trite.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_wraith.script " ) ;
orderedFiles . Append ( " script/ai_monster_flying_lostsoul.script " ) ;
orderedFiles . Append ( " script/ai_monster_flying_cacodemon.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie_morgue.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie_sawyer.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie_bernie.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie_commando_cgun.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie_commando_tentacle.script " ) ;
orderedFiles . Append ( " script/ai_monster_zombie_security_pistol.script " ) ;
orderedFiles . Append ( " script/ai_monster_turret.script " ) ;
orderedFiles . Append ( " script/ai_monster_boss_vagary.script " ) ;
orderedFiles . Append ( " script/ai_monster_boss_cyberdemon.script " ) ;
orderedFiles . Append ( " script/ai_monster_boss_guardian.script " ) ;
orderedFiles . Append ( " script/ai_monster_boss_guardian_seeker.script " ) ;
orderedFiles . Append ( " script/ai_monster_boss_sabaoth.script " ) ;
orderedFiles . Append ( " script/ai_character.script " ) ;
orderedFiles . Append ( " script/ai_character_prone.script " ) ;
orderedFiles . Append ( " script/ai_character_sentry.script " ) ;
orderedFiles . Append ( " script/ai_player.script " ) ;
orderedFiles . Append ( " script/ai_alphalabs2_scientist1.script " ) ;
orderedFiles . Append ( " script/ai_cinematic_le.script " ) ;
orderedFiles . Append ( " script/map_admin1.script " ) ;
orderedFiles . Append ( " script/map_alphalabs1.script " ) ;
orderedFiles . Append ( " script/map_alphalabs2.script " ) ;
orderedFiles . Append ( " script/map_alphalabs3.script " ) ;
orderedFiles . Append ( " script/map_alphalabs3_crane.script " ) ;
orderedFiles . Append ( " script/map_alphalabs4.script " ) ;
orderedFiles . Append ( " script/map_caves.script " ) ;
orderedFiles . Append ( " script/map_caves2.script " ) ;
orderedFiles . Append ( " script/map_comm1.script " ) ;
orderedFiles . Append ( " script/map_commoutside_lift.script " ) ;
orderedFiles . Append ( " script/map_commoutside.script " ) ;
orderedFiles . Append ( " script/map_cpu.script " ) ;
orderedFiles . Append ( " script/map_cpuboss.script " ) ;
orderedFiles . Append ( " script/map_delta1.script " ) ;
orderedFiles . Append ( " script/map_delta2a.script " ) ;
orderedFiles . Append ( " script/map_delta2b.script " ) ;
orderedFiles . Append ( " script/map_delta3.script " ) ;
orderedFiles . Append ( " script/map_delta5.script " ) ;
orderedFiles . Append ( " script/map_enpro.script " ) ;
orderedFiles . Append ( " script/map_hell1.script " ) ;
orderedFiles . Append ( " script/map_hellhole.script " ) ;
orderedFiles . Append ( " script/map_recycling1.script " ) ;
orderedFiles . Append ( " script/map_recycling2.script " ) ;
orderedFiles . Append ( " script/map_site3.script " ) ;
orderedFiles . Append ( " script/map_marscity1.script " ) ;
orderedFiles . Append ( " script/map_marscity2.script " ) ;
orderedFiles . Append ( " script/map_mc_underground.script " ) ;
orderedFiles . Append ( " script/map_monorail.script " ) ;
orderedFiles . Append ( " script/d3xp_events.script " ) ;
orderedFiles . Append ( " script/weapon_bloodstone_passive.script " ) ;
orderedFiles . Append ( " script/weapon_bloodstone_active1.script " ) ;
orderedFiles . Append ( " script/weapon_bloodstone_active2.script " ) ;
orderedFiles . Append ( " script/weapon_bloodstone_active3.script " ) ;
orderedFiles . Append ( " script/weapon_shotgun_double.script " ) ;
orderedFiles . Append ( " script/weapon_grabber.script " ) ;
orderedFiles . Append ( " script/ai_monster_hunter_helltime.script " ) ;
orderedFiles . Append ( " script/ai_monster_hunter_berserk.script " ) ;
orderedFiles . Append ( " script/ai_monster_hunter_invul.script " ) ;
orderedFiles . Append ( " script/ai_monster_boss_maledict.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_vulgar.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_d3xp_bruiser.script " ) ;
orderedFiles . Append ( " script/ai_monster_dummy_target.script " ) ;
orderedFiles . Append ( " script/ai_monster_dummy.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_sentry.script " ) ;
orderedFiles . Append ( " script/ai_monster_demon_trite_jump.script " ) ;
orderedFiles . Append ( " script/ai_monster_turret_ancient.script " ) ;
orderedFiles . Append ( " script/ai_monster_flying_forgotten.script " ) ;
orderedFiles . Append ( " script/ai_character_erebus3.script " ) ;
orderedFiles . Append ( " script/d3xp_airlock.script " ) ;
orderedFiles . Append ( " script/d3xp_bloodstone.script " ) ;
orderedFiles . Append ( " script/map_erebus1.script " ) ;
orderedFiles . Append ( " script/map_erebus2_helltime.script " ) ;
orderedFiles . Append ( " script/map_erebus2.script " ) ;
orderedFiles . Append ( " script/map_erebus3.script " ) ;
orderedFiles . Append ( " script/map_erebus4.script " ) ;
orderedFiles . Append ( " script/map_erebus5.script " ) ;
orderedFiles . Append ( " script/map_erebus5_cloud.script " ) ;
orderedFiles . Append ( " script/map_erebus6.script " ) ;
orderedFiles . Append ( " script/map_erebus6_berzerk.script " ) ;
orderedFiles . Append ( " script/map_phobos1.script " ) ;
orderedFiles . Append ( " script/map_phobos2.script " ) ;
orderedFiles . Append ( " script/map_phobos2_invul.script " ) ;
orderedFiles . Append ( " script/map_phobos3.script " ) ;
orderedFiles . Append ( " script/map_phobos4.script " ) ;
orderedFiles . Append ( " script/map_deltax.script " ) ;
orderedFiles . Append ( " script/map_hell.script " ) ;
orderedFiles . Append ( " script/map_maledict.script " ) ;
orderedFiles . Append ( " script/d3le-ai_monster_boss_guardian2.script " ) ;
orderedFiles . Append ( " script/ai_follower.script " ) ;
orderedFiles . Append ( " generated/swf/shell.bswf " ) ;
fl = ListFilesTree ( " newfonts " , " *.dat " , false ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fl - > GetList ( ) . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
orderedFiles . AddUnique ( fl - > GetList ( ) [ i ] ) ;
}
FreeFileList ( fl ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idResourceContainer : : WriteResourceFile ( " _ordered.resources " , orderedFiles , false ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : WriteResourcePacks
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : WriteResourcePacks ( )
{
2012-11-26 18:58:24 +00:00
idStrList filesNotCommonToAllMaps ( 16384 ) ; // files that are not shared by all maps, used to trim the common list
idStrList filesCommonToAllMaps ( 16384 ) ; // files that are shared by all maps, will include startup files, renderprogs etc..
idPreloadManifest commonPreloads ; // preload entries that exist in all map preload files
2012-11-28 15:47:07 +00:00
idStr path = RelativePathToOSPath ( " maps/ " , " fs_savepath " ) ;
idStrList manifestFiles ;
2012-11-26 18:58:24 +00:00
ListOSFiles ( path , " .manifest " , manifestFiles ) ;
idStrList preloadFiles ;
ListOSFiles ( path , " .preload " , preloadFiles ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idList < idFileManifest > manifests ; // list of all manifest files
// load all file manifests
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < manifestFiles . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
idStr path = " maps/ " ;
path + = manifestFiles [ i ] ;
idFileManifest manifest ;
2012-11-28 15:47:07 +00:00
if ( manifest . LoadManifest ( path ) )
{
2012-11-26 18:58:24 +00:00
//manifest.Print();
manifest . RemoveAll ( va ( " strings/%s " , ID_LANG_ENGLISH ) ) ; // remove all .lang files
manifest . RemoveAll ( va ( " strings/%s " , ID_LANG_FRENCH ) ) ;
manifest . RemoveAll ( va ( " strings/%s " , ID_LANG_ITALIAN ) ) ;
manifest . RemoveAll ( va ( " strings/%s " , ID_LANG_GERMAN ) ) ;
manifest . RemoveAll ( va ( " strings/%s " , ID_LANG_SPANISH ) ) ;
manifest . RemoveAll ( va ( " strings/%s " , ID_LANG_JAPANESE ) ) ;
manifests . Append ( manifest ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idList < idPreloadManifest > preloadManifests ; // list of all preload manifest files
// load all preload manifests
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < preloadFiles . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
idStr path = " maps/ " ;
path + = preloadFiles [ i ] ;
2012-11-28 15:47:07 +00:00
if ( path . Find ( " _startup " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
idPreloadManifest preload ;
2012-11-28 15:47:07 +00:00
if ( preload . LoadManifest ( path ) )
{
2012-11-26 18:58:24 +00:00
preloadManifests . Append ( preload ) ;
//preload.Print();
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// build common list of files
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < manifests . Num ( ) ; i + + )
{
idFileManifest & manifest = manifests [ i ] ;
for ( int j = 0 ; j < manifest . NumFiles ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
idStr name = manifest . GetFileNameByIndex ( j ) ;
2012-11-28 15:47:07 +00:00
if ( name . CheckExtension ( " .cfg " ) | | ( name . Find ( " .lang " , false ) > = 0 ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( FileExistsInAllManifests ( name , manifests ) )
{
2012-11-26 18:58:24 +00:00
filesCommonToAllMaps . AddUnique ( name ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
filesNotCommonToAllMaps . AddUnique ( name ) ;
}
}
}
2012-11-28 15:47:07 +00:00
// common list of preload reosurces, image, sample or models
for ( int i = 0 ; i < preloadManifests . Num ( ) ; i + + )
{
idPreloadManifest & preload = preloadManifests [ i ] ;
for ( int j = 0 ; j < preload . NumResources ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
idStr name = preload . GetResourceNameByIndex ( j ) ;
2012-11-28 15:47:07 +00:00
if ( FileExistsInAllPreloadManifests ( name , preloadManifests ) )
{
2012-11-26 18:58:24 +00:00
commonPreloads . Add ( preload . GetPreloadByIndex ( j ) ) ;
idLib : : Printf ( " Common preload added %s \n " , name . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " preload missed %s \n " , name . c_str ( ) ) ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
AddRenderProgs ( filesCommonToAllMaps ) ;
AddFonts ( filesCommonToAllMaps ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrList work ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// remove all common files from each map manifest
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < manifests . Num ( ) ; i + + )
{
if ( ( strstr ( manifests [ i ] . GetManifestName ( ) , " _startup " ) ! = NULL ) | | ( strstr ( manifests [ i ] . GetManifestName ( ) , " _pc " ) ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
//idLib::Printf( "%04d referenced files for %s\n", manifests[ i ].GetReferencedFileCount(), manifests[ i ].GetManifestName() );
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < filesCommonToAllMaps . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
manifests [ i ] . RemoveAll ( filesCommonToAllMaps [ j ] ) ;
}
//idLib::Printf( "%04d referenced files for %s\n", manifests[ i ].GetReferencedFileCount(), manifests[ i ].GetManifestName() );
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrList commonImages ( 2048 ) ;
idStrList commonModels ( 2048 ) ;
idStrList commonAnims ( 2048 ) ;
idStrList commonCollision ( 2048 ) ;
idStrList soundFiles ( 2048 ) ; // don't write these per map so we fit on disc
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < manifests . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
idStr resourceFileName = manifests [ i ] . GetManifestName ( ) ;
2012-11-28 15:47:07 +00:00
if ( resourceFileName . Find ( " _startup.manifest " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
// add all the startup manifest files to the common list
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < manifests [ i ] . NumFiles ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
idStr check = manifests [ i ] . GetFileNameByIndex ( j ) ;
2012-11-28 15:47:07 +00:00
if ( check . CheckExtension ( " .cfg " ) = = false )
{
2012-11-26 18:58:24 +00:00
filesCommonToAllMaps . AddUnique ( check . c_str ( ) ) ;
}
}
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStaticList < idStr , 16384 > mapFiles ; // map files from the manifest, these are static for easy debugging
idStaticList < idStr , 16384 > mapFilesTwo ; // accumulates non bimage, bmodel and sample files
commonImages . Clear ( ) ; // collect images and models separately so they can be added in linear preload order
commonModels . Clear ( ) ;
commonAnims . Clear ( ) ;
commonCollision . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
manifests [ i ] . PopulateList ( mapFiles ) ;
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < mapFiles . Num ( ) ; j + + )
{
idStr & resName = mapFiles [ j ] ;
if ( resName . Find ( " .bimage " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
commonImages . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( IsBinaryModel ( resName ) )
{
2012-11-26 18:58:24 +00:00
commonModels . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( IsSoundSample ( resName ) )
{
2012-11-26 18:58:24 +00:00
soundFiles . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( resName . Find ( " .bik " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
// don't add bik files
continue ;
}
2012-11-28 15:47:07 +00:00
if ( resName . Find ( " .bmd5anim " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
commonAnims . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( resName . Find ( " .bcmodel " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
commonCollision . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( resName . Find ( " .lang " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
mapFilesTwo . AddUnique ( resName ) ;
}
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < commonImages . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
mapFilesTwo . AddUnique ( commonImages [ j ] ) ;
}
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < commonModels . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
mapFilesTwo . AddUnique ( commonModels [ j ] ) ;
}
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < commonAnims . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
mapFilesTwo . AddUnique ( commonAnims [ j ] ) ;
}
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < commonCollision . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
mapFilesTwo . AddUnique ( commonCollision [ j ] ) ;
}
// write map resources
idStrList mapFilesToWrite ;
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < mapFilesTwo . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
mapFilesToWrite . Append ( mapFilesTwo [ j ] ) ;
}
idResourceContainer : : WriteResourceFile ( resourceFileName , mapFilesToWrite , false ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add the new manifests just written
path = RelativePathToOSPath ( " maps " , " fs_savepath " ) ;
ListOSFiles ( path , " *.preload " , work ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < work . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
filesCommonToAllMaps . Append ( idStr ( " maps/ " ) + work [ i ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
filesCommonToAllMaps . Append ( " _common.preload " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// write out common models, images and sounds to separate containers
//idStrList commonSounds( 2048 );
commonImages . Clear ( ) ;
commonModels . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrList commonFiles ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < filesCommonToAllMaps . Num ( ) ; i + + )
{
idStr & resName = filesCommonToAllMaps [ i ] ;
if ( resName . Find ( " .bimage " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
commonImages . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( IsBinaryModel ( resName ) )
{
2012-11-26 18:58:24 +00:00
commonModels . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( IsSoundSample ( resName ) )
{
2012-11-26 18:58:24 +00:00
soundFiles . AddUnique ( resName ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
if ( resName . Find ( " .bik " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
// no bik files in the .resource
continue ;
}
2012-11-28 15:47:07 +00:00
if ( resName . Find ( " .lang " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
// no bik files in the .resource
continue ;
}
commonFiles . AddUnique ( resName ) ;
}
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < commonImages . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
commonFiles . AddUnique ( commonImages [ j ] ) ;
}
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < commonModels . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
commonFiles . AddUnique ( commonModels [ j ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//idResourceContainer::WriteResourceFile( "_common_images", commonImages );
//idResourceContainer::WriteResourceFile( "_common_models", commonModels );
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
commonPreloads . WriteManifest ( " _common.preload " ) ;
idResourceContainer : : WriteResourceFile ( " _common " , commonFiles , false ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idList < idStrList > soundOutputFiles ;
soundOutputFiles . SetNum ( 16 ) ;
2012-11-28 15:47:07 +00:00
struct soundVOInfo_t
{
const char * filename ;
const char * voqualifier ;
idStrList * samples ;
2012-11-26 18:58:24 +00:00
} ;
2012-11-28 15:47:07 +00:00
const soundVOInfo_t soundFileInfo [ ] =
{
2012-11-26 18:58:24 +00:00
{ " fr " , " sound/vo/french/ " , & soundOutputFiles [ 0 ] } ,
{ " it " , " sound/vo/italian/ " , & soundOutputFiles [ 1 ] } ,
{ " gr " , " sound/vo/german/ " , & soundOutputFiles [ 2 ] } ,
{ " sp " , " sound/vo/spanish/ " , & soundOutputFiles [ 3 ] } ,
{ " jp " , " sound/vo/japanese/ " , & soundOutputFiles [ 4 ] } ,
{ " en " , " sound/vo/ " , & soundOutputFiles [ 5 ] } // english last so the other langs are culled first
} ;
2012-11-28 15:47:07 +00:00
const int numSoundFiles = sizeof ( soundFileInfo ) / sizeof ( soundVOInfo_t ) ;
for ( int k = soundFiles . Num ( ) - 1 ; k > 0 ; k - - )
{
for ( int l = 0 ; l < numSoundFiles ; l + + )
{
if ( soundFiles [ k ] . Find ( soundFileInfo [ l ] . voqualifier , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
soundFileInfo [ l ] . samples - > AddUnique ( soundFiles [ k ] ) ;
soundFiles . RemoveIndex ( k ) ;
}
}
}
2012-11-28 15:47:07 +00:00
for ( int k = 0 ; k < numSoundFiles ; k + + )
{
idStrList & sampleList = * soundFileInfo [ k ] . samples ;
2012-11-26 18:58:24 +00:00
// write pc
idResourceContainer : : WriteResourceFile ( va ( " _sound_pc_%s " , soundFileInfo [ k ] . filename ) , sampleList , false ) ;
2012-11-28 15:47:07 +00:00
for ( int l = 0 ; l < sampleList . Num ( ) ; l + + )
{
2012-11-26 18:58:24 +00:00
sampleList [ l ] . Replace ( " .idwav " , " .idxma " ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idResourceContainer : : WriteResourceFile ( " _sound_pc " , soundFiles , false ) ;
2012-11-28 15:47:07 +00:00
for ( int k = 0 ; k < soundFiles . Num ( ) ; k + + )
{
2012-11-26 18:58:24 +00:00
soundFiles [ k ] . Replace ( " .idwav " , " .idxma " ) ;
}
2012-11-28 15:47:07 +00:00
for ( int k = 0 ; k < soundFiles . Num ( ) ; k + + )
{
2012-11-26 18:58:24 +00:00
soundFiles [ k ] . Replace ( " .idxma " , " .idmsf " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
BuildOrderedStartupContainer ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ClearResourcePacks ( ) ;
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : CopyFile
Copy a fully specified file from one place to another `
= = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : CopyFile ( const char * fromOSPath , const char * toOSPath )
{
idFile * src = OpenExplicitFileRead ( fromOSPath ) ;
if ( src = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Could not open %s for read " , fromOSPath ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( idStr : : Icmp ( fromOSPath , toOSPath ) = = 0 )
{
2012-11-26 18:58:24 +00:00
// same file can happen during build games
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
CopyFile ( src , toOSPath ) ;
delete src ;
2012-11-28 15:47:07 +00:00
if ( strstr ( fromOSPath , " .wav " ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > newFromPath = fromOSPath ;
idStrStatic < MAX_OSPATH > newToPath = toOSPath ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Copying console samples for %s \n " , newFromPath . c_str ( ) ) ;
newFromPath . SetFileExtension ( " xma " ) ;
newToPath . SetFileExtension ( " xma " ) ;
src = OpenExplicitFileRead ( newFromPath ) ;
2012-11-28 15:47:07 +00:00
if ( src = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Could not open %s for read " , newFromPath . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
CopyFile ( src , newToPath ) ;
delete src ;
src = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
newFromPath . SetFileExtension ( " msf " ) ;
newToPath . SetFileExtension ( " msf " ) ;
src = OpenExplicitFileRead ( newFromPath ) ;
2012-11-28 15:47:07 +00:00
if ( src = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Could not open %s for read " , newFromPath . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
CopyFile ( src , newToPath ) ;
delete src ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
newFromPath . BackSlashesToSlashes ( ) ;
newFromPath . ToLower ( ) ;
2012-11-28 15:47:07 +00:00
if ( newFromPath . Find ( " /vo/ " , false ) > = 0 )
{
for ( int i = 0 ; i < Sys_NumLangs ( ) ; i + + )
{
const char * lang = Sys_Lang ( i ) ;
if ( idStr : : Icmp ( lang , ID_LANG_ENGLISH ) = = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
newFromPath = fromOSPath ;
newToPath = toOSPath ;
newFromPath . BackSlashesToSlashes ( ) ;
newFromPath . ToLower ( ) ;
newToPath . BackSlashesToSlashes ( ) ;
newToPath . ToLower ( ) ;
newFromPath . Replace ( " /vo/ " , va ( " /vo/%s/ " , lang ) ) ;
newToPath . Replace ( " /vo/ " , va ( " /vo/%s/ " , lang ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
src = OpenExplicitFileRead ( newFromPath ) ;
2012-11-28 15:47:07 +00:00
if ( src = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " LOCALIZATION PROBLEM: Could not open %s for read " , newFromPath . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
CopyFile ( src , newToPath ) ;
delete src ;
src = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
newFromPath . SetFileExtension ( " xma " ) ;
newToPath . SetFileExtension ( " xma " ) ;
src = OpenExplicitFileRead ( newFromPath ) ;
2012-11-28 15:47:07 +00:00
if ( src = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " LOCALIZATION PROBLEM: Could not open %s for read " , newFromPath . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
CopyFile ( src , newToPath ) ;
delete src ;
src = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
newFromPath . SetFileExtension ( " msf " ) ;
newToPath . SetFileExtension ( " msf " ) ;
src = OpenExplicitFileRead ( newFromPath ) ;
2012-11-28 15:47:07 +00:00
if ( src = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " LOCALIZATION PROBLEM: Could not open %s for read " , newFromPath . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
CopyFile ( src , newToPath ) ;
delete src ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
}
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : CopyFile
= = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : CopyFile ( idFile * src , const char * toOSPath )
{
idFile * dst = OpenExplicitFileWrite ( toOSPath ) ;
if ( dst = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Could not open %s for write " , toOSPath ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > Printf ( " copy %s to %s \n " , src - > GetName ( ) , toOSPath ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int len = src - > Length ( ) ;
int copied = 0 ;
2012-11-28 15:47:07 +00:00
while ( copied < len )
{
2012-11-26 18:58:24 +00:00
byte buffer [ 4096 ] ;
int read = src - > Read ( buffer , Min ( 4096 , len - copied ) ) ;
2012-11-28 15:47:07 +00:00
if ( read < = 0 )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Copy failed during read " ) ;
break ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
int written = dst - > Write ( buffer , read ) ;
2012-11-28 15:47:07 +00:00
if ( written < read )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Copy failed during write " ) ;
break ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
copied + = written ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
delete dst ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : ReplaceSeparators
Fix things up differently for win / unix / mac
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : ReplaceSeparators ( idStr & path , char sep )
{
char * s ;
for ( s = & path [ 0 ] ; * s ; s + + )
{
if ( * s = = ' / ' | | * s = = ' \\ ' )
{
2012-11-26 18:58:24 +00:00
* s = sep ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
IsOSPath
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
static bool IsOSPath ( const char * path )
{
2012-11-26 18:58:24 +00:00
assert ( path ) ;
2012-11-28 15:47:07 +00:00
if ( idStr : : Icmpn ( path , " mtp: " , 4 ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
if ( idStr : : Length ( path ) > = 2 )
{
if ( path [ 1 ] = = ' : ' )
{
if ( ( path [ 0 ] > 64 & & path [ 0 ] < 91 ) | | ( path [ 0 ] > 96 & & path [ 0 ] < 123 ) )
{
2012-11-26 18:58:24 +00:00
// already an OS path starting with a drive.
return true ;
}
}
2012-11-28 15:47:07 +00:00
if ( path [ 0 ] = = ' \\ ' | | path [ 0 ] = = ' / ' )
{
2012-11-26 18:58:24 +00:00
// a root path
return true ;
}
}
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : BuildOSPath
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idFileSystemLocal : : BuildOSPath ( const char * base , const char * relativePath )
{
2012-11-26 18:58:24 +00:00
// handle case of this already being an OS path
2012-11-28 15:47:07 +00:00
if ( IsOSPath ( relativePath ) )
{
2012-11-26 18:58:24 +00:00
return relativePath ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return BuildOSPath ( base , gameFolder , relativePath ) ;
}
/*
= = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : BuildOSPath
= = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idFileSystemLocal : : BuildOSPath ( const char * base , const char * game , const char * relativePath )
{
2012-11-26 18:58:24 +00:00
static char OSPath [ MAX_STRING_CHARS ] ;
idStr newPath ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// handle case of this already being an OS path
2012-11-28 15:47:07 +00:00
if ( IsOSPath ( relativePath ) )
{
2012-11-26 18:58:24 +00:00
return relativePath ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr strBase = base ;
strBase . StripTrailing ( ' / ' ) ;
strBase . StripTrailing ( ' \\ ' ) ;
sprintf ( newPath , " %s/%s/%s " , strBase . c_str ( ) , game , relativePath ) ;
ReplaceSeparators ( newPath ) ;
idStr : : Copynz ( OSPath , newPath , sizeof ( OSPath ) ) ;
return OSPath ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : OSPathToRelativePath
takes a full OS path , as might be found in data from a media creation
program , and converts it to a relativePath by stripping off directories
Returns false if the osPath tree doesn ' t match any of the existing
search paths .
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idFileSystemLocal : : OSPathToRelativePath ( const char * OSPath )
{
if ( ( OSPath [ 0 ] ! = ' / ' ) & & ( OSPath [ 0 ] ! = ' \\ ' ) & & ( idStr : : FindChar ( OSPath , ' : ' ) < 0 ) )
{
2012-11-26 18:58:24 +00:00
// No colon and it doesn't start with a slash... it must already be a relative path
return OSPath ;
}
idStaticList < idStrStatic < 32 > , 5 > basePaths ;
basePaths . Append ( " base " ) ;
basePaths . Append ( " d3xp " ) ;
basePaths . Append ( " d3le " ) ;
2012-11-28 15:47:07 +00:00
if ( fs_game . GetString ( ) [ 0 ] ! = 0 )
{
2012-11-26 18:58:24 +00:00
basePaths . Append ( fs_game . GetString ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( fs_game_base . GetString ( ) [ 0 ] ! = 0 )
{
2012-11-26 18:58:24 +00:00
basePaths . Append ( fs_game_base . GetString ( ) ) ;
}
idStaticList < int , MAX_OSPATH > slashes ;
2012-11-28 15:47:07 +00:00
for ( const char * s = OSPath ; * s ! = 0 ; s + + )
{
if ( * s = = ' / ' | | * s = = ' \\ ' )
{
2012-11-26 18:58:24 +00:00
slashes . Append ( s - OSPath ) ;
}
}
2012-11-28 15:47:07 +00:00
for ( int n = 0 ; n < slashes . Num ( ) - 1 ; n + + )
{
const char * start = OSPath + slashes [ n ] + 1 ;
const char * end = OSPath + slashes [ n + 1 ] ;
2012-11-26 18:58:24 +00:00
int componentLength = end - start ;
2012-11-28 15:47:07 +00:00
if ( componentLength = = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < basePaths . Num ( ) ; i + + )
{
if ( componentLength ! = basePaths [ i ] . Length ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( basePaths [ i ] . Icmpn ( start , componentLength ) = = 0 )
{
2012-11-26 18:58:24 +00:00
// There are some files like:
// W:\d3xp\base\...
// But we can't search backwards because there are others like:
// W:\doom3\base\models\mapobjects\base\...
// So instead we check for 2 base paths next to each other and take the 2nd in that case
2012-11-28 15:47:07 +00:00
if ( n < slashes . Num ( ) - 2 )
{
const char * start2 = OSPath + slashes [ n + 1 ] + 1 ;
const char * end2 = OSPath + slashes [ n + 2 ] ;
2012-11-26 18:58:24 +00:00
int componentLength2 = end2 - start2 ;
2012-11-28 15:47:07 +00:00
if ( componentLength2 > 0 )
{
for ( int j = 0 ; j < basePaths . Num ( ) ; j + + )
{
if ( componentLength2 ! = basePaths [ j ] . Length ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( basePaths [ j ] . Icmpn ( start2 , basePaths [ j ] . Length ( ) ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return end2 + 1 ;
}
}
}
}
return end + 1 ;
}
}
}
idLib : : Warning ( " OSPathToRelativePath failed on %s " , OSPath ) ;
return OSPath ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : RelativePathToOSPath
Returns a fully qualified path that can be used with stdio libraries
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idFileSystemLocal : : RelativePathToOSPath ( const char * relativePath , const char * basePath )
{
const char * path = cvarSystem - > GetCVarString ( basePath ) ;
if ( ! path [ 0 ] )
{
2012-11-26 18:58:24 +00:00
path = fs_savepath . GetString ( ) ;
}
return BuildOSPath ( path , gameFolder , relativePath ) ;
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : RemoveFile
= = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : RemoveFile ( const char * relativePath )
{
2012-11-26 18:58:24 +00:00
idStr OSPath ;
2012-11-28 15:47:07 +00:00
if ( fs_basepath . GetString ( ) [ 0 ] )
{
2012-11-26 18:58:24 +00:00
OSPath = BuildOSPath ( fs_basepath . GetString ( ) , gameFolder , relativePath ) ;
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
// RB begin
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
: : DeleteFile ( OSPath ) ;
2012-12-06 23:09:53 +00:00
# else
remove ( OSPath ) ;
# endif
// RB end
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
OSPath = BuildOSPath ( fs_savepath . GetString ( ) , gameFolder , relativePath ) ;
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
// RB begin
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
: : DeleteFile ( OSPath ) ;
2012-12-06 23:09:53 +00:00
# else
remove ( OSPath ) ;
# endif
// RB end
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : RemoveDir
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idFileSystemLocal : : RemoveDir ( const char * relativePath )
{
2012-11-26 18:58:24 +00:00
bool success = true ;
2012-11-28 15:47:07 +00:00
if ( fs_savepath . GetString ( ) [ 0 ] )
{
2012-11-26 18:58:24 +00:00
success & = Sys_Rmdir ( BuildOSPath ( fs_savepath . GetString ( ) , relativePath ) ) ;
}
success & = Sys_Rmdir ( BuildOSPath ( fs_basepath . GetString ( ) , relativePath ) ) ;
return success ;
}
/*
= = = = = = = = = = = =
idFileSystemLocal : : ReadFile
Filename are relative to the search path
a null buffer will just return the file length and time without loading
timestamp can be NULL if not required
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : ReadFile ( const char * relativePath , void * * buffer , ID_TIME_T * timestamp )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
idFile * f ;
byte * buf ;
2012-11-26 18:58:24 +00:00
int len ;
bool isConfig ;
2012-11-28 15:47:07 +00:00
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
return 0 ;
}
2012-11-28 15:47:07 +00:00
if ( relativePath = = NULL | | ! relativePath [ 0 ] )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " idFileSystemLocal::ReadFile with empty name \n " ) ;
return 0 ;
}
2012-11-28 15:47:07 +00:00
if ( timestamp )
{
2012-11-26 18:58:24 +00:00
* timestamp = FILE_NOT_FOUND_TIMESTAMP ;
}
2012-11-28 15:47:07 +00:00
if ( buffer )
{
2012-11-26 18:58:24 +00:00
* buffer = NULL ;
2012-11-28 15:47:07 +00:00
}
if ( buffer = = NULL & & timestamp ! = NULL & & resourceFiles . Num ( ) > 0 )
{
2012-11-26 18:58:24 +00:00
static idResourceCacheEntry rc ;
int size = 0 ;
2012-11-28 15:47:07 +00:00
if ( GetResourceCacheEntry ( relativePath , rc ) )
{
2012-11-26 18:58:24 +00:00
* timestamp = 0 ;
size = rc . length ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
return size ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
buf = NULL ; // quiet compiler warning
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if this is a .cfg file and we are playing back a journal, read
// it from the journal file
2012-11-28 15:47:07 +00:00
if ( strstr ( relativePath , " .cfg " ) = = relativePath + strlen ( relativePath ) - 4 )
{
2012-11-26 18:58:24 +00:00
isConfig = true ;
2012-11-28 15:47:07 +00:00
if ( eventLoop & & eventLoop - > JournalLevel ( ) = = 2 )
{
2012-11-26 18:58:24 +00:00
int r ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
loadCount + + ;
loadStack + + ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > DPrintf ( " Loading %s from journal file. \n " , relativePath ) ;
len = 0 ;
r = eventLoop - > com_journalDataFile - > Read ( & len , sizeof ( len ) ) ;
2012-11-28 15:47:07 +00:00
if ( r ! = sizeof ( len ) )
{
2012-11-26 18:58:24 +00:00
* buffer = NULL ;
return - 1 ;
}
2012-11-28 15:47:07 +00:00
buf = ( byte * ) Mem_ClearedAlloc ( len + 1 , TAG_IDFILE ) ;
2012-11-26 18:58:24 +00:00
* buffer = buf ;
r = eventLoop - > com_journalDataFile - > Read ( buf , len ) ;
2012-11-28 15:47:07 +00:00
if ( r ! = len )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Read from journalDataFile failed " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// guarantee that it will have a trailing 0 for string operations
buf [ len ] = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return len ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
isConfig = false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// look for it in the filesystem or pack files
f = OpenFileRead ( relativePath , ( buffer ! = NULL ) ) ;
2012-11-28 15:47:07 +00:00
if ( f = = NULL )
{
if ( buffer )
{
2012-11-26 18:58:24 +00:00
* buffer = NULL ;
}
return - 1 ;
}
len = f - > Length ( ) ;
2012-11-28 15:47:07 +00:00
if ( timestamp )
{
2012-11-26 18:58:24 +00:00
* timestamp = f - > Timestamp ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! buffer )
{
2012-11-26 18:58:24 +00:00
CloseFile ( f ) ;
return len ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
loadCount + + ;
loadStack + + ;
2012-11-28 15:47:07 +00:00
buf = ( byte * ) Mem_ClearedAlloc ( len + 1 , TAG_IDFILE ) ;
2012-11-26 18:58:24 +00:00
* buffer = buf ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
f - > Read ( buf , len ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// guarantee that it will have a trailing 0 for string operations
buf [ len ] = 0 ;
CloseFile ( f ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we are journalling and it is a config file, write it to the journal file
2012-11-28 15:47:07 +00:00
if ( isConfig & & eventLoop & & eventLoop - > JournalLevel ( ) = = 1 )
{
2012-11-26 18:58:24 +00:00
common - > DPrintf ( " Writing %s to journal file. \n " , relativePath ) ;
eventLoop - > com_journalDataFile - > Write ( & len , sizeof ( len ) ) ;
eventLoop - > com_journalDataFile - > Write ( buf , len ) ;
eventLoop - > com_journalDataFile - > Flush ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return len ;
}
/*
= = = = = = = = = = = = =
idFileSystemLocal : : FreeFile
= = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : FreeFile ( void * buffer )
{
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! buffer )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " idFileSystemLocal::FreeFile( NULL ) " ) ;
}
loadStack - - ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Mem_Free ( buffer ) ;
}
/*
= = = = = = = = = = = =
idFileSystemLocal : : WriteFile
Filenames are relative to the search path
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : WriteFile ( const char * relativePath , const void * buffer , int size , const char * basePath )
{
idFile * f ;
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! relativePath | | ! buffer )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " idFileSystemLocal::WriteFile: NULL parameter " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
f = idFileSystemLocal : : OpenFileWrite ( relativePath , basePath ) ;
2012-11-28 15:47:07 +00:00
if ( ! f )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Failed to open %s \n " , relativePath ) ;
return - 1 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
size = f - > Write ( buffer , size ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
CloseFile ( f ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return size ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : RenameFile
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idFileSystemLocal : : RenameFile ( const char * relativePath , const char * newName , const char * basePath )
{
const char * path = cvarSystem - > GetCVarString ( basePath ) ;
if ( ! path [ 0 ] )
{
2012-11-26 18:58:24 +00:00
path = fs_savepath . GetString ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr oldOSPath = BuildOSPath ( path , gameFolder , relativePath ) ;
idStr newOSPath = BuildOSPath ( path , gameFolder , newName ) ;
2012-11-28 15:47:07 +00:00
2012-12-06 23:09:53 +00:00
// RB begin
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
// this gives atomic-delete-on-rename, like POSIX rename()
// There is a MoveFileTransacted() on vista and above, not sure if that means there
// is a race condition inside MoveFileEx...
const bool success = ( MoveFileEx ( oldOSPath . c_str ( ) , newOSPath . c_str ( ) , MOVEFILE_REPLACE_EXISTING ) ! = 0 ) ;
2012-11-28 15:47:07 +00:00
if ( ! success )
{
2012-11-26 18:58:24 +00:00
const int err = GetLastError ( ) ;
idLib : : Warning ( " RenameFile( %s, %s ) error %i " , newOSPath . c_str ( ) , oldOSPath . c_str ( ) , err ) ;
}
2012-12-06 23:09:53 +00:00
# else
const bool success = ( rename ( oldOSPath . c_str ( ) , newOSPath . c_str ( ) ) = = 0 ) ;
2012-12-08 17:20:13 +00:00
2012-12-06 23:09:53 +00:00
if ( ! success )
{
const int err = errno ;
idLib : : Warning ( " rename( %s, %s ) error %s " , newOSPath . c_str ( ) , oldOSPath . c_str ( ) , strerror ( errno ) ) ;
}
# endif
// RB end
2012-12-08 17:20:13 +00:00
2012-11-26 18:58:24 +00:00
return success ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : AddUnique
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : AddUnique ( const char * name , idStrList & list , idHashIndex & hashIndex ) const
{
2012-11-26 18:58:24 +00:00
int i , hashKey ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
hashKey = hashIndex . GenerateKey ( name ) ;
2012-11-28 15:47:07 +00:00
for ( i = hashIndex . First ( hashKey ) ; i > = 0 ; i = hashIndex . Next ( i ) )
{
if ( list [ i ] . Icmp ( name ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return i ;
}
}
i = list . Append ( name ) ;
hashIndex . Add ( hashKey , i ) ;
return i ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : GetExtensionList
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : GetExtensionList ( const char * extension , idStrList & extensionList ) const
{
2012-11-26 18:58:24 +00:00
int s , e , l ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
l = idStr : : Length ( extension ) ;
s = 0 ;
2012-11-28 15:47:07 +00:00
while ( 1 )
{
2012-11-26 18:58:24 +00:00
e = idStr : : FindChar ( extension , ' | ' , s , l ) ;
2012-11-28 15:47:07 +00:00
if ( e ! = - 1 )
{
2012-11-26 18:58:24 +00:00
extensionList . Append ( idStr ( extension , s , e ) ) ;
s = e + 1 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
extensionList . Append ( idStr ( extension , s , l ) ) ;
break ;
}
}
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : GetFileList
Does not clear the list first so this can be used to progressively build a file list .
When ' sort ' is true only the new files added to the list are sorted .
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : GetFileList ( const char * relativePath , const idStrList & extensions , idStrList & list , idHashIndex & hashIndex , bool fullRelativePath , const char * gamedir )
{
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! extensions . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
if ( ! relativePath )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int pathLength = strlen ( relativePath ) ;
2012-11-28 15:47:07 +00:00
if ( pathLength )
{
2012-11-26 18:58:24 +00:00
pathLength + + ; // for the trailing '/'
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > strippedName ;
2012-11-28 15:47:07 +00:00
if ( resourceFiles . Num ( ) > 0 )
{
2012-11-26 18:58:24 +00:00
int idx = resourceFiles . Num ( ) - 1 ;
2012-11-28 15:47:07 +00:00
while ( idx > = 0 )
{
for ( int i = 0 ; i < resourceFiles [ idx ] - > cacheTable . Num ( ) ; i + + )
{
idResourceCacheEntry & rt = resourceFiles [ idx ] - > cacheTable [ i ] ;
2012-11-26 18:58:24 +00:00
// if the name is not long anough to at least contain the path
2012-11-28 15:47:07 +00:00
if ( rt . filename . Length ( ) < = pathLength )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check for a path match without the trailing '/'
2012-11-28 15:47:07 +00:00
if ( pathLength & & idStr : : Icmpn ( rt . filename , relativePath , pathLength - 1 ) ! = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// ensure we have a path, and not just a filename containing the path
2012-11-28 15:47:07 +00:00
if ( rt . filename [ pathLength ] = = ' \0 ' | | rt . filename [ pathLength - 1 ] ! = ' / ' )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// make sure the file is not in a subdirectory
int j = pathLength ;
2012-11-28 15:47:07 +00:00
for ( ; rt . filename [ j + 1 ] ! = ' \0 ' ; j + + )
{
if ( rt . filename [ j ] = = ' / ' )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
if ( rt . filename [ j + 1 ] )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check for extension match
2012-11-28 15:47:07 +00:00
for ( j = 0 ; j < extensions . Num ( ) ; j + + )
{
if ( rt . filename . Length ( ) > = extensions [ j ] . Length ( ) & & extensions [ j ] . Icmp ( rt . filename . c_str ( ) + rt . filename . Length ( ) - extensions [ j ] . Length ( ) ) = = 0 )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
if ( j > = extensions . Num ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// unique the match
2012-11-28 15:47:07 +00:00
if ( fullRelativePath )
{
2012-11-26 18:58:24 +00:00
idStr work = relativePath ;
work + = " / " ;
work + = rt . filename . c_str ( ) + pathLength ;
work . StripTrailing ( ' / ' ) ;
AddUnique ( work , list , hashIndex ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
idStr work = rt . filename . c_str ( ) + pathLength ;
work . StripTrailing ( ' / ' ) ;
AddUnique ( work , list , hashIndex ) ;
}
}
idx - - ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// search through the path, one element at a time, adding to list
2012-11-28 15:47:07 +00:00
for ( int sp = searchPaths . Num ( ) - 1 ; sp > = 0 ; sp - - )
{
if ( gamedir ! = NULL & & gamedir [ 0 ] ! = 0 )
{
if ( searchPaths [ sp ] . gamedir ! = gamedir )
{
2012-11-26 18:58:24 +00:00
continue ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr netpath = BuildOSPath ( searchPaths [ sp ] . path , searchPaths [ sp ] . gamedir , relativePath ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < extensions . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
// scan for files in the filesystem
idStrList sysFiles ;
ListOSFiles ( netpath , extensions [ i ] , sysFiles ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we are searching for directories, remove . and ..
2012-11-28 15:47:07 +00:00
if ( extensions [ i ] [ 0 ] = = ' / ' & & extensions [ i ] [ 1 ] = = 0 )
{
2012-11-26 18:58:24 +00:00
sysFiles . Remove ( " . " ) ;
sysFiles . Remove ( " .. " ) ;
}
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < sysFiles . Num ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
// unique the match
2012-11-28 15:47:07 +00:00
if ( fullRelativePath )
{
2012-11-26 18:58:24 +00:00
idStr work = relativePath ;
work + = " / " ;
work + = sysFiles [ j ] ;
AddUnique ( work , list , hashIndex ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
AddUnique ( sysFiles [ j ] , list , hashIndex ) ;
}
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return list . Num ( ) ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : ListFiles
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFileList * idFileSystemLocal : : ListFiles ( const char * relativePath , const char * extension , bool sort , bool fullRelativePath , const char * gamedir )
{
2012-11-26 18:58:24 +00:00
idHashIndex hashIndex ( 4096 , 4096 ) ;
idStrList extensionList ;
2012-11-28 15:47:07 +00:00
idFileList * fileList = new ( TAG_IDFILE ) idFileList ;
2012-11-26 18:58:24 +00:00
fileList - > basePath = relativePath ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
GetExtensionList ( extension , extensionList ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
GetFileList ( relativePath , extensionList , fileList - > list , hashIndex , fullRelativePath , gamedir ) ;
2012-11-28 15:47:07 +00:00
if ( sort )
{
2012-11-26 18:58:24 +00:00
fileList - > list . SortWithTemplate ( idSort_PathStr ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return fileList ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : GetFileListTree
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : GetFileListTree ( const char * relativePath , const idStrList & extensions , idStrList & list , idHashIndex & hashIndex , const char * gamedir )
{
2012-11-26 18:58:24 +00:00
int i ;
idStrList slash , folders ( 128 ) ;
idHashIndex folderHashIndex ( 1024 , 128 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// recurse through the subdirectories
slash . Append ( " / " ) ;
GetFileList ( relativePath , slash , folders , folderHashIndex , true , gamedir ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < folders . Num ( ) ; i + + )
{
if ( folders [ i ] [ 0 ] = = ' . ' )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( folders [ i ] . Icmp ( relativePath ) = = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
GetFileListTree ( folders [ i ] , extensions , list , hashIndex , gamedir ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// list files in the current directory
GetFileList ( relativePath , extensions , list , hashIndex , true , gamedir ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return list . Num ( ) ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : ListFilesTree
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFileList * idFileSystemLocal : : ListFilesTree ( const char * relativePath , const char * extension , bool sort , const char * gamedir )
{
2012-11-26 18:58:24 +00:00
idHashIndex hashIndex ( 4096 , 4096 ) ;
idStrList extensionList ;
2012-11-28 15:47:07 +00:00
idFileList * fileList = new ( TAG_IDFILE ) idFileList ( ) ;
2012-11-26 18:58:24 +00:00
fileList - > basePath = relativePath ;
fileList - > list . SetGranularity ( 4096 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
GetExtensionList ( extension , extensionList ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
GetFileListTree ( relativePath , extensionList , fileList - > list , hashIndex , gamedir ) ;
2012-11-28 15:47:07 +00:00
if ( sort )
{
2012-11-26 18:58:24 +00:00
fileList - > list . SortWithTemplate ( idSort_PathStr ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return fileList ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : FreeFileList
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : FreeFileList ( idFileList * fileList )
{
2012-11-26 18:58:24 +00:00
delete fileList ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : ListOSFiles
call to the OS for a listing of files in an OS directory
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : ListOSFiles ( const char * directory , const char * extension , idStrList & list )
{
if ( ! extension )
{
2012-11-26 18:58:24 +00:00
extension = " " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return Sys_ListFiles ( directory , extension , list ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : Dir_f
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : Dir_f ( const idCmdArgs & args )
{
2012-11-26 18:58:24 +00:00
idStr relativePath ;
idStr extension ;
2012-11-28 15:47:07 +00:00
idFileList * fileList ;
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
if ( args . Argc ( ) < 2 | | args . Argc ( ) > 3 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " usage: dir <directory> [extension] \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( args . Argc ( ) = = 2 )
{
2012-11-26 18:58:24 +00:00
relativePath = args . Argv ( 1 ) ;
extension = " " ;
}
2012-11-28 15:47:07 +00:00
else
{
2012-11-26 18:58:24 +00:00
relativePath = args . Argv ( 1 ) ;
extension = args . Argv ( 2 ) ;
2012-11-28 15:47:07 +00:00
if ( extension [ 0 ] ! = ' . ' )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " extension should have a leading dot " ) ;
}
}
relativePath . BackSlashesToSlashes ( ) ;
relativePath . StripTrailing ( ' / ' ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > Printf ( " Listing of %s/*%s \n " , relativePath . c_str ( ) , extension . c_str ( ) ) ;
common - > Printf ( " --------------- \n " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileList = fileSystemLocal . ListFiles ( relativePath , extension ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < fileList - > GetNumFiles ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " %s \n " , fileList - > GetFile ( i ) ) ;
}
common - > Printf ( " %d files \n " , fileList - > list . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileSystemLocal . FreeFileList ( fileList ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : DirTree_f
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : DirTree_f ( const idCmdArgs & args )
{
2012-11-26 18:58:24 +00:00
idStr relativePath ;
idStr extension ;
2012-11-28 15:47:07 +00:00
idFileList * fileList ;
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
if ( args . Argc ( ) < 2 | | args . Argc ( ) > 3 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " usage: dirtree <directory> [extension] \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( args . Argc ( ) = = 2 )
{
2012-11-26 18:58:24 +00:00
relativePath = args . Argv ( 1 ) ;
extension = " " ;
}
2012-11-28 15:47:07 +00:00
else
{
2012-11-26 18:58:24 +00:00
relativePath = args . Argv ( 1 ) ;
extension = args . Argv ( 2 ) ;
2012-11-28 15:47:07 +00:00
if ( extension [ 0 ] ! = ' . ' )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " extension should have a leading dot " ) ;
}
}
relativePath . BackSlashesToSlashes ( ) ;
relativePath . StripTrailing ( ' / ' ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > Printf ( " Listing of %s/*%s /s \n " , relativePath . c_str ( ) , extension . c_str ( ) ) ;
common - > Printf ( " --------------- \n " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileList = fileSystemLocal . ListFilesTree ( relativePath , extension ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < fileList - > GetNumFiles ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " %s \n " , fileList - > GetFile ( i ) ) ;
}
common - > Printf ( " %d files \n " , fileList - > list . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileSystemLocal . FreeFileList ( fileList ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : ClearResourcePacks
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : ClearResourcePacks ( )
{
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : BuildGame_f
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : BuildGame_f ( const idCmdArgs & args )
{
2012-11-26 18:58:24 +00:00
fileSystemLocal . WriteResourcePacks ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : WriteResourceFile_f
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : WriteResourceFile_f ( const idCmdArgs & args )
{
if ( args . Argc ( ) ! = 2 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Usage: writeResourceFile <manifest file> \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrList manifest ;
idResourceContainer : : ReadManifestFile ( args . Argv ( 1 ) , manifest ) ;
idResourceContainer : : WriteResourceFile ( args . Argv ( 1 ) , manifest , false ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : UpdateResourceFile_f
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : UpdateResourceFile_f ( const idCmdArgs & args )
{
if ( args . Argc ( ) < 3 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Usage: updateResourceFile <resource file> <files> \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr filename = args . Argv ( 1 ) ;
idStrList filesToAdd ;
2012-11-28 15:47:07 +00:00
for ( int i = 2 ; i < args . Argc ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
filesToAdd . Append ( args . Argv ( i ) ) ;
}
idResourceContainer : : UpdateResourceFile ( filename , filesToAdd ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : ExtractResourceFile_f
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : ExtractResourceFile_f ( const idCmdArgs & args )
{
if ( args . Argc ( ) < 3 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Usage: extractResourceFile <resource file> <outpath> <copysound> \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr filename = args . Argv ( 1 ) ;
idStr outPath = args . Argv ( 2 ) ;
bool copyWaves = ( args . Argc ( ) > 3 ) ;
idResourceContainer : : ExtractResourceFile ( filename , outPath , copyWaves ) ;
}
/*
= = = = = = = = = = = =
idFileSystemLocal : : Path_f
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : Path_f ( const idCmdArgs & args )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Current search path: \n " ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < fileSystemLocal . searchPaths . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " %s/%s \n " , fileSystemLocal . searchPaths [ i ] . path . c_str ( ) , fileSystemLocal . searchPaths [ i ] . gamedir . c_str ( ) ) ;
}
}
/*
= = = = = = = = = = = =
idFileSystemLocal : : TouchFile_f
The only purpose of this function is to allow game script files to copy
arbitrary files furing an " fs_copyfiles 1 " run .
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : TouchFile_f ( const idCmdArgs & args )
{
idFile * f ;
if ( args . Argc ( ) ! = 2 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Usage: touchFile <file> \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
f = fileSystemLocal . OpenFileRead ( args . Argv ( 1 ) ) ;
2012-11-28 15:47:07 +00:00
if ( f )
{
2012-11-26 18:58:24 +00:00
fileSystemLocal . CloseFile ( f ) ;
}
}
/*
= = = = = = = = = = = =
idFileSystemLocal : : TouchFileList_f
Takes a text file and touches every file in it , use one file per line .
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : TouchFileList_f ( const idCmdArgs & args )
{
if ( args . Argc ( ) ! = 2 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Usage: touchFileList <filename> \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
const char * buffer = NULL ;
2012-11-26 18:58:24 +00:00
idParser src ( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ) ;
2012-11-28 15:47:07 +00:00
if ( fileSystem - > ReadFile ( args . Argv ( 1 ) , ( void * * ) & buffer , NULL ) & & buffer )
{
2012-11-26 18:58:24 +00:00
src . LoadMemory ( buffer , strlen ( buffer ) , args . Argv ( 1 ) ) ;
2012-11-28 15:47:07 +00:00
if ( src . IsLoaded ( ) )
{
2012-11-26 18:58:24 +00:00
idToken token ;
2012-11-28 15:47:07 +00:00
while ( src . ReadToken ( & token ) )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " %s \n " , token . c_str ( ) ) ;
const bool captureToImage = false ;
common - > UpdateScreen ( captureToImage ) ;
2012-11-28 15:47:07 +00:00
idFile * f = fileSystemLocal . OpenFileRead ( token ) ;
if ( f )
{
2012-11-26 18:58:24 +00:00
fileSystemLocal . CloseFile ( f ) ;
}
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = =
idFileSystemLocal : : GenerateResourceCRCs_f
Generates a CRC checksum file for each . resources file .
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : GenerateResourceCRCs_f ( const idCmdArgs & args )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Generating CRCs for resource files... \n " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
std : : auto_ptr < idFileList > baseResourceFileList ( fileSystem - > ListFiles ( " . " , " .resources " ) ) ;
2012-11-28 15:47:07 +00:00
if ( baseResourceFileList . get ( ) ! = NULL )
{
CreateCRCsForResourceFileList ( * baseResourceFileList ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
std : : auto_ptr < idFileList > mapResourceFileList ( fileSystem - > ListFilesTree ( " maps " , " .resources " ) ) ;
2012-11-28 15:47:07 +00:00
if ( mapResourceFileList . get ( ) ! = NULL )
{
CreateCRCsForResourceFileList ( * mapResourceFileList ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Done generating CRCs for resource files. \n " ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : CreateCRCsForResourceFileList
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : CreateCRCsForResourceFileList ( const idFileList & list )
{
for ( int fileIndex = 0 ; fileIndex < list . GetNumFiles ( ) ; + + fileIndex )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Processing %s. \n " , list . GetFile ( fileIndex ) ) ;
2012-11-28 15:47:07 +00:00
std : : auto_ptr < idFile_Memory > currentFile ( static_cast < idFile_Memory * > ( fileSystem - > OpenFileReadMemory ( list . GetFile ( fileIndex ) ) ) ) ;
if ( currentFile . get ( ) = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Error reading %s. \n " , list . GetFile ( fileIndex ) ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
uint32 resourceMagic ;
currentFile - > ReadBig ( resourceMagic ) ;
2012-11-28 15:47:07 +00:00
if ( resourceMagic ! = RESOURCE_FILE_MAGIC )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Resource file magic number doesn't match, skipping %s. \n " , list . GetFile ( fileIndex ) ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int tableOffset ;
currentFile - > ReadBig ( tableOffset ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int tableLength ;
currentFile - > ReadBig ( tableLength ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Read in the table
currentFile - > Seek ( tableOffset , FS_SEEK_SET ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int numFileResources ;
currentFile - > ReadBig ( numFileResources ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idList < idResourceCacheEntry > cacheEntries ;
cacheEntries . SetNum ( numFileResources ) ;
2012-11-28 15:47:07 +00:00
for ( int innerFileIndex = 0 ; innerFileIndex < numFileResources ; + + innerFileIndex )
{
2012-11-26 18:58:24 +00:00
cacheEntries [ innerFileIndex ] . Read ( currentFile . get ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// All tables read, now seek to each one and calculate the CRC.
idTempArray < unsigned long > innerFileCRCs ( numFileResources ) ;
2012-11-28 15:47:07 +00:00
for ( int innerFileIndex = 0 ; innerFileIndex < numFileResources ; + + innerFileIndex )
{
const char * innerFileDataBegin = currentFile - > GetDataPtr ( ) + cacheEntries [ innerFileIndex ] . offset ;
2012-11-26 18:58:24 +00:00
innerFileCRCs [ innerFileIndex ] = CRC32_BlockChecksum ( innerFileDataBegin , cacheEntries [ innerFileIndex ] . length ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Get the CRC for all the CRCs.
const unsigned long totalCRC = CRC32_BlockChecksum ( innerFileCRCs . Ptr ( ) , innerFileCRCs . Size ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Write the .crc file corresponding to the .resources file.
idStr crcFilename = list . GetFile ( fileIndex ) ;
crcFilename . SetFileExtension ( " .crc " ) ;
std : : auto_ptr < idFile > crcOutputFile ( fileSystem - > OpenFileWrite ( crcFilename , " fs_basepath " ) ) ;
2012-11-28 15:47:07 +00:00
if ( crcOutputFile . get ( ) = = NULL )
{
2012-12-01 16:41:45 +00:00
// RB: fixed potential crash because of "cannot pass objects of non-trivially-copyable type 'class idStr' through '...'"
idLib : : Printf ( " Error writing CRC file %s. \n " , crcFilename . c_str ( ) ) ;
// RB end
2012-11-26 18:58:24 +00:00
continue ;
}
const uint32 CRC_FILE_MAGIC = 0xCC00CC00 ; // I just made this up, it has no meaning.
const uint32 CRC_FILE_VERSION = 1 ;
crcOutputFile - > WriteBig ( CRC_FILE_MAGIC ) ;
crcOutputFile - > WriteBig ( CRC_FILE_VERSION ) ;
crcOutputFile - > WriteBig ( totalCRC ) ;
crcOutputFile - > WriteBig ( numFileResources ) ;
crcOutputFile - > WriteBigArray ( innerFileCRCs . Ptr ( ) , numFileResources ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : AddResourceFile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : AddResourceFile ( const char * resourceFileName )
{
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > resourceFile = va ( " maps/%s " , resourceFileName ) ;
2012-11-28 15:47:07 +00:00
idResourceContainer * rc = new idResourceContainer ( ) ;
if ( rc - > Init ( resourceFile , resourceFiles . Num ( ) ) )
{
2012-11-26 18:58:24 +00:00
resourceFiles . Append ( rc ) ;
common - > Printf ( " Loaded resource file %s \n " , resourceFile . c_str ( ) ) ;
return resourceFiles . Num ( ) - 1 ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
return - 1 ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : FindResourceFile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idFileSystemLocal : : FindResourceFile ( const char * resourceFileName )
{
for ( int i = 0 ; i < resourceFiles . Num ( ) ; i + + )
{
if ( idStr : : Icmp ( resourceFileName , resourceFiles [ i ] - > GetFileName ( ) ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return i ;
}
}
return - 1 ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : RemoveResourceFileByIndex
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : RemoveResourceFileByIndex ( const int & idx )
{
if ( idx > = 0 & & idx < resourceFiles . Num ( ) )
{
if ( idx > = 0 & & idx < resourceFiles . Num ( ) )
{
2012-11-26 18:58:24 +00:00
delete resourceFiles [ idx ] ;
resourceFiles . RemoveIndex ( idx ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < resourceFiles . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
// fixup any container indexes
resourceFiles [ i ] - > SetContainerIndex ( i ) ;
}
}
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : RemoveMapResourceFile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : RemoveMapResourceFile ( const char * resourceFileName )
{
2012-11-26 18:58:24 +00:00
int idx = FindResourceFile ( va ( " maps/%s " , resourceFileName ) ) ;
2012-11-28 15:47:07 +00:00
if ( idx > = 0 )
{
2012-11-26 18:58:24 +00:00
RemoveResourceFileByIndex ( idx ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : RemoveResourceFile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : RemoveResourceFile ( const char * resourceFileName )
{
2012-11-26 18:58:24 +00:00
int idx = FindResourceFile ( resourceFileName ) ;
2012-11-28 15:47:07 +00:00
if ( idx > = 0 )
{
2012-11-26 18:58:24 +00:00
RemoveResourceFileByIndex ( idx ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : AddGameDirectory
Sets gameFolder , adds the directory to the head of the search paths
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : AddGameDirectory ( const char * path , const char * dir )
{
2012-11-26 18:58:24 +00:00
// check if the search path already exists
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < searchPaths . Num ( ) ; i + + )
{
if ( searchPaths [ i ] . path . Cmp ( path ) = = 0 & & searchPaths [ i ] . gamedir . Cmp ( dir ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
gameFolder = dir ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//
// add the directory to the search path
//
2012-11-28 15:47:07 +00:00
searchpath_t & search = searchPaths . Alloc ( ) ;
2012-11-26 18:58:24 +00:00
search . path = path ;
search . gamedir = dir ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr pakfile = BuildOSPath ( path , dir , " " ) ;
pakfile [ pakfile . Length ( ) - 1 ] = 0 ; // strip the trailing slash
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrList pakfiles ;
ListOSFiles ( pakfile , " .resources " , pakfiles ) ;
pakfiles . SortWithTemplate ( idSort_PathStr ( ) ) ;
2012-11-28 15:47:07 +00:00
if ( pakfiles . Num ( ) > 0 )
{
2012-11-26 18:58:24 +00:00
// resource files present, ignore pak files
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < pakfiles . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
pakfile = pakfiles [ i ] ; //BuildOSPath( path, dir, pakfiles[i] );
2012-11-28 15:47:07 +00:00
idResourceContainer * rc = new idResourceContainer ( ) ;
if ( rc - > Init ( pakfile , resourceFiles . Num ( ) ) )
{
2012-11-26 18:58:24 +00:00
resourceFiles . Append ( rc ) ;
common - > Printf ( " Loaded resource file %s \n " , pakfile . c_str ( ) ) ;
//com_productionMode.SetInteger( 2 );
}
}
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : SetupGameDirectories
Takes care of the correct search order .
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : SetupGameDirectories ( const char * gameName )
{
2012-11-26 18:58:24 +00:00
// setup basepath
2012-11-28 15:47:07 +00:00
if ( fs_basepath . GetString ( ) [ 0 ] )
{
2012-11-26 18:58:24 +00:00
AddGameDirectory ( fs_basepath . GetString ( ) , gameName ) ;
}
// setup savepath
2012-11-28 15:47:07 +00:00
if ( fs_savepath . GetString ( ) [ 0 ] )
{
2012-11-26 18:58:24 +00:00
AddGameDirectory ( fs_savepath . GetString ( ) , gameName ) ;
}
}
2012-11-28 15:47:07 +00:00
const char * cachedStartupFiles [ ] =
{
2012-11-26 18:58:24 +00:00
" game: \\ base \\ video \\ loadvideo.bik "
} ;
2012-11-28 15:47:07 +00:00
const int numStartupFiles = sizeof ( cachedStartupFiles ) / sizeof ( cachedStartupFiles [ 0 ] ) ;
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
const char * cachedNormalFiles [ ] =
{
2012-11-26 18:58:24 +00:00
" game: \\ base \\ _sound_xenon_en.resources " , // these will fail silently on the files that are not on disc
" game: \\ base \\ _sound_xenon_fr.resources " ,
" game: \\ base \\ _sound_xenon_jp.resources " ,
" game: \\ base \\ _sound_xenon_sp.resources " ,
" game: \\ base \\ _sound_xenon_it.resources " ,
" game: \\ base \\ _sound_xenon_gr.resources " ,
" game: \\ base \\ _sound_xenon.resources " ,
" game: \\ base \\ _common.resources " ,
" game: \\ base \\ _ordered.resources " ,
" game: \\ base \\ video \\ mars_rotation.bik " // cache this to save the consumer from hearing SEEK.. SEEK... SEEK.. SEEK SEEEK while at the main menu
2012-11-28 15:47:07 +00:00
} ;
const int numNormalFiles = sizeof ( cachedNormalFiles ) / sizeof ( cachedNormalFiles [ 0 ] ) ;
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
const char * dontCacheFiles [ ] =
{
2012-11-26 18:58:24 +00:00
" game: \\ base \\ maps \\ *.* " , // these will fail silently on the files that are not on disc
" game: \\ base \\ video \\ *.* " ,
" game: \\ base \\ sound \\ *.* " ,
2012-11-28 15:47:07 +00:00
} ;
const int numDontCacheFiles = sizeof ( dontCacheFiles ) / sizeof ( dontCacheFiles [ 0 ] ) ;
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : InitPrecache
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : InitPrecache ( )
{
if ( ! fs_enableBackgroundCaching . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
numFilesOpenedAsCached = 0 ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : ReOpenCacheFiles
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : ReOpenCacheFiles ( )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( ! fs_enableBackgroundCaching . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : Startup
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : Startup ( )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " ------ Initializing File System ------ \n " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
InitPrecache ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
SetupGameDirectories ( BASE_GAMEDIR ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// fs_game_base override
2012-11-28 15:47:07 +00:00
if ( fs_game_base . GetString ( ) [ 0 ] & &
idStr : : Icmp ( fs_game_base . GetString ( ) , BASE_GAMEDIR ) )
{
2012-11-26 18:58:24 +00:00
SetupGameDirectories ( fs_game_base . GetString ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// fs_game override
2012-11-28 15:47:07 +00:00
if ( fs_game . GetString ( ) [ 0 ] & &
idStr : : Icmp ( fs_game . GetString ( ) , BASE_GAMEDIR ) & &
idStr : : Icmp ( fs_game . GetString ( ) , fs_game_base . GetString ( ) ) )
{
2012-11-26 18:58:24 +00:00
SetupGameDirectories ( fs_game . GetString ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add our commands
cmdSystem - > AddCommand ( " dir " , Dir_f , CMD_FL_SYSTEM , " lists a folder " , idCmdSystem : : ArgCompletion_FileName ) ;
cmdSystem - > AddCommand ( " dirtree " , DirTree_f , CMD_FL_SYSTEM , " lists a folder with subfolders " ) ;
cmdSystem - > AddCommand ( " path " , Path_f , CMD_FL_SYSTEM , " lists search paths " ) ;
cmdSystem - > AddCommand ( " touchFile " , TouchFile_f , CMD_FL_SYSTEM , " touches a file " ) ;
cmdSystem - > AddCommand ( " touchFileList " , TouchFileList_f , CMD_FL_SYSTEM , " touches a list of files " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
cmdSystem - > AddCommand ( " buildGame " , BuildGame_f , CMD_FL_SYSTEM , " builds game pak files " ) ;
cmdSystem - > AddCommand ( " writeResourceFile " , WriteResourceFile_f , CMD_FL_SYSTEM , " writes a .resources file from a supplied manifest " ) ;
cmdSystem - > AddCommand ( " extractResourceFile " , ExtractResourceFile_f , CMD_FL_SYSTEM , " extracts to the supplied resource file to the supplied path " ) ;
cmdSystem - > AddCommand ( " updateResourceFile " , UpdateResourceFile_f , CMD_FL_SYSTEM , " updates or appends the supplied files in the supplied resource file " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
cmdSystem - > AddCommand ( " generateResourceCRCs " , GenerateResourceCRCs_f , CMD_FL_SYSTEM , " Generates CRC checksums for all the resource files. " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// print the current search paths
Path_f ( idCmdArgs ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > Printf ( " file system initialized. \n " ) ;
common - > Printf ( " -------------------------------------- \n " ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : Init
Called only at inital startup , not when the filesystem
is resetting due to a game change
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : Init ( )
{
2012-11-26 18:58:24 +00:00
// allow command line parms to override our defaults
// we have to specially handle this, because normal command
// line variable sets don't happen until after the filesystem
// has already been initialized
common - > StartupVariable ( " fs_basepath " ) ;
common - > StartupVariable ( " fs_savepath " ) ;
common - > StartupVariable ( " fs_game " ) ;
common - > StartupVariable ( " fs_game_base " ) ;
common - > StartupVariable ( " fs_copyfiles " ) ;
2012-11-28 15:47:07 +00:00
if ( fs_basepath . GetString ( ) [ 0 ] = = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
fs_basepath . SetString ( Sys_DefaultBasePath ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( fs_savepath . GetString ( ) [ 0 ] = = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
fs_savepath . SetString ( Sys_DefaultSavePath ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// try to start up normally
Startup ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we can't find default.cfg, assume that the paths are
// busted and error out now, rather than getting an unreadable
// graphics screen when the font fails to load
// Dedicated servers can run with no outside files at all
2012-11-28 15:47:07 +00:00
if ( ReadFile ( " default.cfg " , NULL , NULL ) < = 0 )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Couldn't load default.cfg " ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : Restart
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : Restart ( )
{
2012-11-26 18:58:24 +00:00
// free anything we currently have loaded
Shutdown ( true ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Startup ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we can't find default.cfg, assume that the paths are
// busted and error out now, rather than getting an unreadable
// graphics screen when the font fails to load
2012-11-28 15:47:07 +00:00
if ( ReadFile ( " default.cfg " , NULL , NULL ) < = 0 )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Couldn't load default.cfg " ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : Shutdown
Frees all resources and closes all files
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : Shutdown ( bool reloading )
{
2012-11-26 18:58:24 +00:00
gameFolder . Clear ( ) ;
searchPaths . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
resourceFiles . DeleteContents ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
cmdSystem - > RemoveCommand ( " path " ) ;
cmdSystem - > RemoveCommand ( " dir " ) ;
cmdSystem - > RemoveCommand ( " dirtree " ) ;
cmdSystem - > RemoveCommand ( " touchFile " ) ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : IsInitialized
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idFileSystemLocal : : IsInitialized ( ) const
{
2012-11-26 18:58:24 +00:00
return ( searchPaths . Num ( ) ! = 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Opening files
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : GetResourceCacheEntry
Returns false if the entry isn ' t found
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idFileSystemLocal : : GetResourceCacheEntry ( const char * fileName , idResourceCacheEntry & rc )
{
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > canonical ;
2012-11-28 15:47:07 +00:00
if ( strstr ( fileName , " : " ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
// os path, convert to relative? scripts can pass in an OS path
//idLib::Printf( "RESOURCE: os path passed %s\n", fileName );
return NULL ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
canonical = fileName ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
canonical . BackSlashesToSlashes ( ) ;
canonical . ToLower ( ) ;
int idx = resourceFiles . Num ( ) - 1 ;
2012-11-28 15:47:07 +00:00
while ( idx > = 0 )
{
2012-11-26 18:58:24 +00:00
const int key = resourceFiles [ idx ] - > cacheHash . GenerateKey ( canonical , false ) ;
2012-11-28 15:47:07 +00:00
for ( int index = resourceFiles [ idx ] - > cacheHash . GetFirst ( key ) ; index ! = idHashIndex : : NULL_INDEX ; index = resourceFiles [ idx ] - > cacheHash . GetNext ( index ) )
{
idResourceCacheEntry & rt = resourceFiles [ idx ] - > cacheTable [ index ] ;
if ( idStr : : Icmp ( rt . filename , canonical ) = = 0 )
{
2012-11-26 18:58:24 +00:00
rc . filename = rt . filename ;
rc . length = rt . length ;
rc . containerIndex = idx ;
rc . offset = rt . offset ;
return true ;
}
}
idx - - ;
}
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idFileSystemLocal : : GetResourceFile
Returns NULL
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : GetResourceFile ( const char * fileName , bool memFile )
{
if ( resourceFiles . Num ( ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
static idResourceCacheEntry rc ;
2012-11-28 15:47:07 +00:00
if ( GetResourceCacheEntry ( fileName , rc ) )
{
if ( fs_debugResources . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " RES: loading file %s \n " , rc . filename . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
idFile_InnerResource * file = new idFile_InnerResource ( rc . filename , resourceFiles [ rc . containerIndex ] - > resourceFile , rc . offset , rc . length ) ;
if ( file ! = NULL & & ( memFile | | rc . length < = resourceBufferAvailable ) | | rc . length < 8 * 1024 * 1024 )
{
byte * buf = NULL ;
if ( rc . length < resourceBufferAvailable )
{
2012-11-26 18:58:24 +00:00
buf = resourceBufferPtr ;
resourceBufferAvailable = 0 ;
}
2012-11-28 15:47:07 +00:00
else
{
if ( fs_debugResources . GetBool ( ) )
{
idLib : : Printf ( " MEM: Allocating %05d bytes for a resource load \n " , rc . length ) ;
}
buf = ( byte * ) Mem_Alloc ( rc . length , TAG_TEMP ) ;
}
file - > Read ( ( void * ) buf , rc . length ) ;
if ( buf = = resourceBufferPtr )
{
2012-11-26 18:58:24 +00:00
file - > SetResourceBuffer ( buf ) ;
return file ;
2012-11-28 15:47:07 +00:00
}
else
{
idFile_Memory * mfile = new idFile_Memory ( rc . filename , ( const char * ) buf , rc . length ) ;
if ( mfile ! = NULL )
{
2012-11-26 18:58:24 +00:00
mfile - > TakeDataOwnership ( ) ;
delete file ;
return mfile ;
}
}
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
return file ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return NULL ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenFileReadFlags
Finds the file in the search path , following search flag recommendations
Returns filesize and an open FILE pointer .
Used for streaming data out of either a
separate file or a ZIP file .
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenFileReadFlags ( const char * relativePath , int searchFlags , bool allowCopyFiles , const char * gamedir )
{
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
return NULL ;
}
2012-11-28 15:47:07 +00:00
if ( relativePath = = NULL )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " idFileSystemLocal::OpenFileRead: NULL 'relativePath' parameter passed \n " ) ;
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// qpaths are not supposed to have a leading slash
2012-11-28 15:47:07 +00:00
if ( relativePath [ 0 ] = = ' / ' | | relativePath [ 0 ] = = ' \\ ' )
{
2012-11-26 18:58:24 +00:00
relativePath + + ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// make absolutely sure that it can't back up the path.
// The searchpaths do guarantee that something will always
2012-11-28 15:47:07 +00:00
// be prepended, so we don't need to worry about "c:" or "//limbo"
if ( strstr ( relativePath , " .. " ) | | strstr ( relativePath , " :: " ) )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
// edge case
2012-11-28 15:47:07 +00:00
if ( relativePath [ 0 ] = = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
if ( fs_debug . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " FILE DEBUG: opening %s \n " , relativePath ) ;
}
2012-11-28 15:47:07 +00:00
if ( resourceFiles . Num ( ) > 0 & & fs_resourceLoadPriority . GetInteger ( ) = = 1 )
{
idFile * rf = GetResourceFile ( relativePath , ( searchFlags & FSFLAG_RETURN_FILE_MEM ) ! = 0 ) ;
if ( rf ! = NULL )
{
2012-11-26 18:58:24 +00:00
return rf ;
}
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
//
// search through the path, one element at a time
//
2012-11-28 15:47:07 +00:00
if ( searchFlags & FSFLAG_SEARCH_DIRS )
{
for ( int sp = searchPaths . Num ( ) - 1 ; sp > = 0 ; sp - - )
{
if ( gamedir ! = NULL & & gamedir [ 0 ] ! = 0 )
{
if ( searchPaths [ sp ] . gamedir ! = gamedir )
{
2012-11-26 18:58:24 +00:00
continue ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr netpath = BuildOSPath ( searchPaths [ sp ] . path , searchPaths [ sp ] . gamedir , relativePath ) ;
idFileHandle fp = OpenOSFile ( netpath , FS_READ ) ;
2012-11-28 15:47:07 +00:00
if ( ! fp )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
idFile_Permanent * file = new ( TAG_IDFILE ) idFile_Permanent ( ) ;
2012-11-26 18:58:24 +00:00
file - > o = fp ;
file - > name = relativePath ;
file - > fullPath = netpath ;
file - > mode = ( 1 < < FS_READ ) ;
file - > fileSize = DirectFileLength ( file - > o ) ;
2012-11-28 15:47:07 +00:00
if ( fs_debug . GetInteger ( ) )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " idFileSystem::OpenFileRead: %s (found in '%s/%s') \n " , relativePath , searchPaths [ sp ] . path . c_str ( ) , searchPaths [ sp ] . gamedir . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if fs_copyfiles is set
2012-11-28 15:47:07 +00:00
if ( allowCopyFiles )
{
2012-11-26 18:58:24 +00:00
idStr copypath ;
idStr name ;
copypath = BuildOSPath ( fs_savepath . GetString ( ) , searchPaths [ sp ] . gamedir , relativePath ) ;
netpath . ExtractFileName ( name ) ;
copypath . StripFilename ( ) ;
copypath + = PATHSEPARATOR_STR ;
copypath + = name ;
2012-11-28 15:47:07 +00:00
if ( fs_buildResources . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > relativePath = OSPathToRelativePath ( copypath ) ;
relativePath . BackSlashesToSlashes ( ) ;
relativePath . ToLower ( ) ;
2012-11-28 15:47:07 +00:00
if ( IsSoundSample ( relativePath ) )
{
2012-11-26 18:58:24 +00:00
idStrStatic < MAX_OSPATH > samplePath = relativePath ;
samplePath . SetFileExtension ( " idwav " ) ;
2012-11-28 15:47:07 +00:00
if ( samplePath . Find ( " generated/ " ) = = - 1 )
{
2012-11-26 18:58:24 +00:00
samplePath . Insert ( " generated/ " , 0 ) ;
}
fileManifest . AddUnique ( samplePath ) ;
2012-11-28 15:47:07 +00:00
if ( relativePath . Find ( " /vo/ " , false ) > = 0 )
{
2012-11-26 18:58:24 +00:00
// this is vo so add the language variants
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < Sys_NumLangs ( ) ; i + + )
{
const char * lang = Sys_Lang ( i ) ;
if ( idStr : : Icmp ( lang , ID_LANG_ENGLISH ) = = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
samplePath = relativePath ;
samplePath . Replace ( " /vo/ " , va ( " /vo/%s/ " , lang ) ) ;
samplePath . SetFileExtension ( " idwav " ) ;
2012-11-28 15:47:07 +00:00
if ( samplePath . Find ( " generated/ " ) = = - 1 )
{
2012-11-26 18:58:24 +00:00
samplePath . Insert ( " generated/ " , 0 ) ;
}
fileManifest . AddUnique ( samplePath ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
}
else if ( relativePath . Icmpn ( " guis/ " , 5 ) = = 0 )
{
2012-11-26 18:58:24 +00:00
// this is a gui so add the language variants
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < Sys_NumLangs ( ) ; i + + )
{
const char * lang = Sys_Lang ( i ) ;
if ( idStr : : Icmp ( lang , ID_LANG_ENGLISH ) = = 0 )
{
2012-11-26 18:58:24 +00:00
fileManifest . Append ( relativePath ) ;
continue ;
}
idStrStatic < MAX_OSPATH > guiPath = relativePath ;
guiPath . Replace ( " guis/ " , va ( " guis/%s/ " , lang ) ) ;
fileManifest . Append ( guiPath ) ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// never add .amp files
2012-11-28 15:47:07 +00:00
if ( strstr ( relativePath , " .amp " ) = = NULL )
{
2012-11-26 18:58:24 +00:00
fileManifest . Append ( relativePath ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
if ( fs_copyfiles . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
CopyFile ( netpath , copypath ) ;
}
}
2012-11-28 15:47:07 +00:00
if ( searchFlags & FSFLAG_RETURN_FILE_MEM )
{
idFile_Memory * memFile = new ( TAG_IDFILE ) idFile_Memory ( file - > name ) ;
2012-11-26 18:58:24 +00:00
memFile - > SetLength ( file - > fileSize ) ;
2012-11-28 15:47:07 +00:00
file - > Read ( ( void * ) memFile - > GetDataPtr ( ) , file - > fileSize ) ;
2012-11-26 18:58:24 +00:00
delete file ;
memFile - > TakeDataOwnership ( ) ;
return memFile ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return file ;
}
}
2012-11-28 15:47:07 +00:00
if ( resourceFiles . Num ( ) > 0 & & fs_resourceLoadPriority . GetInteger ( ) = = 0 )
{
idFile * rf = GetResourceFile ( relativePath , ( searchFlags & FSFLAG_RETURN_FILE_MEM ) ! = 0 ) ;
if ( rf ! = NULL )
{
2012-11-26 18:58:24 +00:00
return rf ;
}
}
2012-11-28 15:47:07 +00:00
if ( fs_debug . GetInteger ( ) )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " Can't find %s \n " , relativePath ) ;
}
return NULL ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenFileRead
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenFileRead ( const char * relativePath , bool allowCopyFiles , const char * gamedir )
{
2012-11-26 18:58:24 +00:00
return OpenFileReadFlags ( relativePath , FSFLAG_SEARCH_DIRS , allowCopyFiles , gamedir ) ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenFileReadMemory
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenFileReadMemory ( const char * relativePath , bool allowCopyFiles , const char * gamedir )
{
2012-11-26 18:58:24 +00:00
return OpenFileReadFlags ( relativePath , FSFLAG_SEARCH_DIRS | FSFLAG_RETURN_FILE_MEM , allowCopyFiles , gamedir ) ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenFileWrite
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenFileWrite ( const char * relativePath , const char * basePath )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
const char * path ;
2012-11-26 18:58:24 +00:00
idStr OSpath ;
2012-11-28 15:47:07 +00:00
idFile_Permanent * f ;
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
path = cvarSystem - > GetCVarString ( basePath ) ;
2012-11-28 15:47:07 +00:00
if ( ! path [ 0 ] )
{
2012-11-26 18:58:24 +00:00
path = fs_savepath . GetString ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
OSpath = BuildOSPath ( path , gameFolder , relativePath ) ;
2012-11-28 15:47:07 +00:00
if ( fs_debug . GetInteger ( ) )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " idFileSystem::OpenFileWrite: %s \n " , OSpath . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > DPrintf ( " writing to: %s \n " , OSpath . c_str ( ) ) ;
CreateOSPath ( OSpath ) ;
2012-11-28 15:47:07 +00:00
f = new ( TAG_IDFILE ) idFile_Permanent ( ) ;
2012-11-26 18:58:24 +00:00
f - > o = OpenOSFile ( OSpath , FS_WRITE ) ;
2012-11-28 15:47:07 +00:00
if ( ! f - > o )
{
2012-11-26 18:58:24 +00:00
delete f ;
return NULL ;
}
f - > name = relativePath ;
f - > fullPath = OSpath ;
f - > mode = ( 1 < < FS_WRITE ) ;
f - > handleSync = false ;
f - > fileSize = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return f ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenExplicitFileRead
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenExplicitFileRead ( const char * OSPath )
{
idFile_Permanent * f ;
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
if ( fs_debug . GetInteger ( ) )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " idFileSystem::OpenExplicitFileRead: %s \n " , OSPath ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//common->DPrintf( "idFileSystem::OpenExplicitFileRead - reading from: %s\n", OSPath );
2012-11-28 15:47:07 +00:00
f = new ( TAG_IDFILE ) idFile_Permanent ( ) ;
2012-11-26 18:58:24 +00:00
f - > o = OpenOSFile ( OSPath , FS_READ ) ;
2012-11-28 15:47:07 +00:00
if ( ! f - > o )
{
2012-11-26 18:58:24 +00:00
delete f ;
return NULL ;
}
f - > name = OSPath ;
f - > fullPath = OSPath ;
f - > mode = ( 1 < < FS_READ ) ;
f - > handleSync = false ;
f - > fileSize = DirectFileLength ( f - > o ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return f ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenExplicitPakFile
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile_Cached * idFileSystemLocal : : OpenExplicitPakFile ( const char * OSPath )
{
idFile_Cached * f ;
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//if ( fs_debug.GetInteger() ) {
// common->Printf( "idFileSystem::OpenExplicitFileRead: %s\n", OSPath );
//}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//common->DPrintf( "idFileSystem::OpenExplicitFileRead - reading from: %s\n", OSPath );
2012-11-28 15:47:07 +00:00
f = new ( TAG_IDFILE ) idFile_Cached ( ) ;
2012-11-26 18:58:24 +00:00
f - > o = OpenOSFile ( OSPath , FS_READ ) ;
2012-11-28 15:47:07 +00:00
if ( ! f - > o )
{
2012-11-26 18:58:24 +00:00
delete f ;
return NULL ;
}
f - > name = OSPath ;
f - > fullPath = OSPath ;
f - > mode = ( 1 < < FS_READ ) ;
f - > handleSync = false ;
f - > fileSize = DirectFileLength ( f - > o ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return f ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenExplicitFileWrite
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenExplicitFileWrite ( const char * OSPath )
{
idFile_Permanent * f ;
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
if ( fs_debug . GetInteger ( ) )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " idFileSystem::OpenExplicitFileWrite: %s \n " , OSPath ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
common - > DPrintf ( " writing to: %s \n " , OSPath ) ;
CreateOSPath ( OSPath ) ;
2012-11-28 15:47:07 +00:00
f = new ( TAG_IDFILE ) idFile_Permanent ( ) ;
2012-11-26 18:58:24 +00:00
f - > o = OpenOSFile ( OSPath , FS_WRITE ) ;
2012-11-28 15:47:07 +00:00
if ( ! f - > o )
{
2012-11-26 18:58:24 +00:00
delete f ;
return NULL ;
}
f - > name = OSPath ;
f - > fullPath = OSPath ;
f - > mode = ( 1 < < FS_WRITE ) ;
f - > handleSync = false ;
f - > fileSize = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return f ;
}
/*
= = = = = = = = = = =
idFileSystemLocal : : OpenFileAppend
= = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenFileAppend ( const char * relativePath , bool sync , const char * basePath )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
const char * path ;
2012-11-26 18:58:24 +00:00
idStr OSpath ;
2012-11-28 15:47:07 +00:00
idFile_Permanent * f ;
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
path = cvarSystem - > GetCVarString ( basePath ) ;
2012-11-28 15:47:07 +00:00
if ( ! path [ 0 ] )
{
2012-11-26 18:58:24 +00:00
path = fs_savepath . GetString ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
OSpath = BuildOSPath ( path , gameFolder , relativePath ) ;
CreateOSPath ( OSpath ) ;
2012-11-28 15:47:07 +00:00
if ( fs_debug . GetInteger ( ) )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " idFileSystem::OpenFileAppend: %s \n " , OSpath . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
f = new ( TAG_IDFILE ) idFile_Permanent ( ) ;
2012-11-26 18:58:24 +00:00
f - > o = OpenOSFile ( OSpath , FS_APPEND ) ;
2012-11-28 15:47:07 +00:00
if ( ! f - > o )
{
2012-11-26 18:58:24 +00:00
delete f ;
return NULL ;
}
f - > name = relativePath ;
f - > fullPath = OSpath ;
f - > mode = ( 1 < < FS_WRITE ) + ( 1 < < FS_APPEND ) ;
f - > handleSync = sync ;
f - > fileSize = DirectFileLength ( f - > o ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return f ;
}
/*
= = = = = = = = = = = = = = = =
idFileSystemLocal : : OpenFileByMode
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idFile * idFileSystemLocal : : OpenFileByMode ( const char * relativePath , fsMode_t mode )
{
if ( mode = = FS_READ )
{
2012-11-26 18:58:24 +00:00
return OpenFileRead ( relativePath ) ;
}
2012-11-28 15:47:07 +00:00
if ( mode = = FS_WRITE )
{
2012-11-26 18:58:24 +00:00
return OpenFileWrite ( relativePath ) ;
}
2012-11-28 15:47:07 +00:00
if ( mode = = FS_APPEND )
{
2012-11-26 18:58:24 +00:00
return OpenFileAppend ( relativePath , true ) ;
}
common - > FatalError ( " idFileSystemLocal::OpenFileByMode: bad mode " ) ;
return NULL ;
}
/*
= = = = = = = = = = = = = =
idFileSystemLocal : : CloseFile
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : CloseFile ( idFile * f )
{
if ( ! IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
common - > FatalError ( " Filesystem call made without initialization \n " ) ;
}
delete f ;
}
/*
= = = = = = = = = = = = = = = = =
idFileSystemLocal : : FindDLL
= = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idFileSystemLocal : : FindDLL ( const char * name , char _dllPath [ MAX_OSPATH ] )
{
2012-11-26 18:58:24 +00:00
char dllName [ MAX_OSPATH ] ;
sys - > DLL_GetFileName ( name , dllName , MAX_OSPATH ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// from executable directory first - this is handy for developement
idStr dllPath = Sys_EXEPath ( ) ;
dllPath . StripFilename ( ) ;
dllPath . AppendPath ( dllName ) ;
2012-11-28 15:47:07 +00:00
idFile * dllFile = OpenExplicitFileRead ( dllPath ) ;
if ( dllFile )
{
2012-11-26 18:58:24 +00:00
dllPath = dllFile - > GetFullPath ( ) ;
CloseFile ( dllFile ) ;
dllFile = NULL ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
dllPath = " " ;
}
idStr : : snPrintf ( _dllPath , MAX_OSPATH , dllPath . c_str ( ) ) ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : FindFile
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
findFile_t idFileSystemLocal : : FindFile ( const char * path )
{
idFile * f = OpenFileReadFlags ( path , FSFLAG_SEARCH_DIRS ) ;
if ( f = = NULL )
{
2012-11-26 18:58:24 +00:00
return FIND_NO ;
}
delete f ;
return FIND_YES ;
}
/*
= = = = = = = = = = = = = = =
idFileSystemLocal : : IsFolder
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
sysFolder_t idFileSystemLocal : : IsFolder ( const char * relativePath , const char * basePath )
{
2012-11-26 18:58:24 +00:00
return Sys_IsFolder ( RelativePathToOSPath ( relativePath , basePath ) ) ;
}