1 /* -------------------------------------------------------------------------------
3 Copyright (C) 1999-2007 id Software, Inc. and contributors.
4 For a list of contributors, see the accompanying CONTRIBUTORS file.
6 This file is part of GtkRadiant.
8 GtkRadiant is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 GtkRadiant is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GtkRadiant; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 ----------------------------------------------------------------------------------
24 This code has been altered significantly from its original form, to support
25 several games based on the Quake III Arena engine, in the form of "Q3Map2."
27 ------------------------------------------------------------------------------- */
42 #define MAX_BASE_PATHS 10
43 #define MAX_GAME_PATHS 10
46 qboolean homePathUsesDot;
47 char installPath[ MAX_OS_PATH ];
50 char *basePaths[ MAX_BASE_PATHS ];
52 char *gamePaths[ MAX_GAME_PATHS ];
53 char *homeBasePath = NULL;
57 some of this code is based off the original q3map port from loki
58 and finds various paths. moved here from bsp.c for clarity.
63 gets the user's home dir (for ~/.q3a)
69 char *LokiGetHomeDir( qboolean *usedot )
76 static char buf[MAX_OS_PATH];
77 TCHAR mydocsdir[MAX_PATH + 1];
78 if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir))
80 snprintf(buf, sizeof(buf), "%s/My Games", mydocsdir);
92 /* get the home environment variable */
93 home = getenv( "HOME" );
96 /* do some more digging */
99 while( (pwd = getpwent()) != NULL )
101 if( pwd->pw_uid == id )
112 static char foo[MAX_OS_PATH];
113 snprintf(foo, sizeof(foo), "%s/Library/Application Support", home);
114 if(access(foo, X_OK) == 0)
131 initializes some paths on linux/os x
134 void LokiInitPaths( char *argv0 )
139 /* this is kinda crap, but hey */
140 strcpy( installPath, "../" );
143 home = LokiGetHomeDir(&homePathUsesDot);
150 char temp[ MAX_OS_PATH ];
159 home = LokiGetHomeDir(&homePathUsesDot);
163 /* do some path divining */
164 strcpy( temp, argv0 );
165 if( strrchr( argv0, '/' ) )
166 argv0 = strrchr( argv0, '/' ) + 1;
169 /* get path environment variable */
170 path = getenv( "PATH" );
174 last[ 0 ] = path[ 0 ];
178 /* go through each : segment of path */
179 while( last[ 0 ] != '\0' && found == qfalse )
184 /* find next chunk */
185 last = strchr( path, ':' );
187 last = path + strlen( path );
189 /* found home dir candidate */
192 strcpy( temp, home );
197 if( last > (path + 1) )
199 strncat( temp, path, (last - path) );
202 strcat( temp, "./" );
203 strcat( temp, argv0 );
205 /* verify the path */
206 if( access( temp, X_OK ) == 0 )
213 if( realpath( temp, installPath ) )
215 /* q3map is in "tools/" */
216 *(strrchr( installPath, '/' )) = '\0';
217 *(strrchr( installPath, '/' ) + 1) = '\0';
229 cleans a dos path \ -> /
232 void CleanPath( char *path )
246 gets the game_t based on a -game argument
247 returns NULL if no match found
250 game_t *GetGame( char *arg )
256 if( arg == NULL || arg[ 0 ] == '\0' )
260 if( !Q_stricmp( arg, "quake1" ) ||
261 !Q_stricmp( arg, "quake2" ) ||
262 !Q_stricmp( arg, "unreal" ) ||
263 !Q_stricmp( arg, "ut2k3" ) ||
264 !Q_stricmp( arg, "dn3d" ) ||
265 !Q_stricmp( arg, "dnf" ) ||
266 !Q_stricmp( arg, "hl" ) )
268 Sys_Printf( "April fools, silly rabbit!\n" );
274 while( games[ i ].arg != NULL )
276 if( Q_stricmp( arg, games[ i ].arg ) == 0 )
281 /* no matching game */
288 AddBasePath() - ydnar
289 adds a base path to the list
292 void AddBasePath( char *path )
295 if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
298 /* add it to the list */
299 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
300 strcpy( basePaths[ numBasePaths ], path );
301 CleanPath( basePaths[ numBasePaths ] );
308 AddHomeBasePath() - ydnar
309 adds a base path to the beginning of the list, prefixed by ~/
312 void AddHomeBasePath( char *path )
315 char temp[ MAX_OS_PATH ];
321 if( path == NULL || path[ 0 ] == '\0' )
324 /* concatenate home dir and path */
325 sprintf( temp, "%s/%s", homePath, homePathUsesDot ? path : (path+1) );
329 /* on Win32, we ONLY add it if the directory already exists */
331 dir = g_dir_open (temp, 0, NULL);
339 for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- )
340 basePaths[ i + 1 ] = basePaths[ i ];
342 /* add it to the list */
343 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
344 strcpy( basePaths[ 0 ], temp );
345 CleanPath( basePaths[ 0 ] );
352 AddGamePath() - ydnar
353 adds a game path to the list
356 void AddGamePath( char *path )
361 if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
364 /* add it to the list */
365 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
366 strcpy( gamePaths[ numGamePaths ], path );
367 CleanPath( gamePaths[ numGamePaths ] );
370 /* don't add it if it's already there */
371 for (i = 0; i < numGamePaths - 1; i++)
373 if (strcmp(gamePaths[i], gamePaths[numGamePaths - 1]) == 0)
375 free(gamePaths[numGamePaths - 1]);
376 gamePaths[numGamePaths - 1] = NULL;
389 cleaned up some of the path initialization code from bsp.c
390 will remove any arguments it uses
393 void InitPaths( int *argc, char **argv )
395 int i, j, k, len, len2;
396 char temp[ MAX_OS_PATH ];
400 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
402 /* get the install path for backup */
403 LokiInitPaths( argv[ 0 ] );
405 /* set game to default (q3a) */
410 /* parse through the arguments and extract those relevant to paths */
411 for( i = 0; i < *argc; i++ )
414 if( argv[ i ] == NULL )
418 if( strcmp( argv[ i ], "-game" ) == 0 )
421 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
422 argv[ i - 1 ] = NULL;
423 game = GetGame( argv[ i ] );
429 /* -fs_forbiddenpath */
430 else if( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 )
433 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
434 argv[ i - 1 ] = NULL;
435 if(g_numForbiddenDirs < VFS_MAXDIRS)
437 strncpy(g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX);
438 g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0;
439 ++g_numForbiddenDirs;
445 else if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
448 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
449 argv[ i - 1 ] = NULL;
450 AddBasePath( argv[ i ] );
455 else if( strcmp( argv[ i ], "-fs_game" ) == 0 )
458 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
459 argv[ i - 1 ] = NULL;
460 AddGamePath( argv[ i ] );
465 else if( strcmp( argv[ i ], "-fs_homebase" ) == 0 )
468 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
469 argv[ i - 1 ] = NULL;
470 homeBasePath = argv[i];
475 /* remove processed arguments */
476 for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
478 for( ; j < *argc && argv[ j ] == NULL; j++ );
479 argv[ i ] = argv[ j ];
480 if( argv[ i ] != NULL )
485 /* add standard game path */
486 AddGamePath( game->gamePath );
488 /* if there is no base path set, figure it out */
489 if( numBasePaths == 0 )
491 /* this is another crappy replacement for SetQdirFromPath() */
492 len2 = strlen( game->magic );
493 for( i = 0; i < *argc && numBasePaths == 0; i++ )
495 /* extract the arg */
496 strcpy( temp, argv[ i ] );
498 len = strlen( temp );
499 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
501 /* this is slow, but only done once */
502 for( j = 0; j < (len - len2); j++ )
504 /* check for the game's magic word */
505 if( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 )
507 /* now find the next slash and nuke everything after it */
508 while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
511 /* add this as a base path */
518 /* add install path */
519 if( numBasePaths == 0 )
520 AddBasePath( installPath );
523 if( numBasePaths == 0 )
524 Error( "Failed to find a valid base path." );
527 /* this only affects unix */
529 AddHomeBasePath( homeBasePath );
531 AddHomeBasePath( game->homeBasePath );
533 /* initialize vfs paths */
534 if( numBasePaths > MAX_BASE_PATHS )
535 numBasePaths = MAX_BASE_PATHS;
536 if( numGamePaths > MAX_GAME_PATHS )
537 numGamePaths = MAX_GAME_PATHS;
539 /* walk the list of game paths */
540 for( j = 0; j < numGamePaths; j++ )
542 /* walk the list of base paths */
543 for( i = 0; i < numBasePaths; i++ )
545 /* create a full path and initialize it */
546 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
547 vfsInitDirectory( temp );