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 ];
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 ){
74 /* get the home environment variable */
75 home = getenv( "HOME" );
77 /* do some more digging */
80 while ( ( pwd = getpwent() ) != NULL )
82 if ( pwd->pw_uid == id ) {
99 initializes some paths on linux/os x
102 void LokiInitPaths( char *argv0 ){
104 /* this is kinda crap, but hey */
105 strcpy( installPath, "../" );
107 char temp[ MAX_OS_PATH ];
115 home = LokiGetHomeDir();
116 if ( home == NULL ) {
120 /* do some path divining */
121 strcpy( temp, argv0 );
122 if ( strrchr( temp, '/' ) ) {
123 argv0 = strrchr( argv0, '/' ) + 1;
127 /* get path environment variable */
128 path = getenv( "PATH" );
131 last[ 0 ] = path[ 0 ];
135 /* go through each : segment of path */
136 while ( last[ 0 ] != '\0' && found == qfalse )
141 /* find next chunk */
142 last = strchr( path, ':' );
143 if ( last == NULL ) {
144 last = path + strlen( path );
147 /* found home dir candidate */
148 if ( *path == '~' ) {
149 strcpy( temp, home );
154 if ( last > ( path + 1 ) ) {
155 strncat( temp, path, ( last - path ) );
158 strcat( temp, "./" );
159 strcat( temp, argv0 );
161 /* verify the path */
162 if ( access( temp, X_OK ) == 0 ) {
170 if ( realpath( temp, installPath ) ) {
171 /* q3map is in "tools/" */
172 *( strrchr( installPath, '/' ) ) = '\0';
173 *( strrchr( installPath, '/' ) + 1 ) = '\0';
185 cleans a dos path \ -> /
188 void CleanPath( char *path ){
191 if ( *path == '\\' ) {
202 gets the game_t based on a -game argument
203 returns NULL if no match found
206 game_t *GetGame( char *arg ){
211 if ( arg == NULL || arg[ 0 ] == '\0' ) {
216 if ( !Q_stricmp( arg, "quake1" ) ||
217 !Q_stricmp( arg, "quake2" ) ||
218 !Q_stricmp( arg, "unreal" ) ||
219 !Q_stricmp( arg, "ut2k3" ) ||
220 !Q_stricmp( arg, "dn3d" ) ||
221 !Q_stricmp( arg, "dnf" ) ||
222 !Q_stricmp( arg, "hl" ) ) {
223 Sys_Printf( "April fools, silly rabbit!\n" );
229 while ( games[ i ].arg != NULL )
231 if ( Q_stricmp( arg, games[ i ].arg ) == 0 ) {
237 /* no matching game */
244 AddBasePath() - ydnar
245 adds a base path to the list
248 void AddBasePath( char *path ){
250 if ( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS ) {
254 /* add it to the list */
255 basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
256 strcpy( basePaths[ numBasePaths ], path );
257 CleanPath( basePaths[ numBasePaths ] );
264 AddHomeBasePath() - ydnar
265 adds a base path to the beginning of the list, prefixed by ~/
268 void AddHomeBasePath( char *path ){
271 char temp[ MAX_OS_PATH ];
275 if ( path == NULL || path[ 0 ] == '\0' ) {
280 for ( i = 0; i < ( MAX_BASE_PATHS - 1 ); i++ )
281 basePaths[ i + 1 ] = basePaths[ i ];
283 /* concatenate home dir and path */
284 sprintf( temp, "%s/%s", homePath, path );
286 /* add it to the list */
287 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
288 strcpy( basePaths[ 0 ], temp );
289 CleanPath( basePaths[ 0 ] );
297 AddGamePath() - ydnar
298 adds a game path to the list
301 void AddGamePath( char *path ){
305 if ( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS ) {
309 /* add it to the list */
310 gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
311 strcpy( gamePaths[ numGamePaths ], path );
312 CleanPath( gamePaths[ numGamePaths ] );
315 /* don't add it if it's already there */
316 for ( i = 0; i < numGamePaths - 1; i++ )
318 if ( strcmp( gamePaths[i], gamePaths[numGamePaths - 1] ) == 0 ) {
319 free( gamePaths[numGamePaths - 1] );
320 gamePaths[numGamePaths - 1] = NULL;
333 cleaned up some of the path initialization code from bsp.c
334 will remove any arguments it uses
337 void InitPaths( int *argc, char **argv ){
338 int i, j, k, len, len2;
339 char temp[ MAX_OS_PATH ];
343 Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
345 /* get the install path for backup */
346 LokiInitPaths( argv[ 0 ] );
348 /* set game to default (q3a) */
353 /* parse through the arguments and extract those relevant to paths */
354 for ( i = 0; i < *argc; i++ )
357 if ( argv[ i ] == NULL ) {
362 if ( strcmp( argv[ i ], "-game" ) == 0 ) {
363 if ( ++i >= *argc ) {
364 Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
366 argv[ i - 1 ] = NULL;
367 game = GetGame( argv[ i ] );
368 if ( game == NULL ) {
375 else if ( strcmp( argv[ i ], "-fs_basepath" ) == 0 ) {
376 if ( ++i >= *argc ) {
377 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
379 argv[ i - 1 ] = NULL;
380 AddBasePath( argv[ i ] );
385 else if ( strcmp( argv[ i ], "-fs_game" ) == 0 ) {
386 if ( ++i >= *argc ) {
387 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
389 argv[ i - 1 ] = NULL;
390 AddGamePath( argv[ i ] );
395 /* remove processed arguments */
396 for ( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
398 for ( ; j < *argc && argv[ j ] == NULL; j++ ) ;
399 argv[ i ] = argv[ j ];
400 if ( argv[ i ] != NULL ) {
406 /* add standard game path */
407 AddGamePath( game->gamePath );
409 /* if there is no base path set, figure it out */
410 if ( numBasePaths == 0 ) {
411 /* this is another crappy replacement for SetQdirFromPath() */
412 len2 = strlen( game->magic );
413 for ( i = 0; i < *argc && numBasePaths == 0; i++ )
415 /* extract the arg */
416 strcpy( temp, argv[ i ] );
418 len = strlen( temp );
419 Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
421 /* this is slow, but only done once */
422 for ( j = 0; j < ( len - len2 ); j++ )
424 /* check for the game's magic word */
425 if ( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 ) {
426 /* now find the next slash and nuke everything after it */
427 while ( temp[ ++j ] != '/' && temp[ j ] != '\0' ) ;
430 /* add this as a base path */
437 /* add install path */
438 if ( numBasePaths == 0 ) {
439 AddBasePath( installPath );
443 if ( numBasePaths == 0 ) {
444 Error( "Failed to find a valid base path." );
448 /* this only affects unix */
449 AddHomeBasePath( game->homeBasePath );
451 /* initialize vfs paths */
452 if ( numBasePaths > MAX_BASE_PATHS ) {
453 numBasePaths = MAX_BASE_PATHS;
455 if ( numGamePaths > MAX_GAME_PATHS ) {
456 numGamePaths = MAX_GAME_PATHS;
459 /* walk the list of game paths */
460 for ( j = 0; j < numGamePaths; j++ )
462 /* walk the list of base paths */
463 for ( i = 0; i < numBasePaths; i++ )
465 /* create a full path and initialize it */
466 sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
467 vfsInitDirectory( temp );