#include "platform/host_platform.h" #include #if defined(_WIN32) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #include #else #include #endif #if defined(__APPLE__) #include #include #endif namespace RuntimePlatform { std::optional ExecutableDirectory() noexcept { #if defined(_WIN32) std::wstring buffer(MAX_PATH, L'\0'); for (;;) { const DWORD length = GetModuleFileNameW(nullptr, buffer.data(), static_cast(buffer.size())); if (length == 0) { return std::nullopt; } if (length < buffer.size() - 1) { buffer.resize(length); return std::filesystem::path(buffer).parent_path(); } buffer.resize(buffer.size() * 2); } #elif defined(__APPLE__) uint32_t size = 0; if (_NSGetExecutablePath(nullptr, &size) != -1 || size == 0) { return std::nullopt; } std::string path(size, '\0'); if (_NSGetExecutablePath(path.data(), &size) != 0) { return std::nullopt; } path.resize(std::char_traits::length(path.c_str())); std::error_code ec; const auto resolved = std::filesystem::weakly_canonical(path, ec); return (ec ? std::filesystem::path(path) : resolved).parent_path(); #else return std::nullopt; #endif } std::filesystem::path ApplicationDataDirectory(std::string_view applicationName) { #if defined(_WIN32) PWSTR rawPath = nullptr; if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &rawPath)) && rawPath) { const std::filesystem::path directory = std::filesystem::path(rawPath) / applicationName; CoTaskMemFree(rawPath); return directory; } #elif defined(MKW_PLATFORM_IOS) // The whole container is already private to this app, so user state lives // in Documents rather than a name-scoped Application Support subdirectory. // That puts Config.toml beside the game data the user copied in, which is // what makes a relative dvd_root resolve, and UIFileSharingEnabled exposes // the directory in Files.app so the user can manage it. if (const char* home = std::getenv("HOME"); home && *home) { return std::filesystem::path(home) / "Documents"; } if (const passwd* user = getpwuid(getuid()); user && user->pw_dir && *user->pw_dir) { return std::filesystem::path(user->pw_dir) / "Documents"; } #elif defined(__APPLE__) if (const char* home = std::getenv("HOME"); home && *home) { return std::filesystem::path(home) / "Library" / "Application Support" / applicationName; } if (const passwd* user = getpwuid(getuid()); user && user->pw_dir && *user->pw_dir) { return std::filesystem::path(user->pw_dir) / "Library" / "Application Support" / applicationName; } #endif return std::filesystem::current_path() / applicationName; } std::filesystem::path LogDirectory(std::string_view applicationName) { return ApplicationDataDirectory(applicationName) / "Logs"; } uint64_t CurrentProcessId() noexcept { #if defined(_WIN32) return static_cast(::GetCurrentProcessId()); #else return static_cast(::getpid()); #endif } } // namespace RuntimePlatform