diff options
author | Steven Noonan <steven@uplinklabs.net> | 2009-09-20 20:33:43 -0700 |
---|---|---|
committer | Steven Noonan <steven@uplinklabs.net> | 2009-09-25 14:32:30 -0700 |
commit | 822c833d1372bdd62dcc3400a529ac107fabe99a (patch) | |
tree | f981c3fb50530620d189a6f5cd860cc42327cfd4 | |
parent | 14cf7497634b4a0467a3bfba1420746733751b2e (diff) | |
download | crawl-ref-822c833d1372bdd62dcc3400a529ac107fabe99a.tar.gz crawl-ref-822c833d1372bdd62dcc3400a529ac107fabe99a.zip |
initfile.cc: improve accuracy of crawl_base variable
Windows, Mac OS X and Linux all provide handy ways to retrieve
the absolute path of the running executable. This is especially
useful since argv[0] can be a relative path.
This fixes a bug on the Mac OS X build where the app cannot
locate the graphics resources when when they're needed, so the
application bombs out instead.
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
-rw-r--r-- | crawl-ref/source/initfile.cc | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index af96637427..d3dda61ca3 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -11,6 +11,15 @@ REVISION("$Rev$"); #include "initfile.h" +// For finding the executable's path +#if defined ( WIN32CONSOLE ) || defined ( WIN32TILES ) +#include <windows.h> +#elif defined ( __linux__ ) +#include <unistd.h> +#elif defined ( __MACH__ ) +extern char **NXArgv; +#endif + #include <stdio.h> #include <stdlib.h> #include <string> @@ -3424,9 +3433,47 @@ static const char *cmd_ops[] = { const int num_cmd_ops = CLO_NOPS; bool arg_seen[num_cmd_ops]; +std::string find_executable_path() +{ + char tempPath[2048]; + + // A lot of OSes give ways to find the location of the running app's + // binary executable. This is useful, because argv[0] can be relative + // when we really need an absolute path in order to locate the game's + // resources. + + // Faster than a memset, and counts as a null-terminated string! + tempPath[0] = 0; + +#if defined ( _MSC_VER ) + + int retval = GetModuleFileName ( NULL, tempPath, sizeof(tempPath) ); + +#elif defined ( __linux__ ) + + int retval = readlink ( "/proc/self/exe", tempPath, sizeof(tempPath) ); + +#elif defined ( __MACH__ ) + + strncpy ( tempPath, NXArgv[0], sizeof(tempPath) ); + +#else + + // We don't know how to find the executable's path on this OS. + +#endif + + return std::string(tempPath); +} + bool parse_args( int argc, char **argv, bool rc_only ) { - set_crawl_base_dir(argv[0]); + std::string exe_path = find_executable_path(); + + if (!exe_path.empty()) + set_crawl_base_dir(exe_path.c_str()); + else + set_crawl_base_dir(argv[0]); SysEnv.rcdirs.clear(); |