diff --git a/README.md b/README.md index cc7d9d42..2ce78e93 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It is written in [OOP](https://en.wikipedia.org/wiki/Object-oriented_programming ## Platform support -This officially supports Linux, Windows, MacOS, Android, Nintendo Switch and Nintendo 3DS. +This officially supports Linux, Windows, MacOS, Android, Serenity OS, Nintendo Switch and Nintendo 3DS. Why these? Because it was fun to port the application to those platforms 😋 diff --git a/docs/develop.md b/docs/develop.md index 2a574225..ed263bb9 100644 --- a/docs/develop.md +++ b/docs/develop.md @@ -10,6 +10,11 @@ For concrete instructions, see the list below: [linux](linux.md) +## Serenity OS + +[serenity](serenity.md) + + ## Windows [windows](windows.md) diff --git a/docs/serenity.md b/docs/serenity.md new file mode 100644 index 00000000..aac79f01 --- /dev/null +++ b/docs/serenity.md @@ -0,0 +1,15 @@ +# Serenity OS build + +## How to build + +To add this to the serenity OS system, you have to build the port for it. + + +Copy `platforms/serenity/package.sh` to `Ports/oopetris/package.sh`, create the directory `Ports/oopetris/` and add the file to it. + +Then just `cd` into the directory and run the `package.sh`, like with all other Serenity OS ports. + + +## NOTE + +We don't have a CI for this port, so please report errors, if you find some. diff --git a/platforms/serenity/package.sh b/platforms/serenity/package.sh new file mode 100644 index 00000000..e8ccccda --- /dev/null +++ b/platforms/serenity/package.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env -S bash ../.port_include.sh +port='oopetris' +version='0.5.6' +files=( + "git+https://github.com/OpenBrickProtocolFoundation/oopetris#${version}" +) +useconfigure='true' +configopts=( + '--cross-file' + "${SERENITY_BUILD_DIR}/meson-cross-file.txt" + "-Dbuildtype=release" +) +depends=( + 'SDL2' + 'SDL2_image' + 'SDL2_mixer' + 'SDL2_ttf' + 'nlohmann-json' +) + +configure() { + run meson setup _build "${configopts[@]}" +} + +build() { + run meson compile -C _build +} + +install() { + export DESTDIR="${SERENITY_INSTALL_ROOT}" + run meson install -C _build +} diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index a58daae8..46acced5 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -92,7 +92,7 @@ namespace { try { -#if defined(__ANDROID__) or defined(__CONSOLE__) +#if defined(__ANDROID__) or defined(__CONSOLE__) or defined(__SERENITY__) window = std::make_shared(window_name, WindowPosition::Centered); #else [[maybe_unused]] static constexpr int width = 1280; diff --git a/src/executables/game/parser.cpp b/src/executables/game/parser.cpp index 591a5e31..b05618f6 100644 --- a/src/executables/game/parser.cpp +++ b/src/executables/game/parser.cpp @@ -41,6 +41,13 @@ helper::expected helper::parse_args(const std spdlog::error("invalid value for target fps ({}), using default value instead (VSYNC)", fps.value()); } } +#if defined(__SERENITY__) + // serenity OS can#t handle vsync very well (Since it's inside qemu), so setting the target_fps value to 60 per default + if (not result.target_fps.has_value()) { + result.target_fps = 60; + } +#endif + const auto level = parser.get("--level"); if (level <= 30) { @@ -56,7 +63,6 @@ helper::expected helper::parse_args(const std result.silent = parser.get("--silent"); return result; - } catch (const std::exception& error) { return helper::unexpected{ error.what() }; } diff --git a/src/graphics/renderer.cpp b/src/graphics/renderer.cpp index b5f71f80..78a8cc46 100644 --- a/src/graphics/renderer.cpp +++ b/src/graphics/renderer.cpp @@ -10,7 +10,7 @@ Renderer::Renderer(const Window& window, const VSync v_sync) window.get_sdl_window(), -1, (v_sync == VSync::Enabled ? SDL_RENDERER_PRESENTVSYNC : 0) | SDL_RENDERER_TARGETTEXTURE -#if defined(__3DS__) +#if defined(__3DS__) || defined(__SERENITY__) | SDL_RENDERER_SOFTWARE #else | SDL_RENDERER_ACCELERATED diff --git a/src/helper/graphic_utils.cpp b/src/helper/graphic_utils.cpp index 080969c2..d387f099 100644 --- a/src/helper/graphic_utils.cpp +++ b/src/helper/graphic_utils.cpp @@ -48,7 +48,7 @@ std::vector utils::supported_features() { throw std::runtime_error{ "Failed to get flatpak data directory (XDG_DATA_HOME)" }; } - return std::filesystem::path{ data_home }; + return std::filesystem::path{ data_home } / "share" / constants::program_name; #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) char* pref_path = SDL_GetPrefPath(constants::author, constants::program_name); if (!pref_path) { @@ -58,6 +58,33 @@ std::vector utils::supported_features() { #else #error "unrecognized installer build" #endif +#elif defined(INSTALL_FILES) +#if !defined(INSTALL_LOCATION) +#error "missing 'INSTALL_LOCATION' define" +#endif + +#if defined(__SERENITY__) + + + // this is a read write location in the serenityos case build, see https://docs.flatpak.org/en/latest/conventions.html + const char* data_home = std::getenv("HOME"); + if (data_home == nullptr) { + throw std::runtime_error{ "Failed to get flatpak data directory (XDG_DATA_HOME)" }; + } + + return std::filesystem::path{ data_home } / "share" / constants::program_name; + +#else + +#define STRINGIFY(a) STRINGIFY_HELPER_(a) //NOLINT(cppcoreguidelines-macro-usage) +#define STRINGIFY_HELPER_(a) #a + + return std::filesystem::path{ STRINGIFY(INSTALL_LOCATION) } / "share" / constants::program_name; + + +#undef STRINGIFY +#undef STRINGIFY_HELPER_ +#endif #else // this is only used in local build for debugging, when compiling in release mode the path is real path where the app can store many things without interfering with other things (eg. AppData\Roaming\... on Windows or .local/share/... on Linux ) return std::filesystem::path{ "." }; @@ -86,7 +113,23 @@ std::vector utils::supported_features() { #else #error "unrecognized installer build" #endif +#elif defined(INSTALL_FILES) +#if !defined(INSTALL_LOCATION) +#error "missing 'INSTALL_LOCATION' define" +#endif + +#define STRINGIFY(a) STRINGIFY_HELPER_(a) //NOLINT(cppcoreguidelines-macro-usage) +#define STRINGIFY_HELPER_(a) #a + + return std::filesystem::path{ STRINGIFY(INSTALL_LOCATION) } / "share" / "oopetris" / "assets"; + + +#undef STRINGIFY +#undef STRINGIFY_HELPER_ + #else + + return std::filesystem::path{ "assets" }; #endif } diff --git a/src/helper/platform.cpp b/src/helper/platform.cpp index 9922cc96..dd464240 100644 --- a/src/helper/platform.cpp +++ b/src/helper/platform.cpp @@ -1,6 +1,8 @@ #include "platform.hpp" +#include + #if defined(__CONSOLE__) #include "helper/console_helpers.hpp" #include "input/console_buttons.hpp" @@ -51,6 +53,8 @@ namespace { return "Windows"; #elif defined(__APPLE__) return "MacOS"; +#elif defined(__SERENITY__) + return "Serenity OS"; #else #error "Unsupported platform" #endif @@ -71,6 +75,9 @@ namespace { auto result = console::open_url(url); spdlog::info("Returned string from url open was: {}", result); return true; +#elif defined(__SERENITY__) + UNUSED(url); + return false; #else //TODO(Totto): this is dangerous, if we supply user input, so use SDL_OpenURL preferably diff --git a/src/libs/core/helper/date.cpp b/src/libs/core/helper/date.cpp index dc78b9e8..2d5e9bac 100644 --- a/src/libs/core/helper/date.cpp +++ b/src/libs/core/helper/date.cpp @@ -32,7 +32,8 @@ helper::expected date::ISO8601Date::from_string( std::tm tm = {}; -#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) \ + || defined(__SERENITY__) std::istringstream input_stream{ input }; diff --git a/tools/options/meson.build b/tools/options/meson.build index 77687208..ff153c1d 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -25,6 +25,17 @@ graphics_lib = { 'deps': [], } +if meson.is_cross_build() and host_machine.system() == 'serenity' + core_lib += { + 'compile_args': [ + core_lib.get('compile_args'), + '-D__SERENITY__', + '-DINSTALL_FILES', + '-DINSTALL_LOCATION=' + get_option('prefix'), + ], + } +endif + cpp = meson.get_compiler('cpp') build_with_libcpp = false