XDG home directory support
This commit is contained in:
parent
da4f9bd13d
commit
0ebf1df742
32
README.md
32
README.md
|
|
@ -202,6 +202,31 @@ set using command line arguments:
|
||||||
ioquake3 +set cl_renderer opengl2 +set r_preferOpenGLES 1
|
ioquake3 +set cl_renderer opengl2 +set r_preferOpenGLES 1
|
||||||
|
|
||||||
|
|
||||||
|
# Filesystem
|
||||||
|
|
||||||
|
Compared to the original release, user configuration and data files are stored
|
||||||
|
in more modern locations. If you want a different behaviour a specific path
|
||||||
|
can be provided by adding `+set fs_homepath <path>` to the command line.
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
`C:\Users\<username>\AppData\Roaming\Quake3`
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
`/Users/<username>/Library/Application Support/Quake3`
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
`/home/<username>/.config/Quake3` Configuration files.
|
||||||
|
`/home/<username>/.local/share/Quake3` Data files (pk3s etc.).
|
||||||
|
`/home/<username>/.local/state/Quake3` Other internal runtime files.
|
||||||
|
|
||||||
|
These directories correspond to the Free Desktop XDG Base Directory
|
||||||
|
Specification. The original release used `/home/.q3a`. This will be used if
|
||||||
|
present, however in this case a prompt will be shown suggesting migration to
|
||||||
|
the above locations, if desired.
|
||||||
|
|
||||||
# Console
|
# Console
|
||||||
|
|
||||||
## New cvars
|
## New cvars
|
||||||
|
|
@ -480,9 +505,8 @@ binary must not detect any original quake3 game pak files. If this
|
||||||
condition is met, the game will set com_standalone to 1 and is then running
|
condition is met, the game will set com_standalone to 1 and is then running
|
||||||
in stand alone mode.
|
in stand alone mode.
|
||||||
|
|
||||||
If you want the engine to use a different directory in your homepath than
|
If you want the engine to use a different directory in your homepaths than
|
||||||
e.g. "Quake3" on Windows or ".q3a" on Linux, then set a new name at startup
|
"Quake3" then set a new name at startup by adding
|
||||||
by adding
|
|
||||||
|
|
||||||
+set com_homepath <homedirname>
|
+set com_homepath <homedirname>
|
||||||
|
|
||||||
|
|
@ -496,7 +520,7 @@ matching game name.
|
||||||
|
|
||||||
Example line:
|
Example line:
|
||||||
|
|
||||||
+set com_basegame basefoo +set com_homepath .foo
|
+set com_basegame basefoo +set com_homepath foo
|
||||||
+set com_gamename foo
|
+set com_gamename foo
|
||||||
|
|
||||||
If you really changed parts that would make vanilla ioquake3 incompatible with
|
If you really changed parts that would make vanilla ioquake3 incompatible with
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ void Log_Open(char *filename)
|
||||||
botimport.Print(PRT_ERROR, "log file %s is already opened\n", logfile.filename);
|
botimport.Print(PRT_ERROR, "log file %s is already opened\n", logfile.filename);
|
||||||
return;
|
return;
|
||||||
} //end if
|
} //end if
|
||||||
ospath = FS_BuildOSPath(Cvar_VariableString("fs_homepath"), Cvar_VariableString("fs_game"), filename);
|
ospath = FS_BuildOSPath(Cvar_VariableString("fs_homestatepath"), Cvar_VariableString("fs_game"), filename);
|
||||||
logfile.fp = fopen(ospath, "wb");
|
logfile.fp = fopen(ospath, "wb");
|
||||||
if (!logfile.fp)
|
if (!logfile.fp)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -335,10 +335,10 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( afd.f = FS_FOpenFileWrite( fileName ) ) <= 0 )
|
if( ( afd.f = FS_FOpenFileWrite_HomeData( fileName ) ) <= 0 )
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
|
||||||
if( ( afd.idxF = FS_FOpenFileWrite(
|
if( ( afd.idxF = FS_FOpenFileWrite_HomeData(
|
||||||
va( "%s" INDEX_FILE_EXTENSION, fileName ) ) ) <= 0 )
|
va( "%s" INDEX_FILE_EXTENSION, fileName ) ) ) <= 0 )
|
||||||
{
|
{
|
||||||
FS_FCloseFile( afd.f );
|
FS_FCloseFile( afd.f );
|
||||||
|
|
@ -635,7 +635,7 @@ qboolean CL_CloseAVI( void )
|
||||||
FS_FCloseFile( afd.idxF );
|
FS_FCloseFile( afd.idxF );
|
||||||
|
|
||||||
// Remove temp index file
|
// Remove temp index file
|
||||||
FS_HomeRemove( idxFileName );
|
FS_Remove_HomeData( idxFileName );
|
||||||
|
|
||||||
// Write the real header
|
// Write the real header
|
||||||
FS_Seek( afd.f, 0, FS_SEEK_SET );
|
FS_Seek( afd.f, 0, FS_SEEK_SET );
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ void Con_Dump_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = FS_FOpenFileWrite( filename );
|
f = FS_FOpenFileWrite_HomeData( filename );
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
Com_Printf ("ERROR: couldn't open %s.\n", filename);
|
Com_Printf ("ERROR: couldn't open %s.\n", filename);
|
||||||
|
|
|
||||||
|
|
@ -1577,7 +1577,7 @@ void CL_SaveConsoleHistory( void )
|
||||||
|
|
||||||
consoleSaveBufferSize = strlen( consoleSaveBuffer );
|
consoleSaveBufferSize = strlen( consoleSaveBuffer );
|
||||||
|
|
||||||
f = FS_FOpenFileWrite( CONSOLE_HISTORY_FILE );
|
f = FS_FOpenFileWrite_HomeState( CONSOLE_HISTORY_FILE );
|
||||||
if( !f )
|
if( !f )
|
||||||
{
|
{
|
||||||
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
|
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
|
||||||
|
|
|
||||||
|
|
@ -742,7 +742,7 @@ void CL_Record_f( void ) {
|
||||||
#endif
|
#endif
|
||||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer);
|
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer);
|
||||||
|
|
||||||
if (!FS_FileExists(name))
|
if (!FS_FileExists_HomeData(name))
|
||||||
break; // file doesn't exist
|
break; // file doesn't exist
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -750,7 +750,7 @@ void CL_Record_f( void ) {
|
||||||
// open the demo file
|
// open the demo file
|
||||||
|
|
||||||
Com_Printf ("recording to %s.\n", name);
|
Com_Printf ("recording to %s.\n", name);
|
||||||
clc.demofile = FS_FOpenFileWrite( name );
|
clc.demofile = FS_FOpenFileWrite_HomeData( name );
|
||||||
if ( !clc.demofile ) {
|
if ( !clc.demofile ) {
|
||||||
Com_Printf ("ERROR: couldn't open.\n");
|
Com_Printf ("ERROR: couldn't open.\n");
|
||||||
return;
|
return;
|
||||||
|
|
@ -903,7 +903,7 @@ void CL_DemoCompleted( void )
|
||||||
else
|
else
|
||||||
numFrames = clc.timeDemoFrames - 1;
|
numFrames = clc.timeDemoFrames - 1;
|
||||||
|
|
||||||
f = FS_FOpenFileWrite( cl_timedemoLog->string );
|
f = FS_FOpenFileWrite_HomeData( cl_timedemoLog->string );
|
||||||
if( f )
|
if( f )
|
||||||
{
|
{
|
||||||
FS_Printf( f, "# %s", buffer );
|
FS_Printf( f, "# %s", buffer );
|
||||||
|
|
@ -2197,7 +2197,7 @@ static void CL_BeginHttpDownload( const char *remoteURL ) {
|
||||||
CL_HTTP_BeginDownload(remoteURL);
|
CL_HTTP_BeginDownload(remoteURL);
|
||||||
Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL));
|
Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL));
|
||||||
|
|
||||||
clc.download = FS_BaseDir_FOpenFileWrite(clc.downloadTempName);
|
clc.download = FS_BaseDir_FOpenFileWrite_HomeData(clc.downloadTempName);
|
||||||
if(!clc.download) {
|
if(!clc.download) {
|
||||||
Com_Error(ERR_DROP, "CL_BeginHTTPDownload: failed to open "
|
Com_Error(ERR_DROP, "CL_BeginHTTPDownload: failed to open "
|
||||||
"%s for writing", clc.downloadTempName);
|
"%s for writing", clc.downloadTempName);
|
||||||
|
|
@ -2233,7 +2233,7 @@ void CL_NextDownload(void)
|
||||||
// A download has finished, check whether this matches a referenced checksum
|
// A download has finished, check whether this matches a referenced checksum
|
||||||
if(*clc.downloadName)
|
if(*clc.downloadName)
|
||||||
{
|
{
|
||||||
char *zippath = FS_BaseDir_BuildOSPath(Cvar_VariableString("fs_homepath"), clc.downloadName);
|
char *zippath = FS_BaseDir_BuildOSPath(Cvar_VariableString("fs_homedatapath"), clc.downloadName);
|
||||||
|
|
||||||
if(!FS_CompareZipChecksum(zippath))
|
if(!FS_CompareZipChecksum(zippath))
|
||||||
Com_Error(ERR_DROP, "Incorrect checksum for file: %s", clc.downloadName);
|
Com_Error(ERR_DROP, "Incorrect checksum for file: %s", clc.downloadName);
|
||||||
|
|
@ -2977,7 +2977,7 @@ void CL_Frame ( int msec ) {
|
||||||
clc.download = 0;
|
clc.download = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FS_BaseDir_Rename(clc.downloadTempName, clc.downloadName, qfalse);
|
FS_BaseDir_Rename_HomeData(clc.downloadTempName, clc.downloadName, qfalse);
|
||||||
clc.downloadRestart = qtrue;
|
clc.downloadRestart = qtrue;
|
||||||
CL_NextDownload();
|
CL_NextDownload();
|
||||||
}
|
}
|
||||||
|
|
@ -3307,7 +3307,7 @@ void CL_InitRef( void ) {
|
||||||
ri.FS_FreeFileList = FS_FreeFileList;
|
ri.FS_FreeFileList = FS_FreeFileList;
|
||||||
ri.FS_ListFiles = FS_ListFiles;
|
ri.FS_ListFiles = FS_ListFiles;
|
||||||
ri.FS_FileIsInPAK = FS_FileIsInPAK;
|
ri.FS_FileIsInPAK = FS_FileIsInPAK;
|
||||||
ri.FS_FileExists = FS_FileExists;
|
ri.FS_FileExists = FS_FileExists_HomeData;
|
||||||
ri.Cvar_Get = Cvar_Get;
|
ri.Cvar_Get = Cvar_Get;
|
||||||
ri.Cvar_Set = Cvar_Set;
|
ri.Cvar_Set = Cvar_Set;
|
||||||
ri.Cvar_SetValue = Cvar_SetValue;
|
ri.Cvar_SetValue = Cvar_SetValue;
|
||||||
|
|
@ -3418,7 +3418,7 @@ void CL_Video_f( void )
|
||||||
Com_sprintf( filename, MAX_OSPATH, "videos/video%d%d%d%d.avi",
|
Com_sprintf( filename, MAX_OSPATH, "videos/video%d%d%d%d.avi",
|
||||||
a, b, c, d );
|
a, b, c, d );
|
||||||
|
|
||||||
if( !FS_FileExists( filename ) )
|
if( !FS_FileExists_HomeData( filename ) )
|
||||||
break; // file doesn't exist
|
break; // file doesn't exist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3471,7 +3471,7 @@ static void CL_GenerateQKey(void)
|
||||||
Com_Printf( "QKEY building random string\n" );
|
Com_Printf( "QKEY building random string\n" );
|
||||||
Com_RandomBytes( buff, sizeof(buff) );
|
Com_RandomBytes( buff, sizeof(buff) );
|
||||||
|
|
||||||
f = FS_BaseDir_FOpenFileWrite( QKEY_FILE );
|
f = FS_BaseDir_FOpenFileWrite_HomeState( QKEY_FILE );
|
||||||
if( !f ) {
|
if( !f ) {
|
||||||
Com_Printf( "QKEY could not open %s for write\n",
|
Com_Printf( "QKEY could not open %s for write\n",
|
||||||
QKEY_FILE );
|
QKEY_FILE );
|
||||||
|
|
|
||||||
|
|
@ -608,7 +608,7 @@ void CL_ParseDownload ( msg_t *msg ) {
|
||||||
// open the file if not opened yet
|
// open the file if not opened yet
|
||||||
if (!clc.download)
|
if (!clc.download)
|
||||||
{
|
{
|
||||||
clc.download = FS_BaseDir_FOpenFileWrite( clc.downloadTempName );
|
clc.download = FS_BaseDir_FOpenFileWrite_HomeData( clc.downloadTempName );
|
||||||
|
|
||||||
if (!clc.download) {
|
if (!clc.download) {
|
||||||
Com_Printf( "Could not create %s\n", clc.downloadTempName );
|
Com_Printf( "Could not create %s\n", clc.downloadTempName );
|
||||||
|
|
@ -635,7 +635,7 @@ void CL_ParseDownload ( msg_t *msg ) {
|
||||||
clc.download = 0;
|
clc.download = 0;
|
||||||
|
|
||||||
// rename the file
|
// rename the file
|
||||||
FS_BaseDir_Rename ( clc.downloadTempName, clc.downloadName, qfalse );
|
FS_BaseDir_Rename_HomeData ( clc.downloadTempName, clc.downloadName, qfalse );
|
||||||
}
|
}
|
||||||
|
|
||||||
// send intentions now
|
// send intentions now
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ LAN_SaveServersToCache
|
||||||
*/
|
*/
|
||||||
void LAN_SaveServersToCache( void ) {
|
void LAN_SaveServersToCache( void ) {
|
||||||
int size;
|
int size;
|
||||||
fileHandle_t fileOut = FS_BaseDir_FOpenFileWrite("servercache.dat");
|
fileHandle_t fileOut = FS_BaseDir_FOpenFileWrite_HomeState("servercache.dat");
|
||||||
FS_Write(&cls.numglobalservers, sizeof(int), fileOut);
|
FS_Write(&cls.numglobalservers, sizeof(int), fileOut);
|
||||||
FS_Write(&cls.numfavoriteservers, sizeof(int), fileOut);
|
FS_Write(&cls.numfavoriteservers, sizeof(int), fileOut);
|
||||||
size = sizeof(cls.globalServers) + sizeof(cls.favoriteServers);
|
size = sizeof(cls.globalServers) + sizeof(cls.favoriteServers);
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ void QDECL Com_Printf( const char *fmt, ... ) {
|
||||||
time( &aclock );
|
time( &aclock );
|
||||||
newtime = localtime( &aclock );
|
newtime = localtime( &aclock );
|
||||||
|
|
||||||
logfile = FS_FOpenFileWrite( "qconsole.log" );
|
logfile = FS_FOpenFileWrite_HomeData( "qconsole.log" );
|
||||||
|
|
||||||
if(logfile)
|
if(logfile)
|
||||||
{
|
{
|
||||||
|
|
@ -1921,8 +1921,8 @@ void Com_InitJournaling( void ) {
|
||||||
|
|
||||||
if ( com_journal->integer == 1 ) {
|
if ( com_journal->integer == 1 ) {
|
||||||
Com_Printf( "Journaling events\n");
|
Com_Printf( "Journaling events\n");
|
||||||
com_journalFile = FS_FOpenFileWrite( "journal.dat" );
|
com_journalFile = FS_FOpenFileWrite_HomeState( "journal.dat" );
|
||||||
com_journalDataFile = FS_FOpenFileWrite( "journaldata.dat" );
|
com_journalDataFile = FS_FOpenFileWrite_HomeState( "journaldata.dat" );
|
||||||
} else if ( com_journal->integer == 2 ) {
|
} else if ( com_journal->integer == 2 ) {
|
||||||
Com_Printf( "Replaying journaled events\n");
|
Com_Printf( "Replaying journaled events\n");
|
||||||
FS_FOpenFileRead( "journal.dat", &com_journalFile, qtrue );
|
FS_FOpenFileRead( "journal.dat", &com_journalFile, qtrue );
|
||||||
|
|
@ -2547,7 +2547,7 @@ static void Com_WriteCDKey( const char *filename, const char *ikey ) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
savedumask = umask(0077);
|
savedumask = umask(0077);
|
||||||
#endif
|
#endif
|
||||||
f = FS_BaseDir_FOpenFileWrite( fbuffer );
|
f = FS_BaseDir_FOpenFileWrite_HomeState( fbuffer );
|
||||||
if ( !f ) {
|
if ( !f ) {
|
||||||
Com_Printf ("Couldn't write CD key to %s.\n", fbuffer );
|
Com_Printf ("Couldn't write CD key to %s.\n", fbuffer );
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -2921,7 +2921,7 @@ void Com_ReadFromPipe( void )
|
||||||
void Com_WriteConfigToFile( const char *filename ) {
|
void Com_WriteConfigToFile( const char *filename ) {
|
||||||
fileHandle_t f;
|
fileHandle_t f;
|
||||||
|
|
||||||
f = FS_FOpenFileWrite( filename );
|
f = FS_FOpenFileWrite_HomeConfig( filename );
|
||||||
if ( !f ) {
|
if ( !f ) {
|
||||||
Com_Printf ("Couldn't write %s.\n", filename );
|
Com_Printf ("Couldn't write %s.\n", filename );
|
||||||
return;
|
return;
|
||||||
|
|
@ -3293,7 +3293,7 @@ void Com_Shutdown (void) {
|
||||||
|
|
||||||
if( pipefile ) {
|
if( pipefile ) {
|
||||||
FS_FCloseFile( pipefile );
|
FS_FCloseFile( pipefile );
|
||||||
FS_HomeRemove( com_pipefile->string );
|
FS_Remove_HomeData( com_pipefile->string );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,9 @@ typedef struct searchpath_s {
|
||||||
|
|
||||||
static char fs_gamedir[MAX_OSPATH]; // this will be a single file name with no separators
|
static char fs_gamedir[MAX_OSPATH]; // this will be a single file name with no separators
|
||||||
static cvar_t *fs_debug;
|
static cvar_t *fs_debug;
|
||||||
static cvar_t *fs_homepath;
|
static cvar_t *fs_homeconfigpath;
|
||||||
|
static cvar_t *fs_homedatapath;
|
||||||
|
static cvar_t *fs_homestatepath;
|
||||||
|
|
||||||
static cvar_t *fs_apppath;
|
static cvar_t *fs_apppath;
|
||||||
static cvar_t *fs_steampath;
|
static cvar_t *fs_steampath;
|
||||||
|
|
@ -609,14 +611,14 @@ void FS_Remove( const char *osPath ) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
FS_HomeRemove
|
FS_Remove_HomeData
|
||||||
|
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
void FS_HomeRemove( const char *homePath ) {
|
void FS_Remove_HomeData( const char *homePath ) {
|
||||||
FS_CheckFilenameIsMutable( homePath, __func__ );
|
FS_CheckFilenameIsMutable( homePath, __func__ );
|
||||||
|
|
||||||
remove( FS_BuildOSPath( fs_homepath->string,
|
remove( FS_BuildOSPath( fs_homedatapath->string,
|
||||||
fs_gamedir, homePath ) );
|
fs_gamedir, homePath ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -644,7 +646,7 @@ qboolean FS_FileInPathExists(const char *testpath)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
FS_FileExists
|
FS_FileExists_HomeData
|
||||||
|
|
||||||
Tests if the file exists in the current gamedir, this DOES NOT
|
Tests if the file exists in the current gamedir, this DOES NOT
|
||||||
search the paths. This is to determine if opening a file to write
|
search the paths. This is to determine if opening a file to write
|
||||||
|
|
@ -652,21 +654,21 @@ search the paths. This is to determine if opening a file to write
|
||||||
NOTE TTimo: this goes with FS_FOpenFileWrite for opening the file afterwards
|
NOTE TTimo: this goes with FS_FOpenFileWrite for opening the file afterwards
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
qboolean FS_FileExists(const char *file)
|
qboolean FS_FileExists_HomeData(const char *file)
|
||||||
{
|
{
|
||||||
return FS_FileInPathExists(FS_BuildOSPath(fs_homepath->string, fs_gamedir, file));
|
return FS_FileInPathExists(FS_BuildOSPath(fs_homedatapath->string, fs_gamedir, file));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
FS_BaseDir_FileExists
|
FS_BaseDir_FileExists_HomeData
|
||||||
|
|
||||||
Tests if the file exists
|
Tests if the file exists
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
qboolean FS_BaseDir_FileExists( const char *file )
|
static qboolean FS_BaseDir_FileExists_HomeData( const char *file )
|
||||||
{
|
{
|
||||||
return FS_FileInPathExists(FS_BaseDir_BuildOSPath(fs_homepath->string, file));
|
return FS_FileInPathExists(FS_BaseDir_BuildOSPath(fs_homedatapath->string, file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -708,13 +710,32 @@ static fileHandle_t FS_OSPath_FOpenFileWrite( const char *ospath, const char *fi
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
FS_BaseDir_FOpenFileWrite
|
FS_BaseDir_FOpenFileWrite_HomeConfig
|
||||||
|
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
fileHandle_t FS_BaseDir_FOpenFileWrite( const char *filename ) {
|
fileHandle_t FS_BaseDir_FOpenFileWrite_HomeConfig( const char *filename ) {
|
||||||
return FS_OSPath_FOpenFileWrite(
|
return FS_OSPath_FOpenFileWrite(
|
||||||
FS_BaseDir_BuildOSPath(fs_homepath->string, filename), filename);
|
FS_BaseDir_BuildOSPath(fs_homeconfigpath->string, filename), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
FS_BaseDir_FOpenFileWrite_HomeData
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
fileHandle_t FS_BaseDir_FOpenFileWrite_HomeData( const char *filename ) {
|
||||||
|
return FS_OSPath_FOpenFileWrite(
|
||||||
|
FS_BaseDir_BuildOSPath(fs_homedatapath->string, filename), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
FS_BaseDir_FOpenFileWrite_HomeState
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
fileHandle_t FS_BaseDir_FOpenFileWrite_HomeState( const char *filename ) {
|
||||||
|
return FS_OSPath_FOpenFileWrite(
|
||||||
|
FS_BaseDir_BuildOSPath(fs_homestatepath->string, filename), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -776,11 +797,11 @@ long FS_BaseDir_FOpenFileRead(const char *filename, fileHandle_t *fp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
FS_BaseDir_Rename
|
FS_BaseDir_Rename_HomeData
|
||||||
|
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
void FS_BaseDir_Rename( const char *from, const char *to, qboolean safe ) {
|
void FS_BaseDir_Rename_HomeData( const char *from, const char *to, qboolean safe ) {
|
||||||
char *from_ospath, *to_ospath;
|
char *from_ospath, *to_ospath;
|
||||||
|
|
||||||
if ( !fs_searchpaths ) {
|
if ( !fs_searchpaths ) {
|
||||||
|
|
@ -790,11 +811,11 @@ void FS_BaseDir_Rename( const char *from, const char *to, qboolean safe ) {
|
||||||
// don't let sound stutter
|
// don't let sound stutter
|
||||||
S_ClearSoundBuffer();
|
S_ClearSoundBuffer();
|
||||||
|
|
||||||
from_ospath = FS_BaseDir_BuildOSPath( fs_homepath->string, from );
|
from_ospath = FS_BaseDir_BuildOSPath( fs_homedatapath->string, from );
|
||||||
to_ospath = FS_BaseDir_BuildOSPath( fs_homepath->string, to );
|
to_ospath = FS_BaseDir_BuildOSPath( fs_homedatapath->string, to );
|
||||||
|
|
||||||
if ( fs_debug->integer ) {
|
if ( fs_debug->integer ) {
|
||||||
Com_Printf( "FS_BaseDir_Rename: %s --> %s\n", from_ospath, to_ospath );
|
Com_Printf( "FS_BaseDir_Rename_HomeData: %s --> %s\n", from_ospath, to_ospath );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( safe ) {
|
if ( safe ) {
|
||||||
|
|
@ -837,22 +858,41 @@ void FS_FCloseFile( fileHandle_t f ) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
FS_FOpenFileWrite
|
FS_FOpenFileWrite_HomeConfig
|
||||||
|
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
fileHandle_t FS_FOpenFileWrite( const char *filename ) {
|
fileHandle_t FS_FOpenFileWrite_HomeConfig( const char *filename ) {
|
||||||
return FS_OSPath_FOpenFileWrite(
|
return FS_OSPath_FOpenFileWrite(
|
||||||
FS_BuildOSPath(fs_homepath->string, fs_gamedir, filename), filename);
|
FS_BuildOSPath(fs_homeconfigpath->string, fs_gamedir, filename), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
FS_FOpenFileAppend
|
FS_FOpenFileWrite_HomeData
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
fileHandle_t FS_FOpenFileWrite_HomeData( const char *filename ) {
|
||||||
|
return FS_OSPath_FOpenFileWrite(
|
||||||
|
FS_BuildOSPath(fs_homedatapath->string, fs_gamedir, filename), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
FS_FOpenFileWrite_HomeState
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
fileHandle_t FS_FOpenFileWrite_HomeState( const char *filename ) {
|
||||||
|
return FS_OSPath_FOpenFileWrite(
|
||||||
|
FS_BuildOSPath(fs_homestatepath->string, fs_gamedir, filename), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
FS_FOpenFileAppend_HomeData
|
||||||
|
|
||||||
===========
|
===========
|
||||||
*/
|
*/
|
||||||
fileHandle_t FS_FOpenFileAppend( const char *filename ) {
|
fileHandle_t FS_FOpenFileAppend_HomeData( const char *filename ) {
|
||||||
char *ospath;
|
char *ospath;
|
||||||
fileHandle_t f;
|
fileHandle_t f;
|
||||||
|
|
||||||
|
|
@ -868,10 +908,10 @@ fileHandle_t FS_FOpenFileAppend( const char *filename ) {
|
||||||
// don't let sound stutter
|
// don't let sound stutter
|
||||||
S_ClearSoundBuffer();
|
S_ClearSoundBuffer();
|
||||||
|
|
||||||
ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename );
|
ospath = FS_BuildOSPath( fs_homedatapath->string, fs_gamedir, filename );
|
||||||
|
|
||||||
if ( fs_debug->integer ) {
|
if ( fs_debug->integer ) {
|
||||||
Com_Printf( "FS_FOpenFileAppend: %s\n", ospath );
|
Com_Printf( "FS_FOpenFileAppend_HomeData: %s\n", ospath );
|
||||||
}
|
}
|
||||||
|
|
||||||
FS_CheckFilenameIsMutable( ospath, __func__ );
|
FS_CheckFilenameIsMutable( ospath, __func__ );
|
||||||
|
|
@ -911,7 +951,7 @@ fileHandle_t FS_FCreateOpenPipeFile( const char *filename ) {
|
||||||
// don't let sound stutter
|
// don't let sound stutter
|
||||||
S_ClearSoundBuffer();
|
S_ClearSoundBuffer();
|
||||||
|
|
||||||
ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename );
|
ospath = FS_BuildOSPath( fs_homedatapath->string, fs_gamedir, filename );
|
||||||
|
|
||||||
if ( fs_debug->integer ) {
|
if ( fs_debug->integer ) {
|
||||||
Com_Printf( "FS_FCreateOpenPipeFile: %s\n", ospath );
|
Com_Printf( "FS_FCreateOpenPipeFile: %s\n", ospath );
|
||||||
|
|
@ -1237,7 +1277,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_
|
||||||
// if you are using FS_ReadFile to find out if a file exists,
|
// if you are using FS_ReadFile to find out if a file exists,
|
||||||
// this test can make the search fail although the file is in the directory
|
// this test can make the search fail although the file is in the directory
|
||||||
// I had the problem on https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=8
|
// I had the problem on https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=8
|
||||||
// turned out I used FS_FileExists instead
|
// turned out I used FS_FileExists_HomeData instead
|
||||||
if(!unpure && fs_numServerPaks)
|
if(!unpure && fs_numServerPaks)
|
||||||
{
|
{
|
||||||
if(!FS_IsExt(filename, ".cfg", len) && // for config files
|
if(!FS_IsExt(filename, ".cfg", len) && // for config files
|
||||||
|
|
@ -1909,7 +1949,7 @@ void FS_WriteFile( const char *qpath, const void *buffer, int size ) {
|
||||||
Com_Error( ERR_FATAL, "FS_WriteFile: NULL parameter" );
|
Com_Error( ERR_FATAL, "FS_WriteFile: NULL parameter" );
|
||||||
}
|
}
|
||||||
|
|
||||||
f = FS_FOpenFileWrite( qpath );
|
f = FS_FOpenFileWrite_HomeData( qpath );
|
||||||
if ( !f ) {
|
if ( !f ) {
|
||||||
Com_Printf( "Failed to open %s\n", qpath );
|
Com_Printf( "Failed to open %s\n", qpath );
|
||||||
return;
|
return;
|
||||||
|
|
@ -3132,7 +3172,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
||||||
// Local name
|
// Local name
|
||||||
Q_strcat( neededpaks, len, "@");
|
Q_strcat( neededpaks, len, "@");
|
||||||
// Do we have one with the same name?
|
// Do we have one with the same name?
|
||||||
if ( FS_BaseDir_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
|
if ( FS_BaseDir_FileExists_HomeData( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
|
||||||
{
|
{
|
||||||
char st[MAX_ZPATH];
|
char st[MAX_ZPATH];
|
||||||
// We already have one called this, we need to download it to another name
|
// We already have one called this, we need to download it to another name
|
||||||
|
|
@ -3159,7 +3199,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
||||||
Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
|
Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
|
||||||
Q_strcat( neededpaks, len, ".pk3" );
|
Q_strcat( neededpaks, len, ".pk3" );
|
||||||
// Do we have one with the same name?
|
// Do we have one with the same name?
|
||||||
if ( FS_BaseDir_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
|
if ( FS_BaseDir_FileExists_HomeData( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
|
||||||
{
|
{
|
||||||
Q_strcat( neededpaks, len, " (local file exists with wrong checksum)");
|
Q_strcat( neededpaks, len, " (local file exists with wrong checksum)");
|
||||||
}
|
}
|
||||||
|
|
@ -3302,7 +3342,9 @@ FS_InitPathVars
|
||||||
static void FS_InitPathVars( void ) {
|
static void FS_InitPathVars( void ) {
|
||||||
memset( fs_pathVars, 0, sizeof( fs_pathVars ) );
|
memset( fs_pathVars, 0, sizeof( fs_pathVars ) );
|
||||||
|
|
||||||
FS_AddPathVar( fs_homepath );
|
FS_AddPathVar( fs_homeconfigpath );
|
||||||
|
FS_AddPathVar( fs_homedatapath );
|
||||||
|
FS_AddPathVar( fs_homestatepath );
|
||||||
FS_AddPathVar( fs_basepath );
|
FS_AddPathVar( fs_basepath );
|
||||||
FS_AddPathVar( fs_apppath );
|
FS_AddPathVar( fs_apppath );
|
||||||
FS_AddPathVar( fs_steampath );
|
FS_AddPathVar( fs_steampath );
|
||||||
|
|
@ -3317,7 +3359,18 @@ FS_Startup
|
||||||
*/
|
*/
|
||||||
static void FS_Startup( const char *gameName )
|
static void FS_Startup( const char *gameName )
|
||||||
{
|
{
|
||||||
const char *homePath;
|
cvar_t *fs_homepath = Cvar_Get("fs_homepath", "", CVAR_INIT|CVAR_PROTECTED);
|
||||||
|
const char *configPath = Sys_DefaultHomeConfigPath();
|
||||||
|
const char *dataPath = Sys_DefaultHomeDataPath();
|
||||||
|
const char *statePath = Sys_DefaultHomeStatePath();
|
||||||
|
|
||||||
|
if(*(fs_homepath)->string) {
|
||||||
|
// Setting fs_homepath manually overrides everything else
|
||||||
|
configPath = dataPath = statePath = fs_homepath->string;
|
||||||
|
} else if(!*configPath || !*dataPath || !*statePath) {
|
||||||
|
// #shouldneverhappen; just a sensible fallback
|
||||||
|
configPath = dataPath = statePath = Sys_DefaultInstallPath();
|
||||||
|
}
|
||||||
|
|
||||||
Com_Printf( "----- FS_Startup -----\n" );
|
Com_Printf( "----- FS_Startup -----\n" );
|
||||||
|
|
||||||
|
|
@ -3326,11 +3379,9 @@ static void FS_Startup( const char *gameName )
|
||||||
fs_debug = Cvar_Get( "fs_debug", "0", 0 );
|
fs_debug = Cvar_Get( "fs_debug", "0", 0 );
|
||||||
fs_basepath = Cvar_Get ("fs_basepath", Sys_DefaultInstallPath(), CVAR_INIT|CVAR_PROTECTED );
|
fs_basepath = Cvar_Get ("fs_basepath", Sys_DefaultInstallPath(), CVAR_INIT|CVAR_PROTECTED );
|
||||||
fs_basegame = Cvar_Get ("fs_basegame", "", CVAR_INIT );
|
fs_basegame = Cvar_Get ("fs_basegame", "", CVAR_INIT );
|
||||||
homePath = Sys_DefaultHomePath();
|
fs_homeconfigpath = Cvar_Get ("fs_homeconfigpath", configPath, CVAR_INIT|CVAR_PROTECTED );
|
||||||
if (!homePath || !homePath[0]) {
|
fs_homedatapath = Cvar_Get ("fs_homedatapath", dataPath, CVAR_INIT|CVAR_PROTECTED );
|
||||||
homePath = fs_basepath->string;
|
fs_homestatepath = Cvar_Get ("fs_homestatepath", statePath, CVAR_INIT|CVAR_PROTECTED );
|
||||||
}
|
|
||||||
fs_homepath = Cvar_Get ("fs_homepath", homePath, CVAR_INIT|CVAR_PROTECTED );
|
|
||||||
fs_gamedirvar = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
|
fs_gamedirvar = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
|
||||||
fs_steampath = Cvar_Get ("fs_steampath", Sys_SteamPath(), CVAR_INIT|CVAR_PROTECTED );
|
fs_steampath = Cvar_Get ("fs_steampath", Sys_SteamPath(), CVAR_INIT|CVAR_PROTECTED );
|
||||||
fs_gogpath = Cvar_Get ("fs_gogpath", Sys_GogPath(), CVAR_INIT|CVAR_PROTECTED );
|
fs_gogpath = Cvar_Get ("fs_gogpath", Sys_GogPath(), CVAR_INIT|CVAR_PROTECTED );
|
||||||
|
|
@ -3363,9 +3414,9 @@ static void FS_Startup( const char *gameName )
|
||||||
Com_Error( ERR_DROP, "Invalid fs_game '%s'", fs_gamedirvar->string );
|
Com_Error( ERR_DROP, "Invalid fs_game '%s'", fs_gamedirvar->string );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_homepath->string[0] && Q_stricmp(fs_homepath->string, fs_basepath->string)) {
|
FS_CreatePath(fs_homeconfigpath->string);
|
||||||
FS_CreatePath ( fs_homepath->string );
|
FS_CreatePath(fs_homedatapath->string);
|
||||||
}
|
FS_CreatePath(fs_homestatepath->string);
|
||||||
|
|
||||||
FS_AddGameDirectories(gameName);
|
FS_AddGameDirectories(gameName);
|
||||||
|
|
||||||
|
|
@ -3639,7 +3690,7 @@ static void FS_CheckPak0( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(installHome)
|
if(installHome)
|
||||||
installPath = fs_homepath->string;
|
installPath = fs_homedatapath->string;
|
||||||
else
|
else
|
||||||
installPath = fs_basepath->string;
|
installPath = fs_basepath->string;
|
||||||
|
|
||||||
|
|
@ -4059,6 +4110,9 @@ void FS_InitFilesystem( void ) {
|
||||||
// has already been initialized
|
// has already been initialized
|
||||||
Com_StartupVariable("fs_basepath");
|
Com_StartupVariable("fs_basepath");
|
||||||
Com_StartupVariable("fs_homepath");
|
Com_StartupVariable("fs_homepath");
|
||||||
|
Com_StartupVariable("fs_homeconfigpath");
|
||||||
|
Com_StartupVariable("fs_homedatapath");
|
||||||
|
Com_StartupVariable("fs_homestatepath");
|
||||||
Com_StartupVariable("fs_game");
|
Com_StartupVariable("fs_game");
|
||||||
|
|
||||||
if(!FS_FilenameCompare(Cvar_VariableString("fs_game"), com_basegame->string))
|
if(!FS_FilenameCompare(Cvar_VariableString("fs_game"), com_basegame->string))
|
||||||
|
|
@ -4201,7 +4255,7 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode ) {
|
||||||
r = FS_FOpenFileRead( qpath, f, qtrue );
|
r = FS_FOpenFileRead( qpath, f, qtrue );
|
||||||
break;
|
break;
|
||||||
case FS_WRITE:
|
case FS_WRITE:
|
||||||
*f = FS_FOpenFileWrite( qpath );
|
*f = FS_FOpenFileWrite_HomeData( qpath );
|
||||||
r = 0;
|
r = 0;
|
||||||
if (*f == 0) {
|
if (*f == 0) {
|
||||||
r = -1;
|
r = -1;
|
||||||
|
|
@ -4210,7 +4264,7 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode ) {
|
||||||
case FS_APPEND_SYNC:
|
case FS_APPEND_SYNC:
|
||||||
sync = qtrue;
|
sync = qtrue;
|
||||||
case FS_APPEND:
|
case FS_APPEND:
|
||||||
*f = FS_FOpenFileAppend( qpath );
|
*f = FS_FOpenFileAppend_HomeData( qpath );
|
||||||
r = 0;
|
r = 0;
|
||||||
if (*f == 0) {
|
if (*f == 0) {
|
||||||
r = -1;
|
r = -1;
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#define BASEGAME "foobar"
|
#define BASEGAME "foobar"
|
||||||
#define CLIENT_WINDOW_TITLE "changeme"
|
#define CLIENT_WINDOW_TITLE "changeme"
|
||||||
#define CLIENT_WINDOW_MIN_TITLE "changeme2"
|
#define CLIENT_WINDOW_MIN_TITLE "changeme2"
|
||||||
#define HOMEPATH_NAME_UNIX ".foo"
|
#define HOMEPATH_NAME_UNIX_LEGACY ".foo"
|
||||||
#define HOMEPATH_NAME_WIN "FooBar"
|
#define HOMEPATH_NAME "FooBar"
|
||||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
|
||||||
#define GAMENAME_FOR_MASTER "foobar" // must NOT contain whitespace
|
#define GAMENAME_FOR_MASTER "foobar" // must NOT contain whitespace
|
||||||
#define CINEMATICS_LOGO "foologo.roq"
|
#define CINEMATICS_LOGO "foologo.roq"
|
||||||
#define CINEMATICS_INTRO "intro.roq"
|
#define CINEMATICS_INTRO "intro.roq"
|
||||||
|
|
@ -45,9 +44,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#define BASEGAME "baseq3"
|
#define BASEGAME "baseq3"
|
||||||
#define CLIENT_WINDOW_TITLE "ioquake3"
|
#define CLIENT_WINDOW_TITLE "ioquake3"
|
||||||
#define CLIENT_WINDOW_MIN_TITLE "ioq3"
|
#define CLIENT_WINDOW_MIN_TITLE "ioq3"
|
||||||
#define HOMEPATH_NAME_UNIX ".q3a"
|
#define HOMEPATH_NAME_UNIX_LEGACY ".q3a"
|
||||||
#define HOMEPATH_NAME_WIN "Quake3"
|
#define HOMEPATH_NAME "Quake3"
|
||||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
|
||||||
#define GAMENAME_FOR_MASTER "Quake3Arena"
|
#define GAMENAME_FOR_MASTER "Quake3Arena"
|
||||||
#define CINEMATICS_LOGO "idlogo.RoQ"
|
#define CINEMATICS_LOGO "idlogo.RoQ"
|
||||||
#define CINEMATICS_INTRO "intro.RoQ"
|
#define CINEMATICS_INTRO "intro.RoQ"
|
||||||
|
|
|
||||||
|
|
@ -616,7 +616,7 @@ char **FS_ListFiles( const char *directory, const char *extension, int *numfiles
|
||||||
|
|
||||||
void FS_FreeFileList( char **list );
|
void FS_FreeFileList( char **list );
|
||||||
|
|
||||||
qboolean FS_FileExists( const char *file );
|
qboolean FS_FileExists_HomeData( const char *file );
|
||||||
|
|
||||||
qboolean FS_CreatePath (const char *OSPath);
|
qboolean FS_CreatePath (const char *OSPath);
|
||||||
|
|
||||||
|
|
@ -633,14 +633,18 @@ int FS_GetModList( char *listbuf, int bufsize );
|
||||||
|
|
||||||
void FS_GetModDescription( const char *modDir, char *description, int descriptionLen );
|
void FS_GetModDescription( const char *modDir, char *description, int descriptionLen );
|
||||||
|
|
||||||
fileHandle_t FS_FOpenFileWrite( const char *qpath );
|
fileHandle_t FS_FOpenFileWrite_HomeConfig( const char *filename );
|
||||||
fileHandle_t FS_FOpenFileAppend( const char *filename );
|
fileHandle_t FS_FOpenFileWrite_HomeData( const char *filename );
|
||||||
|
fileHandle_t FS_FOpenFileWrite_HomeState( const char *filename );
|
||||||
|
fileHandle_t FS_FOpenFileAppend_HomeData( const char *filename );
|
||||||
fileHandle_t FS_FCreateOpenPipeFile( const char *filename );
|
fileHandle_t FS_FCreateOpenPipeFile( const char *filename );
|
||||||
// will properly create any needed paths and deal with seperater character issues
|
// will properly create any needed paths and deal with seperater character issues
|
||||||
|
|
||||||
fileHandle_t FS_BaseDir_FOpenFileWrite( const char *filename );
|
fileHandle_t FS_BaseDir_FOpenFileWrite_HomeConfig( const char *filename );
|
||||||
|
fileHandle_t FS_BaseDir_FOpenFileWrite_HomeData( const char *filename );
|
||||||
|
fileHandle_t FS_BaseDir_FOpenFileWrite_HomeState( const char *filename );
|
||||||
long FS_BaseDir_FOpenFileRead( const char *filename, fileHandle_t *fp );
|
long FS_BaseDir_FOpenFileRead( const char *filename, fileHandle_t *fp );
|
||||||
void FS_BaseDir_Rename( const char *from, const char *to, qboolean safe );
|
void FS_BaseDir_Rename_HomeData( const char *from, const char *to, qboolean safe );
|
||||||
long FS_FOpenFileRead( const char *qpath, fileHandle_t *file, qboolean uniqueFILE );
|
long FS_FOpenFileRead( const char *qpath, fileHandle_t *file, qboolean uniqueFILE );
|
||||||
// if uniqueFILE is true, then a new FILE will be fopened even if the file
|
// if uniqueFILE is true, then a new FILE will be fopened even if the file
|
||||||
// is found in an already open pak file. If uniqueFILE is false, you must call
|
// is found in an already open pak file. If uniqueFILE is false, you must call
|
||||||
|
|
@ -725,7 +729,7 @@ qboolean FS_idPak(char *pak, char *base, int numPaks);
|
||||||
qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring );
|
qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring );
|
||||||
|
|
||||||
void FS_Remove( const char *osPath );
|
void FS_Remove( const char *osPath );
|
||||||
void FS_HomeRemove( const char *homePath );
|
void FS_Remove_HomeData( const char *homePath );
|
||||||
|
|
||||||
void FS_FilenameCompletion( const char *dir, const char *ext, char *filter,
|
void FS_FilenameCompletion( const char *dir, const char *ext, char *filter,
|
||||||
qboolean stripExt, void(*callback)(const char *s), qboolean allowNonPureFilesOnDisk );
|
qboolean stripExt, void(*callback)(const char *s), qboolean allowNonPureFilesOnDisk );
|
||||||
|
|
@ -1122,7 +1126,9 @@ char *Sys_MicrosoftStorePath(void);
|
||||||
char *Sys_DefaultAppPath(void);
|
char *Sys_DefaultAppPath(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *Sys_DefaultHomePath(void);
|
char *Sys_DefaultHomeConfigPath(void);
|
||||||
|
char *Sys_DefaultHomeDataPath(void);
|
||||||
|
char *Sys_DefaultHomeStatePath(void);
|
||||||
const char *Sys_Dirname( char *path );
|
const char *Sys_Dirname( char *path );
|
||||||
const char *Sys_Basename( char *path );
|
const char *Sys_Basename( char *path );
|
||||||
char *Sys_ConsoleInput(void);
|
char *Sys_ConsoleInput(void);
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ static void R_ModeList_f( void )
|
||||||
|
|
||||||
NOTE TTimo
|
NOTE TTimo
|
||||||
some thoughts about the screenshots system:
|
some thoughts about the screenshots system:
|
||||||
screenshots get written in fs_homepath + fs_gamedir
|
screenshots get written in fs_homedatapath + fs_gamedir
|
||||||
vanilla q3 .. baseq3/screenshots/ *.tga
|
vanilla q3 .. baseq3/screenshots/ *.tga
|
||||||
team arena .. missionpack/screenshots/ *.tga
|
team arena .. missionpack/screenshots/ *.tga
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ static void R_ModeList_f( void )
|
||||||
|
|
||||||
NOTE TTimo
|
NOTE TTimo
|
||||||
some thoughts about the screenshots system:
|
some thoughts about the screenshots system:
|
||||||
screenshots get written in fs_homepath + fs_gamedir
|
screenshots get written in fs_homedatapath + fs_gamedir
|
||||||
vanilla q3 .. baseq3/screenshots/ *.tga
|
vanilla q3 .. baseq3/screenshots/ *.tga
|
||||||
team arena .. missionpack/screenshots/ *.tga
|
team arena .. missionpack/screenshots/ *.tga
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -725,7 +725,7 @@ static void SV_WriteBans(void)
|
||||||
|
|
||||||
Com_sprintf(filepath, sizeof(filepath), "%s/%s", FS_GetCurrentGameDir(), sv_banFile->string);
|
Com_sprintf(filepath, sizeof(filepath), "%s/%s", FS_GetCurrentGameDir(), sv_banFile->string);
|
||||||
|
|
||||||
if((writeto = FS_BaseDir_FOpenFileWrite(filepath)))
|
if((writeto = FS_BaseDir_FOpenFileWrite_HomeState(filepath)))
|
||||||
{
|
{
|
||||||
char writebuf[128];
|
char writebuf[128];
|
||||||
serverBan_t *curban;
|
serverBan_t *curban;
|
||||||
|
|
|
||||||
|
|
@ -181,10 +181,10 @@ Sys_PIDFileName
|
||||||
*/
|
*/
|
||||||
static char *Sys_PIDFileName( const char *gamedir )
|
static char *Sys_PIDFileName( const char *gamedir )
|
||||||
{
|
{
|
||||||
const char *homePath = Cvar_VariableString( "fs_homepath" );
|
const char *homeStatePath = Cvar_VariableString( "fs_homestatepath" );
|
||||||
|
|
||||||
if( *homePath != '\0' )
|
if( *homeStatePath != '\0' )
|
||||||
return va( "%s/%s/%s", homePath, gamedir, PID_FILENAME );
|
return va( "%s/%s/%s", homeStatePath, gamedir, PID_FILENAME );
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,73 +112,371 @@ static int Sys_Exec( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
Sys_DefaultHomePath
|
Sys_DefaultHomePath
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
char *Sys_DefaultHomePath(void)
|
static char *Sys_DefaultHomePath(void)
|
||||||
{
|
{
|
||||||
static char homePath[ MAX_OSPATH ] = { 0 };
|
static char homePath[ MAX_OSPATH ] = { 0 };
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if( !*homePath && com_homepath != NULL )
|
if( !*homePath )
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
|
||||||
if( ( p = getenv( "HOME" ) ) != NULL )
|
if( ( p = getenv( "HOME" ) ) != NULL )
|
||||||
{
|
{
|
||||||
Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP);
|
Com_sprintf( homePath, sizeof(homePath), "%s%c%s",
|
||||||
|
p, PATH_SEP, "Library/Application Support/" );
|
||||||
|
|
||||||
Q_strcat(homePath, sizeof(homePath),
|
if( com_homepath && com_homepath->string[0] )
|
||||||
"Library/Application Support/");
|
|
||||||
|
|
||||||
if(com_homepath->string[0])
|
|
||||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||||
else
|
else
|
||||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
|
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if( ( p = getenv( "FLATPAK_ID" ) ) != NULL && *p != '\0' )
|
|
||||||
{
|
|
||||||
if( ( p = getenv( "XDG_DATA_HOME" ) ) != NULL && *p != '\0' )
|
|
||||||
{
|
|
||||||
Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP);
|
|
||||||
}
|
|
||||||
else if( ( p = getenv( "HOME" ) ) != NULL && *p != '\0' )
|
|
||||||
{
|
|
||||||
Com_sprintf(homePath, sizeof(homePath), "%s%c.local%cshare%c", p, PATH_SEP, PATH_SEP, PATH_SEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( *homePath )
|
|
||||||
{
|
|
||||||
char *dir;
|
|
||||||
|
|
||||||
if(com_homepath->string[0])
|
|
||||||
dir = com_homepath->string;
|
|
||||||
else
|
|
||||||
dir = HOMEPATH_NAME_UNIX;
|
|
||||||
|
|
||||||
if(dir[0] == '.' && dir[1] != '\0')
|
|
||||||
dir++;
|
|
||||||
|
|
||||||
Q_strcat(homePath, sizeof(homePath), dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( ( p = getenv( "HOME" ) ) != NULL )
|
|
||||||
{
|
|
||||||
Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP);
|
|
||||||
|
|
||||||
if(com_homepath->string[0])
|
|
||||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
|
||||||
else
|
|
||||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return homePath;
|
return homePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *Sys_DefaultHomeConfigPath(void) { return Sys_DefaultHomePath(); }
|
||||||
|
char *Sys_DefaultHomeDataPath(void) { return Sys_DefaultHomePath(); }
|
||||||
|
char *Sys_DefaultHomeStatePath(void) { return Sys_DefaultHomePath(); }
|
||||||
|
|
||||||
|
#else // __APPLE__
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_HomeConfigPath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
char *Sys_HomeConfigPath(void)
|
||||||
|
{
|
||||||
|
static char homeConfigPath[ MAX_OSPATH ] = { 0 };
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if( !*homeConfigPath )
|
||||||
|
{
|
||||||
|
if( ( p = getenv( "XDG_CONFIG_HOME" ) ) != NULL && *p != '\0' )
|
||||||
|
Com_sprintf(homeConfigPath, sizeof(homeConfigPath), "%s%c", p, PATH_SEP);
|
||||||
|
else if( ( p = getenv( "HOME" ) ) != NULL && *p != '\0' )
|
||||||
|
Com_sprintf(homeConfigPath, sizeof(homeConfigPath), "%s%c.config%c", p, PATH_SEP, PATH_SEP);
|
||||||
|
|
||||||
|
if( *homeConfigPath )
|
||||||
|
{
|
||||||
|
if( com_homepath && com_homepath->string[0] )
|
||||||
|
Q_strcat(homeConfigPath, sizeof(homeConfigPath), com_homepath->string);
|
||||||
|
else
|
||||||
|
Q_strcat(homeConfigPath, sizeof(homeConfigPath), HOMEPATH_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return homeConfigPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_HomeDataPath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
char *Sys_HomeDataPath(void)
|
||||||
|
{
|
||||||
|
static char homeDataPath[ MAX_OSPATH ] = { 0 };
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if( !*homeDataPath )
|
||||||
|
{
|
||||||
|
if( ( p = getenv( "XDG_DATA_HOME" ) ) != NULL && *p != '\0' )
|
||||||
|
Com_sprintf(homeDataPath, sizeof(homeDataPath), "%s%c", p, PATH_SEP);
|
||||||
|
else if( ( p = getenv( "HOME" ) ) != NULL && *p != '\0' )
|
||||||
|
Com_sprintf(homeDataPath, sizeof(homeDataPath), "%s%c.local%cshare%c", p, PATH_SEP, PATH_SEP, PATH_SEP);
|
||||||
|
|
||||||
|
if( *homeDataPath )
|
||||||
|
{
|
||||||
|
if( com_homepath && com_homepath->string[0] )
|
||||||
|
Q_strcat(homeDataPath, sizeof(homeDataPath), com_homepath->string);
|
||||||
|
else
|
||||||
|
Q_strcat(homeDataPath, sizeof(homeDataPath), HOMEPATH_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return homeDataPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_HomeStatePath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
char *Sys_HomeStatePath(void)
|
||||||
|
{
|
||||||
|
static char homeStatePath[ MAX_OSPATH ] = { 0 };
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if( !*homeStatePath )
|
||||||
|
{
|
||||||
|
if( ( p = getenv( "XDG_STATE_HOME" ) ) != NULL && *p != '\0' )
|
||||||
|
Com_sprintf(homeStatePath, sizeof(homeStatePath), "%s%c", p, PATH_SEP);
|
||||||
|
else if( ( p = getenv( "HOME" ) ) != NULL && *p != '\0' )
|
||||||
|
Com_sprintf(homeStatePath, sizeof(homeStatePath), "%s%c.local%cstate%c", p, PATH_SEP, PATH_SEP, PATH_SEP);
|
||||||
|
|
||||||
|
if( *homeStatePath )
|
||||||
|
{
|
||||||
|
if( com_homepath && com_homepath->string[0] )
|
||||||
|
Q_strcat(homeStatePath, sizeof(homeStatePath), com_homepath->string);
|
||||||
|
else
|
||||||
|
Q_strcat(homeStatePath, sizeof(homeStatePath), HOMEPATH_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return homeStatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_LegacyHomePath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
static char *Sys_LegacyHomePath(void)
|
||||||
|
{
|
||||||
|
static char homePath[ MAX_OSPATH ] = { 0 };
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if( ( p = getenv( "FLATPAK_ID" ) ) != NULL && *p != '\0' )
|
||||||
|
{
|
||||||
|
// Flatpaks always use XDG
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !*homePath )
|
||||||
|
{
|
||||||
|
if( ( p = getenv( "HOME" ) ) != NULL && *p != '\0' )
|
||||||
|
{
|
||||||
|
Com_sprintf(homePath, sizeof(homePath), "%s%c%s",
|
||||||
|
p, PATH_SEP, HOMEPATH_NAME_UNIX_LEGACY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return homePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_MigrateToXDG
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
qboolean Sys_MigrateToXDG(void)
|
||||||
|
{
|
||||||
|
const char *scriptTemplate =
|
||||||
|
"#!/bin/sh\n"
|
||||||
|
|
||||||
|
"set -eu\n"
|
||||||
|
|
||||||
|
"legacy_home=\"%s\"\n"
|
||||||
|
"xdg_config_home=\"%s\"\n"
|
||||||
|
"xdg_data_home=\"%s\"\n"
|
||||||
|
"xdg_state_home=\"%s\"\n"
|
||||||
|
|
||||||
|
"xdg_config_pattern=\"*.cfg\"\n"
|
||||||
|
"xdg_data_pattern=\"demos/*.dm_* *.log *.pk3 *.txt \\\n"
|
||||||
|
" screenshots/*.jpg screenshots/*.tga videos/*.avi\"\n"
|
||||||
|
"xdg_state_pattern=\"*.dat q3history q3key\"\n"
|
||||||
|
|
||||||
|
"glob_copy() {\n"
|
||||||
|
" game_dir=${1:+$1/}\n"
|
||||||
|
" dst=\"$2\"\n"
|
||||||
|
" shift 2\n"
|
||||||
|
" for pattern in \"$@\"; do\n"
|
||||||
|
" subdir=$(dirname \"$pattern\")\n"
|
||||||
|
" [ \"$subdir\" = \".\" ] && subdir=\"\"\n"
|
||||||
|
" find \"$legacy_home/$game_dir\" \\\n"
|
||||||
|
" -path \"$legacy_home/$game_dir$pattern\" -type f \\\n"
|
||||||
|
" -exec mkdir -p \"$dst/$game_dir$subdir\" \\; \\\n"
|
||||||
|
" -exec cp -av {} \"$dst/$game_dir$subdir\" \\;\n"
|
||||||
|
" done\n"
|
||||||
|
"}\n"
|
||||||
|
|
||||||
|
"unmatched_copy() {\n"
|
||||||
|
" game_dir=${1:+$1/}\n"
|
||||||
|
" shift\n"
|
||||||
|
" find_args=\"\"\n"
|
||||||
|
" for pattern in \"$@\"; do\n"
|
||||||
|
" find_args=\"$find_args \\\n"
|
||||||
|
" -not -path \\\"$legacy_home/$game_dir$pattern\\\"\"\n"
|
||||||
|
" done\n"
|
||||||
|
" eval \"find '$legacy_home/$game_dir' -type f $find_args\" | \\\n"
|
||||||
|
" while IFS= read -r file; do\n"
|
||||||
|
" dst=\"$xdg_data_home${file#$legacy_home}\"\n"
|
||||||
|
" dst_dir=$(dirname \"$dst\")\n"
|
||||||
|
" mkdir -p \"$dst_dir\"\n"
|
||||||
|
" cp -av \"$file\" \"$dst\"\n"
|
||||||
|
" done\n"
|
||||||
|
"}\n"
|
||||||
|
|
||||||
|
"echo \"Starting XDG migration...\"\n"
|
||||||
|
|
||||||
|
"glob_copy \"\" \"$xdg_state_home\" \"qkey\"\n"
|
||||||
|
|
||||||
|
"for game_dir in \"$legacy_home\"/*; do\n"
|
||||||
|
" [ -d \"$game_dir\" ] || continue\n"
|
||||||
|
" game=$(basename \"$game_dir\")\n"
|
||||||
|
" glob_copy \"$game\" \"$xdg_config_home\" $xdg_config_pattern\n"
|
||||||
|
" glob_copy \"$game\" \"$xdg_data_home\" $xdg_data_pattern\n"
|
||||||
|
" glob_copy \"$game\" \"$xdg_state_home\" $xdg_state_pattern\n"
|
||||||
|
" unmatched_copy \"$game\" \\\n"
|
||||||
|
" $xdg_config_pattern \\\n"
|
||||||
|
" $xdg_data_pattern \\\n"
|
||||||
|
" $xdg_state_pattern\n"
|
||||||
|
"done\n"
|
||||||
|
|
||||||
|
"echo \"XDG migration complete!\"\n";
|
||||||
|
|
||||||
|
char scriptBuffer[2048];
|
||||||
|
int len = Com_sprintf( scriptBuffer, sizeof( scriptBuffer ), scriptTemplate,
|
||||||
|
Sys_LegacyHomePath( ), Sys_HomeConfigPath( ),
|
||||||
|
Sys_HomeDataPath( ), Sys_HomeStatePath( ) );
|
||||||
|
|
||||||
|
if( len < 0 || len >= (int)sizeof( scriptBuffer ) )
|
||||||
|
{
|
||||||
|
Com_Printf( "XDG migration error: substitution failed.\n" );
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
char scriptPath[] = "/tmp/xdgmigrationXXXXXX";
|
||||||
|
int fd = mkstemp( scriptPath );
|
||||||
|
if( fd == -1 )
|
||||||
|
{
|
||||||
|
Com_Printf( "XDG migration error: script creation failed.\n" );
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( write( fd, scriptBuffer, len ) != len )
|
||||||
|
{
|
||||||
|
close( fd );
|
||||||
|
unlink( scriptPath );
|
||||||
|
Com_Printf( "XDG migration error: script write failed.\n" );
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
close( fd );
|
||||||
|
|
||||||
|
if( chmod( scriptPath, 0700 ) == -1 )
|
||||||
|
{
|
||||||
|
unlink( scriptPath );
|
||||||
|
Com_Printf( "XDG migration error: script chmod failed.\n" );
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_ClearExecBuffer( );
|
||||||
|
Sys_AppendToExecBuffer( scriptPath );
|
||||||
|
int result = Sys_Exec( );
|
||||||
|
unlink( scriptPath );
|
||||||
|
|
||||||
|
return result == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_ShouldUseLegacyHomePath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
static qboolean Sys_ShouldUseLegacyHomePath(void)
|
||||||
|
{
|
||||||
|
if( access( Sys_HomeConfigPath( ), F_OK ) == 0 )
|
||||||
|
{
|
||||||
|
// If the XDG config directory exists, prefer XDG layout, regardless
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( com_homepath && com_homepath->string[0] ) ||
|
||||||
|
Cvar_VariableString( "fs_homepath" )[0] )
|
||||||
|
{
|
||||||
|
// If a custom homepath has been explicity set then
|
||||||
|
// that strongly implies that migration isn't desired
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *legacyHomePath = Sys_LegacyHomePath();
|
||||||
|
|
||||||
|
if( !*legacyHomePath || access( legacyHomePath, F_OK ) != 0 )
|
||||||
|
{
|
||||||
|
// The legacy home path doesn't exist
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
char migrationRefusedPath[ MAX_OSPATH ];
|
||||||
|
Com_sprintf( migrationRefusedPath, sizeof( migrationRefusedPath ),
|
||||||
|
"%s/.xdgMigrationRefused", legacyHomePath );
|
||||||
|
|
||||||
|
// If the user hasn't already refused, ask if they want to migrate
|
||||||
|
if( access( migrationRefusedPath, F_OK ) != 0 )
|
||||||
|
{
|
||||||
|
dialogResult_t result = Sys_Dialog( DT_YES_NO, va(
|
||||||
|
"Modern games and applications store files in "
|
||||||
|
"directories according to the Free Desktop standard. "
|
||||||
|
"Here's what that would look like for %s:\n\n"
|
||||||
|
"Configuration files:\n %s\n\n"
|
||||||
|
"Data files; pk3s, screenshots, logs, demos, etc.:\n %s\n\n"
|
||||||
|
"Internal runtime files:\n %s\n\n"
|
||||||
|
"At the moment all of these files are found here:\n %s\n\n"
|
||||||
|
"Do you want to copy your files to these new directories?",
|
||||||
|
PRODUCT_NAME,
|
||||||
|
Sys_HomeConfigPath( ), Sys_HomeDataPath( ), Sys_HomeStatePath( ),
|
||||||
|
legacyHomePath ),
|
||||||
|
"Home Directory Files Upgrade" );
|
||||||
|
|
||||||
|
if( result == DR_YES )
|
||||||
|
return !Sys_MigrateToXDG( );
|
||||||
|
|
||||||
|
// Guard against asking again in future
|
||||||
|
fclose( fopen( migrationRefusedPath, "w" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DefaultHomeConfigPath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
char *Sys_DefaultHomeConfigPath(void)
|
||||||
|
{
|
||||||
|
if( Sys_ShouldUseLegacyHomePath( ) )
|
||||||
|
return Sys_LegacyHomePath( );
|
||||||
|
|
||||||
|
return Sys_HomeConfigPath( );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DefaultHomeDataPath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
char *Sys_DefaultHomeDataPath(void)
|
||||||
|
{
|
||||||
|
if( Sys_ShouldUseLegacyHomePath( ) )
|
||||||
|
return Sys_LegacyHomePath( );
|
||||||
|
|
||||||
|
return Sys_HomeDataPath( );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DefaultHomeStatePath
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
char *Sys_DefaultHomeStatePath(void)
|
||||||
|
{
|
||||||
|
if( Sys_ShouldUseLegacyHomePath( ) )
|
||||||
|
return Sys_LegacyHomePath( );
|
||||||
|
|
||||||
|
return Sys_HomeStatePath( );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_SteamPath
|
Sys_SteamPath
|
||||||
|
|
@ -668,10 +966,10 @@ void Sys_ErrorDialog( const char *error )
|
||||||
char buffer[ 1024 ];
|
char buffer[ 1024 ];
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int f = -1;
|
int f = -1;
|
||||||
const char *homepath = Cvar_VariableString( "fs_homepath" );
|
const char *homedatapath = Cvar_VariableString( "fs_homedatapath" );
|
||||||
const char *gamedir = Cvar_VariableString( "fs_game" );
|
const char *gamedir = Cvar_VariableString( "fs_game" );
|
||||||
const char *fileName = "crashlog.txt";
|
const char *fileName = "crashlog.txt";
|
||||||
char *ospath = FS_BuildOSPath( homepath, gamedir, fileName );
|
char *ospath = FS_BuildOSPath( homedatapath, gamedir, fileName );
|
||||||
|
|
||||||
Sys_Print( va( "%s\n", error ) );
|
Sys_Print( va( "%s\n", error ) );
|
||||||
|
|
||||||
|
|
@ -680,7 +978,7 @@ void Sys_ErrorDialog( const char *error )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make sure the write path for the crashlog exists...
|
// Make sure the write path for the crashlog exists...
|
||||||
if( FS_CreatePath( ospath ) )
|
if( FS_CreatePath( homedatapath ) )
|
||||||
{
|
{
|
||||||
Com_Printf("ERROR: couldn't create path '%s' for crash log.\n", ospath);
|
Com_Printf("ERROR: couldn't create path '%s' for crash log.\n", ospath);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ void Sys_SetFloatEnv(void)
|
||||||
Sys_DefaultHomePath
|
Sys_DefaultHomePath
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
char *Sys_DefaultHomePath( void )
|
static char *Sys_DefaultHomePath( void )
|
||||||
{
|
{
|
||||||
static char homePath[ MAX_OSPATH ] = { 0 };
|
static char homePath[ MAX_OSPATH ] = { 0 };
|
||||||
|
|
||||||
|
|
@ -108,12 +108,16 @@ char *Sys_DefaultHomePath( void )
|
||||||
if(com_homepath->string[0])
|
if(com_homepath->string[0])
|
||||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||||
else
|
else
|
||||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_WIN);
|
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
return homePath;
|
return homePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *Sys_DefaultHomeConfigPath(void) { return Sys_DefaultHomePath(); }
|
||||||
|
char *Sys_DefaultHomeDataPath(void) { return Sys_DefaultHomePath(); }
|
||||||
|
char *Sys_DefaultHomeStatePath(void) { return Sys_DefaultHomePath(); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_SteamPath
|
Sys_SteamPath
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user