diff --git a/src/raylib.h b/src/raylib.h index 3805ba34..04795de5 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1047,6 +1047,7 @@ RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filenam RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string) RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) +RLAPI const char* GetApplicationDirectory(void); // Get the directory if the running application (uses static string) RLAPI char **GetDirectoryFiles(const char *dirPath, int *count); // Get filenames in a directory path (memory should be freed) RLAPI void ClearDirectoryFiles(void); // Clear directory files paths buffers (free memory) RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success diff --git a/src/rcore.c b/src/rcore.c index 7752a7cc..422168f0 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -160,6 +160,39 @@ #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. #endif + +// platform specific defines to handle GetApplicationDirectory +#if defined (PLATFORM_DESKTOP) + #if defined(_WIN32) + #ifndef MAX_PATH + #define MAX_PATH 1025 + #endif + void* LoadLibraryA(void* lpLibFileName); + void* LoadLibraryW(void* lpLibFileName); + + #ifdef UNICODE + #define LoadLibrary LoadLibraryW + #else + #define LoadLibrary LoadLibraryA + #endif // !UNICODE + + void* GetProcAddress(void* hModule, void* lpProcName); + + void* GetCurrentProcess(void); + bool FreeLibrary(void* hLibModule); + + int WideCharToMultiByte(unsigned int cp, unsigned long flags, const unsigned short* widestr, int cchwide, char* str, int cbmb, const char* defchar, int* used_default); + + const char PathDelim = '\\'; + #elif defined(__linux__) + #include + const char PathDelim = '/'; + #elif defined(__APPLE__) + #include + const char PathDelim = '/'; + #endif // OSs +#endif // PLATFORM_DESKTOP + #include // Required for: srand(), rand(), atexit() #include // Required for: sprintf() [Used in OpenURL()] #include // Required for: strrchr(), strcmp(), strlen() @@ -2969,6 +3002,92 @@ const char *GetWorkingDirectory(void) return path; } +const char* GetApplicationDirectory(void) +{ + static char appDir[MAX_FILEPATH_LENGTH] = { 0 }; + memset(appDir, 0, MAX_FILEPATH_LENGTH); + +#if defined(_WIN32) + typedef unsigned long(*GetModuleFileNameFunc)(void*, void*, void*, unsigned long); + + GetModuleFileNameFunc getModuleFileNameExWPtr = NULL; + void* lib = LoadLibrary(L"psapi.dll"); + if (lib == NULL) + { + appDir[0] = '\\'; + } + else + { +#if defined (UNICODE) + getModuleFileNameExWPtr = (GetModuleFileNameFunc)GetProcAddress(lib, "GetModuleFileNameExW"); +#else + getModuleFileNameExWPtr = (GetModuleFileNameFunc)GetProcAddress(lib, "GetModuleFileNameExA"); +#endif + + if (getModuleFileNameExWPtr == NULL) + { + appDir[0] = '\\'; + } + else + { + int len = 0; +#if defined (UNICODE) + unsigned short widePath[MAX_PATH]; + len = getModuleFileNameExWPtr(GetCurrentProcess(), NULL, widePath, MAX_PATH); + + len = WideCharToMultiByte(0, 0, widePath, len, appDir, MAX_PATH, NULL, NULL); +#else + len = getModuleFileNameExWPtr(GetCurrentProcess(), NULL, appDir, MAX_PATH); +#endif + if (len > 0) + { + for (int i = len; i >= 0; --i) + { + if (appDir[i] == '\\') + { + appDir[i + 1] = '\0'; + i = -1; + } + } + } + } + FreeLibrary(lib); + } +#elif defined(__linux__) + unsigned int size = sizeof(appDir); + + ssize_t len = readlink("/proc/self/exe", appDir, size); + if (len > 0) + { + for (int i = len; i >= 0; --i) + { + if (appDir[i] == '/') + { + appDir[i + 1] = '\0'; + i = -1; + } + } + } +#elif defined(__APPLE__) + uint32_t size = sizeof(appDir); + + if (_NSGetExecutablePath(appDir, &size) == 0) + { + int len = strlen(appDir); + for (int i = len; i >= 0; --i) + { + if (appDir[i] == '/') + { + appDir[i + 1] = '\0'; + i = -1; + } + } + } +#endif + + return appDir; +} + // Get filenames in a directory path // NOTE: Files count is returned by parameters pointer char **GetDirectoryFiles(const char *dirPath, int *fileCount)