summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Noonan <steven@uplinklabs.net>2009-09-20 20:33:43 -0700
committerSteven Noonan <steven@uplinklabs.net>2009-09-25 14:32:30 -0700
commit822c833d1372bdd62dcc3400a529ac107fabe99a (patch)
treef981c3fb50530620d189a6f5cd860cc42327cfd4
parent14cf7497634b4a0467a3bfba1420746733751b2e (diff)
downloadcrawl-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.cc49
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();