diff options
author | Steven Noonan <steven@uplinklabs.net> | 2009-09-20 20:33:43 -0700 |
---|---|---|
committer | Steven Noonan <steven@uplinklabs.net> | 2009-09-23 11:34:37 -0700 |
commit | df8438dc4caa9d1c79304e9e3519ffa7a5b46c3f (patch) | |
tree | c2f2fc478d7a9bd10d950303f7137946c96b893c | |
parent | fc34e6860c51592204c11112613ef368c86e6ccc (diff) | |
download | crawl-ref-df8438dc4caa9d1c79304e9e3519ffa7a5b46c3f.tar.gz crawl-ref-df8438dc4caa9d1c79304e9e3519ffa7a5b46c3f.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 2f7d9a504d..5cd896cce6 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> @@ -3429,9 +3438,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(); |