This commit is contained in:
2025-05-25 23:37:40 +03:00
commit 7f054e2904
79 changed files with 4850 additions and 0 deletions

210
engine/filesystem.cpp Normal file
View File

@@ -0,0 +1,210 @@
#include "tier0/platform.h"
#include "tier1/commandline.h"
#include "filesystem.h"
#include "unistd.h"
#include <cstdio>
#define BASEDIR "rtt"
#define GAMEDIR "funnygame"
struct PackHeader_t
{
char id[8];
unsigned long long offset;
unsigned long long size;
};
struct PackDirectory_t
{
char name[56];
unsigned long long offset;
unsigned long long size;
};
struct Pack_t
{
FILE* handle;
PackHeader_t header;
CUtlVector<PackDirectory_t> files;
};
struct FileDirectory_t
{
CUtlString path;
Pack_t pack;
};
CUtlString fs_basedir;
CUtlString fs_gamedir;
CUtlSelfReferencingVector<FileDirectory_t> fs_directories;
class CFileSystem: public IFileSystem
{
public:
static void AddDirectory( const char *psz );
static void AddFile( const char *psz );
};
void IFileSystem::InitFilesystem()
{
fs_basedir = ICommandLine::ParamValue("-basedir");
if ( fs_basedir == 0 )
fs_basedir=BASEDIR;
if ( fs_basedir.GetString()[0] == '-' )
fs_basedir=BASEDIR;
fs_gamedir = ICommandLine::ParamValue("-gamedir");
if ( fs_gamedir == 0 )
fs_gamedir=GAMEDIR;
if ( fs_gamedir.GetString()[0] == '-' )
fs_gamedir=GAMEDIR;
AddGameDirectory(fs_gamedir);
}
void CFileSystem::AddFile( const char *psz )
{
CUtlString extension = Plat_GetExtension(psz);
if (extension=="pak")
{
IFileSystem::LoadPackFile(psz);
};
}
void IFileSystem::AddGameDirectory( const char *psz )
{
FileDirectory_t dir = {};
dir.path = psz;
fs_directories.AppendTail(dir);
Plat_ListDirRecursive(psz, CFileSystem::AddFile, 0);
for (auto &dir: fs_directories)
{
V_printf("%s\n",(char*)dir.path);
};
};
bool IFileSystem::LoadPackFile( const char *szFilename )
{
Pack_t pack = {};
PackHeader_t header = {};
unsigned long long nNumFiles = 0;
PackDirectory_t *pDirs = NULL;
FILE* f = V_fopen(szFilename, "r");
if (!f)
Plat_FatalErrorFunc("Failed to open %s",szFilename);
V_fread(&header,1,sizeof(header),f);
// check for rttpacku
if (
header.id[0]!='r' || header.id[1] != 't' || header.id[2] != 't' || header.id[3]!='p' ||
header.id[4]!='a' || header.id[5] != 'c' || header.id[6] != 'k' || header.id[7]!='u'
)
{
Plat_FatalErrorFunc("%s is not a pack file",szFilename);
}
nNumFiles = header.size/sizeof(PackDirectory_t);
pDirs = (PackDirectory_t*)V_malloc(header.size);
V_fseek(f, header.offset, SEEK_SET);
V_fread(pDirs, sizeof(PackDirectory_t), nNumFiles, f);
pack.header = header;
pack.handle = f;
pack.files = CUtlVector<PackDirectory_t>(nNumFiles);
V_memcpy(pack.files.GetData(),pDirs, header.size);
for (auto &i: pack.files)
{
V_printf(" LOADED %s\n",i.name);
}
V_free(pDirs);
nNumFiles = header.size/sizeof(PackDirectory_t);
FileDirectory_t fd = {};
fd.path = szFilename;
fd.pack = pack;
fs_directories.AppendTail(fd);
return true;
}
void IFileSystem::CreatePath( const char *szPath )
{
}
FileHandle_t IFileSystem::Open( const char *szFilename, EFileOptions options )
{
if (options == IFILE_READ)
{
FILE *file = V_fopen(szFilename, "rb");
/* found in fs */
if ( file != NULL )
{
FileHandle_t filehandle = new FileHandle_s;
filehandle->file = file;
filehandle->nPtr = 0;
filehandle->options = IFILE_READ;
/* get size */
V_fseek(file, 0, SEEK_END);
filehandle->nSize = V_ftell(file);
V_fseek(file, 0, SEEK_SET);
return filehandle;
}
/* not found in fs, try to search in packs */
for ( auto &pak: fs_directories )
{
for ( auto &file: pak.pack.files )
{
if ( !strncmp(file.name, szFilename, 56) )
{
FileHandle_t filehandle = new FileHandle_s;
filehandle->file = 0;
filehandle->parent = pak.pack.handle;
filehandle->nSize = file.size;
filehandle->nOffset = file.offset;
filehandle->nPtr = 0;
filehandle->options = IFILE_READ;
return filehandle;
}
}
};
}
return 0;
}
void IFileSystem::Close( FileHandle_t file )
{
/* close only fs files */
if (file->file)
{
V_fclose(file->file);
}
delete file;
}
size_t IFileSystem::Size( FileHandle_t file )
{
return file->nSize;
}
size_t IFileSystem::Read( FileHandle_t file, void *pOutput, size_t nSize)
{
if (file->file)
{
size_t readsize = V_fread(pOutput, 1, nSize, file->file);
file->nPtr+=readsize;
return readsize;
}
size_t readsize = V_fseek(file->parent, file->nOffset, file->nPtr);
V_fread(pOutput, 1, nSize, file->parent);
return readsize;
}
size_t IFileSystem::ReadLine( FileHandle_t file, void *pOutput, size_t nSize)
{
}
size_t IFileSystem::Write( FileHandle_t file, void *pInput, size_t nSize)
{
}