summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJeffery Myers <[email protected]>2022-01-08 10:47:52 -0800
committerGitHub <[email protected]>2022-01-08 19:47:52 +0100
commitfbf34f7c0d41b7281b195a082b3370a72e193150 (patch)
treeeb23830ff33fc65a0c9865ca81543f6704367273
parent549ca669aa42462662a610ff240aa4d5736240e5 (diff)
downloadraylib-fbf34f7c0d41b7281b195a082b3370a72e193150.tar.gz
raylib-fbf34f7c0d41b7281b195a082b3370a72e193150.zip
[CORE] Add a function to return the application directory. (#2256)
* Add a function to return the application directory. * CI fixes
-rw-r--r--src/raylib.h1
-rw-r--r--src/rcore.c119
2 files changed, 120 insertions, 0 deletions
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 <unistd.h>
+ const char PathDelim = '/';
+ #elif defined(__APPLE__)
+ #include <sys/syslimits.h>
+ const char PathDelim = '/';
+ #endif // OSs
+#endif // PLATFORM_DESKTOP
+
#include <stdlib.h> // Required for: srand(), rand(), atexit()
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
#include <string.h> // 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)