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); |