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 ];
120 home = LokiGetHomeDir();
124 /* do some path divining */
125 strcpy( temp, argv0 );
126 if( strrchr( argv0, '/' ) )
127 argv0 = strrchr( argv0, '/' ) + 1;
130 /* get path environment variable */
131 path = getenv( "PATH" );
135 last[ 0 ] = path[ 0 ];
139 /* go through each : segment of path */
140 while( last[ 0 ] != '\0' && found == qfalse )
145 /* find next chunk */
146 last = strchr( path, ':' );
148 last = path + strlen( path );
150 /* found home dir candidate */
153 strcpy( temp, home );
158 if( last > (path + 1) )
160 strncat( temp, path, (last - path) );
163 strcat( temp, "./" );
164 strcat( temp, argv0 );
166 /* verify the path */
167 if( access( temp, X_OK ) == 0 )
174 if( realpath( temp, installPath ) )
176 /* q3map is in "tools/" */
177 *(strrchr( installPath, '/' )) = '\0';
178 *(strrchr( installPath, '/' ) + 1) = '\0';
190 cleans a dos path \ -> /
193 void CleanPath( char *path )
207 gets the game_t based on a -game argument
208 returns NULL if no match found
211 game_t *GetGame( char *arg )
217 if( arg == NULL || arg[ 0 ] == '\0' )
221 if( !Q_stricmp( arg, "quake1" ) ||
222 !Q_stricmp( arg, "quake2" ) ||
223 !Q_stricmp( arg, "unreal" ) ||
224 !Q_stricmp( arg, "ut2k3" ) ||
225 !Q_stricmp( arg, "dn3d" ) ||
226 !Q_stricmp( arg, "dnf" ) ||
227 !Q_stricmp( arg, "hl" ) )
229 Sys_Printf( "April fools, silly rabbit!\n" );
235 while( games[ i ].arg != NULL )
237 if( Q_stricmp( arg, games[ i ].arg ) == 0 )
242 /* no matching game */
249 AddBasePath() - ydnar
250 adds a base path to the list
253 void AddBasePath( char *path )
256 if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
259 /* add it to the list */
260 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
261 strcpy( basePaths[ numBasePaths ], path );
262 CleanPath( basePaths[ numBasePaths ] );
269 AddHomeBasePath() - ydnar
270 adds a base path to the beginning of the list, prefixed by ~/
273 void AddHomeBasePath( char *path )
277 char temp[ MAX_OS_PATH ];
281 if( path == NULL || path[ 0 ] == '\0' )
285 for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- )
286 basePaths[ i + 1 ] = basePaths[ i ];
288 /* concatenate home dir and path */
289 sprintf( temp, "%s/%s", homePath, path );
291 /* add it to the list */
292 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
293 strcpy( basePaths[ 0 ], temp );
294 CleanPath( basePaths[ 0 ] );
302 AddGamePath() - ydnar
303 adds a game path to the list
306 void AddGamePath( char *path )
311 if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
314 /* add it to the list */
315 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
316 strcpy( gamePaths[ numGamePaths ], path );
317 CleanPath( gamePaths[ numGamePaths ] );
320 /* don't add it if it's already there */
321 for (i = 0; i < numGamePaths - 1; i++)
323 if (strcmp(gamePaths[i], gamePaths[numGamePaths - 1]) == 0)
325 free(gamePaths[numGamePaths - 1]);
326 gamePaths[numGamePaths - 1] = NULL;
339 cleaned up some of the path initialization code from bsp.c
340 will remove any arguments it uses
343 void InitPaths( int *argc, char **argv )
345 int i, j, k, len, len2;
346 char temp[ MAX_OS_PATH ];
350 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
352 /* get the install path for backup */
353 LokiInitPaths( argv[ 0 ] );
355 /* set game to default (q3a) */
360 /* parse through the arguments and extract those relevant to paths */
361 for( i = 0; i < *argc; i++ )
364 if( argv[ i ] == NULL )
368 if( strcmp( argv[ i ], "-game" ) == 0 )
371 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
372 argv[ i - 1 ] = NULL;
373 game = GetGame( argv[ i ] );
379 /* -fs_forbiddenpath */
380 else if( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 )
383 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
384 argv[ i - 1 ] = NULL;
385 if(g_numForbiddenDirs < VFS_MAXDIRS)
387 strncpy(g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX);
388 g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0;
389 ++g_numForbiddenDirs;
395 else if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
398 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
399 argv[ i - 1 ] = NULL;
400 AddBasePath( argv[ i ] );
405 else if( strcmp( argv[ i ], "-fs_game" ) == 0 )
408 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
409 argv[ i - 1 ] = NULL;
410 AddGamePath( argv[ i ] );
415 else if( strcmp( argv[ i ], "-fs_homebase" ) == 0 )
418 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
419 argv[ i - 1 ] = NULL;
420 homeBasePath = argv[i];
425 /* remove processed arguments */
426 for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
428 for( ; j < *argc && argv[ j ] == NULL; j++ );
429 argv[ i ] = argv[ j ];
430 if( argv[ i ] != NULL )
435 /* add standard game path */
436 AddGamePath( game->gamePath );
438 /* if there is no base path set, figure it out */
439 if( numBasePaths == 0 )
441 /* this is another crappy replacement for SetQdirFromPath() */
442 len2 = strlen( game->magic );
443 for( i = 0; i < *argc && numBasePaths == 0; i++ )
445 /* extract the arg */
446 strcpy( temp, argv[ i ] );
448 len = strlen( temp );
449 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
451 /* this is slow, but only done once */
452 for( j = 0; j < (len - len2); j++ )
454 /* check for the game's magic word */
455 if( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 )
457 /* now find the next slash and nuke everything after it */
458 while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
461 /* add this as a base path */
468 /* add install path */
469 if( numBasePaths == 0 )
470 AddBasePath( installPath );
473 if( numBasePaths == 0 )
474 Error( "Failed to find a valid base path." );
477 /* this only affects unix */
479 AddHomeBasePath( homeBasePath );
481 AddHomeBasePath( game->homeBasePath );
483 /* initialize vfs paths */
484 if( numBasePaths > MAX_BASE_PATHS )
485 numBasePaths = MAX_BASE_PATHS;
486 if( numGamePaths > MAX_GAME_PATHS )
487 numGamePaths = MAX_GAME_PATHS;
489 /* walk the list of game paths */
490 for( j = 0; j < numGamePaths; j++ )
492 /* walk the list of base paths */
493 for( i = 0; i < numBasePaths; i++ )
495 /* create a full path and initialize it */
496 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
497 vfsInitDirectory( temp );