diff --git a/CMakeLists.txt b/CMakeLists.txt index b6edd7f277..83943f2cb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,7 +368,7 @@ else () set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif () - if (APPLE AND NOT USE_MMAP) + if (HAIKU OR (APPLE AND NOT USE_MMAP)) set(CMAKE_POSITION_INDEPENDENT_CODE OFF) else () set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -517,23 +517,25 @@ if (NOT MACOS_BUNDLE OR (MACOS_BUNDLE AND WITH_TESTS)) endif() install(TARGETS "openrct2-cli" OPTIONAL RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") install(FILES ${DOC_FILES} DESTINATION "${CMAKE_INSTALL_DOCDIR}") - install(FILES "distribution/linux/io.openrct2.openrct2.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") - if (NOT DISABLE_GUI) - install(FILES "resources/logo/icon_x16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x24.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/24x24/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x48.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x96.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/96x96/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x128.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_x256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "openrct2.png") - install(FILES "resources/logo/icon_flag.svg" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps" RENAME "openrct2.svg") - install(FILES "distribution/linux/io.openrct2.openrct2.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") - install(FILES "distribution/linux/io.openrct2.savegame.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") - install(FILES "distribution/linux/io.openrct2.scenario.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") - install(FILES "distribution/linux/io.openrct2.uri.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + if (NOT HAIKU) + install(FILES "distribution/linux/io.openrct2.openrct2.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") + if (NOT DISABLE_GUI) + install(FILES "resources/logo/icon_x16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x24.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/24x24/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x48.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x96.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/96x96/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x128.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_x256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "openrct2.png") + install(FILES "resources/logo/icon_flag.svg" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps" RENAME "openrct2.svg") + install(FILES "distribution/linux/io.openrct2.openrct2.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + install(FILES "distribution/linux/io.openrct2.savegame.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + install(FILES "distribution/linux/io.openrct2.scenario.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + install(FILES "distribution/linux/io.openrct2.uri.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") + endif() + install(FILES "distribution/linux/io.openrct2.mimeinfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages/" RENAME "openrct2.xml") endif() - install(FILES "distribution/linux/io.openrct2.mimeinfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages/" RENAME "openrct2.xml") install(DIRECTORY "distribution/man/" DESTINATION "${CMAKE_INSTALL_MANDIR}/man6" FILES_MATCHING PATTERN "*.6") if (MACOS_USE_DEPENDENCIES) diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index cd3e3ccc7f..d46972e059 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -38,7 +38,7 @@ endif () if (NOT DISABLE_OPENGL AND NOT EMSCRIPTEN) # GL doesn't work nicely with macOS, while find_package doesn't work with multiarch on Ubuntu. - if (APPLE) + if (APPLE OR HAIKU) find_package(OpenGL REQUIRED) elseif (NOT WIN32) PKG_CHECK_MODULES(GL REQUIRED gl) @@ -100,7 +100,7 @@ endif () if (NOT DISABLE_OPENGL) if (WIN32) target_link_libraries(openrct2 opengl32) - elseif (APPLE) + elseif (APPLE OR HAIKU) target_link_libraries(openrct2 ${OPENGL_LIBRARY}) else () target_link_libraries(openrct2 ${GL_LIBRARIES}) diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index b6227623cd..6c3f7d3523 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -7,7 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#if (defined(__unix__) || defined(__EMSCRIPTEN__)) && !defined(__ANDROID__) && !defined(__APPLE__) +#if (defined(__unix__) || defined(__HAIKU__) || defined(__EMSCRIPTEN__)) && !defined(__ANDROID__) && !defined(__APPLE__) #include "UiContext.h" @@ -129,14 +129,22 @@ namespace OpenRCT2::Ui void OpenFolder(const std::string& path) override { + #ifdef __HAIKU__ + const char* args[] = { "open", path.c_str(), nullptr }; + #else const char* args[] = { "xdg-open", path.c_str(), nullptr }; + #endif Platform::Execute(args); } void OpenURL(const std::string& url) override { #ifndef __EMSCRIPTEN__ + #ifdef __HAIKU__ + const char* args[] = { "open", url.c_str(), nullptr }; + #else const char* args[] = { "xdg-open", url.c_str(), nullptr }; + #endif Platform::Execute(args); #else MAIN_THREAD_EM_ASM({ window.open(UTF8ToString($0)); }, url.c_str()); diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index f314c9c33f..e74c6be4a7 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -180,7 +180,7 @@ if (MINGW) target_link_libraries(libopenrct2 -fstack-protector-strong) endif() -if (UNIX AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "BSD") +if (UNIX AND NOT HAIKU AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "BSD") # Include libdl for dlopen target_link_libraries(libopenrct2 dl) endif () diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 79b953873a..b9d2659522 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -483,6 +483,7 @@ namespace OpenRCT2 } #endif +#ifndef __HAIKU__ // Haiku's user is always root, skip warning them about it. if (Platform::ProcessIsElevated()) { std::string elevationWarning = _localisationService->GetString(STR_ADMIN_NOT_RECOMMENDED); @@ -495,6 +496,7 @@ namespace OpenRCT2 _uiContext->ShowMessageBox(elevationWarning); } } +#endif if (Platform::IsRunningInWine()) { diff --git a/src/openrct2/Version.h b/src/openrct2/Version.h index e089cab8e6..cb63bc4dd2 100644 --- a/src/openrct2/Version.h +++ b/src/openrct2/Version.h @@ -72,6 +72,9 @@ #ifdef __EMSCRIPTEN__ #define OPENRCT2_PLATFORM "Emscripten" #endif +#ifdef __HAIKU__ + #define OPENRCT2_PLATFORM "Haiku" +#endif #ifndef OPENRCT2_PLATFORM #error Unknown platform! #endif diff --git a/src/openrct2/audio/Audio.cpp b/src/openrct2/audio/Audio.cpp index a088e8e10d..c57f37e153 100644 --- a/src/openrct2/audio/Audio.cpp +++ b/src/openrct2/audio/Audio.cpp @@ -128,11 +128,12 @@ namespace OpenRCT2::Audio } } -#ifndef __linux__ - // The first device is always system default on Windows and macOS + // The first device is always system default std::string defaultDevice = LanguageGetString(STR_OPTIONS_SOUND_VALUE_DEFAULT); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnull-dereference" devices.insert(devices.begin(), defaultDevice); -#endif +#pragma GCC diagnostic pop _audioDevices = devices; } diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index ead2328319..30097e931f 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -50,6 +50,11 @@ static constexpr bool kEnlargedUiDefault = true; #else static constexpr bool kEnlargedUiDefault = false; #endif +#ifdef __HAIKU__ // Multi-threading is unstable here +static constexpr bool kMultiThreadingDefault = false; +#else +static constexpr bool kMultiThreadingDefault = true; +#endif namespace OpenRCT2::Config { @@ -238,7 +243,7 @@ namespace OpenRCT2::Config // Always have multi-threading disabled in debug builds, this makes things slower. model->multiThreading = false; #else - model->multiThreading = reader->GetBoolean("multithreading", true); + model->multiThreading = reader->GetBoolean("multithreading", kMultiThreadingDefault); #endif // _DEBUG model->trapCursor = reader->GetBoolean("trap_cursor", false); model->autoOpenShops = reader->GetBoolean("auto_open_shops", false); diff --git a/src/openrct2/core/FileScanner.cpp b/src/openrct2/core/FileScanner.cpp index 95599bfb0f..18d3c72075 100644 --- a/src/openrct2/core/FileScanner.cpp +++ b/src/openrct2/core/FileScanner.cpp @@ -12,7 +12,7 @@ #define WIN32_LEAN_AND_MEAN #endif #include -#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#elif defined(__unix__) || defined(__HAIKU__) || (defined(__APPLE__) && defined(__MACH__)) #include #include #include @@ -251,7 +251,7 @@ private: #endif // _WIN32 -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#if defined(__unix__) || defined(__HAIKU__) || (defined(__APPLE__) && defined(__MACH__)) class FileScannerUnix final : public FileScannerBase { @@ -290,7 +290,13 @@ private: { DirectoryChild result; result.Name = std::string(node->d_name); + #ifdef __HAIKU__ + struct stat stbuf; + stat(node->d_name, &stbuf); + if (S_ISDIR(stbuf.st_mode)) + #else if (node->d_type == DT_DIR) + #endif { result.Type = DirectoryChildType::directory; } @@ -318,13 +324,13 @@ private: } }; -#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#endif // defined(__unix__) || defined(__HAIKU__) || (defined(__APPLE__) && defined(__MACH__)) std::unique_ptr Path::ScanDirectory(const std::string& pattern, bool recurse) { #ifdef _WIN32 return std::make_unique(pattern, recurse); -#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#elif defined(__unix__) || defined(__HAIKU__) || (defined(__APPLE__) && defined(__MACH__)) return std::make_unique(pattern, recurse); #endif } diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index 71cb20ae3c..09d5212f26 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -72,6 +72,10 @@ #define FLAG_NO_PIPE 0 #endif // defined(__linux__) #endif // _WIN32 + +#ifdef __HAIKU__ + #include +#endif // clang-format on #include "Socket.h" diff --git a/src/openrct2/platform/Platform.Linux.cpp b/src/openrct2/platform/Platform.Linux.cpp index 9eb095f59d..1c53ba864e 100644 --- a/src/openrct2/platform/Platform.Linux.cpp +++ b/src/openrct2/platform/Platform.Linux.cpp @@ -7,7 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#if defined(__unix__) && !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) +#if (defined(__unix__) || defined(__HAIKU__)) && !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) #include "../Diagnostic.h" @@ -38,6 +38,10 @@ #include "../localisation/Language.h" #include "Platform.h" + #ifdef __HAIKU__ + #include + #endif + namespace OpenRCT2::Platform { // EnvLangGuard allows us to temporarily set the user's locale @@ -154,6 +158,12 @@ namespace OpenRCT2::Platform "/usr/local/share/openrct2", "/var/lib/openrct2", "/usr/share/openrct2", + #ifdef __HAIKU__ + "/boot/system/data/openrct2", + "/boot/home/config/data/openrct2", + "/boot/system/non-packaged/data/openrct2", + "/boot/home/config/non-packaged/data/openrct2", + #endif }; // clang-format on for (const auto& prefix : prefixes) @@ -180,6 +190,18 @@ namespace OpenRCT2::Platform { LOG_FATAL("failed to read /proc/self/exe"); } + #elif defined(__HAIKU__) + image_info info; + int32 cookie = 0; + + while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) >= B_OK) + { + if (info.type == B_APP_IMAGE) + { + strlcpy(exePath, info.name, sizeof(exePath)); + break; + } + } #elif defined(__FreeBSD__) || defined(__NetBSD__) #if defined(__FreeBSD__) const int32_t mib[] = { diff --git a/src/openrct2/platform/Platform.Posix.cpp b/src/openrct2/platform/Platform.Posix.cpp index b33d3e17ee..98777973cd 100644 --- a/src/openrct2/platform/Platform.Posix.cpp +++ b/src/openrct2/platform/Platform.Posix.cpp @@ -7,7 +7,8 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__NetBSD__) \ + || defined(__HAIKU__) #include "Platform.h" diff --git a/src/openrct2/platform/Platform.h b/src/openrct2/platform/Platform.h index b96ee1f6ee..63ff5f0473 100644 --- a/src/openrct2/platform/Platform.h +++ b/src/openrct2/platform/Platform.h @@ -147,7 +147,8 @@ namespace OpenRCT2::Platform SteamPaths GetSteamPaths(); bool triggerSteamDownload(); -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__NetBSD__) \ + || defined(__HAIKU__) std::string GetEnvironmentPath(const char* name); std::string GetHomePath(); #endif