158 lines
3.6 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #if defined HAVE_UNISTD_H
  14. # include <unistd.h>
  15. #endif
  16. #ifdef _WIN32
  17. # define WIN32_LEAN_AND_MEAN
  18. # include <direct.h>
  19. #endif
  20. #include "core.h"
  21. namespace lol
  22. {
  23. namespace System
  24. {
  25. #if defined _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. /*
  38. * Retrieve binary directory, defaulting to current dir.
  39. */
  40. #if __ANDROID__
  41. /* Android assets are accessed using no prefix at all. */
  42. String binarydir = "";
  43. #elif defined HAVE_GETCWD
  44. char *cwd = getcwd(nullptr, 0);
  45. String binarydir = String(cwd ? cwd : ".") + SEPARATOR;
  46. free(cwd);
  47. #elif defined HAVE__GETCWD || (defined _WIN32 && !defined _XBOX)
  48. char *cwd = _getcwd(nullptr, 0);
  49. String binarydir = String(cwd ? cwd : ".") + SEPARATOR;
  50. free(cwd);
  51. #else
  52. String binarydir = "./";
  53. #endif
  54. if (argc > 0)
  55. {
  56. char const *last_sep = strrchr(argv[0], SEPARATOR);
  57. if (last_sep)
  58. binarydir = String(argv[0], last_sep - argv[0] + 1);
  59. }
  60. /*
  61. * Find the common prefix between project dir and solution dir.
  62. */
  63. bool got_rootdir = false;
  64. for (int i = 0; ; i++)
  65. {
  66. if (projectdir[i] != solutiondir[i] || projectdir[i] == '\0')
  67. {
  68. /* FIXME: at this point we should check whether the binary
  69. * was launched from this subdirectory; from now we just
  70. * assume it was. */
  71. if (i)
  72. {
  73. String rootdir = solutiondir;
  74. if (rootdir.Last() != SEPARATOR)
  75. rootdir += SEPARATOR;
  76. rootdir += "../../src/"; /* FIXME: use SEPARATOR? */
  77. AddDataDir(rootdir);
  78. rootdir = projectdir;
  79. if (rootdir.Last() != SEPARATOR)
  80. rootdir += SEPARATOR;
  81. AddDataDir(rootdir);
  82. got_rootdir = true;
  83. }
  84. break;
  85. }
  86. }
  87. /* If no rootdir found, use the executable location */
  88. if (!got_rootdir)
  89. {
  90. String rootdir = binarydir;
  91. if (rootdir.Count() && rootdir.Last() != SEPARATOR)
  92. rootdir += SEPARATOR;
  93. for (int i = 1; i < sourcesubdir.Count(); ++i)
  94. {
  95. if ((sourcesubdir[i] == SEPARATOR
  96. && sourcesubdir[i - 1] != SEPARATOR)
  97. || i == sourcesubdir.Count() - 1)
  98. rootdir += "../";
  99. }
  100. rootdir += "src/";
  101. AddDataDir(rootdir);
  102. rootdir = binarydir;
  103. AddDataDir(rootdir);
  104. got_rootdir = true;
  105. }
  106. Log::Debug("binary dir: “%s”\n", binarydir.C());
  107. for (int i = 0; i < data_dir.Count(); ++i)
  108. Log::Debug("data dir %d/%d: “%s”\n", i + 1, data_dir.Count(),
  109. data_dir[i].C());
  110. }
  111. /*
  112. * Data directory handling
  113. */
  114. void AddDataDir(String const &dir)
  115. {
  116. data_dir << dir;
  117. }
  118. Array<String> GetPathList(String const &file)
  119. {
  120. Array<String> ret;
  121. for (int i = 0; i < data_dir.Count(); ++i)
  122. ret << data_dir[i] + file;
  123. if (ret.Count() == 0)
  124. ret << file;
  125. return ret;
  126. }
  127. } /* namespace System */
  128. } /* namespace lol */