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 char installPath[ MAX_OS_PATH ];
49 char *basePaths[ MAX_BASE_PATHS ];
51 char *gamePaths[ MAX_GAME_PATHS ];
52 char *homeBasePath = NULL;
56 some of this code is based off the original q3map port from loki
57 and finds various paths. moved here from bsp.c for clarity.
62 gets the user's home dir (for ~/.q3a)
68 char *LokiGetHomeDir( void )
74 static char buf[MAX_OS_PATH];
75 TCHAR mydocsdir[MAX_PATH + 1];
76 if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir))
78 snprintf(buf, sizeof(buf), "%s/My Games", mydocsdir);
89 /* get the home environment variable */
90 home = getenv( "HOME" );
93 /* do some more digging */
96 while( (pwd = getpwent()) != NULL )
98 if( pwd->pw_uid == id )
116 initializes some paths on linux/os x
119 void LokiInitPaths( char *argv0 )
124 /* this is kinda crap, but hey */
125 strcpy( installPath, "../" );
128 home = LokiGetHomeDir();
135 char temp[ MAX_OS_PATH ];
144 home = LokiGetHomeDir();
148 /* do some path divining */
149 strcpy( temp, argv0 );
150 if( strrchr( argv0, '/' ) )
151 argv0 = strrchr( argv0, '/' ) + 1;
154 /* get path environment variable */
155 path = getenv( "PATH" );
159 last[ 0 ] = path[ 0 ];
163 /* go through each : segment of path */
164 while( last[ 0 ] != '\0' && found == qfalse )
169 /* find next chunk */
170 last = strchr( path, ':' );
172 last = path + strlen( path );
174 /* found home dir candidate */
177 strcpy( temp, home );
182 if( last > (path + 1) )
184 strncat( temp, path, (last - path) );
187 strcat( temp, "./" );
188 strcat( temp, argv0 );
190 /* verify the path */
191 if( access( temp, X_OK ) == 0 )
198 if( realpath( temp, installPath ) )
200 /* q3map is in "tools/" */
201 *(strrchr( installPath, '/' )) = '\0';
202 *(strrchr( installPath, '/' ) + 1) = '\0';
214 cleans a dos path \ -> /
217 void CleanPath( char *path )
231 gets the game_t based on a -game argument
232 returns NULL if no match found
235 game_t *GetGame( char *arg )
241 if( arg == NULL || arg[ 0 ] == '\0' )
245 if( !Q_stricmp( arg, "quake1" ) ||
246 !Q_stricmp( arg, "quake2" ) ||
247 !Q_stricmp( arg, "unreal" ) ||
248 !Q_stricmp( arg, "ut2k3" ) ||
249 !Q_stricmp( arg, "dn3d" ) ||
250 !Q_stricmp( arg, "dnf" ) ||
251 !Q_stricmp( arg, "hl" ) )
253 Sys_Printf( "April fools, silly rabbit!\n" );
259 while( games[ i ].arg != NULL )
261 if( Q_stricmp( arg, games[ i ].arg ) == 0 )
266 /* no matching game */
273 AddBasePath() - ydnar
274 adds a base path to the list
277 void AddBasePath( char *path )
280 if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
283 /* add it to the list */
284 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
285 strcpy( basePaths[ numBasePaths ], path );
286 CleanPath( basePaths[ numBasePaths ] );
293 AddHomeBasePath() - ydnar
294 adds a base path to the beginning of the list, prefixed by ~/
297 void AddHomeBasePath( char *path )
300 char temp[ MAX_OS_PATH ];
306 if( path == NULL || path[ 0 ] == '\0' )
309 /* concatenate home dir and path */
310 sprintf( temp, "%s/%s", homePath, path );
314 /* on Win32, we ONLY add it if the directory already exists */
316 dir = g_dir_open (temp, 0, NULL);
324 for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- )
325 basePaths[ i + 1 ] = basePaths[ i ];
327 /* add it to the list */
328 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
329 strcpy( basePaths[ 0 ], temp );
330 CleanPath( basePaths[ 0 ] );
337 AddGamePath() - ydnar
338 adds a game path to the list
341 void AddGamePath( char *path )
346 if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
349 /* add it to the list */
350 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
351 strcpy( gamePaths[ numGamePaths ], path );
352 CleanPath( gamePaths[ numGamePaths ] );
355 /* don't add it if it's already there */
356 for (i = 0; i < numGamePaths - 1; i++)
358 if (strcmp(gamePaths[i], gamePaths[numGamePaths - 1]) == 0)
360 free(gamePaths[numGamePaths - 1]);
361 gamePaths[numGamePaths - 1] = NULL;
374 cleaned up some of the path initialization code from bsp.c
375 will remove any arguments it uses
378 void InitPaths( int *argc, char **argv )
380 int i, j, k, len, len2;
381 char temp[ MAX_OS_PATH ];
385 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
387 /* get the install path for backup */
388 LokiInitPaths( argv[ 0 ] );
390 /* set game to default (q3a) */
395 /* parse through the arguments and extract those relevant to paths */
396 for( i = 0; i < *argc; i++ )
399 if( argv[ i ] == NULL )
403 if( strcmp( argv[ i ], "-game" ) == 0 )
406 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
407 argv[ i - 1 ] = NULL;
408 game = GetGame( argv[ i ] );
414 /* -fs_forbiddenpath */
415 else if( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 )
418 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
419 argv[ i - 1 ] = NULL;
420 if(g_numForbiddenDirs < VFS_MAXDIRS)
422 strncpy(g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX);
423 g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0;
424 ++g_numForbiddenDirs;
430 else if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
433 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
434 argv[ i - 1 ] = NULL;
435 AddBasePath( argv[ i ] );
440 else if( strcmp( argv[ i ], "-fs_game" ) == 0 )
443 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
444 argv[ i - 1 ] = NULL;
445 AddGamePath( argv[ i ] );
450 else if( strcmp( argv[ i ], "-fs_homebase" ) == 0 )
453 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
454 argv[ i - 1 ] = NULL;
455 homeBasePath = argv[i];
460 /* remove processed arguments */
461 for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
463 for( ; j < *argc && argv[ j ] == NULL; j++ );
464 argv[ i ] = argv[ j ];
465 if( argv[ i ] != NULL )
470 /* add standard game path */
471 AddGamePath( game->gamePath );
473 /* if there is no base path set, figure it out */
474 if( numBasePaths == 0 )
476 /* this is another crappy replacement for SetQdirFromPath() */
477 len2 = strlen( game->magic );
478 for( i = 0; i < *argc && numBasePaths == 0; i++ )
480 /* extract the arg */
481 strcpy( temp, argv[ i ] );
483 len = strlen( temp );
484 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
486 /* this is slow, but only done once */
487 for( j = 0; j < (len - len2); j++ )
489 /* check for the game's magic word */
490 if( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 )
492 /* now find the next slash and nuke everything after it */
493 while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
496 /* add this as a base path */
503 /* add install path */
504 if( numBasePaths == 0 )
505 AddBasePath( installPath );
508 if( numBasePaths == 0 )
509 Error( "Failed to find a valid base path." );
512 /* this only affects unix */
514 AddHomeBasePath( homeBasePath );
516 AddHomeBasePath( game->homeBasePath );
518 /* initialize vfs paths */
519 if( numBasePaths > MAX_BASE_PATHS )
520 numBasePaths = MAX_BASE_PATHS;
521 if( numGamePaths > MAX_GAME_PATHS )
522 numGamePaths = MAX_GAME_PATHS;
524 /* walk the list of game paths */
525 for( j = 0; j < numGamePaths; j++ )
527 /* walk the list of base paths */
528 for( i = 0; i < numBasePaths; i++ )
530 /* create a full path and initialize it */
531 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
532 vfsInitDirectory( temp );