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)
65 char *LokiGetHomeDir( void )
75 /* get the home environment variable */
76 home = getenv( "HOME" );
79 /* do some more digging */
82 while( (pwd = getpwent()) != NULL )
84 if( pwd->pw_uid == id )
102 initializes some paths on linux/os x
105 void LokiInitPaths( char *argv0 )
108 /* this is kinda crap, but hey */
109 strcpy( installPath, "../" );
111 char temp[ MAX_OS_PATH ];
119 home = LokiGetHomeDir();
123 /* do some path divining */
124 strcpy( temp, argv0 );
125 if( strrchr( temp, '/' ) )
126 argv0 = strrchr( argv0, '/' ) + 1;
129 /* get path environment variable */
130 path = getenv( "PATH" );
133 last[ 0 ] = path[ 0 ];
137 /* go through each : segment of path */
138 while( last[ 0 ] != '\0' && found == qfalse )
143 /* find next chunk */
144 last = strchr( path, ':' );
146 last = path + strlen( path );
148 /* found home dir candidate */
151 strcpy( temp, home );
156 if( last > (path + 1) )
158 strncat( temp, path, (last - path) );
161 strcat( temp, "./" );
162 strcat( temp, argv0 );
164 /* verify the path */
165 if( access( temp, X_OK ) == 0 )
172 if( realpath( temp, installPath ) )
174 /* q3map is in "tools/" */
175 *(strrchr( installPath, '/' )) = '\0';
176 *(strrchr( installPath, '/' ) + 1) = '\0';
188 cleans a dos path \ -> /
191 void CleanPath( char *path )
205 gets the game_t based on a -game argument
206 returns NULL if no match found
209 game_t *GetGame( char *arg )
215 if( arg == NULL || arg[ 0 ] == '\0' )
219 if( !Q_stricmp( arg, "quake1" ) ||
220 !Q_stricmp( arg, "quake2" ) ||
221 !Q_stricmp( arg, "unreal" ) ||
222 !Q_stricmp( arg, "ut2k3" ) ||
223 !Q_stricmp( arg, "dn3d" ) ||
224 !Q_stricmp( arg, "dnf" ) ||
225 !Q_stricmp( arg, "hl" ) )
227 Sys_Printf( "April fools, silly rabbit!\n" );
233 while( games[ i ].arg != NULL )
235 if( Q_stricmp( arg, games[ i ].arg ) == 0 )
240 /* no matching game */
247 AddBasePath() - ydnar
248 adds a base path to the list
251 void AddBasePath( char *path )
254 if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
257 /* add it to the list */
258 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
259 strcpy( basePaths[ numBasePaths ], path );
260 CleanPath( basePaths[ numBasePaths ] );
267 AddHomeBasePath() - ydnar
268 adds a base path to the beginning of the list, prefixed by ~/
271 void AddHomeBasePath( char *path )
275 char temp[ MAX_OS_PATH ];
279 if( path == NULL || path[ 0 ] == '\0' )
283 for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- )
284 basePaths[ i + 1 ] = basePaths[ i ];
286 /* concatenate home dir and path */
287 sprintf( temp, "%s/%s", homePath, path );
289 /* add it to the list */
290 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
291 strcpy( basePaths[ 0 ], temp );
292 CleanPath( basePaths[ 0 ] );
300 AddGamePath() - ydnar
301 adds a game path to the list
304 void AddGamePath( char *path )
307 if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
310 /* add it to the list */
311 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
312 strcpy( gamePaths[ numGamePaths ], path );
313 CleanPath( gamePaths[ numGamePaths ] );
322 cleaned up some of the path initialization code from bsp.c
323 will remove any arguments it uses
326 void InitPaths( int *argc, char **argv )
328 int i, j, k, len, len2;
329 char temp[ MAX_OS_PATH ];
333 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
335 /* get the install path for backup */
336 LokiInitPaths( argv[ 0 ] );
338 /* set game to default (q3a) */
343 /* parse through the arguments and extract those relevant to paths */
344 for( i = 0; i < *argc; i++ )
347 if( argv[ i ] == NULL )
351 if( strcmp( argv[ i ], "-game" ) == 0 )
354 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
355 argv[ i - 1 ] = NULL;
356 game = GetGame( argv[ i ] );
362 /* -fs_forbiddenpath */
363 else if( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 )
366 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
367 argv[ i - 1 ] = NULL;
368 if(g_numForbiddenDirs < VFS_MAXDIRS)
370 strncpy(g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX);
371 g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0;
372 ++g_numForbiddenDirs;
378 else if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
381 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
382 argv[ i - 1 ] = NULL;
383 AddBasePath( argv[ i ] );
388 else if( strcmp( argv[ i ], "-fs_game" ) == 0 )
391 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
392 argv[ i - 1 ] = NULL;
393 AddGamePath( argv[ i ] );
398 else if( strcmp( argv[ i ], "-fs_homebase" ) == 0 )
401 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
402 argv[ i - 1 ] = NULL;
403 homeBasePath = argv[i];
408 /* remove processed arguments */
409 for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
411 for( ; j < *argc && argv[ j ] == NULL; j++ );
412 argv[ i ] = argv[ j ];
413 if( argv[ i ] != NULL )
418 /* add standard game path */
419 AddGamePath( game->gamePath );
421 /* if there is no base path set, figure it out */
422 if( numBasePaths == 0 )
424 /* this is another crappy replacement for SetQdirFromPath() */
425 len2 = strlen( game->magic );
426 for( i = 0; i < *argc && numBasePaths == 0; i++ )
428 /* extract the arg */
429 strcpy( temp, argv[ i ] );
431 len = strlen( temp );
432 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
434 /* this is slow, but only done once */
435 for( j = 0; j < (len - len2); j++ )
437 /* check for the game's magic word */
438 if( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 )
440 /* now find the next slash and nuke everything after it */
441 while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
444 /* add this as a base path */
451 /* add install path */
452 if( numBasePaths == 0 )
453 AddBasePath( installPath );
456 if( numBasePaths == 0 )
457 Error( "Failed to find a valid base path." );
460 /* this only affects unix */
462 AddHomeBasePath( homeBasePath );
464 AddHomeBasePath( game->homeBasePath );
466 /* initialize vfs paths */
467 if( numBasePaths > MAX_BASE_PATHS )
468 numBasePaths = MAX_BASE_PATHS;
469 if( numGamePaths > MAX_GAME_PATHS )
470 numGamePaths = MAX_GAME_PATHS;
472 /* walk the list of game paths */
473 for( j = 0; j < numGamePaths; j++ )
475 /* walk the list of base paths */
476 for( i = 0; i < numBasePaths; i++ )
478 /* create a full path and initialize it */
479 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
480 vfsInitDirectory( temp );