2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 ----------------------------------------------------------------------------------
23 This code has been altered significantly from its original form, to support
24 several games based on the Quake III Arena engine, in the form of "Q3Map2."
26 ------------------------------------------------------------------------------- */
41 #define MAX_BASE_PATHS 10
42 #define MAX_GAME_PATHS 10
45 char installPath[ MAX_OS_PATH ];
48 char *basePaths[ MAX_BASE_PATHS ];
50 char *gamePaths[ MAX_GAME_PATHS ];
55 some of this code is based off the original q3map port from loki
56 and finds various paths. moved here from bsp.c for clarity.
61 gets the user's home dir (for ~/.q3a)
64 char *LokiGetHomeDir( void )
74 /* get the home environment variable */
75 home = getenv( "HOME" );
78 /* do some more digging */
81 while( (pwd = getpwent()) != NULL )
83 if( pwd->pw_uid == id )
101 initializes some paths on linux/os x
104 void LokiInitPaths( char *argv0 )
107 /* this is kinda crap, but hey */
108 strcpy( installPath, "../" );
110 char temp[ MAX_OS_PATH ];
118 home = LokiGetHomeDir();
122 /* do some path divining */
123 strcpy( temp, argv0 );
124 if( strrchr( temp, '/' ) )
125 argv0 = strrchr( argv0, '/' ) + 1;
128 /* get path environment variable */
129 path = getenv( "PATH" );
132 last[ 0 ] = path[ 0 ];
136 /* go through each : segment of path */
137 while( last[ 0 ] != '\0' && found == qfalse )
142 /* find next chunk */
143 last = strchr( path, ':' );
145 last = path + strlen( path );
147 /* found home dir candidate */
150 strcpy( temp, home );
155 if( last > (path + 1) )
157 strncat( temp, path, (last - path) );
160 strcat( temp, "./" );
161 strcat( temp, argv0 );
163 /* verify the path */
164 if( access( temp, X_OK ) == 0 )
171 if( realpath( temp, installPath ) )
173 /* q3map is in "tools/" */
174 *(strrchr( installPath, '/' )) = '\0';
175 *(strrchr( installPath, '/' ) + 1) = '\0';
187 cleans a dos path \ -> /
190 void CleanPath( char *path )
204 sets the game based on a -game argument
205 doesn't set it if the game doesn't match any known games
208 void SetGame( char *arg )
214 if( arg == NULL || arg[ 0 ] == '\0' )
218 if( !Q_stricmp( arg, "quake1" ) ||
219 !Q_stricmp( arg, "quake2" ) ||
220 !Q_stricmp( arg, "unreal" ) ||
221 !Q_stricmp( arg, "ut2k3" ) ||
222 !Q_stricmp( arg, "dn3d" ) ||
223 !Q_stricmp( arg, "dnf" ) ||
224 !Q_stricmp( arg, "hl" ) )
226 Sys_Printf( "April fools, silly rabbit!\n" );
232 while( games[ i ].arg != NULL )
234 if( Q_stricmp( arg, games[ i ].arg ) == 0 )
243 AddBasePath() - ydnar
244 adds a base path to the list
247 void AddBasePath( char *path )
250 if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
253 /* add it to the list */
254 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
255 strcpy( basePaths[ numBasePaths ], path );
256 CleanPath( basePaths[ numBasePaths ] );
263 AddHomeBasePath() - ydnar
264 adds a base path to the beginning of the list, prefixed by ~/
267 void AddHomeBasePath( char *path )
271 char temp[ MAX_OS_PATH ];
275 if( path == NULL || path[ 0 ] == '\0' )
279 for( i = 0; i < (MAX_BASE_PATHS - 1); i++ )
280 basePaths[ i + 1 ] = basePaths[ i ];
282 /* concatenate home dir and path */
283 sprintf( temp, "%s/%s", homePath, path );
285 /* add it to the list */
286 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
287 strcpy( basePaths[ 0 ], temp );
288 CleanPath( basePaths[ 0 ] );
296 AddGamePath() - ydnar
297 adds a game path to the list
300 void AddGamePath( char *path )
303 if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
306 /* add it to the list */
307 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
308 strcpy( gamePaths[ numGamePaths ], path );
309 CleanPath( gamePaths[ numGamePaths ] );
318 cleaned up some of the path initialization code from bsp.c
319 will remove any arguments it uses
322 void InitPaths( int *argc, char **argv )
324 int i, j, k, len, len2;
325 char temp[ MAX_OS_PATH ];
329 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
331 /* get the install path for backup */
332 LokiInitPaths( argv[ 0 ] );
334 /* set game to default (q3a) */
339 /* parse through the arguments and extract those relevant to paths */
340 for( i = 0; i < *argc; i++ )
343 if( argv[ i ] == NULL )
347 if( strcmp( argv[ i ], "-game" ) == 0 )
350 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
351 argv[ i - 1 ] = NULL;
352 SetGame( argv[ i ] );
357 else if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
360 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
361 argv[ i - 1 ] = NULL;
362 AddBasePath( argv[ i ] );
367 else if( strcmp( argv[ i ], "-fs_game" ) == 0 )
370 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
371 argv[ i - 1 ] = NULL;
372 AddGamePath( argv[ i ] );
377 /* remove processed arguments */
378 for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
380 for( j; j < *argc && argv[ j ] == NULL; j++ );
381 argv[ i ] = argv[ j ];
382 if( argv[ i ] != NULL )
387 /* add standard game path */
388 AddGamePath( game->gamePath );
390 /* if there is no base path set, figure it out */
391 if( numBasePaths == 0 )
393 /* this is another crappy replacement for SetQdirFromPath() */
394 len2 = strlen( game->magic );
395 for( i = 0; i < *argc && numBasePaths == 0; i++ )
397 /* extract the arg */
398 strcpy( temp, argv[ i ] );
400 len = strlen( temp );
401 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
403 /* this is slow, but only done once */
404 for( j = 0; j < (len - len2); j++ )
406 /* check for the game's magic word */
407 if( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 )
409 /* now find the next slash and nuke everything after it */
410 while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
413 /* add this as a base path */
420 /* add install path */
421 if( numBasePaths == 0 )
422 AddBasePath( installPath );
425 if( numBasePaths == 0 )
426 Error( "Failed to find a valid base path." );
429 /* this only affects unix */
430 AddHomeBasePath( game->homeBasePath );
432 /* initialize vfs paths */
433 if( numBasePaths > MAX_BASE_PATHS )
434 numBasePaths = MAX_BASE_PATHS;
435 if( numGamePaths > MAX_GAME_PATHS )
436 numGamePaths = MAX_GAME_PATHS;
438 /* walk the list of game paths */
439 for( j = 0; j < numGamePaths; j++ )
441 /* walk the list of base paths */
442 for( i = 0; i < numBasePaths; i++ )
444 /* create a full path and initialize it */
445 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
446 vfsInitDirectory( temp );