|
- //
- // Lol Engine
- //
- // Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
- //
- // Lol Engine is free software. It comes without any warranty, to
- // the extent permitted by applicable law. You can redistribute it
- // and/or modify it under the terms of the Do What the Fuck You Want
- // to Public License, Version 2, as published by the WTFPL Task Force.
- // See http://www.wtfpl.net/ for more details.
- //
-
- #include <lol/engine-internal.h>
-
- #include <cctype>
-
- #if HAVE_UNISTD_H
- # include <unistd.h>
- #endif
-
- #if _WIN32
- # define WIN32_LEAN_AND_MEAN
- # include <direct.h>
- #endif
-
- namespace lol
- {
-
- namespace System
- {
-
- #if _WIN32
- # define SEPARATOR '\\'
- #else
- # define SEPARATOR '/'
- #endif
-
- static array<String> data_dir;
-
- void Init(int argc, char *argv[],
- String const &projectdir,
- String const &solutiondir,
- String const &sourcesubdir)
- {
- using namespace std;
-
- msg::debug("project dir: “%s”\n", projectdir.C());
- msg::debug("solution dir: “%s”\n", solutiondir.C());
- msg::debug("source subdir: “%s”\n", sourcesubdir.C());
-
- /*
- * Retrieve binary directory, defaulting to no directory on Android
- * and emscripten, and the current directory on other platforms.
- */
-
- #if __ANDROID__ || EMSCRIPTEN
- String binarydir = "";
- #else
- String binarydir = ".";
- char *cwd = nullptr;
-
- # if HAVE_GETCWD
- cwd = getcwd(nullptr, 0);
- # elif HAVE__GETCWD || (_WIN32 && !_XBOX)
- cwd = _getcwd(nullptr, 0);
- # endif
-
- if (cwd)
- {
- binarydir = cwd;
- free(cwd);
- }
-
- binarydir += SEPARATOR;
-
- if (argc > 0)
- {
- char const *last_sep = strrchr(argv[0], SEPARATOR);
- if (last_sep)
- binarydir = String(argv[0], last_sep - argv[0] + 1);
- }
- #endif
-
- bool got_rootdir = false;
-
- /*
- * If project dir and solution dir are set, add them to data; also
- * add current directory in case we were launched from another place.
- */
-
- if (!got_rootdir && projectdir.count() && solutiondir.count())
- {
- /* This data dir is for standalone executables */
- String rootdir = binarydir;
- if (rootdir.count() && rootdir.last() != SEPARATOR)
- rootdir += SEPARATOR;
- AddDataDir(rootdir);
-
- /* This data dir is for engine stuff */
- rootdir = solutiondir;
- if (rootdir.count() && rootdir.last() != SEPARATOR)
- rootdir += SEPARATOR;
- rootdir += "../src/"; /* FIXME: use SEPARATOR? */
- AddDataDir(rootdir);
-
- /* This data dir is for project-specific stuff */
- rootdir = projectdir;
- if (rootdir.count() && rootdir.last() != SEPARATOR)
- rootdir += SEPARATOR;
- AddDataDir(rootdir);
-
- got_rootdir = true;
- }
-
- /*
- * If no project dir, use the executable location as the starting point
- * to guess the data dir.
- */
- if (!got_rootdir)
- {
- /* First climb back the hierarchy to get to the engine root and
- * add a data dir for engine stuff. */
- String rootdir = binarydir;
- if (rootdir.count() && rootdir.last() != SEPARATOR)
- rootdir += SEPARATOR;
- for (int i = 1; i < sourcesubdir.count(); ++i)
- {
- if ((sourcesubdir[i] == SEPARATOR
- && sourcesubdir[i - 1] != SEPARATOR)
- || i == sourcesubdir.count() - 1)
- rootdir += "../";
- }
- rootdir += "src/";
- AddDataDir(rootdir);
-
- /* This data dir is for project-specific stuff */
- rootdir = binarydir;
- AddDataDir(rootdir);
-
- got_rootdir = true;
- }
-
- msg::debug("binary dir: “%s”\n", binarydir.C());
- for (int i = 0; i < data_dir.count(); ++i)
- msg::debug("data dir %d/%d: “%s”\n", i + 1, data_dir.count(),
- data_dir[i].C());
- }
-
- /*
- * Data directory handling
- */
-
- void AddDataDir(String const &dir)
- {
- data_dir << dir;
- }
-
- array<String> GetPathList(String const &file)
- {
- array<String> ret;
-
- for (int i = 0; i < data_dir.count(); ++i)
- ret << data_dir[i] + file;
-
- if (ret.count() == 0)
- ret << file;
-
- return ret;
- }
-
- } /* namespace System */
-
- } /* namespace lol */
|