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 )
71 static char buf[MAX_OS_PATH];
72 TCHAR mydocsdir[MAX_PATH + 1];
73 if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir))
75 snprintf(buf, "%s/My Games", mydocsdir);
86 /* get the home environment variable */
87 home = getenv( "HOME" );
90 /* do some more digging */
93 while( (pwd = getpwent()) != NULL )
95 if( pwd->pw_uid == id )
113 initializes some paths on linux/os x
116 void LokiInitPaths( char *argv0 )
119 /* this is kinda crap, but hey */
120 strcpy( installPath, "../" );
123 home = LokiGetHomeDir();
130 char temp[ MAX_OS_PATH ];
139 home = LokiGetHomeDir();
143 /* do some path divining */
144 strcpy( temp, argv0 );
145 if( strrchr( argv0, '/' ) )
146 argv0 = strrchr( argv0, '/' ) + 1;
149 /* get path environment variable */
150 path = getenv( "PATH" );
154 last[ 0 ] = path[ 0 ];
158 /* go through each : segment of path */
159 while( last[ 0 ] != '\0' && found == qfalse )
164 /* find next chunk */
165 last = strchr( path, ':' );
167 last = path + strlen( path );
169 /* found home dir candidate */
172 strcpy( temp, home );
177 if( last > (path + 1) )
179 strncat( temp, path, (last - path) );
182 strcat( temp, "./" );
183 strcat( temp, argv0 );
185 /* verify the path */
186 if( access( temp, X_OK ) == 0 )
193 if( realpath( temp, installPath ) )
195 /* q3map is in "tools/" */
196 *(strrchr( installPath, '/' )) = '\0';
197 *(strrchr( installPath, '/' ) + 1) = '\0';
209 cleans a dos path \ -> /
212 void CleanPath( char *path )
226 gets the game_t based on a -game argument
227 returns NULL if no match found
230 game_t *GetGame( char *arg )
236 if( arg == NULL || arg[ 0 ] == '\0' )
240 if( !Q_stricmp( arg, "quake1" ) ||
241 !Q_stricmp( arg, "quake2" ) ||
242 !Q_stricmp( arg, "unreal" ) ||
243 !Q_stricmp( arg, "ut2k3" ) ||
244 !Q_stricmp( arg, "dn3d" ) ||
245 !Q_stricmp( arg, "dnf" ) ||
246 !Q_stricmp( arg, "hl" ) )
248 Sys_Printf( "April fools, silly rabbit!\n" );
254 while( games[ i ].arg != NULL )
256 if( Q_stricmp( arg, games[ i ].arg ) == 0 )
261 /* no matching game */
268 AddBasePath() - ydnar
269 adds a base path to the list
272 void AddBasePath( char *path )
275 if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
278 /* add it to the list */
279 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
280 strcpy( basePaths[ numBasePaths ], path );
281 CleanPath( basePaths[ numBasePaths ] );
288 AddHomeBasePath() - ydnar
289 adds a base path to the beginning of the list, prefixed by ~/
292 void AddHomeBasePath( char *path )
295 char temp[ MAX_OS_PATH ];
301 if( path == NULL || path[ 0 ] == '\0' )
304 /* concatenate home dir and path */
305 sprintf( temp, "%s/%s", homePath, path );
309 /* on Win32, we ONLY add it if the directory already exists */
311 dir = g_dir_open (temp, 0, NULL);
319 for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- )
320 basePaths[ i + 1 ] = basePaths[ i ];
322 /* add it to the list */
323 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
324 strcpy( basePaths[ 0 ], temp );
325 CleanPath( basePaths[ 0 ] );
332 AddGamePath() - ydnar
333 adds a game path to the list
336 void AddGamePath( char *path )
341 if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
344 /* add it to the list */
345 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
346 strcpy( gamePaths[ numGamePaths ], path );
347 CleanPath( gamePaths[ numGamePaths ] );
350 /* don't add it if it's already there */
351 for (i = 0; i < numGamePaths - 1; i++)
353 if (strcmp(gamePaths[i], gamePaths[numGamePaths - 1]) == 0)
355 free(gamePaths[numGamePaths - 1]);
356 gamePaths[numGamePaths - 1] = NULL;
369 cleaned up some of the path initialization code from bsp.c
370 will remove any arguments it uses
373 void InitPaths( int *argc, char **argv )
375 int i, j, k, len, len2;
376 char temp[ MAX_OS_PATH ];
380 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
382 /* get the install path for backup */
383 LokiInitPaths( argv[ 0 ] );
385 /* set game to default (q3a) */
390 /* parse through the arguments and extract those relevant to paths */
391 for( i = 0; i < *argc; i++ )
394 if( argv[ i ] == NULL )
398 if( strcmp( argv[ i ], "-game" ) == 0 )
401 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
402 argv[ i - 1 ] = NULL;
403 game = GetGame( argv[ i ] );
409 /* -fs_forbiddenpath */
410 else if( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 )
413 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
414 argv[ i - 1 ] = NULL;
415 if(g_numForbiddenDirs < VFS_MAXDIRS)
417 strncpy(g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX);
418 g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0;
419 ++g_numForbiddenDirs;
425 else if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
428 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
429 argv[ i - 1 ] = NULL;
430 AddBasePath( argv[ i ] );
435 else if( strcmp( argv[ i ], "-fs_game" ) == 0 )
438 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
439 argv[ i - 1 ] = NULL;
440 AddGamePath( argv[ i ] );
445 else if( strcmp( argv[ i ], "-fs_homebase" ) == 0 )
448 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
449 argv[ i - 1 ] = NULL;
450 homeBasePath = argv[i];
455 /* remove processed arguments */
456 for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
458 for( ; j < *argc && argv[ j ] == NULL; j++ );
459 argv[ i ] = argv[ j ];
460 if( argv[ i ] != NULL )
465 /* add standard game path */
466 AddGamePath( game->gamePath );
468 /* if there is no base path set, figure it out */
469 if( numBasePaths == 0 )
471 /* this is another crappy replacement for SetQdirFromPath() */
472 len2 = strlen( game->magic );
473 for( i = 0; i < *argc && numBasePaths == 0; i++ )
475 /* extract the arg */
476 strcpy( temp, argv[ i ] );
478 len = strlen( temp );
479 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
481 /* this is slow, but only done once */
482 for( j = 0; j < (len - len2); j++ )
484 /* check for the game's magic word */
485 if( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 )
487 /* now find the next slash and nuke everything after it */
488 while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
491 /* add this as a base path */
498 /* add install path */
499 if( numBasePaths == 0 )
500 AddBasePath( installPath );
503 if( numBasePaths == 0 )
504 Error( "Failed to find a valid base path." );
507 /* this only affects unix */
509 AddHomeBasePath( homeBasePath );
511 AddHomeBasePath( game->homeBasePath );
513 /* initialize vfs paths */
514 if( numBasePaths > MAX_BASE_PATHS )
515 numBasePaths = MAX_BASE_PATHS;
516 if( numGamePaths > MAX_GAME_PATHS )
517 numGamePaths = MAX_GAME_PATHS;
519 /* walk the list of game paths */
520 for( j = 0; j < numGamePaths; j++ )
522 /* walk the list of base paths */
523 for( i = 0; i < numBasePaths; i++ )
525 /* create a full path and initialize it */
526 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
527 vfsInitDirectory( temp );