src/fileio.cpp
changeset 6317 70f4e9e52eb1
parent 6299 a3757291fd8c
child 6320 32d0f299e2fd
equal deleted inserted replaced
6316:d2b70e10f106 6317:70f4e9e52eb1
    10 #include "macros.h"
    10 #include "macros.h"
    11 #include "variables.h"
    11 #include "variables.h"
    12 #include "debug.h"
    12 #include "debug.h"
    13 #include "fios.h"
    13 #include "fios.h"
    14 #ifndef WIN32
    14 #ifndef WIN32
       
    15 #include <unistd.h>
    15 #include <sys/stat.h>
    16 #include <sys/stat.h>
    16 #endif
    17 #endif
    17 
    18 
    18 /*************************************************/
    19 /*************************************************/
    19 /* FILE IO ROUTINES ******************************/
    20 /* FILE IO ROUTINES ******************************/
   256 		buf[s]     = PATHSEPCHAR;
   257 		buf[s]     = PATHSEPCHAR;
   257 		buf[s + 1] = '\0';
   258 		buf[s + 1] = '\0';
   258 	}
   259 	}
   259 }
   260 }
   260 
   261 
       
   262 #if defined(WIN32) || defined(WINCE)
   261 /**
   263 /**
   262  * Determine the base (personal dir and game data dir) paths
   264  * Determine the base (personal dir and game data dir) paths
   263  * @note defined in the OS related files (os2.cpp, win32.cpp, unix.cpp etc)
   265  * @param exe the path to the executable
   264  */
   266  */
   265 extern void DetermineBasePaths();
   267 extern void DetermineBasePaths(const char *exe);
       
   268 #else /* defined(WIN32) || defined(WINCE) */
       
   269 
       
   270 /**
       
   271  * Changes the working directory to the path of the give executable.
       
   272  * For OSX application bundles '.app' is the required extension of the bundle,
       
   273  * so when we crop the path to there, when can remove the name of the bundle
       
   274  * in the same way we remove the name from the executable name.
       
   275  * @param exe the path to the executable
       
   276  */
       
   277 void ChangeWorkingDirectory(const char *exe)
       
   278 {
       
   279 #ifdef WITH_COCOA
       
   280 	char *app_bundle = strchr(exe, '.');
       
   281 	while (app_bundle != NULL && strncasecmp(app_bundle, ".app", 4) != 0) app_bundle = strchr(&app_bundle[1], '.');
       
   282 
       
   283 	if (app_bundle != NULL) app_bundle[0] = '\0';
       
   284 #endif /* WITH_COCOA */
       
   285 	char *s = strrchr(exe, PATHSEPCHAR);
       
   286 	if (s != NULL) {
       
   287 		*s = '\0';
       
   288 		chdir(exe);
       
   289 		*s = PATHSEPCHAR;
       
   290 	}
       
   291 #ifdef WITH_COCOA
       
   292 	if (app_bundle != NULL) app_bundle[0] = '.';
       
   293 #endif /* WITH_COCOA */
       
   294 }
       
   295 
       
   296 /**
       
   297  * Determine the base (personal dir and game data dir) paths
       
   298  * @param exe the path to the executable
       
   299  */
       
   300 void DetermineBasePaths(const char *exe)
       
   301 {
       
   302 	/* Change the working directory to enable doubleclicking in UIs */
       
   303 	ChangeWorkingDirectory(exe);
       
   304 
       
   305 	_paths.game_data_dir = MallocT<char>(MAX_PATH);
       
   306 	ttd_strlcpy(_paths.game_data_dir, GAME_DATA_DIR, MAX_PATH);
       
   307 #if defined(SECOND_DATA_DIR)
       
   308 	_paths.second_data_dir = MallocT<char>(MAX_PATH);
       
   309 	ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH);
       
   310 #endif
       
   311 
       
   312 #if defined(USE_HOMEDIR)
       
   313 	const char *homedir = getenv("HOME");
       
   314 
       
   315 	if (homedir == NULL) {
       
   316 		const struct passwd *pw = getpwuid(getuid());
       
   317 		if (pw != NULL) homedir = pw->pw_dir;
       
   318 	}
       
   319 
       
   320 	_paths.personal_dir = str_fmt("%s" PATHSEP "%s", homedir, PERSONAL_DIR);
       
   321 #else /* not defined(USE_HOMEDIR) */
       
   322 	_paths.personal_dir = MallocT<char>(MAX_PATH);
       
   323 	ttd_strlcpy(_paths.personal_dir, PERSONAL_DIR, MAX_PATH);
       
   324 
       
   325 	/* check if absolute or relative path */
       
   326 	const char *s = strchr(_paths.personal_dir, PATHSEPCHAR);
       
   327 
       
   328 	/* add absolute path */
       
   329 	if (s == NULL || _paths.personal_dir != s) {
       
   330 		getcwd(_paths.personal_dir, MAX_PATH);
       
   331 		AppendPathSeparator(_paths.personal_dir, MAX_PATH);
       
   332 		ttd_strlcat(_paths.personal_dir, PERSONAL_DIR, MAX_PATH);
       
   333 	}
       
   334 #endif /* defined(USE_HOMEDIR) */
       
   335 
       
   336 	AppendPathSeparator(_paths.personal_dir,  MAX_PATH);
       
   337 	AppendPathSeparator(_paths.game_data_dir, MAX_PATH);
       
   338 }
       
   339 #endif /* defined(WIN32) || defined(WINCE) */
   266 
   340 
   267 /**
   341 /**
   268  * Acquire the base paths (personal dir and game data dir),
   342  * Acquire the base paths (personal dir and game data dir),
   269  * fill all other paths (save dir, autosave dir etc) and
   343  * fill all other paths (save dir, autosave dir etc) and
   270  * make the save and scenario directories.
   344  * make the save and scenario directories.
       
   345  * @param exe the path to the executable
   271  * @todo for save_dir, autosave_dir, scenario_dir and heightmap_dir the
   346  * @todo for save_dir, autosave_dir, scenario_dir and heightmap_dir the
   272  *       assumption is that there is no path separator, however for gm_dir
   347  *       assumption is that there is no path separator, however for gm_dir
   273  *       lang_dir and data_dir that assumption is made.
   348  *       lang_dir and data_dir that assumption is made.
   274  *       This inconsistency should be resolved.
   349  *       This inconsistency should be resolved.
   275  */
   350  */
   276 void DeterminePaths()
   351 void DeterminePaths(const char *exe)
   277 {
   352 {
   278 	DetermineBasePaths();
   353 	DetermineBasePaths(exe);
   279 
   354 
   280 	_paths.save_dir      = str_fmt("%ssave", _paths.personal_dir);
   355 	_paths.save_dir      = str_fmt("%ssave", _paths.personal_dir);
   281 	_paths.autosave_dir  = str_fmt("%s" PATHSEP "autosave", _paths.save_dir);
   356 	_paths.autosave_dir  = str_fmt("%s" PATHSEP "autosave", _paths.save_dir);
   282 	_paths.scenario_dir  = str_fmt("%sscenario", _paths.personal_dir);
   357 	_paths.scenario_dir  = str_fmt("%sscenario", _paths.personal_dir);
   283 	_paths.heightmap_dir = str_fmt("%s" PATHSEP "heightmap", _paths.scenario_dir);
   358 	_paths.heightmap_dir = str_fmt("%s" PATHSEP "heightmap", _paths.scenario_dir);