diff --git a/src/openrct2/core/File.cpp b/src/openrct2/core/File.cpp index af5753da13..df722e1196 100644 --- a/src/openrct2/core/File.cpp +++ b/src/openrct2/core/File.cpp @@ -121,30 +121,7 @@ namespace File uint64_t GetLastModified(const std::string& path) { - uint64_t lastModified = 0; -#ifdef _WIN32 - auto pathW = String::ToWideChar(path); - auto hFile = CreateFileW(pathW.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if (hFile != INVALID_HANDLE_VALUE) - { - FILETIME ftCreate, ftAccess, ftWrite; - if (GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) - { - lastModified = (static_cast(ftWrite.dwHighDateTime) << 32ULL) - | static_cast(ftWrite.dwLowDateTime); - } - CloseHandle(hFile); - } -#else - struct stat statInfo - { - }; - if (stat(path.c_str(), &statInfo) == 0) - { - lastModified = statInfo.st_mtime; - } -#endif - return lastModified; + return Platform::GetLastModified(path); } } // namespace File diff --git a/src/openrct2/core/Path.cpp b/src/openrct2/core/Path.cpp index 8bb3269049..33a3667d28 100644 --- a/src/openrct2/core/Path.cpp +++ b/src/openrct2/core/Path.cpp @@ -7,20 +7,18 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include -#ifndef _WIN32 -# include -#endif +#include "Path.hpp" #include "../localisation/Language.h" +#include "../platform/Platform2.h" #include "../platform/platform.h" #include "../util/Util.h" #include "File.h" #include "FileSystem.hpp" #include "Memory.hpp" -#include "Path.hpp" #include "String.hpp" +#include #include namespace Path @@ -30,15 +28,6 @@ namespace Path return safe_strcat_path(buffer, src, bufferSize); } - static constexpr bool IsPathSeparator(char c) - { -#ifdef _WIN32 - if (c == '\\') - return true; -#endif - return c == '/'; - } - std::string Combine(std::string_view a, std::string_view b) { if (a.empty()) @@ -47,9 +36,9 @@ namespace Path return std::string(a); auto aEnd = a.back(); auto bBegin = b.front(); - if (IsPathSeparator(aEnd)) + if (Platform::IsPathSeparator(aEnd)) { - if (IsPathSeparator(bBegin)) + if (Platform::IsPathSeparator(bBegin)) { return std::string(a) + std::string(b.substr(1)); } @@ -60,7 +49,7 @@ namespace Path } else { - if (IsPathSeparator(bBegin)) + if (Platform::IsPathSeparator(bBegin)) { return std::string(a) + std::string(b); } @@ -204,34 +193,7 @@ namespace Path utf8* GetAbsolute(utf8* buffer, size_t bufferSize, const utf8* relativePath) { -#ifdef _WIN32 - auto relativePathW = String::ToWideChar(relativePath); - wchar_t absolutePathW[MAX_PATH]; - DWORD length = GetFullPathNameW( - relativePathW.c_str(), static_cast(std::size(absolutePathW)), absolutePathW, nullptr); - if (length == 0) - { - return String::Set(buffer, bufferSize, relativePath); - } - else - { - auto absolutePath = String::ToUtf8(absolutePathW); - String::Set(buffer, bufferSize, absolutePath.c_str()); - return buffer; - } -#else - utf8* absolutePath = realpath(relativePath, nullptr); - if (absolutePath == nullptr) - { - return String::Set(buffer, bufferSize, relativePath); - } - else - { - String::Set(buffer, bufferSize, absolutePath); - Memory::Free(absolutePath); - return buffer; - } -#endif + return Platform::GetAbsolutePath(buffer, bufferSize, relativePath); } std::string GetAbsolute(const std::string& relative) @@ -247,51 +209,11 @@ namespace Path bool Equals(const utf8* a, const utf8* b) { - bool ignoreCase = false; -#ifdef _WIN32 - ignoreCase = true; -#endif - return String::Equals(a, b, ignoreCase); + return String::Equals(a, b, Platform::ShouldIgnoreCase()); } std::string ResolveCasing(const std::string& path) { - std::string result; - if (File::Exists(path)) - { - // Windows is case insensitive so it will exist and that is all that matters - // for now. We can properly resolve the casing if we ever need to. - result = path; - } -#ifndef _WIN32 - else - { - std::string fileName = Path::GetFileName(path); - std::string directory = Path::GetDirectory(path); - - struct dirent** files; - auto count = scandir(directory.c_str(), &files, nullptr, alphasort); - if (count != -1) - { - // Find a file which matches by name (case insensitive) - for (int32_t i = 0; i < count; i++) - { - if (String::Equals(files[i]->d_name, fileName.c_str(), true)) - { - result = Path::Combine(directory, std::string(files[i]->d_name)); - break; - } - } - - // Free memory - for (int32_t i = 0; i < count; i++) - { - free(files[i]); - } - free(files); - } - } -#endif - return result; + return Platform::ResolveCasing(path, File::Exists(path)); } } // namespace Path diff --git a/src/openrct2/drawing/NewDrawing.cpp b/src/openrct2/drawing/NewDrawing.cpp index 29aa3622aa..c1eb196933 100644 --- a/src/openrct2/drawing/NewDrawing.cpp +++ b/src/openrct2/drawing/NewDrawing.cpp @@ -15,6 +15,7 @@ #include "../interface/Screenshot.h" #include "../localisation/StringIds.h" #include "../paint/Painter.h" +#include "../platform/Platform2.h" #include "../ui/UiContext.h" #include "../world/Location.hpp" #include "IDrawingContext.h" @@ -52,16 +53,8 @@ static IDrawingEngine* GetDrawingEngine() bool drawing_engine_requires_new_window(DrawingEngine srcEngine, DrawingEngine dstEngine) { -#ifdef _WIN32 - if (srcEngine != DrawingEngine::OpenGL && dstEngine != DrawingEngine::OpenGL) - { - // Windows is apparently able to switch to hardware rendering on the fly although - // using the same window in an unaccelerated and accelerated context is unsupported by SDL2 - return false; - } -#endif - - return true; + bool openGL = srcEngine == DrawingEngine::OpenGL || dstEngine == DrawingEngine::OpenGL; + return Platform::RequireNewWindow(openGL); } void drawing_engine_init() diff --git a/src/openrct2/platform/Platform.Posix.cpp b/src/openrct2/platform/Platform.Posix.cpp index aee87c5764..8889749720 100644 --- a/src/openrct2/platform/Platform.Posix.cpp +++ b/src/openrct2/platform/Platform.Posix.cpp @@ -9,6 +9,8 @@ #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) +# include "../core/Memory.hpp" +# include "../core/Path.hpp" # include "../core/String.hpp" # include "Platform2.h" # include "platform.h" @@ -17,7 +19,9 @@ # include # include # include +# include # include +# include namespace Platform { @@ -159,6 +163,88 @@ namespace Platform return -1; # endif // __EMSCRIPTEN__ } + + uint64_t GetLastModified(const std::string& path) + { + uint64_t lastModified = 0; + struct stat statInfo + { + }; + if (stat(path.c_str(), &statInfo) == 0) + { + lastModified = statInfo.st_mtime; + } + return lastModified; + } + + bool ShouldIgnoreCase() + { + return false; + } + + bool IsPathSeparator(char c) + { + return c == '/'; + } + + utf8* GetAbsolutePath(utf8* buffer, size_t bufferSize, const utf8* relativePath) + { + utf8* absolutePath = realpath(relativePath, nullptr); + if (absolutePath == nullptr) + { + return String::Set(buffer, bufferSize, relativePath); + } + else + { + String::Set(buffer, bufferSize, absolutePath); + Memory::Free(absolutePath); + return buffer; + } + } + + std::string ResolveCasing(const std::string& path, bool fileExists) + { + std::string result; + if (fileExists) + { + // Windows is case insensitive so it will exist and that is all that matters + // for now. We can properly resolve the casing if we ever need to. + result = path; + } + else + { + std::string fileName = Path::GetFileName(path); + std::string directory = Path::GetDirectory(path); + + struct dirent** files; + auto count = scandir(directory.c_str(), &files, nullptr, alphasort); + if (count != -1) + { + // Find a file which matches by name (case insensitive) + for (int32_t i = 0; i < count; i++) + { + if (String::Equals(files[i]->d_name, fileName.c_str(), true)) + { + result = Path::Combine(directory, std::string(files[i]->d_name)); + break; + } + } + + // Free memory + for (int32_t i = 0; i < count; i++) + { + free(files[i]); + } + free(files); + } + } + return result; + } + + bool RequireNewWindow(bool openGL) + { + return true; + } } // namespace Platform #endif diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index 08e029887e..d7d22fbbea 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -535,6 +535,71 @@ namespace Platform log_warning("Execute() not implemented for Windows!"); return -1; } + + uint64_t GetLastModified(const std::string& path) + { + uint64_t lastModified = 0; + auto pathW = String::ToWideChar(path); + auto hFile = CreateFileW(pathW.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if (hFile != INVALID_HANDLE_VALUE) + { + FILETIME ftCreate, ftAccess, ftWrite; + if (GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) + { + lastModified = (static_cast(ftWrite.dwHighDateTime) << 32ULL) + | static_cast(ftWrite.dwLowDateTime); + } + CloseHandle(hFile); + } + return lastModified; + } + + bool ShouldIgnoreCase() + { + return true; + } + + bool IsPathSeparator(char c) + { + return c == '\\' || c == '/'; + } + + utf8* GetAbsolutePath(utf8* buffer, size_t bufferSize, const utf8* relativePath) + { + auto relativePathW = String::ToWideChar(relativePath); + wchar_t absolutePathW[MAX_PATH]; + DWORD length = GetFullPathNameW( + relativePathW.c_str(), static_cast(std::size(absolutePathW)), absolutePathW, nullptr); + if (length == 0) + { + return String::Set(buffer, bufferSize, relativePath); + } + else + { + auto absolutePath = String::ToUtf8(absolutePathW); + String::Set(buffer, bufferSize, absolutePath.c_str()); + return buffer; + } + } + + std::string ResolveCasing(const std::string& path, bool fileExists) + { + std::string result; + if (fileExists) + { + // Windows is case insensitive so it will exist and that is all that matters + // for now. We can properly resolve the casing if we ever need to. + result = path; + } + return result; + } + + bool RequireNewWindow(bool openGL) + { + // Windows is apparently able to switch to hardware rendering on the fly although + // using the same window in an unaccelerated and accelerated context is unsupported by SDL2 + return openGL; + } } // namespace Platform #endif diff --git a/src/openrct2/platform/Platform2.h b/src/openrct2/platform/Platform2.h index 2c73971df0..6189f21b96 100644 --- a/src/openrct2/platform/Platform2.h +++ b/src/openrct2/platform/Platform2.h @@ -34,7 +34,12 @@ namespace Platform std::string GetDocsPath(); std::string GetCurrentExecutablePath(); std::string GetCurrentExecutableDirectory(); + bool ShouldIgnoreCase(); bool FileExists(const std::string path); + bool IsPathSeparator(char c); + utf8* GetAbsolutePath(utf8* buffer, size_t bufferSize, const utf8* relativePath); + uint64_t GetLastModified(const std::string& path); + std::string ResolveCasing(const std::string& path, bool fileExists); rct2_time GetTimeLocal(); rct2_date GetDateLocal(); bool FindApp(const std::string& app, std::string* output); @@ -61,4 +66,5 @@ namespace Platform bool IsColourTerminalSupported(); bool HandleSpecialCommandLineArgument(const char* argument); utf8* StrDecompToPrecomp(utf8* input); + bool RequireNewWindow(bool openGL); } // namespace Platform