mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-24 00:03:11 +01:00
Merge pull request #6765 from IntelOrca/refactor/resolve-data-path
Rewrite Platform::GetInstallPath
This commit is contained in:
@@ -200,7 +200,6 @@
|
||||
4CE462411FD0710E0001CD98 /* Game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4623F1FD0710E0001CD98 /* Game.cpp */; };
|
||||
4CE462451FD161360001CD98 /* Platform.Android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE462441FD161360001CD98 /* Platform.Android.cpp */; };
|
||||
4CE4624A1FD1613D0001CD98 /* Platform.Linux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE462461FD1613D0001CD98 /* Platform.Linux.cpp */; };
|
||||
4CE4624B1FD1613D0001CD98 /* Platform.macOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE462471FD1613D0001CD98 /* Platform.macOS.cpp */; };
|
||||
4CE4624C1FD1613D0001CD98 /* Platform.Posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE462481FD1613D0001CD98 /* Platform.Posix.cpp */; };
|
||||
4CE4624D1FD1613D0001CD98 /* Platform.Win32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE462491FD1613D0001CD98 /* Platform.Win32.cpp */; };
|
||||
4CFE4E801F90A3F1005243C2 /* Peep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFE4E7B1F90A3F1005243C2 /* Peep.cpp */; };
|
||||
@@ -485,6 +484,7 @@
|
||||
F775F5371EE3724F001F00E7 /* DummyAudioContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F775F5361EE3724F001F00E7 /* DummyAudioContext.cpp */; };
|
||||
F775F5381EE3725C001F00E7 /* DummyAudioContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F775F5361EE3724F001F00E7 /* DummyAudioContext.cpp */; };
|
||||
F79F428F1F3260F1009E42F8 /* changelog.txt in Resources */ = {isa = PBXBuildFile; fileRef = F79F428E1F3260F1009E42F8 /* changelog.txt */; };
|
||||
F7B2048A201E91BF0000AD7E /* Platform.macOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7B20489201E91BF0000AD7E /* Platform.macOS.mm */; };
|
||||
F7CB863F1EEDA0B50030C877 /* WindowManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7CB863D1EEDA0B50030C877 /* WindowManager.cpp */; };
|
||||
F7CB864A1EEDA1330030C877 /* KeyboardShortcuts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7CB86471EEDA1330030C877 /* KeyboardShortcuts.cpp */; };
|
||||
F7CB864D1EEDA1A80030C877 /* DummyWindowManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7CB864B1EEDA1A80030C877 /* DummyWindowManager.cpp */; };
|
||||
@@ -867,7 +867,6 @@
|
||||
4CE462401FD0710E0001CD98 /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Game.h; sourceTree = "<group>"; };
|
||||
4CE462441FD161360001CD98 /* Platform.Android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Platform.Android.cpp; sourceTree = "<group>"; };
|
||||
4CE462461FD1613D0001CD98 /* Platform.Linux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Platform.Linux.cpp; sourceTree = "<group>"; };
|
||||
4CE462471FD1613D0001CD98 /* Platform.macOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Platform.macOS.cpp; sourceTree = "<group>"; };
|
||||
4CE462481FD1613D0001CD98 /* Platform.Posix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Platform.Posix.cpp; sourceTree = "<group>"; };
|
||||
4CE462491FD1613D0001CD98 /* Platform.Win32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Platform.Win32.cpp; sourceTree = "<group>"; };
|
||||
4CFE4E7B1F90A3F1005243C2 /* Peep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Peep.cpp; sourceTree = "<group>"; };
|
||||
@@ -1414,6 +1413,7 @@
|
||||
F775F5331EE35A6B001F00E7 /* DummyUiContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DummyUiContext.cpp; sourceTree = "<group>"; };
|
||||
F775F5361EE3724F001F00E7 /* DummyAudioContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DummyAudioContext.cpp; sourceTree = "<group>"; };
|
||||
F79F428E1F3260F1009E42F8 /* changelog.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = changelog.txt; path = distribution/changelog.txt; sourceTree = SOURCE_ROOT; };
|
||||
F7B20489201E91BF0000AD7E /* Platform.macOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Platform.macOS.mm; sourceTree = "<group>"; };
|
||||
F7CB863D1EEDA0B50030C877 /* WindowManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WindowManager.cpp; sourceTree = "<group>"; };
|
||||
F7CB863E1EEDA0B50030C877 /* WindowManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowManager.h; sourceTree = "<group>"; };
|
||||
F7CB86471EEDA1330030C877 /* KeyboardShortcuts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardShortcuts.cpp; sourceTree = "<group>"; };
|
||||
@@ -2243,7 +2243,7 @@
|
||||
4CE462441FD161360001CD98 /* Platform.Android.cpp */,
|
||||
F76C845E1EC4E7CC00FA49E2 /* platform.h */,
|
||||
4CE462461FD1613D0001CD98 /* Platform.Linux.cpp */,
|
||||
4CE462471FD1613D0001CD98 /* Platform.macOS.cpp */,
|
||||
F7B20489201E91BF0000AD7E /* Platform.macOS.mm */,
|
||||
4CE462481FD1613D0001CD98 /* Platform.Posix.cpp */,
|
||||
4CE462491FD1613D0001CD98 /* Platform.Win32.cpp */,
|
||||
F76C84601EC4E7CC00FA49E2 /* Platform2.h */,
|
||||
@@ -3201,7 +3201,6 @@
|
||||
4C7B53F3200143C200A52E21 /* Chat.cpp in Sources */,
|
||||
4C7B53F4200143C200A52E21 /* Colour.cpp in Sources */,
|
||||
4C7B547B2010DF4C00A52E21 /* Posix.cpp in Sources */,
|
||||
4CE4624B1FD1613D0001CD98 /* Platform.macOS.cpp in Sources */,
|
||||
4C7B53A51FFC180400A52E21 /* ObjectList.cpp in Sources */,
|
||||
4C93F1501F8B744400A9330D /* SideFrictionRollerCoaster.cpp in Sources */,
|
||||
4C93F13D1F8B744400A9330D /* CompactInvertedCoaster.cpp in Sources */,
|
||||
@@ -3238,6 +3237,7 @@
|
||||
4C93F1541F8B744400A9330D /* TwisterRollerCoaster.cpp in Sources */,
|
||||
4CC4B8E71FE00C4E00660D62 /* Diagnostic.cpp in Sources */,
|
||||
C666EE7B1F37ACB10061AA04 /* TitleExit.cpp in Sources */,
|
||||
F7B2048A201E91BF0000AD7E /* Platform.macOS.mm in Sources */,
|
||||
F7D7747F1EC61E5100BE6EBC /* UiContext.macOS.mm in Sources */,
|
||||
F76C887E1EC5324E00FA49E2 /* CursorRepository.cpp in Sources */,
|
||||
4C7B53FD200143C200A52E21 /* Window.cpp in Sources */,
|
||||
|
||||
@@ -1169,4 +1169,15 @@ extern "C"
|
||||
}
|
||||
String::Set(outPath, outSize, path.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is deprecated.
|
||||
* Use IPlatformEnvironment instad.
|
||||
*/
|
||||
void platform_get_openrct_data_path(utf8 * outPath, size_t outSize)
|
||||
{
|
||||
auto env = GetContext()->GetPlatformEnvironment();
|
||||
auto path = env->GetDirectoryPath(DIRBASE::OPENRCT2);
|
||||
String::Set(outPath, outSize, path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,11 @@ namespace Path
|
||||
platform_ensure_directory_exists(path.c_str());
|
||||
}
|
||||
|
||||
bool DirectoryExists(const std::string &path)
|
||||
{
|
||||
return platform_directory_exists(path.c_str());
|
||||
}
|
||||
|
||||
std::string GetFileName(const std::string &path)
|
||||
{
|
||||
return GetFileName(path.c_str());
|
||||
@@ -208,6 +213,12 @@ namespace Path
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string GetAbsolute(const std::string &relative)
|
||||
{
|
||||
utf8 absolute[MAX_PATH];
|
||||
return GetAbsolute(absolute, sizeof(absolute), relative.c_str());
|
||||
}
|
||||
|
||||
bool Equals(const std::string &a, const std::string &b)
|
||||
{
|
||||
return String::Equals(a.c_str(), b.c_str());
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace Path
|
||||
utf8 * GetDirectory(const utf8 * path);
|
||||
utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path);
|
||||
void CreateDirectory(const std::string &path);
|
||||
bool DirectoryExists(const std::string &path);
|
||||
std::string GetFileName(const std::string &path);
|
||||
const utf8 * GetFileName(const utf8 * path);
|
||||
std::string GetFileNameWithoutExtension(const std::string &path);
|
||||
@@ -42,6 +43,7 @@ namespace Path
|
||||
const std::string GetExtension(const std::string &path);
|
||||
const utf8 * GetExtension(const utf8 * path);
|
||||
utf8 * GetAbsolute(utf8 * buffer, size_t bufferSize, const utf8 * relativePath);
|
||||
std::string GetAbsolute(const std::string &relative);
|
||||
bool Equals(const std::string &a, const std::string &b);
|
||||
bool Equals(const utf8 * a, const utf8 * b);
|
||||
|
||||
|
||||
@@ -24,11 +24,6 @@
|
||||
#include <jni.h>
|
||||
#include <SDL.h>
|
||||
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
safe_strcpy(outPath, "/sdcard/openrct2", outSize);
|
||||
}
|
||||
|
||||
#ifndef NO_TTF
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
|
||||
{
|
||||
@@ -37,11 +32,6 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
|
||||
}
|
||||
#endif
|
||||
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size) {
|
||||
safe_strcpy(out, "/sdcard/openrct2", size);
|
||||
}
|
||||
|
||||
|
||||
uint16 platform_get_locale_language() {
|
||||
return LANGUAGE_ENGLISH_UK;
|
||||
}
|
||||
|
||||
@@ -42,72 +42,6 @@
|
||||
#include "../util/Util.h"
|
||||
#include "platform.h"
|
||||
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
char exePath[MAX_PATH];
|
||||
#ifdef __linux__
|
||||
ssize_t bytesRead;
|
||||
bytesRead = readlink("/proc/self/exe", exePath, MAX_PATH);
|
||||
if (bytesRead == -1) {
|
||||
log_fatal("failed to read /proc/self/exe");
|
||||
}
|
||||
exePath[bytesRead - 1] = '\0';
|
||||
#elif defined(__FreeBSD__)
|
||||
size_t exeLen = sizeof(exePath);
|
||||
const sint32 mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
if (sysctl(mib, 4, exePath, &exeLen, NULL, 0) == -1) {
|
||||
log_fatal("failed to get process path");
|
||||
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
// There is no way to get the path name of a running executable.
|
||||
// If you are not using the port or package, you may have to change this line!
|
||||
strlcpy(exePath, "/usr/local/bin/", sizeof(exePath));
|
||||
#else
|
||||
#error "Platform does not support full path exe retrieval"
|
||||
#endif
|
||||
char *exeDelimiter = strrchr(exePath, *PATH_SEPARATOR);
|
||||
if (exeDelimiter == nullptr)
|
||||
{
|
||||
log_error("should never happen here");
|
||||
outPath[0] = '\0';
|
||||
return;
|
||||
}
|
||||
*exeDelimiter = '\0';
|
||||
|
||||
safe_strcpy(outPath, exePath, outSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default directory fallback is:
|
||||
* - (command line argument)
|
||||
* - <exePath>/data
|
||||
* - /usr/local/share/openrct2
|
||||
* - /var/lib/openrct2
|
||||
* - /usr/share/openrct2
|
||||
*/
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size) {
|
||||
static const utf8 *searchLocations[] = {
|
||||
"../share/openrct2",
|
||||
#ifdef ORCT2_RESOURCE_DIR
|
||||
// defined in CMakeLists.txt
|
||||
ORCT2_RESOURCE_DIR,
|
||||
#endif // ORCT2_RESOURCE_DIR
|
||||
"/usr/local/share/openrct2",
|
||||
"/var/lib/openrct2",
|
||||
"/usr/share/openrct2",
|
||||
};
|
||||
for (auto searchLocation : searchLocations)
|
||||
{
|
||||
log_verbose("Looking for OpenRCT2 data in %s", searchLocation);
|
||||
if (platform_directory_exists(searchLocation))
|
||||
{
|
||||
safe_strcpy(out, searchLocation, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16 platform_get_locale_language(){
|
||||
const char *langString = setlocale(LC_MESSAGES, "");
|
||||
if(langString != nullptr){
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#include <cassert>
|
||||
#include "Platform2.h"
|
||||
|
||||
namespace Platform
|
||||
@@ -39,6 +40,17 @@ namespace Platform
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string GetInstallPath()
|
||||
{
|
||||
return "/sdcard/openrct2";
|
||||
}
|
||||
|
||||
std::string GetCurrentExecutablePath()
|
||||
{
|
||||
assert(false, "GetCurrentExecutablePath() not implemented for Android.");
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,10 +14,13 @@
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__linux__) && !defined(__ANDROID__))
|
||||
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include "../core/Path.hpp"
|
||||
#include "../core/Util.hpp"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "platform.h"
|
||||
#include "Platform2.h"
|
||||
|
||||
@@ -63,6 +66,102 @@ namespace Platform
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static std::string FindInstallPath()
|
||||
{
|
||||
static const char * SearchLocations[] =
|
||||
{
|
||||
"../share/openrct2",
|
||||
#ifdef ORCT2_RESOURCE_DIR
|
||||
// defined in CMakeLists.txt
|
||||
ORCT2_RESOURCE_DIR,
|
||||
#endif // ORCT2_RESOURCE_DIR
|
||||
"/usr/local/share/openrct2",
|
||||
"/var/lib/openrct2",
|
||||
"/usr/share/openrct2",
|
||||
};
|
||||
for (auto searchLocation : SearchLocations)
|
||||
{
|
||||
log_verbose("Looking for OpenRCT2 data in %s", searchLocation);
|
||||
if (Path::DirectoryExists(searchLocation))
|
||||
{
|
||||
return searchLocation;
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static std::string GetCurrentWorkingDirectory()
|
||||
{
|
||||
char cwdPath[PATH_MAX];
|
||||
if (getcwd(cwdPath, sizeof(cwdPath)) != nullptr)
|
||||
{
|
||||
return cwdPath;
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string GetInstallPath()
|
||||
{
|
||||
// 1. Try command line argument
|
||||
auto path = std::string(gCustomOpenrctDataPath);
|
||||
if (!path.empty())
|
||||
{
|
||||
path = Path::GetAbsolute(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2. Try ${exeDir}/data
|
||||
auto exePath = Platform::GetCurrentExecutablePath();
|
||||
auto exeDirectory = Path::GetDirectory(exePath);
|
||||
path = Path::Combine(exeDirectory, "data");
|
||||
if (!Path::DirectoryExists(path))
|
||||
{
|
||||
// 3. Try standard system app directories
|
||||
path = FindInstallPath();
|
||||
if (path.empty())
|
||||
{
|
||||
// 4. Fallback to ${cwd}/data
|
||||
path = GetCurrentWorkingDirectory();
|
||||
if (!path.empty())
|
||||
{
|
||||
path = Path::Combine(path, "data");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string GetCurrentExecutablePath()
|
||||
{
|
||||
char exePath[PATH_MAX] = { 0 };
|
||||
#ifdef __linux__
|
||||
auto bytesRead = readlink("/proc/self/exe", exePath, sizeof(exePath));
|
||||
if (bytesRead == -1)
|
||||
{
|
||||
log_fatal("failed to read /proc/self/exe");
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
const sint32 mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
auto exeLen = sizeof(exePath);
|
||||
if (sysctl(mib, 4, exePath, &exeLen, nullptr, 0) == -1)
|
||||
{
|
||||
log_fatal("failed to get process path");
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
// There is no way to get the path name of a running executable.
|
||||
// If you are not using the port or package, you may have to change this line!
|
||||
strlcpy(exePath, "/usr/local/bin/", sizeof(exePath));
|
||||
#else
|
||||
#error "Platform does not support full path exe retrieval"
|
||||
#endif
|
||||
return exePath;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -76,14 +76,6 @@ namespace Platform
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string GetInstallPath()
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
platform_resolve_openrct_data_path();
|
||||
platform_get_openrct_data_path(path, sizeof(path));
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string FormatShortDate(std::time_t timestamp)
|
||||
{
|
||||
char date[20];
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <datetimeapi.h>
|
||||
@@ -30,11 +32,19 @@
|
||||
#include "../core/Path.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "../core/Util.hpp"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "Platform2.h"
|
||||
#include "platform.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
#ifdef __USE_SHGETKNOWNFOLDERPATH__
|
||||
static std::string WIN32_GetKnownFolderPath(REFKNOWNFOLDERID rfid);
|
||||
#else
|
||||
static std::string WIN32_GetFolderPath(int nFolder);
|
||||
#endif
|
||||
static std::string WIN32_GetModuleFileNameW(HMODULE hModule);
|
||||
|
||||
uint32 GetTicks()
|
||||
{
|
||||
return platform_get_ticks();
|
||||
@@ -72,31 +82,6 @@ namespace Platform
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __USE_SHGETKNOWNFOLDERPATH__
|
||||
static std::string WIN32_GetKnownFolderPath(REFKNOWNFOLDERID rfid)
|
||||
{
|
||||
std::string path;
|
||||
wchar_t * wpath = nullptr;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(rfid, KF_FLAG_CREATE, nullptr, &wpath)))
|
||||
{
|
||||
path = String::ToUtf8(std::wstring(wpath));
|
||||
}
|
||||
CoTaskMemFree(wpath);
|
||||
return path;
|
||||
}
|
||||
#else
|
||||
static std::string WIN32_GetFolderPath(int nFolder)
|
||||
{
|
||||
std::string path;
|
||||
wchar_t wpath[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPathW(nullptr, nFolder | CSIDL_FLAG_CREATE, nullptr, 0, wpath)))
|
||||
{
|
||||
path = String::ToUtf8(std::wstring(wpath));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string GetFolderPath(SPECIAL_FOLDER folder)
|
||||
{
|
||||
switch (folder)
|
||||
@@ -141,12 +126,25 @@ namespace Platform
|
||||
|
||||
std::string GetInstallPath()
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
platform_resolve_openrct_data_path();
|
||||
platform_get_openrct_data_path(path, sizeof(path));
|
||||
auto path = std::string(gCustomOpenrctDataPath);
|
||||
if (!path.empty())
|
||||
{
|
||||
path = Path::GetAbsolute(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto exePath = GetCurrentExecutablePath();
|
||||
auto exeDirectory = Path::GetDirectory(exePath);
|
||||
path = Path::Combine(exeDirectory, "data");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string GetCurrentExecutablePath()
|
||||
{
|
||||
return WIN32_GetModuleFileNameW(nullptr);
|
||||
}
|
||||
|
||||
std::string GetDocsPath()
|
||||
{
|
||||
return std::string();
|
||||
@@ -198,6 +196,46 @@ namespace Platform
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __USE_SHGETKNOWNFOLDERPATH__
|
||||
static std::string WIN32_GetKnownFolderPath(REFKNOWNFOLDERID rfid)
|
||||
{
|
||||
std::string path;
|
||||
wchar_t * wpath = nullptr;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(rfid, KF_FLAG_CREATE, nullptr, &wpath)))
|
||||
{
|
||||
path = String::ToUtf8(std::wstring(wpath));
|
||||
}
|
||||
CoTaskMemFree(wpath);
|
||||
return path;
|
||||
}
|
||||
#else
|
||||
static std::string WIN32_GetFolderPath(int nFolder)
|
||||
{
|
||||
std::string path;
|
||||
wchar_t wpath[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPathW(nullptr, nFolder | CSIDL_FLAG_CREATE, nullptr, 0, wpath)))
|
||||
{
|
||||
path = String::ToUtf8(std::wstring(wpath));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
static std::string WIN32_GetModuleFileNameW(HMODULE hModule)
|
||||
{
|
||||
uint32 wExePathCapacity = MAX_PATH;
|
||||
std::unique_ptr<wchar_t[]> wExePath;
|
||||
uint32 size;
|
||||
do
|
||||
{
|
||||
wExePathCapacity *= 2;
|
||||
wExePath = std::make_unique<wchar_t[]>(wExePathCapacity);
|
||||
size = GetModuleFileNameW(hModule, wExePath.get(), wExePathCapacity);
|
||||
}
|
||||
while (size >= wExePathCapacity);
|
||||
return String::ToUtf8(wExePath.get());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
#include "../core/Path.hpp"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "Platform2.h"
|
||||
|
||||
namespace Platform
|
||||
@@ -44,6 +48,63 @@ namespace Platform
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static std::string GetBundlePath()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
NSBundle * bundle = [NSBundle mainBundle];
|
||||
if (bundle)
|
||||
{
|
||||
auto resources = bundle.resourcePath.UTF8String;
|
||||
if (Path::DirectoryExists(resources))
|
||||
{
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetInstallPath()
|
||||
{
|
||||
auto path = std::string(gCustomOpenrctDataPath);
|
||||
if (!path.empty())
|
||||
{
|
||||
path = Path::GetAbsolute(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto exePath = GetCurrentExecutablePath();
|
||||
auto exeDirectory = Path::GetDirectory(exePath);
|
||||
path = Path::Combine(exeDirectory, "data");
|
||||
NSString * nsPath = [NSString stringWithUTF8String:path.c_str()];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:nsPath])
|
||||
{
|
||||
path = GetBundlePath();
|
||||
if (path.empty())
|
||||
{
|
||||
path = "/";
|
||||
}
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string GetCurrentExecutablePath()
|
||||
{
|
||||
char exePath[MAX_PATH];
|
||||
uint32 size = MAX_PATH;
|
||||
int result = _NSGetExecutablePath(exePath, &size);
|
||||
if (result == 0)
|
||||
{
|
||||
return exePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -37,6 +37,7 @@ namespace Platform
|
||||
std::string GetFolderPath(SPECIAL_FOLDER folder);
|
||||
std::string GetInstallPath();
|
||||
std::string GetDocsPath();
|
||||
std::string GetCurrentExecutablePath();
|
||||
|
||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
|
||||
std::string GetEnvironmentPath(const char * name);
|
||||
|
||||
@@ -48,7 +48,6 @@ extern "C"
|
||||
{
|
||||
|
||||
static utf8 _userDataDirectoryPath[MAX_PATH] = { 0 };
|
||||
static utf8 _openrctDataDirectoryPath[MAX_PATH] = { 0 };
|
||||
|
||||
void platform_get_date_utc(rct2_date *out_date)
|
||||
{
|
||||
@@ -400,53 +399,6 @@ static wchar_t *regular_to_wchar(const char* src)
|
||||
return w_buffer;
|
||||
}
|
||||
|
||||
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
safe_strcpy(outPath, _openrctDataDirectoryPath, outSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default directory fallback is:
|
||||
* - (command line argument)
|
||||
* - <exePath>/data
|
||||
* - <platform dependent>
|
||||
*/
|
||||
void platform_resolve_openrct_data_path()
|
||||
{
|
||||
if (gCustomOpenrctDataPath[0] != 0) {
|
||||
// NOTE: second argument to `realpath` is meant to either be NULL or `PATH_MAX`-sized buffer,
|
||||
// since our `MAX_PATH` macro is set to some other value, pass NULL to have `realpath` return
|
||||
// a `malloc`ed buffer.
|
||||
char *resolved_path = realpath(gCustomOpenrctDataPath, NULL);
|
||||
if (resolved_path == nullptr) {
|
||||
log_error("Could not resolve path \"%s\", errno = %d", gCustomOpenrctDataPath, errno);
|
||||
return;
|
||||
} else {
|
||||
safe_strcpy(_openrctDataDirectoryPath, resolved_path, MAX_PATH);
|
||||
free(resolved_path);
|
||||
}
|
||||
|
||||
path_end_with_separator(_openrctDataDirectoryPath, MAX_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[MAX_PATH];
|
||||
platform_get_exe_path(buffer, sizeof(buffer));
|
||||
|
||||
safe_strcat_path(buffer, "data", MAX_PATH);
|
||||
log_verbose("Looking for OpenRCT2 data in %s", buffer);
|
||||
if (platform_directory_exists(buffer))
|
||||
{
|
||||
_openrctDataDirectoryPath[0] = '\0';
|
||||
safe_strcpy(_openrctDataDirectoryPath, buffer, MAX_PATH);
|
||||
log_verbose("Found OpenRCT2 data in %s", _openrctDataDirectoryPath);
|
||||
return;
|
||||
}
|
||||
|
||||
platform_posix_sub_resolve_openrct_data_path(_openrctDataDirectoryPath, sizeof(_openrctDataDirectoryPath));
|
||||
log_verbose("Trying to use OpenRCT2 data in %s", _openrctDataDirectoryPath);
|
||||
}
|
||||
|
||||
time_t platform_file_get_modified_time(const utf8* path){
|
||||
struct stat buf;
|
||||
if (stat(path, &buf) == 0) {
|
||||
|
||||
@@ -53,8 +53,6 @@
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static utf8 _openrctDataDirectoryPath[MAX_PATH] = { 0 };
|
||||
|
||||
#define OPENRCT2_DLL_MODULE_NAME "openrct2.dll"
|
||||
|
||||
static HMODULE _dllModule = nullptr;
|
||||
@@ -205,45 +203,6 @@ bool platform_file_delete(const utf8 *path)
|
||||
return success == TRUE;
|
||||
}
|
||||
|
||||
void platform_resolve_openrct_data_path()
|
||||
{
|
||||
wchar_t wOutPath[MAX_PATH];
|
||||
|
||||
if (gCustomOpenrctDataPath[0] != 0) {
|
||||
wchar_t *customOpenrctDataPathW = utf8_to_widechar(gCustomOpenrctDataPath);
|
||||
if (GetFullPathNameW(customOpenrctDataPathW, (DWORD)Util::CountOf(wOutPath), wOutPath, NULL) == 0) {
|
||||
log_fatal("Unable to resolve path '%s'.", gCustomOpenrctDataPath);
|
||||
exit(-1);
|
||||
}
|
||||
utf8 *outPathTemp = widechar_to_utf8(wOutPath);
|
||||
safe_strcpy(_openrctDataDirectoryPath, outPathTemp, sizeof(_openrctDataDirectoryPath));
|
||||
free(outPathTemp);
|
||||
free(customOpenrctDataPathW);
|
||||
|
||||
path_end_with_separator(_openrctDataDirectoryPath, sizeof(_openrctDataDirectoryPath));
|
||||
return;
|
||||
}
|
||||
char buffer[MAX_PATH];
|
||||
platform_get_exe_path(buffer, sizeof(buffer));
|
||||
|
||||
safe_strcat_path(buffer, "data", MAX_PATH);
|
||||
|
||||
if (platform_directory_exists(buffer))
|
||||
{
|
||||
_openrctDataDirectoryPath[0] = '\0';
|
||||
safe_strcpy(_openrctDataDirectoryPath, buffer, sizeof(_openrctDataDirectoryPath));
|
||||
return;
|
||||
} else {
|
||||
log_fatal("Unable to resolve openrct data path.");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
safe_strcpy(outPath, _openrctDataDirectoryPath, outSize);
|
||||
}
|
||||
|
||||
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
|
||||
{
|
||||
wchar_t * wSteamPath;
|
||||
@@ -488,20 +447,6 @@ uint8 platform_get_locale_date_format()
|
||||
return DATE_FORMAT_DAY_MONTH_YEAR;
|
||||
}
|
||||
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
wchar_t exePath[MAX_PATH];
|
||||
wchar_t tempPath[MAX_PATH];
|
||||
wchar_t *exeDelimiter;
|
||||
|
||||
GetModuleFileNameW(NULL, exePath, MAX_PATH);
|
||||
exeDelimiter = wcsrchr(exePath, *PATH_SEPARATOR);
|
||||
*exeDelimiter = L'\0';
|
||||
wcscpy_s(tempPath, MAX_PATH, exePath);
|
||||
_wfullpath(exePath, tempPath, MAX_PATH);
|
||||
WideCharToMultiByte(CP_UTF8, 0, exePath, MAX_PATH, outPath, (sint32) outSize, NULL, NULL);
|
||||
}
|
||||
|
||||
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
|
||||
{
|
||||
#if !defined(__MINGW32__) && ((NTDDI_VERSION >= NTDDI_VISTA) && !defined(_USING_V110_SDK71_) && !defined(_ATL_XP_TARGETING))
|
||||
|
||||
@@ -34,51 +34,6 @@ void macos_disallow_automatic_window_tabbing()
|
||||
}
|
||||
}
|
||||
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
if (outSize == 0) return;
|
||||
char exePath[MAX_PATH];
|
||||
uint32_t size = MAX_PATH;
|
||||
int result = _NSGetExecutablePath(exePath, &size);
|
||||
if (result != 0) {
|
||||
log_fatal("failed to get path");
|
||||
}
|
||||
exePath[MAX_PATH - 1] = '\0';
|
||||
char *exeDelimiter = strrchr(exePath, *PATH_SEPARATOR);
|
||||
if (exeDelimiter == NULL)
|
||||
{
|
||||
log_error("should never happen here");
|
||||
outPath[0] = '\0';
|
||||
return;
|
||||
}
|
||||
*exeDelimiter = '\0';
|
||||
|
||||
safe_strcpy(outPath, exePath, outSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default directory fallback is:
|
||||
* - (command line argument)
|
||||
* - <exePath>/data
|
||||
* - <Resources Folder>
|
||||
*/
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size) {
|
||||
@autoreleasepool
|
||||
{
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
if (bundle)
|
||||
{
|
||||
const utf8 *resources = bundle.resourcePath.UTF8String;
|
||||
if (platform_directory_exists(resources))
|
||||
{
|
||||
out[0] = '\0';
|
||||
safe_strcpy(out, resources, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
utf8* macos_str_decomp_to_precomp(utf8 *input)
|
||||
{
|
||||
@autoreleasepool
|
||||
|
||||
@@ -95,7 +95,6 @@ void platform_get_date_local(rct2_date *out_date);
|
||||
void platform_get_time_local(rct2_time *out_time);
|
||||
|
||||
// Platform specific definitions
|
||||
void platform_get_exe_path(utf8 *outPath, size_t outSize);
|
||||
bool platform_file_exists(const utf8 *path);
|
||||
bool platform_directory_exists(const utf8 *path);
|
||||
bool platform_original_game_data_exists(const utf8 *path);
|
||||
@@ -114,7 +113,6 @@ bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath);
|
||||
bool platform_file_delete(const utf8 *path);
|
||||
uint32 platform_get_ticks();
|
||||
void platform_sleep(uint32 ms);
|
||||
void platform_resolve_openrct_data_path();
|
||||
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize);
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t outSize);
|
||||
utf8* platform_get_username();
|
||||
@@ -162,10 +160,6 @@ void core_init();
|
||||
__declspec(dllexport) sint32 StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, sint32 nCmdShow);
|
||||
#endif // _WIN32
|
||||
|
||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__ANDROID__)
|
||||
void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size);
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
void macos_disallow_automatic_window_tabbing();
|
||||
utf8* macos_str_decomp_to_precomp(utf8 *input);
|
||||
|
||||
Reference in New Issue
Block a user