175 lines
4.1 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. #include <cctype>
  14. #if HAVE_UNISTD_H
  15. # include <unistd.h>
  16. #endif
  17. #if _WIN32
  18. # define WIN32_LEAN_AND_MEAN
  19. # include <direct.h>
  20. #endif
  21. namespace lol
  22. {
  23. namespace System
  24. {
  25. #if _WIN32
  26. # define SEPARATOR '\\'
  27. #else
  28. # define SEPARATOR '/'
  29. #endif
  30. static array<String> data_dir;
  31. void Init(int argc, char *argv[],
  32. String const &projectdir,
  33. String const &solutiondir,
  34. String const &sourcesubdir)
  35. {
  36. using namespace std;
  37. msg::debug("project dir: “%s”\n", projectdir.C());
  38. msg::debug("solution dir: “%s”\n", solutiondir.C());
  39. msg::debug("source subdir: “%s”\n", sourcesubdir.C());
  40. /*
  41. * Retrieve binary directory, defaulting to no directory on Android
  42. * and emscripten, and the current directory on other platforms.
  43. */
  44. #if __ANDROID__ || EMSCRIPTEN
  45. String binarydir = "";
  46. #else
  47. String binarydir = ".";
  48. char *cwd = nullptr;
  49. # if HAVE_GETCWD
  50. cwd = getcwd(nullptr, 0);
  51. # elif HAVE__GETCWD || (_WIN32 && !_XBOX)
  52. cwd = _getcwd(nullptr, 0);
  53. # endif
  54. if (cwd)
  55. {
  56. binarydir = cwd;
  57. free(cwd);
  58. }
  59. binarydir += SEPARATOR;
  60. if (argc > 0)
  61. {
  62. char const *last_sep = strrchr(argv[0], SEPARATOR);
  63. if (last_sep)
  64. binarydir = String(argv[0], last_sep - argv[0] + 1);
  65. }
  66. #endif
  67. bool got_rootdir = false;
  68. /*
  69. * If project dir and solution dir are set, add them to data; also
  70. * add current directory in case we were launched from another place.
  71. */
  72. if (!got_rootdir && projectdir.count() && solutiondir.count())
  73. {
  74. /* This data dir is for standalone executables */
  75. String rootdir = binarydir;
  76. if (rootdir.count() && rootdir.last() != SEPARATOR)
  77. rootdir += SEPARATOR;
  78. AddDataDir(rootdir);
  79. /* This data dir is for engine stuff */
  80. rootdir = solutiondir;
  81. if (rootdir.count() && rootdir.last() != SEPARATOR)
  82. rootdir += SEPARATOR;
  83. rootdir += "../src/"; /* FIXME: use SEPARATOR? */
  84. AddDataDir(rootdir);
  85. /* This data dir is for project-specific stuff */
  86. rootdir = projectdir;
  87. if (rootdir.count() && rootdir.last() != SEPARATOR)
  88. rootdir += SEPARATOR;
  89. AddDataDir(rootdir);
  90. got_rootdir = true;
  91. }
  92. /*
  93. * If no project dir, use the executable location as the starting point
  94. * to guess the data dir.
  95. */
  96. if (!got_rootdir)
  97. {
  98. /* First climb back the hierarchy to get to the engine root and
  99. * add a data dir for engine stuff. */
  100. String rootdir = binarydir;
  101. if (rootdir.count() && rootdir.last() != SEPARATOR)
  102. rootdir += SEPARATOR;
  103. for (int i = 1; i < sourcesubdir.count(); ++i)
  104. {
  105. if ((sourcesubdir[i] == SEPARATOR
  106. && sourcesubdir[i - 1] != SEPARATOR)
  107. || i == sourcesubdir.count() - 1)
  108. rootdir += "../";
  109. }
  110. rootdir += "src/";
  111. AddDataDir(rootdir);
  112. /* This data dir is for project-specific stuff */
  113. rootdir = binarydir;
  114. AddDataDir(rootdir);
  115. got_rootdir = true;
  116. }
  117. msg::debug("binary dir: “%s”\n", binarydir.C());
  118. for (int i = 0; i < data_dir.count(); ++i)
  119. msg::debug("data dir %d/%d: “%s”\n", i + 1, data_dir.count(),
  120. data_dir[i].C());
  121. }
  122. /*
  123. * Data directory handling
  124. */
  125. void AddDataDir(String const &dir)
  126. {
  127. data_dir << dir;
  128. }
  129. array<String> GetPathList(String const &file)
  130. {
  131. array<String> ret;
  132. for (int i = 0; i < data_dir.count(); ++i)
  133. ret << data_dir[i] + file;
  134. if (ret.count() == 0)
  135. ret << file;
  136. return ret;
  137. }
  138. } /* namespace System */
  139. } /* namespace lol */