b3ResourcePath.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "b3ResourcePath.h"
  2. #include "Bullet3Common/b3Logging.h"
  3. #ifdef __APPLE__
  4. #include <mach-o/dyld.h> /* _NSGetExecutablePath */
  5. #else
  6. #ifdef _WIN32
  7. #include <windows.h>
  8. #else
  9. //not Mac, not Windows, let's cross the fingers it is Linux :-)
  10. #include <unistd.h>
  11. #endif
  12. #endif
  13. #include "Bullet3Common/b3FileUtils.h"
  14. #define B3_MAX_EXE_PATH_LEN 4096
  15. int b3ResourcePath::getExePath(char* path, int maxPathLenInBytes)
  16. {
  17. int numBytes = 0;
  18. #if __APPLE__
  19. uint32_t bufsize = uint32_t(maxPathLenInBytes);
  20. if (_NSGetExecutablePath(path, &bufsize) != 0)
  21. {
  22. b3Warning("Cannot find executable path\n");
  23. return false;
  24. }
  25. else
  26. {
  27. numBytes = strlen(path);
  28. }
  29. #else
  30. #ifdef _WIN32
  31. //https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx
  32. HMODULE hModule = GetModuleHandle(NULL);
  33. numBytes = GetModuleFileNameA(hModule, path, maxPathLenInBytes);
  34. #else
  35. ///http://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c
  36. numBytes = (int)readlink("/proc/self/exe", path, maxPathLenInBytes - 1);
  37. if (numBytes > 0)
  38. {
  39. path[numBytes] = 0;
  40. }
  41. else
  42. {
  43. b3Warning("Cannot find executable path\n");
  44. }
  45. #endif //_WIN32
  46. #endif //__APPLE__
  47. return numBytes;
  48. }
  49. struct TempResourcePath
  50. {
  51. char* m_path;
  52. TempResourcePath(int len)
  53. {
  54. m_path = (char*)malloc(len);
  55. memset(m_path, 0, len);
  56. }
  57. virtual ~TempResourcePath()
  58. {
  59. free(m_path);
  60. }
  61. };
  62. static char sAdditionalSearchPath[B3_MAX_EXE_PATH_LEN] = {0};
  63. void b3ResourcePath::setAdditionalSearchPath(const char* path)
  64. {
  65. if (path)
  66. {
  67. int len = strlen(path);
  68. if (len < (B3_MAX_EXE_PATH_LEN - 1))
  69. {
  70. strcpy(sAdditionalSearchPath, path);
  71. sAdditionalSearchPath[len] = 0;
  72. }
  73. }
  74. else
  75. {
  76. sAdditionalSearchPath[0] = 0;
  77. }
  78. }
  79. bool b3MyFindFile(void* userPointer, const char* orgFileName, char* relativeFileName, int maxRelativeFileNameMaxLen)
  80. {
  81. return b3FileUtils::findFile(orgFileName, relativeFileName, maxRelativeFileNameMaxLen);
  82. }
  83. int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePathOut, int resourcePathMaxNumBytes, PFN_FIND_FILE findFile, void* userPointer)
  84. {
  85. if (findFile==0)
  86. {
  87. findFile=b3MyFindFile;
  88. }
  89. //first find in a resource/<exeName> location, then in various folders within 'data' using b3FileUtils
  90. char exePath[B3_MAX_EXE_PATH_LEN];
  91. bool res = findFile(userPointer, resourceName, resourcePathOut, resourcePathMaxNumBytes);
  92. if (res)
  93. {
  94. return strlen(resourcePathOut);
  95. }
  96. if (sAdditionalSearchPath[0])
  97. {
  98. TempResourcePath tmpPath(resourcePathMaxNumBytes + 1024);
  99. char* resourcePathIn = tmpPath.m_path;
  100. sprintf(resourcePathIn, "%s/%s", sAdditionalSearchPath, resourceName);
  101. //printf("try resource at %s\n", resourcePath);
  102. if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
  103. {
  104. return strlen(resourcePathOut);
  105. }
  106. }
  107. int l = b3ResourcePath::getExePath(exePath, B3_MAX_EXE_PATH_LEN);
  108. if (l)
  109. {
  110. char pathToExe[B3_MAX_EXE_PATH_LEN];
  111. int exeNamePos = b3FileUtils::extractPath(exePath, pathToExe, B3_MAX_EXE_PATH_LEN);
  112. if (exeNamePos)
  113. {
  114. TempResourcePath tmpPath(resourcePathMaxNumBytes + 1024);
  115. char* resourcePathIn = tmpPath.m_path;
  116. sprintf(resourcePathIn, "%s../data/%s", pathToExe, resourceName);
  117. //printf("try resource at %s\n", resourcePath);
  118. if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
  119. {
  120. return strlen(resourcePathOut);
  121. }
  122. sprintf(resourcePathIn, "%s../resources/%s/%s", pathToExe, &exePath[exeNamePos], resourceName);
  123. //printf("try resource at %s\n", resourcePath);
  124. if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
  125. {
  126. return strlen(resourcePathOut);
  127. }
  128. sprintf(resourcePathIn, "%s.runfiles/google3/third_party/bullet/data/%s", exePath, resourceName);
  129. //printf("try resource at %s\n", resourcePath);
  130. if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
  131. {
  132. return strlen(resourcePathOut);
  133. }
  134. }
  135. }
  136. return 0;
  137. }