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, "%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 )
122 /* this is kinda crap, but hey */
123 strcpy( installPath, "../" );
126 home = LokiGetHomeDir();
133 char temp[ MAX_OS_PATH ];
142 home = LokiGetHomeDir();
146 /* do some path divining */
147 strcpy( temp, argv0 );
148 if( strrchr( argv0, '/' ) )
149 argv0 = strrchr( argv0, '/' ) + 1;
152 /* get path environment variable */
153 path = getenv( "PATH" );
157 last[ 0 ] = path[ 0 ];
161 /* go through each : segment of path */
162 while( last[ 0 ] != '\0' && found == qfalse )
167 /* find next chunk */
168 last = strchr( path, ':' );
170 last = path + strlen( path );
172 /* found home dir candidate */
175 strcpy( temp, home );
180 if( last > (path + 1) )
182 strncat( temp, path, (last - path) );
185 strcat( temp, "./" );
186 strcat( temp, argv0 );
188 /* verify the path */
189 if( access( temp, X_OK ) == 0 )
196 if( realpath( temp, installPath ) )
198 /* q3map is in "tools/" */
199 *(strrchr( installPath, '/' )) = '\0';
200 *(strrchr( installPath, '/' ) + 1) = '\0';
212 cleans a dos path \ -> /
215 void CleanPath( char *path )
229 gets the game_t based on a -game argument
230 returns NULL if no match found
233 game_t *GetGame( char *arg )
239 if( arg == NULL || arg[ 0 ] == '\0' )
243 if( !Q_stricmp( arg, "quake1" ) ||
244 !Q_stricmp( arg, "quake2" ) ||
245 !Q_stricmp( arg, "unreal" ) ||
246 !Q_stricmp( arg, "ut2k3" ) ||
247 !Q_stricmp( arg, "dn3d" ) ||
248 !Q_stricmp( arg, "dnf" ) ||
249 !Q_stricmp( arg, "hl" ) )
251 Sys_Printf( "April fools, silly rabbit!\n" );
257 while( games[ i ].arg != NULL )
259 if( Q_stricmp( arg, games[ i ].arg ) == 0 )
264 /* no matching game */
271 AddBasePath() - ydnar
272 adds a base path to the list
275 void AddBasePath( char *path )
278 if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
281 /* add it to the list */
282 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
283 strcpy( basePaths[ numBasePaths ], path );
284 CleanPath( basePaths[ numBasePaths ] );
291 AddHomeBasePath() - ydnar
292 adds a base path to the beginning of the list, prefixed by ~/
295 void AddHomeBasePath( char *path )
298 char temp[ MAX_OS_PATH ];
304 if( path == NULL || path[ 0 ] == '\0' )
307 /* concatenate home dir and path */
308 sprintf( temp, "%s/%s", homePath, path );
312 /* on Win32, we ONLY add it if the directory already exists */
314 dir = g_dir_open (temp, 0, NULL);
322 for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- )
323 basePaths[ i + 1 ] = basePaths[ i ];
325 /* add it to the list */
326 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
327 strcpy( basePaths[ 0 ], temp );
328 CleanPath( basePaths[ 0 ] );
335 AddGamePath() - ydnar
336 adds a game path to the list
339 void AddGamePath( char *path )
344 if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
347 /* add it to the list */
348 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
349 strcpy( gamePaths[ numGamePaths ], path );
350 CleanPath( gamePaths[ numGamePaths ] );
353 /* don't add it if it's already there */
354 for (i = 0; i < numGamePaths - 1; i++)
356 if (strcmp(gamePaths[i], gamePaths[numGamePaths - 1]) == 0)
358 free(gamePaths[numGamePaths - 1]);
359 gamePaths[numGamePaths - 1] = NULL;
372 cleaned up some of the path initialization code from bsp.c
373 will remove any arguments it uses
376 void InitPaths( int *argc, char **argv )
378 int i, j, k, len, len2;
379 char temp[ MAX_OS_PATH ];
383 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
385 /* get the install path for backup */
386 LokiInitPaths( argv[ 0 ] );
388 /* set game to default (q3a) */
393 /* parse through the arguments and extract those relevant to paths */
394 for( i = 0; i < *argc; i++ )
397 if( argv[ i ] == NULL )
401 if( strcmp( argv[ i ], "-game" ) == 0 )
404 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
405 argv[ i - 1 ] = NULL;
406 game = GetGame( argv[ i ] );
412 /* -fs_forbiddenpath */
413 else if( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 )
416 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
417 argv[ i - 1 ] = NULL;
418 if(g_numForbiddenDirs < VFS_MAXDIRS)
420 strncpy(g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX);
421 g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0;
422 ++g_numForbiddenDirs;
428 else if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
431 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
432 argv[ i - 1 ] = NULL;
433 AddBasePath( argv[ i ] );
438 else if( strcmp( argv[ i ], "-fs_game" ) == 0 )
441 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
442 argv[ i - 1 ] = NULL;
443 AddGamePath( argv[ i ] );
448 else if( strcmp( argv[ i ], "-fs_homebase" ) == 0 )
451 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
452 argv[ i - 1 ] = NULL;
453 homeBasePath = argv[i];
458 /* remove processed arguments */
459 for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
461 for( ; j < *argc && argv[ j ] == NULL; j++ );
462 argv[ i ] = argv[ j ];
463 if( argv[ i ] != NULL )
468 /* add standard game path */
469 AddGamePath( game->gamePath );
471 /* if there is no base path set, figure it out */
472 if( numBasePaths == 0 )
474 /* this is another crappy replacement for SetQdirFromPath() */
475 len2 = strlen( game->magic );
476 for( i = 0; i < *argc && numBasePaths == 0; i++ )
478 /* extract the arg */
479 strcpy( temp, argv[ i ] );
481 len = strlen( temp );
482 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
484 /* this is slow, but only done once */
485 for( j = 0; j < (len - len2); j++ )
487 /* check for the game's magic word */
488 if( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 )
490 /* now find the next slash and nuke everything after it */
491 while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
494 /* add this as a base path */
501 /* add install path */
502 if( numBasePaths == 0 )
503 AddBasePath( installPath );
506 if( numBasePaths == 0 )
507 Error( "Failed to find a valid base path." );
510 /* this only affects unix */
512 AddHomeBasePath( homeBasePath );
514 AddHomeBasePath( game->homeBasePath );
516 /* initialize vfs paths */
517 if( numBasePaths > MAX_BASE_PATHS )
518 numBasePaths = MAX_BASE_PATHS;
519 if( numGamePaths > MAX_GAME_PATHS )
520 numGamePaths = MAX_GAME_PATHS;
522 /* walk the list of game paths */
523 for( j = 0; j < numGamePaths; j++ )
525 /* walk the list of base paths */
526 for( i = 0; i < numBasePaths; i++ )
528 /* create a full path and initialize it */
529 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
530 vfsInitDirectory( temp );