diff --git a/.github/workflows/nintendo.yml b/.github/workflows/nintendo.yml index 3163c1d9..7399e252 100644 --- a/.github/workflows/nintendo.yml +++ b/.github/workflows/nintendo.yml @@ -24,6 +24,10 @@ jobs: extension: nro container: devkita64 + - name: wii + extension: dol + container: devkitppc + steps: - uses: actions/checkout@v4 with: diff --git a/README.md b/README.md index cc7d9d42..baa7ab34 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, Nintendo Switch , Nintendo Wii and Nintendo 3DS. Why these? Because it was fun to port the application to those platforms 😋 diff --git a/assets/oopetris.desktop.in b/assets/oopetris.desktop.in index bcc24871..d066a847 100644 --- a/assets/oopetris.desktop.in +++ b/assets/oopetris.desktop.in @@ -2,7 +2,7 @@ Version=1.0 Type=Application Name=OOPetris -Comment=A Tetris clone in OOP +Comment=@DESCRIPTION@ Exec=oopetris Icon=@APP_NAME@ Terminal=false diff --git a/docs/develop.md b/docs/develop.md index 2a574225..7a1e9708 100644 --- a/docs/develop.md +++ b/docs/develop.md @@ -28,6 +28,10 @@ For concrete instructions, see the list below: [switch](3ds.md) +## Nintendo Wii + +[wii](wii.md) + ## Android [android](android.md) diff --git a/docs/switch.md b/docs/switch.md index 7eaa30a8..79c9517f 100644 --- a/docs/switch.md +++ b/docs/switch.md @@ -4,7 +4,7 @@ - a C++23 compatible cross compiler, we only support The [devkitpro](https://devkitpro.org/) one - meson -- some portlibs from devkitpro, namely sdl2, sld2_ttf, sdl2_mix. +- some portlibs from devkitpro, namely sdl2, sdl2_ttf, sdl2_mix. ## Compiling diff --git a/docs/wii.md b/docs/wii.md new file mode 100644 index 00000000..7c486cd5 --- /dev/null +++ b/docs/wii.md @@ -0,0 +1,37 @@ +# Nintendo Wii build + +## Prerequisites + +- a C++23 compatible cross compiler, we only support The [devkitpro](https://devkitpro.org/) one +- meson +- some portlibs from devkitpro, namely sdl2, sdl2_ttf, sdl2_mix. + + +## Compiling + + +Cross Compiling is only possible on linux-like systems. + +We use meson and cross-compilation files, everything is wrapped into shell script, so you just need to run: + + +```bash +./platforms/build-wii.sh + +``` +After that you can find the runnable executable (also supports emulators) +in `build-wii/oopetris.dol` + +Typically this would be moved into a folder on an external SD card of the WII, than you can load it with Homebrew. + + +The Folder structure would be: + +`/apps/OOPetris/` +- `boot.dol` +- `icon.png` +- `meta.xml` + +At the moment we don't package that like this, but in the future we might. + +The `meta.xml` file is being generated, the `boot.dol` file has to be renamed and the `icon.png` can be taken from the `assets/icon/` folder diff --git a/platforms/build-3ds.sh b/platforms/build-3ds.sh index a01e3734..1f64a6eb 100755 --- a/platforms/build-3ds.sh +++ b/platforms/build-3ds.sh @@ -103,14 +103,11 @@ needs_exe_wrapper = true library_dirs= ['$LIBCTRU_LIB','$PORTLIBS_LIB'] libctru='$LIBCTRU' -APP_NAME = 'oopetris' -APP_AUTHOR = 'coder2k' -APP_DESC = 'A Tetris clone in OOP' - -USE_SMDH = true - -APP_ROMFS='$ROMFS' +USE_SMDH = true +APP_ROMFS = '$ROMFS' +APP_ICON = './assets/icon/48x48.png' +APP_SMALL_ICON='./assets/icon/24x24.png' EOF ## build sdl2 and libraries (ttf, mixer, image) diff --git a/platforms/build-switch.sh b/platforms/build-switch.sh index 0f0f9213..e9e83fed 100755 --- a/platforms/build-switch.sh +++ b/platforms/build-switch.sh @@ -101,13 +101,10 @@ needs_exe_wrapper = true library_dirs= ['$LIBNX_LIB','$PORTLIBS_LIB'] libnx='$LIBNX' -APP_NAME = 'oopetris' -APP_AUTHOR = 'coder2k' -APP_VERSION = true - USE_NACP = true APP_ROMFS='$ROMFS' +APP_ICON = './assets/icon/1024x1024.png' EOF diff --git a/platforms/build-wii.sh b/platforms/build-wii.sh new file mode 100755 index 00000000..b66d1bf8 --- /dev/null +++ b/platforms/build-wii.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash + +set -e + +export DEVKITPRO="/opt/devkitpro" +export ARCH_DEVKIT_FOLDER="$DEVKITPRO/devkitPPC" +export COMPILER_BIN="$ARCH_DEVKIT_FOLDER/bin" +export PATH="$DEVKITPRO/tools/bin:$COMPILER_BIN:$PATH" + +export OGC_CONSOLE="wii" +export OGC_SUBDIR="wii" +export OGC_MACHINE="rvl" + +export PORTLIBS_PATH="$DEVKITPRO/portlibs" +export LIBOGC="$DEVKITPRO/libogc" + +export PORTLIBS_PATH_OGC="$PORTLIBS_PATH/$OGC_CONSOLE" +export PORTLIBS_PATH_PPC="$PORTLIBS_PATH/ppc" + +export PORTLIBS_LIB_OGC="$PORTLIBS_PATH_OGC/lib" +export PORTLIBS_LIB_PPC="$PORTLIBS_PATH_PPC/lib" +export LIBOGC_LIB="$LIBOGC/lib/$OGC_SUBDIR" + +export PKG_CONFIG_PATH_OGC="$PORTLIBS_LIB_OGC/pkgconfig/" +export PKG_CONFIG_PATH_PPC="$PORTLIBS_LIB_PPC/pkgconfig/" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH_OGC:$PKG_CONFIG_PATH_PPC" + +export ROMFS="platforms/romfs" + +export BUILD_DIR="build-wii" + +export TOOL_PREFIX="powerpc-eabi" + +export BIN_DIR_OGC="$PORTLIBS_PATH_OGC/bin" +export BIN_DIR_PPC="$PORTLIBS_LIB_PPC/bin" +export PKG_CONFIG_EXEC="$BIN_DIR_OGC/$TOOL_PREFIX-pkg-config" +export CMAKE="$BIN_DIR_OGC/$TOOL_PREFIX-cmake" + +export PATH="$BIN_DIR_PPC:$BIN_DIR_OGC:$PATH" + +export CC="$COMPILER_BIN/$TOOL_PREFIX-gcc" +export CXX="$COMPILER_BIN/$TOOL_PREFIX-g++" +export AS="$COMPILER_BIN/$TOOL_PREFIX-as" +export AR="$COMPILER_BIN/$TOOL_PREFIX-gcc-ar" +export RANLIB="$COMPILER_BIN/$TOOL_PREFIX-gcc-ranlib" +export NM="$COMPILER_BIN/$TOOL_PREFIX-gcc-nm" +export OBJCOPY="$COMPILER_BIN/$TOOL_PREFIX-objcopy" +export STRIP="$COMPILER_BIN/$TOOL_PREFIX-strip" + +export ARCH="ppc" +export CPU_VERSION="ppc750" +export ENDIANESS="big" + +export COMMON_FLAGS="'-m${OGC_MACHINE}','-mcpu=750','-meabi','-mhard-float','-ffunction-sections','-fdata-sections'" + +export COMPILE_FLAGS="'-D__WII__','-D__CONSOLE__','-D__NINTENDO_CONSOLE__','-D_OGC_','-DGEKKO','-isystem', '$LIBOGC/include', '-I$PORTLIBS_PATH_PPC/include', '-I$PORTLIBS_PATH_OGC/include'" + +export LINK_FLAGS="'-L$LIBOGC_LIB','-L$PORTLIBS_LIB_PPC','-L$PORTLIBS_LIB_OGC'" + +export CROSS_FILE="./platforms/crossbuild-wii.ini" + +cat <"$CROSS_FILE" +[host_machine] +system = 'wii' +cpu_family = '$ARCH' +cpu = '$CPU_VERSION' +endian = '$ENDIANESS' + +[target_machine] +system = 'wii' +cpu_family = '$ARCH' +cpu = '$CPU_VERSION' +endian = '$ENDIANESS' + +[constants] +devkitpro = '$DEVKITPRO' + +[binaries] +c = '$CC' +cpp = '$CXX' +c_ld = 'bfd' +cpp_ld = 'bfd' +ar = '$AR' +as = '$AS' +ranlib = '$RANLIB' +strip = '$STRIP' +objcopy = '$OBJCOPY' +nm = '$NM' +pkg-config = '$PKG_CONFIG_EXEC' +cmake='$CMAKE' +freetype-config='$BIN_DIR_PPC/freetype-config' +libpng16-config='$BIN_DIR_PPC/libpng16-config' +libpng-config='$BIN_DIR_PPC/libpng-config' +sdl2-config='$BIN_DIR_OGC/sdl2-config' + +[built-in options] +c_std = 'gnu11' +cpp_std = 'c++23' +c_args = [$COMMON_FLAGS, $COMPILE_FLAGS] +cpp_args = [$COMMON_FLAGS, $COMPILE_FLAGS] +c_link_args = [$COMMON_FLAGS, $LINK_FLAGS] +cpp_link_args = [$COMMON_FLAGS, $LINK_FLAGS] + + +[properties] +pkg_config_libdir = '$PKG_CONFIG_PATH' +needs_exe_wrapper = true +library_dirs= ['$LIBOGC_LIB', '$PORTLIBS_LIB_OGC','$PORTLIBS_LIB_PPC'] + +USE_META_XML = true + + +APP_ROMFS='$ROMFS' + +EOF + +## options: "smart, complete_rebuild" +export COMPILE_TYPE="smart" + +export BUILDTYPE="debug" + +if [ "$#" -eq 0 ]; then + # nothing + echo "Using compile type '$COMPILE_TYPE'" +elif [ "$#" -eq 1 ]; then + COMPILE_TYPE="$1" +elif [ "$#" -eq 2 ]; then + COMPILE_TYPE="$1" + BUILDTYPE="$2" +else + echo "Too many arguments given, expected 1 or 2" + exit 1 +fi + +if [ "$COMPILE_TYPE" == "smart" ]; then + : # noop +elif [ "$COMPILE_TYPE" == "complete_rebuild" ]; then + : # noop +else + echo "Invalid COMPILE_TYPE, expected: 'smart' or 'complete_rebuild'" + exit 1 +fi + +if [ ! -d "$ROMFS" ]; then + + mkdir -p "$ROMFS" + + cp -r assets "$ROMFS/" + +fi + +if [ "$COMPILE_TYPE" == "complete_rebuild" ] || [ ! -e "$BUILD_DIR" ]; then + + meson setup "$BUILD_DIR" \ + "--wipe" \ + --cross-file "$CROSS_FILE" \ + "-Dbuildtype=$BUILDTYPE" \ + -Ddefault_library=static + +fi + +meson compile -C "$BUILD_DIR" -j 3 diff --git a/src/executables/game/application.cpp b/src/executables/game/application.cpp index d0fee17d..4cc06fd1 100644 --- a/src/executables/game/application.cpp +++ b/src/executables/game/application.cpp @@ -18,6 +18,8 @@ #include #include +#include "helper/logger.hpp" + #if defined(__CONSOLE__) #include "helper/console_helpers.hpp" #endif @@ -43,11 +45,15 @@ Application::Application(std::shared_ptr&& window, CommandLineArguments& m_renderer{ *m_window, m_command_line_arguments.target_fps.has_value() ? Renderer::VSync::Disabled : Renderer::VSync::Enabled }, m_target_framerate{ m_command_line_arguments.target_fps } { + console::debug_print(fmt::format("app: b\nefore\n")); initialize(); + console::debug_print(fmt::format("app: a\nfter\n")); } catch (const helper::GeneralError& general_error) { const auto severity = general_error.severity(); const auto notification_level = get_notification_level(severity); + + console::debug_print(fmt::format("Initialization Error", general_error.message())); window->show_simple(notification_level, "Initialization Error", general_error.message()); if (severity == helper::error::Severity::Fatal) { @@ -258,45 +264,49 @@ void Application::render() const { void Application::initialize() { + console::debug_print(fmt::format("app: 1\n")); + auto loading_screen = scenes::LoadingScreen{ this }; + console::debug_print(fmt::format("app: 2\n")); const auto start_time = SDL_GetTicks64(); - const std::future load_everything = std::async(std::launch::async, [this] { - this->m_music_manager = std::make_unique(this, num_audio_channels); - - this->m_input_manager = std::make_shared(this->m_window); - - this->m_settings_manager = std::make_unique(this); - - this->m_font_manager = std::make_unique(); + console::debug_print(fmt::format("app: 3\n")); - this->load_resources(); + this->m_music_manager = std::make_unique(this, num_audio_channels); + console::debug_print(fmt::format("app: 4\n")); + this->m_input_manager = std::make_shared(this->m_window); + console::debug_print(fmt::format("app: 5\n")); + this->m_settings_manager = std::make_unique(this); + console::debug_print(fmt::format("app: 6\n")); + this->m_font_manager = std::make_unique(); + console::debug_print(fmt::format("app: 7\n")); + this->load_resources(); + console::debug_print(fmt::format("app: 8\n")); #if !defined(NDEBUG) - m_fps_text = std::make_unique( - this, "FPS: ?", font_manager().get(FontId::Default), Color::white(), - std::pair{ 0.95, 0.95 }, - ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Center }, - ui::RelativeLayout{ window(), 0.0, 0.0, 0.1, 0.05 }, false - ); + m_fps_text = std::make_unique( + this, "FPS: ?", font_manager().get(FontId::Default), Color::white(), + std::pair{ 0.95, 0.95 }, + ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Center }, + ui::RelativeLayout{ window(), 0.0, 0.0, 0.1, 0.05 }, false + ); #endif #if defined(_HAVE_DISCORD_SDK) - if (m_settings_manager->settings().discord) { - auto discord_instance = DiscordInstance::initialize(); - if (not discord_instance.has_value()) { - spdlog::warn( - "Error initializing the discord instance, it might not be running: {}", discord_instance.error() - ); - } else { - m_discord_instance = std::move(discord_instance.value()); - m_discord_instance->after_setup(); - } + if (m_settings_manager->settings().discord) { + auto discord_instance = DiscordInstance::initialize(); + if (not discord_instance.has_value()) { + spdlog::warn( + "Error initializing the discord instance, it might not be running: {}", discord_instance.error() + ); + } else { + m_discord_instance = std::move(discord_instance.value()); + m_discord_instance->after_setup(); } + } #endif - }); using namespace std::chrono_literals; @@ -306,7 +316,7 @@ void Application::initialize() { : 0s; auto start_execution_time = std::chrono::steady_clock::now(); - bool finished_loading = false; + bool finished_loading = true; // this is a duplicate of below in some cases, but it's just for the loading screen and can't be factored out easily // this also only uses a subset of all things, the real event loop uses, so that nothing breaks while doing multithreading @@ -361,8 +371,8 @@ void Application::initialize() { // end waiting // wait until is faster, since it just compares two time_points instead of getting now() and than adding the wait-for argument - finished_loading = - load_everything.wait_until(std::chrono::system_clock::time_point::min()) == std::future_status::ready; + // finished_loading = + // load_everything.wait_until(std::chrono::system_clock::time_point::min()) == std::future_status::ready; } @@ -394,13 +404,15 @@ void Application::load_resources() { { FontId::Default, "PressStart2P.ttf" }, #endif { FontId::Arial, "arial.ttf" }, - { FontId::NotoColorEmoji, "NotoColorEmoji.ttf" }, + /* { FontId::NotoColorEmoji, "NotoColorEmoji.ttf" }, */ { FontId::Symbola, "Symbola.ttf" } }; for (const auto& [font_id, path] : fonts) { const auto font_path = utils::get_assets_folder() / "fonts" / path; m_font_manager->load(font_id, font_path, fonts_size); } + +// throw std::runtime_error("HELLO END"); } #if defined(_HAVE_DISCORD_SDK) diff --git a/src/executables/game/main.cpp b/src/executables/game/main.cpp index a58daae8..7be83d11 100644 --- a/src/executables/game/main.cpp +++ b/src/executables/game/main.cpp @@ -8,6 +8,7 @@ #include "application.hpp" #include "helper/constants.hpp" #include "helper/graphic_utils.hpp" +#include "helper/logger.hpp" #include "helper/message_box.hpp" #include @@ -16,49 +17,10 @@ #include #include -#if defined(__ANDROID__) -#include -#endif - -#if defined(__CONSOLE__) #include "helper/console_helpers.hpp" -#endif - - -#include -#include -#include namespace { - void initialize_spdlog() { - - const auto logs_path = utils::get_root_folder() / "logs"; - if (not std::filesystem::exists(logs_path)) { - std::filesystem::create_directory(logs_path); - } - - std::vector sinks; -#if defined(__ANDROID__) - sinks.push_back(std::make_shared()); -#elif defined(__CONSOLE__) - sinks.push_back(std::make_shared()); -#else - sinks.push_back(std::make_shared()); -#endif - sinks.push_back(std::make_shared( - fmt::format("{}/oopetris.log", logs_path.string()), 1024 * 1024 * 10, 5, true - )); - auto combined_logger = std::make_shared("combined_logger", begin(sinks), end(sinks)); - spdlog::set_default_logger(combined_logger); - -#if !defined(NDEBUG) - spdlog::set_level(spdlog::level::debug); -#else - spdlog::set_level(spdlog::level::err); -#endif - } - int main_no_sdl_replace(int argc, char** argv) noexcept { @@ -66,7 +28,16 @@ namespace { try { - initialize_spdlog(); + console::debug_print("TEST 2\n"); + SYS_Report("%s\n", "TEST 3"); + + + logger::initialize(); + + console::debug_print("TEST 4\n"); + spdlog::error("SPDLOG TESTSTSTSTS"); + SYS_Report("%s\n", "TEST 5"); + std::vector arguments_vector{}; arguments_vector.reserve(argc); @@ -78,45 +49,67 @@ namespace { arguments_vector.emplace_back("oopetris"); } + console::debug_print("TEST 6\n"); + auto parsed_arguments = helper::parse_args(arguments_vector); + console::debug_print("TEST 7\n"); + if (not parsed_arguments.has_value()) { - spdlog::error("error parsing command line arguments: {}", parsed_arguments.error()); + console::debug_print("erro 1\n"); + // spdlog::error("error parsing command line arguments: {}", parsed_arguments.error()); return EXIT_FAILURE; } + console::debug_print("TEST 8\n"); + auto arguments = std::move(parsed_arguments.value()); [[maybe_unused]] constexpr auto window_name = constants::program_name.c_str(); + console::debug_print("TEST 9\n"); + try { #if defined(__ANDROID__) or defined(__CONSOLE__) + console::debug_print("TEST 10\n"); window = std::make_shared(window_name, WindowPosition::Centered); + console::debug_print("TEST 11\n"); #else [[maybe_unused]] static constexpr int width = 1280; [[maybe_unused]] static constexpr int height = 720; window = std::make_shared(window_name, WindowPosition::Centered, width, height); #endif } catch (const helper::GeneralError& general_error) { - spdlog::error("Couldn't initialize window: {}", general_error.message()); + console::debug_print("error 5" + general_error.message() + "\n"); + // spdlog::error("Couldn't initialize window: {}", general_error.message()); } + console::debug_print(fmt::format("TEST 12 {}\n", static_cast(window.get()))); + + if (window == nullptr) { + console::debug_print("window nullptr\n"); + helper::MessageBox::show_simple( helper::MessageBox::Type::Error, "Initialization Error", "failed to create SDL window", nullptr ); return EXIT_FAILURE; } + console::debug_print(fmt::format("TEST 13\n")); + Application app{ std::move(window), std::move(arguments) }; + console::debug_print("before app run\n"); + app.run(); return EXIT_SUCCESS; } catch (const helper::GeneralError& general_error) { - spdlog::error("{}", general_error.message()); + console::debug_print("error 44:" + general_error.message() + "\n"); + // spdlog::error("{}", general_error.message()); if (window == nullptr) { @@ -130,9 +123,22 @@ namespace { return EXIT_FAILURE; } catch (const utils::ExitException& exit_exception) { + console::debug_print("error 45s\n"); spdlog::debug("Requested exit with status code {}", exit_exception.status_code()); return exit_exception.status_code(); + } catch (const std::system_error& error) { + + console::debug_print(fmt::format( + "Caught system_error with code [{}] meaning [{}]\n", (std::stringstream{} << error.code()).str(), + error.what() + )); + + std::cerr << "Caught system_error with code [" << error.code() << "] meaning [" << error.what() << "]\n"; + + return EXIT_FAILURE; + } catch (const std::exception& error) { + spdlog::error("error: {}", error.what()); // this is the last resort, so using std::cerr and no sdl show_simple messagebox! std::cerr << error.what(); return EXIT_FAILURE; @@ -143,6 +149,139 @@ namespace { } // namespace +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static void* xfb = NULL; +static GXRModeObj* rmode = NULL; + +//--------------------------------------------------------------------------------- +int main2() { + //--------------------------------------------------------------------------------- + + // Initialise the video system + VIDEO_Init(); + + // This function initialises the attached controllers + WPAD_Init(); + + // Obtain the preferred video mode from the system + // This will correspond to the settings in the Wii menu + rmode = VIDEO_GetPreferredMode(NULL); + + // Allocate memory for the display in the uncached region + xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + + // Initialise the console, required for SYS_Report + console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ); + + // Set up the video registers with the chosen mode + VIDEO_Configure(rmode); + + // Tell the video hardware where our display memory is + VIDEO_SetNextFramebuffer(xfb); + + // Make the display visible + VIDEO_SetBlack(true); + + // Flush the video register changes to the hardware + VIDEO_Flush(); + + // Wait for Video setup to complete + VIDEO_WaitVSync(); + if (rmode->viTVMode & VI_NON_INTERLACE) + VIDEO_WaitVSync(); + + + SYS_Report("TESTTESTETS\n"); + + // The console understands VT terminal escape codes + // This positions the cursor on row 2, column 0 + // we can use variables for this with format codes too + // e.g. SYS_Report ("\x1b[%d;%dH", row, column ); + console::debug_print("\x1b[2;0H"); + + if (!fatInitDefault()) { + SYS_Report("fatInitDefault failure: terminating\n"); + goto error; + } + + DIR* pdir; + struct dirent* pent; + struct stat statbuf; + + pdir = opendir("."); + + if (!pdir) { + SYS_Report("opendir() failure; terminating\n"); + goto error; + } + + while ((pent = readdir(pdir)) != NULL) { + stat(pent->d_name, &statbuf); + if (strcmp(".", pent->d_name) == 0 || strcmp("..", pent->d_name) == 0) + continue; + if (S_ISDIR(statbuf.st_mode)) + SYS_Report("%s \n", pent->d_name); + if (!(S_ISDIR(statbuf.st_mode))) + SYS_Report("%s %lld\n", pent->d_name, statbuf.st_size); + } + closedir(pdir); + +error: + while (1) { + + // Call WPAD_ScanPads each loop, this reads the latest controller states + WPAD_ScanPads(); + + // WPAD_ButtonsDown tells us which buttons were pressed in this loop + // this is a "one shot" state which will not fire again until the button has been released + u32 pressed = WPAD_ButtonsDown(0); + + // We return to the launcher application via exit + if (pressed & WPAD_BUTTON_HOME) + exit(0); + + // Wait for the next frame + VIDEO_WaitVSync(); + } + + return 0; +} + + +#include + int main(int argc, char** argv) { - return main_no_sdl_replace(argc, argv); + + + //after your network is initialized using if_config() function, you can call + // Init debug over BBA...change IPs to suite your needs + tcp_localip = "10.0.0.106"; + tcp_netmask = "255.255.255.0"; + tcp_gateway = "192.168.1.1"; + + + DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT); + + _break(); + + + // main2(); + int z = main_no_sdl_replace(argc, argv); + console::debug_print("return value: " + std::to_string(z) + "\n"); + return z; } + + +// target remote 127.0.0.1:2828 diff --git a/src/executables/meson.build b/src/executables/meson.build index fb9b687c..08d22228 100644 --- a/src/executables/meson.build +++ b/src/executables/meson.build @@ -4,32 +4,48 @@ if build_application subdir('game') - if meson.is_cross_build() and host_machine.system() == 'android' - - library( - 'oopetris', - main_files, - dependencies: [liboopetris_graphics_dep, graphic_application_deps], - override_options: { - 'warning_level': '3', - 'werror': true, - }, - ) + if meson.is_cross_build() + + if host_machine.system() == 'android' + + library( + 'oopetris', + main_files, + dependencies: [ + liboopetris_graphics_dep, + graphic_application_deps, + ], + override_options: { + 'warning_level': '3', + 'werror': true, + }, + ) + + elif meson.is_cross_build() and host_machine.system() == 'switch' + nintendo_options = [ + app_name, + main_files, + [liboopetris_graphics_dep, graphic_application_deps], + ] + subdir('platforms/switch') + elif meson.is_cross_build() and host_machine.system() == '3ds' + nintendo_options = [ + app_name, + main_files, + [liboopetris_graphics_dep, graphic_application_deps], + ] + subdir('platforms/3ds') + elif host_machine.system() == 'wii' + nintendo_options = [ + app_name, + main_files, + [liboopetris_graphics_dep, graphic_application_deps], + ] + subdir('platforms/wii') + else + error('not supported platform: ' + host_machine.system()) + endif - elif meson.is_cross_build() and host_machine.system() == 'switch' - switch_options = [ - app_name, - main_files, - [liboopetris_graphics_dep, graphic_application_deps], - ] - subdir('platforms/switch') - elif meson.is_cross_build() and host_machine.system() == '3ds' - _3ds_options = [ - app_name, - main_files, - [liboopetris_graphics_dep, graphic_application_deps], - ] - subdir('platforms/3ds') else if host_machine.system() == 'windows' @@ -55,7 +71,10 @@ if build_application oopetris_recordings_utility_exe = executable( 'oopetris_recordings_utility', recordings_main_files, - dependencies: [liboopetris_recordings_dep, recordings_application_deps], + dependencies: [ + liboopetris_recordings_dep, + recordings_application_deps, + ], override_options: { 'warning_level': '3', 'werror': true, @@ -69,7 +88,9 @@ if build_application makensis = find_program('makensis') - nsis_script = meson.project_source_root() / 'tools' / 'installer' / 'setup.nsi' + nsis_script = ( + meson.project_source_root() / 'tools' / 'installer' / 'setup.nsi' + ) run_target( 'windows_installer', @@ -78,8 +99,7 @@ if build_application '-DVERSION=' + meson.project_version(), '-DNAME=' + oopetris_name, '-DAUTHOR=' + oopetris_author, - '-DPROJECT_SOURCE_DIR=' - + meson.project_source_root(), + '-DPROJECT_SOURCE_DIR=' + meson.project_source_root(), '-DPROJECT_BUILD_DIR=' + meson.project_build_root(), nsis_script, ], diff --git a/src/executables/platforms/3ds/meson.build b/src/executables/platforms/3ds/meson.build index f8524f36..3fea9b3e 100644 --- a/src/executables/platforms/3ds/meson.build +++ b/src/executables/platforms/3ds/meson.build @@ -1,12 +1,12 @@ ## get the options object and "unpack" it -_3ds_exe_name = _3ds_options[0] -_3ds_src_files = _3ds_options[1] -_3ds_deps = _3ds_options[2] +exe_name = nintendo_options[0] +src_files = nintendo_options[1] +deps = nintendo_options[2] # libraries -_3ds_dependencies = [ +dependencies = [ 'flac', 'freetype2', 'ogg', @@ -17,7 +17,7 @@ _3ds_dependencies = [ 'zlib', ] -_3ds_dependencies_native = [ +dependencies_native = [ 'bz2', 'ctru', 'mad', @@ -27,13 +27,13 @@ _3ds_dependencies_native = [ 'SDL2main', ] -_3ds_library_dirs = meson.get_external_property('library_dirs', ['']) -if _3ds_library_dirs.length() == 0 +library_dirs = meson.get_external_property('library_dirs', ['']) +if library_dirs.length() == 0 error('property \'library_dirs\' has to be set!') endif -foreach dep : _3ds_dependencies - _3ds_deps += dependency( +foreach dep : dependencies + deps += dependency( dep, required: true, allow_fallback: false, @@ -42,20 +42,20 @@ foreach dep : _3ds_dependencies endforeach c = meson.get_compiler('c') -foreach dep : _3ds_dependencies_native - _3ds_deps += c.find_library( +foreach dep : dependencies_native + deps += c.find_library( dep, required: true, - dirs: _3ds_library_dirs, + dirs: library_dirs, ) endforeach ## compilation -_3ds_elf_file = build_target( - _3ds_exe_name + '.elf', - _3ds_src_files, - dependencies: _3ds_deps, +elf_file = build_target( + exe_name + '.elf', + src_files, + dependencies: deps, override_options: { 'warning_level': '3', 'werror': true, @@ -70,8 +70,8 @@ use_smdh = ['true', 'True', '1', true].contains( _3dsxtool = find_program('3dsxtool') -_3DSX_FLAGS = [_3dsxtool, _3ds_elf_file.full_path(), _3ds_exe_name + '.3dsx'] -_3DSX_DEPS = [_3ds_elf_file] +_3DSX_FLAGS = [_3dsxtool, elf_file.full_path(), exe_name + '.3dsx'] +_3DSX_DEPS = [elf_file] SMDH_DEPS = _3DSX_DEPS fs = import('fs') @@ -79,31 +79,21 @@ fs = import('fs') if use_smdh smdhtool = find_program('smdhtool') - SMDH_FLAGS = [smdhtool, '--create'] - - APP_NAME = meson.get_external_property('APP_NAME', _3ds_exe_name) - SMDH_FLAGS += APP_NAME - - APP_DESC = meson.get_external_property('APP_DESC', '') - if APP_DESC == '' - error('If USE_SMDH is set, you have to provide an APP_DESC') - endif - SMDH_FLAGS += APP_DESC - - APP_AUTHOR = meson.get_external_property('APP_AUTHOR', '') - if APP_AUTHOR == '' - error('If USE_SMDH is set, you have to provide an APP_AUTHOR') - endif - SMDH_FLAGS += APP_AUTHOR + SMDH_FLAGS = [ + smdhtool, + '--create', oopetris_name, + oopetris_desc, + oopetris_author, + ] LIBCTRU = meson.get_external_property('libctru', '') if LIBCTRU == '' error('property \'libctru\' has to be set!') endif - _3ds_default_icon = LIBCTRU / 'default_icon.png' + default_icon = LIBCTRU / 'default_icon.png' - APP_ICON = meson.get_external_property('APP_ICON', _3ds_default_icon) + APP_ICON = meson.get_external_property('APP_ICON', default_icon) if not fs.is_absolute(APP_ICON) APP_ICON = meson.project_source_root() / APP_ICON @@ -115,7 +105,7 @@ if use_smdh SMDH_FLAGS += APP_ICON - SMDH_FLAGS += (_3ds_exe_name + '.smdh') + SMDH_FLAGS += (exe_name + '.smdh') APP_SMALL_ICON = meson.get_external_property('APP_SMALL_ICON', '') @@ -135,14 +125,14 @@ if use_smdh SMDH_FLAGS += APP_SMALL_ICON endif - # smdhtool --create <_3ds_exe_name>.smdh [] + # smdhtool --create .smdh [] smdh_file = custom_target( - _3ds_exe_name + '.smdh', + exe_name + '.smdh', command: SMDH_FLAGS, - output: [_3ds_exe_name + '.smdh'], + output: [exe_name + '.smdh'], depends: SMDH_DEPS, ) - _3DSX_FLAGS += '--smdh=' + _3ds_exe_name + '.smdh' + _3DSX_FLAGS += '--smdh=' + exe_name + '.smdh' _3DSX_DEPS += smdh_file endif @@ -163,11 +153,11 @@ if APP_ROMFS != '' endif -# 3dsxtool <_3ds_exe_name>.elf <_3ds_exe_name>.3dsx <_3DSX_FLAGS> +# 3dsxtool .elf .3dsx <_3DSX_FLAGS> custom_target( - _3ds_exe_name + '.3dsx', + exe_name + '.3dsx', command: _3DSX_FLAGS, depends: _3DSX_DEPS, - output: [_3ds_exe_name + '.3dsx'], + output: [exe_name + '.3dsx'], build_by_default: true, ) diff --git a/src/executables/platforms/switch/meson.build b/src/executables/platforms/switch/meson.build index 7017f9fe..fde8c7d8 100644 --- a/src/executables/platforms/switch/meson.build +++ b/src/executables/platforms/switch/meson.build @@ -1,12 +1,12 @@ ## get the options object and "unpack" it -switch_exe_name = switch_options[0] -switch_src_files = switch_options[1] -switch_deps = switch_options[2] +exe_name = nintendo_options[0] +src_files = nintendo_options[1] +deps = nintendo_options[2] # libraries -switch_dependencies = [ +dependencies = [ 'harfbuzz', 'egl', 'flac', @@ -21,7 +21,7 @@ switch_dependencies = [ 'zlib', ] -switch_dependencies_native = [ +dependencies_native = [ 'bz2', 'drm_nouveau', 'modplug', @@ -30,8 +30,8 @@ switch_dependencies_native = [ 'SDL2main', ] -foreach dep : switch_dependencies - switch_deps += dependency( +foreach dep : dependencies + deps += dependency( dep, required: true, allow_fallback: false, @@ -39,26 +39,26 @@ foreach dep : switch_dependencies ) endforeach -switch_library_dirs = meson.get_external_property('library_dirs', ['']) -if switch_library_dirs.length() == 0 +library_dirs = meson.get_external_property('library_dirs', ['']) +if library_dirs.length() == 0 error('property \'library_dirs\' has to be set!') endif c = meson.get_compiler('c') -foreach dep : switch_dependencies_native - switch_deps += c.find_library( +foreach dep : dependencies_native + deps += c.find_library( dep, required: true, - dirs: switch_library_dirs, + dirs: library_dirs, ) endforeach ## compilation -switch_elf_file = build_target( - switch_exe_name + '.elf', - switch_src_files, - dependencies: switch_deps, +elf_file = build_target( + exe_name + '.elf', + src_files, + dependencies: deps, override_options: { 'warning_level': '3', 'werror': true, @@ -73,36 +73,22 @@ use_nacp = ['true', 'True', '1', true].contains( elf2nro = find_program('elf2nro') # executable input elf file, output nro file -NRO_FLAGS = [elf2nro, switch_elf_file.full_path(), switch_exe_name + '.nro'] -NRO_DEPS = [switch_elf_file] +NRO_FLAGS = [elf2nro, elf_file.full_path(), exe_name + '.nro'] +NRO_DEPS = [elf_file] NACP_DEPS = NRO_DEPS fs = import('fs') if use_nacp nacptool = find_program('nacptool') - NACP_FLAGS = [nacptool, '--create'] - - APP_NAME = meson.get_external_property('APP_NAME', switch_exe_name) - NACP_FLAGS += APP_NAME - - APP_AUTHOR = meson.get_external_property('APP_AUTHOR', '') - if APP_AUTHOR == '' - error('If USE_NACP is set, you have to provide an APP_AUTHOR') - endif - NACP_FLAGS += APP_AUTHOR - - APP_VERSION = meson.get_external_property('APP_VERSION', '') - if APP_VERSION == true - APP_VERSION = meson.project_version() - endif - - if APP_VERSION == '' - error('If USE_NACP is set, you have to provide an APP_VERSION') - endif - NACP_FLAGS += APP_VERSION - - NACP_FLAGS += (switch_exe_name + '.nacp') + NACP_FLAGS = [ + nacptool, + '--create', + oopetris_name, + oopetris_author, + meson.project_version(), + exe_name + '.nacp', + ] APP_TITLEID = meson.get_external_property('APP_TITLEID', '') @@ -111,15 +97,16 @@ if use_nacp NACP_FLAGS += '--titleid=' + APP_TITLEID endif - # nacptool --create .nacp + # nacptool --create .nacp # optional: --titleid= nacp_file = custom_target( - switch_exe_name + '.nacp', + exe_name + '.nacp', command: NACP_FLAGS, - output: [switch_exe_name + '.nacp'], + output: [exe_name + '.nacp'], depends: NACP_DEPS, ) - NRO_FLAGS += '--nacp=' + switch_exe_name + '.nacp' + + NRO_FLAGS += '--nacp=' + exe_name + '.nacp' NRO_DEPS += nacp_file endif @@ -129,9 +116,9 @@ if LIBNX == '' error('property \'libnx\' has to be set!') endif -switch_default_icon = LIBNX / 'default_icon.jpg' +default_icon = LIBNX / 'default_icon.jpg' -APP_ICON = meson.get_external_property('APP_ICON', switch_default_icon) +APP_ICON = meson.get_external_property('APP_ICON', default_icon) if not fs.is_absolute(APP_ICON) APP_ICON = meson.project_source_root() / APP_ICON @@ -158,11 +145,11 @@ if APP_ROMFS != '' endif -# elf2nro .elf .nro +# elf2nro .elf .nro custom_target( - switch_exe_name + '.nro', + exe_name + '.nro', command: NRO_FLAGS, depends: NRO_DEPS, - output: [switch_exe_name + '.nro'], + output: [exe_name + '.nro'], build_by_default: true, ) diff --git a/src/executables/platforms/wii/meson.build b/src/executables/platforms/wii/meson.build new file mode 100644 index 00000000..aac059f5 --- /dev/null +++ b/src/executables/platforms/wii/meson.build @@ -0,0 +1,116 @@ +## get the options object and "unpack" it + +exe_name = nintendo_options[0] +src_files = nintendo_options[1] +deps = nintendo_options[2] + + +# libraries + +dependencies = [ + 'freetype2', + 'harfbuzz', + 'ogg', + 'vorbis', + 'vorbisfile', + 'vorbisidec', + 'zlib', +] + +dependencies_native = [ + 'bte', + 'bz2', + 'fat', + 'jpeg', + 'm', + 'modplug', + 'ogc', + 'fat', + 'png16', + 'SDL2main', + 'wiikeyboard', + 'wiiuse', + 'aesnd', + 'stdc++', + 'mpg123', + 'opusfile', + 'opus', + 'FLAC', + 'ogg', + 'db', +] + +foreach dep : dependencies + deps += dependency( + dep, + required: true, + allow_fallback: false, + native: false, + ) +endforeach + +library_dirs = meson.get_external_property('library_dirs', ['']) +if library_dirs.length() == 0 + error('property \'library_dirs\' has to be set!') +endif + +c = meson.get_compiler('c') +foreach dep : dependencies_native + deps += c.find_library( + dep, + required: true, + dirs: library_dirs, + ) +endforeach + +## compilation + +elf_file = build_target( + exe_name + '.elf', + src_files, + dependencies: deps, + override_options: { + 'warning_level': '3', + 'werror': true, + }, + native: false, + target_type: 'executable', +) + +DOL_DEPS = [elf_file] + + +elf2dol = find_program('elf2dol') + +# elf2dol .elf .dol +custom_target( + exe_name + '.dol', + command: [elf2dol, elf_file.full_path(), exe_name + '.dol'], + depends: DOL_DEPS, + output: [exe_name + '.dol'], + build_by_default: true, +) + +use_meta_xml = ['true', 'True', '1', true].contains( + meson.get_external_property('USE_META_XML', ''), +) + +if use_meta_xml + + meta_xml_conf = configuration_data( + { + 'OOPETRIS_VERSION': meson.project_version(), + 'OOPETRIS_NAME': oopetris_name, + 'OOPETRIS_AUTHOR': oopetris_author, + 'OOPETRIS_SHORT_DESCRIPTION': oopetris_desc, + 'OOPETRIS_LONG_DESCRIPTION': oopetris_desc, + }, + ) + + meta_xml = configure_file( + input: 'meta.xml.in', + output: 'meta.xml', + configuration: meta_xml_conf, + ) + +endif diff --git a/src/executables/platforms/wii/meta.xml.in b/src/executables/platforms/wii/meta.xml.in new file mode 100644 index 00000000..6898e0cf --- /dev/null +++ b/src/executables/platforms/wii/meta.xml.in @@ -0,0 +1,10 @@ + + + @OOPETRIS_NAME@ + @OOPETRIS_AUTHOR@ + @OOPETRIS_VERSION@ + @OOPETRIS_SHORT_DESCRIPTION@ + @OOPETRIS_LONG_DESCRIPTION@ + + + diff --git a/src/graphics/renderer.cpp b/src/graphics/renderer.cpp index b5f71f80..868148d4 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(__WII__) | SDL_RENDERER_SOFTWARE #else | SDL_RENDERER_ACCELERATED diff --git a/src/helper/console_helpers.cpp b/src/helper/console_helpers.cpp index c804a0ac..32673012 100644 --- a/src/helper/console_helpers.cpp +++ b/src/helper/console_helpers.cpp @@ -12,6 +12,13 @@ #elif defined(__3DS__) #include <3ds.h> #include +#elif defined(__WII__) +#include +#include + +#include +#include +#include #endif #include @@ -21,6 +28,8 @@ void console::debug_write(const char* text, size_t size) { svcOutputDebugString(text, size); #elif defined(__SWITCH__) svcOutputDebugString(text, size); +#elif defined(__WII__) + SYS_Report("%.*s", size, text); #else #error "not implemented" #endif @@ -47,14 +56,23 @@ void console::debug_write(const char* text, size_t size) { #elif defined(__SWITCH__) UNUSED(url); return ""; +#elif defined(__WII__) + UNUSED(url); + return ""; #else #error "not implemented" #endif } +#if defined(__WII__) +#define R_FAILED(x) ((x) != 0) +#define Result int +#endif + + void console::platform_init() { -#if defined(__3DS__) || defined(__SWITCH__) +#if defined(__3DS__) || defined(__SWITCH__) || defined(__WII__) Result ret = romfsInit(); if (R_FAILED(ret)) { throw helper::InitializationError(fmt::format("romfsInit() failed: {:#2x}", static_cast(ret))); @@ -62,10 +80,30 @@ void console::platform_init() { #else #error "not implemented" #endif + + +#if defined(_WII__) + + debug_write("IO WIISD startup\n"); + + // Initialize FAT so we can write to SD. + int res1 = __io_wiisd.startup(); + + debug_write("IO WIISD startup 2 \n"); + + // int res = fatInitDefault(); + int res2 = fatMountSimple("sd", &__io_wiisd); + + debug_write("IO WIISD startup 3\n"); + + if (res1 || res || res2) { + throw helper::InitializationError("fatInitDefault() failed!"); + } +#endif } void console::platform_exit() { -#if defined(__3DS__) || defined(__SWITCH__) +#if defined(__3DS__) || defined(__SWITCH__) || defined(__WII__) Result ret = romfsExit(); if (R_FAILED(ret)) { throw helper::InitializationError(fmt::format("romfsExit() failed: {:#2x}", static_cast(ret))); @@ -73,6 +111,13 @@ void console::platform_exit() { #else #error "not implemented" #endif + +#if defined(__WII__) + + fatUnmount("sd"); + __io_wiisd.shutdown(); + +#endif } bool console::inMainLoop() { @@ -80,6 +125,9 @@ bool console::inMainLoop() { return aptMainLoop(); #elif defined(__SWITCH__) return appletMainLoop(); +#elif defined(__WII__) + // the wii has no such logic + return true; #else #error "not implemented" #endif diff --git a/src/helper/console_helpers.hpp b/src/helper/console_helpers.hpp index 05df762d..793ffdd7 100644 --- a/src/helper/console_helpers.hpp +++ b/src/helper/console_helpers.hpp @@ -41,11 +41,13 @@ namespace console { auto size = formatted.size(); - // debug_write already writes an newline at the end! +#if !defined(__WII__) + // debug_write already writes an newline at the end (only on 3ds and switch) if (size > 0 and formatted.data()[size - 1] == '\n') { formatted.data()[size - 1] = '\0'; --size; } +#endif debug_write(formatted.data(), size); } diff --git a/src/helper/graphic_utils.cpp b/src/helper/graphic_utils.cpp index 080969c2..f1d04c5a 100644 --- a/src/helper/graphic_utils.cpp +++ b/src/helper/graphic_utils.cpp @@ -38,8 +38,16 @@ std::vector utils::supported_features() { } return std::filesystem::path{ std::string{ pref_path } }; #elif defined(__CONSOLE__) +#if defined(__WII__) + // the sdcard of the wii is at the special mounted device (sd:/) + const auto sdcard_path = "sd:/"; +#else // this is in the sdcard of the switch / 3ds , since internal storage is read-only for applications! - return std::filesystem::path{ "." }; + const auto sdcard_path = "./"; +#endif + // to not pollute the sdcard, we save things in a folder with the name of the application + return std::filesystem::path{ std::string{ sdcard_path } + constants::program_name.c_str() }; + #elif defined(BUILD_INSTALLER) #if defined(FLATPAK_BUILD) // this is a read write location in the flatpak build, see https://docs.flatpak.org/en/latest/conventions.html diff --git a/src/helper/logger.cpp b/src/helper/logger.cpp new file mode 100644 index 00000000..abec2d64 --- /dev/null +++ b/src/helper/logger.cpp @@ -0,0 +1,76 @@ + + +#include "logger.hpp" + + +#include +#include +#include + + +#if defined(__ANDROID__) +#include +#endif + +#if defined(__CONSOLE__) +#include "helper/console_helpers.hpp" +#endif + +#include "helper/graphic_utils.hpp" + +#include +#include + + +#if !defined(SPDLOG_THREAD_USAGE) +#define SPDLOG_THREAD_USAGE 0 +#endif + +#if SPDLOG_THREAD_USAGE == 0 +#define SPDLOG_THREAD_DEF(x) x##_mt +#elif SPDLOG_THREAD_USAGE == 1 +#define SPDLOG_THREAD_DEF(x) x##_st +#else +#error "SPDLOG_THREAD_USAGE has unknown value" +#endif + + +void logger::initialize() { + console::debug_print("logger: 1\n"); + +/* + const auto logs_path = utils::get_root_folder() / "logs"; + if (not std::filesystem::exists(logs_path)) { + std::filesystem::create_directory(utils::get_root_folder()); + std::filesystem::create_directory(logs_path); + } + */ + console::debug_print("logger: 2\n"); + + std::vector sinks; +#if defined(__ANDROID__) + sinks.push_back(std::make_shared()); +#elif defined(__CONSOLE__) + console::debug_print("logger: 3\n"); + sinks.push_back(std::make_shared()); + console::debug_print("logger: 4\n"); +#else + sinks.push_back(std::make_shared()); +#endif + console::debug_print("logger: 5\n"); + /* sinks.push_back(std::make_shared( + fmt::format("{}/oopetris.log", logs_path.string()), 1024 * 1024 * 10, 5, true + )); */ + console::debug_print("logger: 6\n"); + auto combined_logger = std::make_shared("combined_logger", begin(sinks), end(sinks)); + console::debug_print("logger: 7\n"); + spdlog::set_default_logger(combined_logger); + console::debug_print("logger: 8\n"); + +#if !defined(NDEBUG) + spdlog::set_level(spdlog::level::debug); +#else + spdlog::set_level(spdlog::level::err); +#endif + console::debug_print("logger: 9\n"); +} diff --git a/src/helper/logger.hpp b/src/helper/logger.hpp new file mode 100644 index 00000000..155e4107 --- /dev/null +++ b/src/helper/logger.hpp @@ -0,0 +1,10 @@ + +#pragma once + +namespace logger { + + + void initialize(); + + +} diff --git a/src/helper/meson.build b/src/helper/meson.build index f7210ff3..568b67bf 100644 --- a/src/helper/meson.build +++ b/src/helper/meson.build @@ -7,6 +7,8 @@ graphics_src_files += files( 'git_helper.hpp', 'graphic_utils.cpp', 'graphic_utils.hpp', + 'logger.cpp', + 'logger.hpp', 'message_box.cpp', 'message_box.hpp', 'music_utils.hpp', diff --git a/src/helper/platform.cpp b/src/helper/platform.cpp index 9922cc96..61bd395c 100644 --- a/src/helper/platform.cpp +++ b/src/helper/platform.cpp @@ -43,6 +43,8 @@ namespace { return "Nintendo Switch"; #elif defined(__3DS__) return "Nintendo 3DS"; +#elif defined(__WII__) + return "Wii"; #elif defined(FLATPAK_BUILD) return "Linux (Flatpak)"; #elif defined(__linux__) diff --git a/src/input/console_buttons.hpp b/src/input/console_buttons.hpp index 7b9b75fa..843cf52c 100644 --- a/src/input/console_buttons.hpp +++ b/src/input/console_buttons.hpp @@ -131,6 +131,57 @@ enum JOYCON { static_assert(BIT(JOYCON_B) == KEY_B); static_assert(BIT(JOYCON_SELECT) == KEY_SELECT); +#elif defined(__WII__) + + +// some wii buttons, from (lib)wut, but since SDL doesn't handle inputs as flags, like (lib)wut), the have to be reversed and reversing 1 << x = log_2(x), this is done constexpr + + +namespace { + // this is rounding down since >> 1 throws away the least significant bit, but if its a power of two it is spot on + constexpr unsigned int BIT_REVERSE(unsigned int x) { + return x == 1 ? 0 : 1 + BIT_REVERSE(x >> 1); + } +}; // namespace + + +#include + + +//using C enum (not enum class) on purpose +enum JOYCON { + + // see /opt/devkitpro/wut/include/padscore/wpad.h + + JOYCON_LEFT = BIT_REVERSE(WPAD_BUTTON_LEFT), ///! The left button of the D-pad. + JOYCON_RIGHT = BIT_REVERSE(WPAD_BUTTON_RIGHT), ///! The right button of the D-pad. + JOYCON_DOWN = BIT_REVERSE(WPAD_BUTTON_DOWN), ///! The down button of the D-pad. + JOYCON_UP = BIT_REVERSE(WPAD_BUTTON_UP), ///! The up button of the D-pad. + + JOYCON_PLUS = BIT_REVERSE(WPAD_BUTTON_PLUS), ///! The + button. + JOYCON_MINUS = BIT_REVERSE(WPAD_BUTTON_MINUS), ///! The - button. + + JOYCON_1 = BIT_REVERSE(WPAD_BUTTON_1), ///! The 1 button. + JOYCON_2 = BIT_REVERSE(WPAD_BUTTON_2), ///! The 2 button. + + JOYCON_A = BIT_REVERSE(WPAD_BUTTON_A), ///! The A button. + JOYCON_B = BIT_REVERSE(WPAD_BUTTON_B), ///! The B button. + + NUNCHUK_C = BIT_REVERSE(WPAD_NUNCHUK_BUTTON_C), ///! The C button on the Nunchuk extension. + NUNCHUK_Z = BIT_REVERSE(WPAD_NUNCHUK_BUTTON_Z), ///! The Z button on the Nunchuk extension. + + JOYCON_HOME = BIT_REVERSE(WPAD_BUTTON_HOME), ///! The HOME button. +}; + +/// Creates a bitmask from a bit number. +#define BIT(n) (1U << (n)) + +// some static asserts to check if BIT_REVERSE works as expected +static_assert(BIT(JOYCON_LEFT) == WPAD_BUTTON_LEFT); +static_assert(BIT(JOYCON_HOME) == WPAD_BUTTON_HOME); + +#else +#error "unsupported console" #endif diff --git a/src/input/input.cpp b/src/input/input.cpp index 90b34c49..e78a2efd 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -17,6 +17,8 @@ #include +#include "helper/console_helpers.hpp" + input::Input::Input(std::string name, InputType type) : m_name{ std::move(name) }, m_type{ type } { } input::Input::~Input() = default; @@ -78,17 +80,27 @@ input::PointerEventHelper::PointerEventHelper(shapes::IPoint pos, PointerEvent e input::InputManager::InputManager(const std::shared_ptr& window) { + ::console::debug_print(fmt::format("inputman: 1 \n")); + //initialize mouse input m_inputs.push_back(std::make_unique()); + ::console::debug_print(fmt::format("inputman: 2 \n")); + //initialize keyboard input m_inputs.push_back(std::make_unique()); + ::console::debug_print(fmt::format("inputman: 3 \n")); + //initialize touch inputs by using the manager(needs window) input::TouchInputManager::discover_devices(m_inputs, window); + ::console::debug_print(fmt::format("inputman: 4 \n")); + //initialize joystick inputs by using the manager input::JoyStickInputManager::discover_devices(m_inputs); + + ::console::debug_print(fmt::format("inputman: 5 \n")); } [[nodiscard]] const std::vector>& input::InputManager::inputs() const { diff --git a/src/input/joystick_input.cpp b/src/input/joystick_input.cpp index 6608fb66..b959d9ee 100644 --- a/src/input/joystick_input.cpp +++ b/src/input/joystick_input.cpp @@ -14,6 +14,8 @@ #include #include +#include "helper/console_helpers.hpp" + input::JoystickLikeInput::JoystickLikeInput(SDL_JoystickID instance_id, const std::string& name, JoystickLikeType type) : input::Input{ name, @@ -59,6 +61,11 @@ input::JoystickInput& input::JoystickInput::operator=(JoystickInput&& input) noe return std::make_unique<_3DSJoystickInput_Type1>(joystick, instance_id, name); } +#elif defined(__WII__) + if (guid == WiiJoystickInput_Type1::guid) { + return std::make_unique(joystick, instance_id, name); + } + #endif #endif @@ -84,23 +91,34 @@ input::JoystickInput& input::JoystickInput::operator=(JoystickInput&& input) noe void input::JoyStickInputManager::discover_devices(std::vector>& inputs) { //initialize joystick input, this needs to call some sdl things + ::console::debug_print(fmt::format("joyman: 1 \n")); + const auto result = SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); + ::console::debug_print(fmt::format("joyman: 2 \n")); + if (result != 0) { - spdlog::warn("Failed to initialize the joystick / game controller system: {}", SDL_GetError()); + ::console::debug_print( + fmt::format("Failed to initialize the joystick / game controller system: {}\n", SDL_GetError()) + ); + // spdlog::warn("Failed to initialize the joystick / game controller system: {}", SDL_GetError()); return; } + ::console::debug_print(fmt::format("joyman: 3 \n")); const auto enable_result = SDL_JoystickEventState(SDL_ENABLE); if (enable_result != 1) { const auto* const error = enable_result == 0 ? "it was disabled" : SDL_GetError(); - spdlog::warn("Failed to set JoystickEventState (automatic polling by SDL): {}", error); + // spdlog::warn("Failed to set JoystickEventState (automatic polling by SDL): {}", error); + ::console::debug_print(fmt::format("Failed to set JoystickEventState (automatic polling by SDL): {}\n", error)); return; } + ::console::debug_print(fmt::format("joyman: 4 \n")); + const auto enable_controller_result = SDL_GameControllerEventState(SDL_ENABLE); if (enable_controller_result != 1) { @@ -110,28 +128,36 @@ void input::JoyStickInputManager::discover_devices(std::vector input::WiiJoystickInput_Type1::get_navigation_event( + const SDL_Event& event +) const { + if (event.type == SDL_JOYBUTTONDOWN) { + + if (event.jbutton.which != instance_id()) { + return std::nullopt; + } + + switch (event.jbutton.button) { + case JOYCON_A: + return NavigationEvent::OK; + case JOYCON_DOWN: + return NavigationEvent::DOWN; + case JOYCON_UP: + return NavigationEvent::UP; + case JOYCON_LEFT: + return NavigationEvent::LEFT; + case JOYCON_RIGHT: + return NavigationEvent::RIGHT; + case JOYCON_B: + return NavigationEvent::BACK; + default: + return std::nullopt; + + //note, that NavigationEvent::TAB is not supported + } + } + + return handle_axis_navigation_event(event); +} + +[[nodiscard]] std::string input::WiiJoystickInput_Type1::describe_navigation_event(NavigationEvent event) const { + switch (event) { + case NavigationEvent::OK: + return "A"; + case NavigationEvent::BACK: + return "B"; + case NavigationEvent::DOWN: + return "Down"; + case NavigationEvent::UP: + return "Up"; + case NavigationEvent::LEFT: + return "Left"; + case NavigationEvent::RIGHT: + return "Right"; + case NavigationEvent::TAB: + throw std::runtime_error("Tab is not supported"); + default: + utils::unreachable(); + } +} + + +[[nodiscard]] std::string input::WiiJoystickInput_Type1::key_to_string(console::SettingsType key) const { + switch (key) { + case JOYCON_LEFT: + return "LEFT"; + case JOYCON_RIGHT: + return "RIGHT"; + case JOYCON_DOWN: + return "DOWN"; + case JOYCON_UP: + return "UP"; + case JOYCON_PLUS: + return "PLUS"; + case JOYCON_MINUS: + return "MINUS"; + case JOYCON_1: + return "1"; + case JOYCON_2: + return "2"; + case JOYCON_A: + return "A"; + case JOYCON_B: + return "B"; + case NUNCHUK_C: + return "NUNCHUCK_C"; + case NUNCHUK_Z: + return "NUNCHUCK_Z"; + case JOYCON_HOME: + return "HOME"; + + default: + utils::unreachable(); + } +} + +[[nodiscard]] input::JoystickSettings input::WiiJoystickInput_Type1::to_normal_settings( + const AbstractJoystickSettings& settings +) const { + + JoystickSettings result{}; + +#define X_LIST_MACRO(x) SETTINGS_TO_STRING(settings, result, key_to_string, x); + + X_LIST_OF_SETTINGS_KEYS + +#undef X_LIST_MACRO + + return result; +} +[[nodiscard]] input::AbstractJoystickSettings +input::WiiJoystickInput_Type1::default_settings_raw() const { + const AbstractJoystickSettings settings = // + { + .identification = JoystickIdentification{ .guid = WiiJoystickInput_Type1::guid, .name = "TODO" }, + .rotate_left = JOYCON_1, + .rotate_right = JOYCON_2, + .move_left = JOYCON_LEFT, + .move_right = JOYCON_RIGHT, + .move_down = JOYCON_DOWN, + .drop = JOYCON_A, + .hold = JOYCON_B, + .pause = JOYCON_MINUS, + .open_settings = JOYCON_PLUS + }; + + return settings; +} + #endif #endif diff --git a/src/input/joystick_input.hpp b/src/input/joystick_input.hpp index add8bf27..9d6df398 100644 --- a/src/input/joystick_input.hpp +++ b/src/input/joystick_input.hpp @@ -196,8 +196,32 @@ namespace input { }; +#elif defined(__WII__) + + struct WiiJoystickInput_Type1 : ConsoleJoystickInput { + + //TODO + static constexpr sdl::GUID guid{}; + + WiiJoystickInput_Type1(SDL_Joystick* joystick, SDL_JoystickID instance_id, const std::string& name); + + [[nodiscard]] std::optional get_navigation_event(const SDL_Event& event) const override; + + [[nodiscard]] std::string describe_navigation_event(NavigationEvent event) const override; + + [[nodiscard]] std::string key_to_string(console::SettingsType key) const override; + + [[nodiscard]] JoystickSettings to_normal_settings( + const AbstractJoystickSettings& settings + ) const override; + + [[nodiscard]] AbstractJoystickSettings default_settings_raw() const override; + }; + + #endif + #endif @@ -315,7 +339,7 @@ namespace input { protected: [[nodiscard]] std::optional sdl_event_to_input_event(const SDL_Event& event) const override; }; -#if !defined(__SWITCH__) && !defined(__3DS__) +#if !defined(__SWITCH__) && !defined(__3DS__) && !defined(__WII__) #error "unsupported console" #endif #endif diff --git a/src/libs/core/hash-library/sha256.cpp b/src/libs/core/hash-library/sha256.cpp index d085a97e..bc4fb49d 100644 --- a/src/libs/core/hash-library/sha256.cpp +++ b/src/libs/core/hash-library/sha256.cpp @@ -27,6 +27,13 @@ #define __BYTE_ORDER __BYTE_ORDER__ #define __BIG_ENDIAN __ORDER_BIG_ENDIAN__ #endif +#elif defined(__WII__) +#if !(defined(__BYTE_ORDER__) or defined(__ORDER_BIG_ENDIAN__)) +#error "__BYTE_ORDER__ or __ORDER_BIG_ENDIAN__ not defined"! +#else +#define __BYTE_ORDER __BYTE_ORDER__ +#define __BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#endif #elif defined(__APPLE__) #include #else diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index cd6923f2..e81abb9e 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -17,6 +17,10 @@ #include #include + +#include +#include + // START: general json parser helper //helper for std::optional json conversion @@ -69,11 +73,11 @@ namespace json { template [[nodiscard]] helper::expected try_parse_json_file(const std::filesystem::path& file) noexcept { - + SYS_Report("%s\n", "jsonp: 1"); if (not std::filesystem::exists(file)) { return helper::unexpected{ fmt::format("File '{}' doesn't exist", file.string()) }; } - + SYS_Report("%s\n", "jsonp: 2"); std::ifstream file_stream{ file }; if (!file_stream.is_open()) { diff --git a/src/manager/event_dispatcher.hpp b/src/manager/event_dispatcher.hpp index 2f00636e..c98a262e 100644 --- a/src/manager/event_dispatcher.hpp +++ b/src/manager/event_dispatcher.hpp @@ -9,6 +9,9 @@ #include #include +#include +#include + struct EventDispatcher final { private: std::vector m_listeners; @@ -54,6 +57,10 @@ struct EventDispatcher final { switch (event.type) { case SDL_KEYDOWN: case SDL_KEYUP: { + + const auto key = sdl::Key{ event.key.keysym }; + + SYS_Report("%s %s\n", "KEYUP or down", key.to_string().c_str()); if (std::ranges::find(m_allowed_input_keys, sdl::Key{ event.key.keysym }) == m_allowed_input_keys.cend()) { return; diff --git a/src/manager/settings_manager.cpp b/src/manager/settings_manager.cpp index ff1d99ad..1a3d0229 100644 --- a/src/manager/settings_manager.cpp +++ b/src/manager/settings_manager.cpp @@ -3,24 +3,29 @@ #include "input/keyboard_input.hpp" #include "input/touch_input.hpp" +#include "helper/console_helpers.hpp" #include SettingsManager::SettingsManager(ServiceProvider* service_provider) : m_service_provider{ service_provider } { const std::filesystem::path settings_file = utils::get_root_folder() / detail::settings_filename; - + console::debug_print(fmt::format("settings: 1\n")); const auto result = json::try_parse_json_file(settings_file); - + console::debug_print(fmt::format("settings: 2\n")); if (result.has_value()) { m_settings = result.value(); } else { + console::debug_print(fmt::format("settings: 4\n")); spdlog::error("unable to load settings from \"{}\": {}", detail::settings_filename, result.error()); spdlog::warn("applying default settings"); m_settings = { detail::Settings{ {}, std::nullopt, 1.0, false } }; + console::debug_print(fmt::format("settings: 5\n")); } + + console::debug_print(fmt::format("settings: 6\n")); } diff --git a/src/scenes/recording_selector/recording_selector.cpp b/src/scenes/recording_selector/recording_selector.cpp index 373e504c..13c3ff91 100644 --- a/src/scenes/recording_selector/recording_selector.cpp +++ b/src/scenes/recording_selector/recording_selector.cpp @@ -160,7 +160,7 @@ namespace scenes { std::vector metadata_vector{}; - const auto recording_directory_path = utils::get_root_folder() / constants::recordings_directory; + const auto recording_directory_path = utils::get_assets_folder() / constants::recordings_directory; if (std::filesystem::exists(recording_directory_path)) { for (const auto& file : std::filesystem::recursive_directory_iterator(recording_directory_path)) { diff --git a/subprojects/libromfs.wrap b/subprojects/libromfs.wrap new file mode 100644 index 00000000..0daa6c8b --- /dev/null +++ b/subprojects/libromfs.wrap @@ -0,0 +1,12 @@ + + +[wrap-git] +directory = libromfs-0.7 +url = https://github.com/yawut/libromfs-wiiu.git +revision = master +depth = 1 +patch_directory = libromfs +diff_files = libromfs-0.7_patches.diff + +[provide] +libromfs = libromfs_dep diff --git a/subprojects/packagefiles/discord_game_sdk/meson_options.txt b/subprojects/packagefiles/discord_game_sdk/meson.options similarity index 100% rename from subprojects/packagefiles/discord_game_sdk/meson_options.txt rename to subprojects/packagefiles/discord_game_sdk/meson.options diff --git a/subprojects/packagefiles/libromfs-0.7_patches.diff b/subprojects/packagefiles/libromfs-0.7_patches.diff new file mode 100644 index 00000000..7595cfba --- /dev/null +++ b/subprojects/packagefiles/libromfs-0.7_patches.diff @@ -0,0 +1,23 @@ +diff --git a/source/romfs.c b/source/romfs.c +index 02d6bd5..17b0cf7 100644 +--- a/source/romfs.c ++++ b/source/romfs.c +@@ -15,7 +15,18 @@ + #include + #include + #include ++ ++#if defined(__WII__) || defined(__GAMECUBE__) ++#include ++ ++#define OSBlockMove(dest, src, size, flush) memmove((dest), (src), (size)) ++ ++#elif defined(__WIIU__) + #include ++#else ++#error "Unsupported platform" ++#endif ++ + + + /* include the implementation files (needed for static functions) */ diff --git a/subprojects/packagefiles/libromfs/meson.build b/subprojects/packagefiles/libromfs/meson.build new file mode 100644 index 00000000..17bc4c62 --- /dev/null +++ b/subprojects/packagefiles/libromfs/meson.build @@ -0,0 +1,137 @@ +project( + 'libromfs', + 'c', + version: '0.7.0', + meson_version: '>=1.2.0', + default_options: { + 'c_std': ['gnu11'], + }, +) + +deps = [] + +if meson.is_cross_build() + if ( + host_machine.system() == 'wiiu' + or host_machine.system() == 'wii' + or host_machine.system() == 'gamecube' + ) + + object_target = 'elf32-powerpc' + binary_arch = 'powerpc:common' + + library_dirs = meson.get_external_property('library_dirs', ['']) + if library_dirs.length() == 0 + error('property \'library_dirs\' has to be set!') + endif + + c = meson.get_compiler('c') + + if host_machine.system() == 'wiiu' + deps += c.find_library( + 'wut', + required: true, + dirs: library_dirs, + ) + elif ( + host_machine.system() == 'wii' + or host_machine.system() == 'gamecube' + ) + + deps += c.find_library( + 'ogc', + required: true, + dirs: library_dirs, + ) + endif + + else + error('not supported platform: ' + host_machine.system()) + endif +else + error('only cross build is supported') +endif + +romfs_dir = get_option('romfs_dir') + +if romfs_dir == '' + error('\'romfs_dir\' option is required') +endif + +fs = import('fs') + +if not fs.exists(romfs_dir) + error('\'romfs_dir\' should exist, but doesn\'t: \'' + romfs_dir + '\'') +endif + +message('Using folder \'' + romfs_dir + '\' for ROMFS') + + +find = find_program('find', native: true) + +romfs_files = run_command(find, romfs_dir, check: true).stdout().strip().split( + '\n', +) + +tar = find_program('tar', native: true) + +objcopy = find_program('objcopy', native: false) + +romfs_tar_name = 'romfs.tar' +romfs_obj_name = 'romfs.o' + +romfs_tar = custom_target( + depend_files: romfs_files, + command: [ + tar, + '--format', 'ustar', + '-cvf', '@OUTPUT@', + '-C', romfs_dir, + '.', + ], + output: [romfs_tar_name], +) + +binary_start_name = ( + '_binary' + ( + romfs_tar.full_path().replace(meson.global_build_root(), '').replace( + '/', + '_', + ).replace('.', '_').replace('-', '_') + ) +) +binary_final_name = '_binary_romfs_tar' + +romfs_object = custom_target( + romfs_obj_name, + command: [ + objcopy, + '--input-target', 'binary', + '--output-target', object_target, + '--binary-architecture', binary_arch, + '--redefine-sym', binary_start_name + '_start=' + binary_final_name + '_start', + '--redefine-sym', binary_start_name + '_end=' + binary_final_name + '_end', + '--redefine-sym', binary_start_name + '_size=' + binary_final_name + '_size', + '@INPUT@', + '@OUTPUT@', + ], + input: romfs_tar, + output: [romfs_obj_name], +) + +inc_dirs = include_directories('include') + +libromfs_lib = library( + 'romfs', + files('source/romfs.c'), + include_directories: inc_dirs, + dependencies: deps, + install: true, + objects: romfs_object, +) + +libromfs_dep = declare_dependency( + include_directories: inc_dirs, + version: meson.project_version(), + link_with: libromfs_lib, +) diff --git a/subprojects/packagefiles/libromfs/meson.options b/subprojects/packagefiles/libromfs/meson.options new file mode 100644 index 00000000..de184f86 --- /dev/null +++ b/subprojects/packagefiles/libromfs/meson.options @@ -0,0 +1,8 @@ + + +option( + 'romfs_dir', + type: 'string', + value: '', + description: 'The directory to use as ROM file system', +) diff --git a/subprojects/packagefiles/spdlog-1.14.1_wii.diff b/subprojects/packagefiles/spdlog-1.14.1_wii.diff new file mode 100644 index 00000000..c59387b3 --- /dev/null +++ b/subprojects/packagefiles/spdlog-1.14.1_wii.diff @@ -0,0 +1,817 @@ +diff --git a/include/spdlog/common.h b/include/spdlog/common.h +index aca483c..a265945 100644 +--- a/include/spdlog/common.h ++++ b/include/spdlog/common.h +@@ -93,6 +93,42 @@ + #define SPDLOG_DEPRECATED + #endif + ++#if defined(__WII__) ++ #include ++ #include ++ #include ++ ++ #include ++ ++namespace console { ++ ++inline void assert_mutex_result_success(int res) { ++ if (res != 0) { ++ throw std::system_error(std::make_error_code(std::errc::no_lock_available), "mutex error"); ++ } ++} ++ ++struct mutex { ++private: ++ mutex_t m_mutex; ++ ++public: ++ mutex() { assert_mutex_result_success(LWP_MutexInit(&this->m_mutex, false)); } ++ ++ ~mutex() { assert_mutex_result_success(LWP_MutexDestroy(this->m_mutex)); } ++ ++ inline void lock() { assert_mutex_result_success(LWP_MutexLock(this->m_mutex)); } ++ ++ inline void unlock() { assert_mutex_result_success(LWP_MutexUnlock(this->m_mutex)); } ++}; ++} // namespace console ++ ++ #define MUTEX console::mutex ++ ++#else ++ #define MUTEX std::mutex ++#endif ++ + // disable thread local on msvc 2013 + #ifndef SPDLOG_NO_TLS + #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt) +diff --git a/include/spdlog/details/backtracer-inl.h b/include/spdlog/details/backtracer-inl.h +index 43d1002..95e05e7 100644 +--- a/include/spdlog/details/backtracer-inl.h ++++ b/include/spdlog/details/backtracer-inl.h +@@ -9,50 +9,50 @@ + namespace spdlog { + namespace details { + SPDLOG_INLINE backtracer::backtracer(const backtracer &other) { +- std::lock_guard lock(other.mutex_); ++ std::lock_guard lock(other.mutex_); + enabled_ = other.enabled(); + messages_ = other.messages_; + } + + SPDLOG_INLINE backtracer::backtracer(backtracer &&other) SPDLOG_NOEXCEPT { +- std::lock_guard lock(other.mutex_); ++ std::lock_guard lock(other.mutex_); + enabled_ = other.enabled(); + messages_ = std::move(other.messages_); + } + + SPDLOG_INLINE backtracer &backtracer::operator=(backtracer other) { +- std::lock_guard lock(mutex_); ++ std::lock_guard lock(mutex_); + enabled_ = other.enabled(); + messages_ = std::move(other.messages_); + return *this; + } + + SPDLOG_INLINE void backtracer::enable(size_t size) { +- std::lock_guard lock{mutex_}; ++ std::lock_guard lock{mutex_}; + enabled_.store(true, std::memory_order_relaxed); + messages_ = circular_q{size}; + } + + SPDLOG_INLINE void backtracer::disable() { +- std::lock_guard lock{mutex_}; ++ std::lock_guard lock{mutex_}; + enabled_.store(false, std::memory_order_relaxed); + } + + SPDLOG_INLINE bool backtracer::enabled() const { return enabled_.load(std::memory_order_relaxed); } + + SPDLOG_INLINE void backtracer::push_back(const log_msg &msg) { +- std::lock_guard lock{mutex_}; ++ std::lock_guard lock{mutex_}; + messages_.push_back(log_msg_buffer{msg}); + } + + SPDLOG_INLINE bool backtracer::empty() const { +- std::lock_guard lock{mutex_}; ++ std::lock_guard lock{mutex_}; + return messages_.empty(); + } + + // pop all items in the q and apply the given fun on each of them. + SPDLOG_INLINE void backtracer::foreach_pop(std::function fun) { +- std::lock_guard lock{mutex_}; ++ std::lock_guard lock{mutex_}; + while (!messages_.empty()) { + auto &front_msg = messages_.front(); + fun(front_msg); +diff --git a/include/spdlog/details/backtracer.h b/include/spdlog/details/backtracer.h +index 541339c..3dc300c 100644 +--- a/include/spdlog/details/backtracer.h ++++ b/include/spdlog/details/backtracer.h +@@ -16,7 +16,7 @@ + namespace spdlog { + namespace details { + class SPDLOG_API backtracer { +- mutable std::mutex mutex_; ++ mutable MUTEX mutex_; + std::atomic enabled_{false}; + circular_q messages_; + +diff --git a/include/spdlog/details/console_globals.h b/include/spdlog/details/console_globals.h +index 9c55210..e74b310 100644 +--- a/include/spdlog/details/console_globals.h ++++ b/include/spdlog/details/console_globals.h +@@ -10,7 +10,7 @@ namespace spdlog { + namespace details { + + struct console_mutex { +- using mutex_t = std::mutex; ++ using mutex_t = MUTEX; + static mutex_t &mutex() { + static mutex_t s_mutex; + return s_mutex; +diff --git a/include/spdlog/details/mpmc_blocking_q.h b/include/spdlog/details/mpmc_blocking_q.h +index 5a474bf..516837f 100644 +--- a/include/spdlog/details/mpmc_blocking_q.h ++++ b/include/spdlog/details/mpmc_blocking_q.h +@@ -30,7 +30,7 @@ public: + // try to enqueue and block if no room left + void enqueue(T &&item) { + { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + pop_cv_.wait(lock, [this] { return !this->q_.full(); }); + q_.push_back(std::move(item)); + } +@@ -40,7 +40,7 @@ public: + // enqueue immediately. overrun oldest message in the queue if no room left. + void enqueue_nowait(T &&item) { + { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + q_.push_back(std::move(item)); + } + push_cv_.notify_one(); +@@ -49,7 +49,7 @@ public: + void enqueue_if_have_room(T &&item) { + bool pushed = false; + { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + if (!q_.full()) { + q_.push_back(std::move(item)); + pushed = true; +@@ -67,7 +67,7 @@ public: + // Return true, if succeeded dequeue item, false otherwise + bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) { + { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + if (!push_cv_.wait_for(lock, wait_duration, [this] { return !this->q_.empty(); })) { + return false; + } +@@ -81,7 +81,7 @@ public: + // blocking dequeue without a timeout. + void dequeue(T &popped_item) { + { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + push_cv_.wait(lock, [this] { return !this->q_.empty(); }); + popped_item = std::move(q_.front()); + q_.pop_front(); +@@ -95,7 +95,7 @@ public: + + // try to enqueue and block if no room left + void enqueue(T &&item) { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + pop_cv_.wait(lock, [this] { return !this->q_.full(); }); + q_.push_back(std::move(item)); + push_cv_.notify_one(); +@@ -103,14 +103,14 @@ public: + + // enqueue immediately. overrun oldest message in the queue if no room left. + void enqueue_nowait(T &&item) { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + q_.push_back(std::move(item)); + push_cv_.notify_one(); + } + + void enqueue_if_have_room(T &&item) { + bool pushed = false; +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + if (!q_.full()) { + q_.push_back(std::move(item)); + pushed = true; +@@ -126,7 +126,7 @@ public: + // dequeue with a timeout. + // Return true, if succeeded dequeue item, false otherwise + bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + if (!push_cv_.wait_for(lock, wait_duration, [this] { return !this->q_.empty(); })) { + return false; + } +@@ -138,7 +138,7 @@ public: + + // blocking dequeue without a timeout. + void dequeue(T &popped_item) { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + push_cv_.wait(lock, [this] { return !this->q_.empty(); }); + popped_item = std::move(q_.front()); + q_.pop_front(); +@@ -148,26 +148,26 @@ public: + #endif + + size_t overrun_counter() { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + return q_.overrun_counter(); + } + + size_t discard_counter() { return discard_counter_.load(std::memory_order_relaxed); } + + size_t size() { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + return q_.size(); + } + + void reset_overrun_counter() { +- std::unique_lock lock(queue_mutex_); ++ std::unique_lock lock(queue_mutex_); + q_.reset_overrun_counter(); + } + + void reset_discard_counter() { discard_counter_.store(0, std::memory_order_relaxed); } + + private: +- std::mutex queue_mutex_; ++ MUTEX queue_mutex_; + std::condition_variable push_cv_; + std::condition_variable pop_cv_; + spdlog::details::circular_q q_; +diff --git a/include/spdlog/details/periodic_worker-inl.h b/include/spdlog/details/periodic_worker-inl.h +index 18f11fb..db9d712 100644 +--- a/include/spdlog/details/periodic_worker-inl.h ++++ b/include/spdlog/details/periodic_worker-inl.h +@@ -14,7 +14,7 @@ namespace details { + SPDLOG_INLINE periodic_worker::~periodic_worker() { + if (worker_thread_.joinable()) { + { +- std::lock_guard lock(mutex_); ++ std::lock_guard lock(mutex_); + active_ = false; + } + cv_.notify_one(); +diff --git a/include/spdlog/details/periodic_worker.h b/include/spdlog/details/periodic_worker.h +index d647b66..914cccc 100644 +--- a/include/spdlog/details/periodic_worker.h ++++ b/include/spdlog/details/periodic_worker.h +@@ -30,7 +30,7 @@ public: + + worker_thread_ = std::thread([this, callback_fun, interval]() { + for (;;) { +- std::unique_lock lock(this->mutex_); ++ std::unique_lock lock(this->mutex_); + if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; })) { + return; // active_ == false, so exit this thread + } +@@ -47,7 +47,7 @@ public: + private: + bool active_; + std::thread worker_thread_; +- std::mutex mutex_; ++ MUTEX mutex_; + std::condition_variable cv_; + }; + } // namespace details +diff --git a/include/spdlog/details/registry-inl.h b/include/spdlog/details/registry-inl.h +index f447848..b06cce8 100644 +--- a/include/spdlog/details/registry-inl.h ++++ b/include/spdlog/details/registry-inl.h +@@ -50,12 +50,12 @@ SPDLOG_INLINE registry::registry() + SPDLOG_INLINE registry::~registry() = default; + + SPDLOG_INLINE void registry::register_logger(std::shared_ptr new_logger) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + register_logger_(std::move(new_logger)); + } + + SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr new_logger) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + new_logger->set_formatter(formatter_->clone()); + + if (err_handler_) { +@@ -79,13 +79,13 @@ SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr new_logge + } + + SPDLOG_INLINE std::shared_ptr registry::get(const std::string &logger_name) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + auto found = loggers_.find(logger_name); + return found == loggers_.end() ? nullptr : found->second; + } + + SPDLOG_INLINE std::shared_ptr registry::default_logger() { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + return default_logger_; + } + +@@ -98,7 +98,7 @@ SPDLOG_INLINE logger *registry::get_default_raw() { return default_logger_.get() + // set default logger. + // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map. + SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr new_default_logger) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + if (new_default_logger != nullptr) { + loggers_[new_default_logger->name()] = new_default_logger; + } +@@ -117,7 +117,7 @@ SPDLOG_INLINE std::shared_ptr registry::get_tp() { + + // Set global formatter. Each sink in each logger will get a clone of this object + SPDLOG_INLINE void registry::set_formatter(std::unique_ptr formatter) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + formatter_ = std::move(formatter); + for (auto &l : loggers_) { + l.second->set_formatter(formatter_->clone()); +@@ -125,7 +125,7 @@ SPDLOG_INLINE void registry::set_formatter(std::unique_ptr formatter) + } + + SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + backtrace_n_messages_ = n_messages; + + for (auto &l : loggers_) { +@@ -134,7 +134,7 @@ SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages) { + } + + SPDLOG_INLINE void registry::disable_backtrace() { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + backtrace_n_messages_ = 0; + for (auto &l : loggers_) { + l.second->disable_backtrace(); +@@ -142,7 +142,7 @@ SPDLOG_INLINE void registry::disable_backtrace() { + } + + SPDLOG_INLINE void registry::set_level(level::level_enum log_level) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + for (auto &l : loggers_) { + l.second->set_level(log_level); + } +@@ -150,7 +150,7 @@ SPDLOG_INLINE void registry::set_level(level::level_enum log_level) { + } + + SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + for (auto &l : loggers_) { + l.second->flush_on(log_level); + } +@@ -158,7 +158,7 @@ SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) { + } + + SPDLOG_INLINE void registry::set_error_handler(err_handler handler) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + for (auto &l : loggers_) { + l.second->set_error_handler(handler); + } +@@ -167,21 +167,21 @@ SPDLOG_INLINE void registry::set_error_handler(err_handler handler) { + + SPDLOG_INLINE void registry::apply_all( + const std::function)> &fun) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + for (auto &l : loggers_) { + fun(l.second); + } + } + + SPDLOG_INLINE void registry::flush_all() { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + for (auto &l : loggers_) { + l.second->flush(); + } + } + + SPDLOG_INLINE void registry::drop(const std::string &logger_name) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + auto is_default_logger = default_logger_ && default_logger_->name() == logger_name; + loggers_.erase(logger_name); + if (is_default_logger) { +@@ -190,7 +190,7 @@ SPDLOG_INLINE void registry::drop(const std::string &logger_name) { + } + + SPDLOG_INLINE void registry::drop_all() { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + loggers_.clear(); + default_logger_.reset(); + } +@@ -198,7 +198,7 @@ SPDLOG_INLINE void registry::drop_all() { + // clean all resources and threads started by the registry + SPDLOG_INLINE void registry::shutdown() { + { +- std::lock_guard lock(flusher_mutex_); ++ std::lock_guard lock(flusher_mutex_); + periodic_flusher_.reset(); + } + +@@ -213,12 +213,12 @@ SPDLOG_INLINE void registry::shutdown() { + SPDLOG_INLINE std::recursive_mutex ®istry::tp_mutex() { return tp_mutex_; } + + SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registration) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + automatic_registration_ = automatic_registration; + } + + SPDLOG_INLINE void registry::set_levels(log_levels levels, level::level_enum *global_level) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + log_levels_ = std::move(levels); + auto global_level_requested = global_level != nullptr; + global_log_level_ = global_level_requested ? *global_level : global_log_level_; +@@ -239,7 +239,7 @@ SPDLOG_INLINE registry ®istry::instance() { + } + + SPDLOG_INLINE void registry::apply_logger_env_levels(std::shared_ptr new_logger) { +- std::lock_guard lock(logger_map_mutex_); ++ std::lock_guard lock(logger_map_mutex_); + auto it = log_levels_.find(new_logger->name()); + auto new_level = it != log_levels_.end() ? it->second : global_log_level_; + new_logger->set_level(new_level); +diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h +index 8afcbd6..2339a49 100644 +--- a/include/spdlog/details/registry.h ++++ b/include/spdlog/details/registry.h +@@ -65,13 +65,13 @@ public: + + template + void flush_every(std::chrono::duration interval) { +- std::lock_guard lock(flusher_mutex_); ++ std::lock_guard lock(flusher_mutex_); + auto clbk = [this]() { this->flush_all(); }; + periodic_flusher_ = details::make_unique(clbk, interval); + } + + std::unique_ptr &get_flusher() { +- std::lock_guard lock(flusher_mutex_); ++ std::lock_guard lock(flusher_mutex_); + return periodic_flusher_; + } + +@@ -106,7 +106,7 @@ private: + void throw_if_exists_(const std::string &logger_name); + void register_logger_(std::shared_ptr new_logger); + bool set_level_from_cfg_(logger *logger); +- std::mutex logger_map_mutex_, flusher_mutex_; ++ MUTEX logger_map_mutex_, flusher_mutex_; + std::recursive_mutex tp_mutex_; + std::unordered_map> loggers_; + log_levels log_levels_; +diff --git a/include/spdlog/logger-inl.h b/include/spdlog/logger-inl.h +index 5218fe4..0dd4e76 100644 +--- a/include/spdlog/logger-inl.h ++++ b/include/spdlog/logger-inl.h +@@ -173,10 +173,10 @@ SPDLOG_INLINE void logger::err_handler_(const std::string &msg) { + custom_err_handler_(msg); + } else { + using std::chrono::system_clock; +- static std::mutex mutex; ++ static MUTEX mutex; + static std::chrono::system_clock::time_point last_report_time; + static size_t err_counter = 0; +- std::lock_guard lk{mutex}; ++ std::lock_guard lk{mutex}; + auto now = system_clock::now(); + err_counter++; + if (now - last_report_time < std::chrono::seconds(1)) { +diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h +index 4435a56..b063654 100644 +--- a/include/spdlog/sinks/android_sink.h ++++ b/include/spdlog/sinks/android_sink.h +@@ -108,11 +108,11 @@ private: + bool use_raw_msg_; + }; + +-using android_sink_mt = android_sink; ++using android_sink_mt = android_sink; + using android_sink_st = android_sink; + + template +-using android_sink_buf_mt = android_sink; ++using android_sink_buf_mt = android_sink; + template + using android_sink_buf_st = android_sink; + +diff --git a/include/spdlog/sinks/basic_file_sink.h b/include/spdlog/sinks/basic_file_sink.h +index 699caa1..72d3da7 100644 +--- a/include/spdlog/sinks/basic_file_sink.h ++++ b/include/spdlog/sinks/basic_file_sink.h +@@ -32,7 +32,7 @@ private: + details::file_helper file_helper_; + }; + +-using basic_file_sink_mt = basic_file_sink; ++using basic_file_sink_mt = basic_file_sink; + using basic_file_sink_st = basic_file_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/callback_sink.h b/include/spdlog/sinks/callback_sink.h +index 71668ef..5afda8c 100644 +--- a/include/spdlog/sinks/callback_sink.h ++++ b/include/spdlog/sinks/callback_sink.h +@@ -33,7 +33,7 @@ private: + custom_log_callback callback_; + }; + +-using callback_sink_mt = callback_sink; ++using callback_sink_mt = callback_sink; + using callback_sink_st = callback_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/daily_file_sink.h b/include/spdlog/sinks/daily_file_sink.h +index 1b1dc44..a43436b 100644 +--- a/include/spdlog/sinks/daily_file_sink.h ++++ b/include/spdlog/sinks/daily_file_sink.h +@@ -189,9 +189,9 @@ private: + details::circular_q filenames_q_; + }; + +-using daily_file_sink_mt = daily_file_sink; ++using daily_file_sink_mt = daily_file_sink; + using daily_file_sink_st = daily_file_sink; +-using daily_file_format_sink_mt = daily_file_sink; ++using daily_file_format_sink_mt = daily_file_sink; + using daily_file_format_sink_st = + daily_file_sink; + +diff --git a/include/spdlog/sinks/dist_sink.h b/include/spdlog/sinks/dist_sink.h +index 69c4971..78ca5d2 100644 +--- a/include/spdlog/sinks/dist_sink.h ++++ b/include/spdlog/sinks/dist_sink.h +@@ -74,7 +74,7 @@ protected: + std::vector> sinks_; + }; + +-using dist_sink_mt = dist_sink; ++using dist_sink_mt = dist_sink; + using dist_sink_st = dist_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/dup_filter_sink.h b/include/spdlog/sinks/dup_filter_sink.h +index 1498142..29d53b4 100644 +--- a/include/spdlog/sinks/dup_filter_sink.h ++++ b/include/spdlog/sinks/dup_filter_sink.h +@@ -85,7 +85,7 @@ protected: + } + }; + +-using dup_filter_sink_mt = dup_filter_sink; ++using dup_filter_sink_mt = dup_filter_sink; + using dup_filter_sink_st = dup_filter_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/hourly_file_sink.h b/include/spdlog/sinks/hourly_file_sink.h +index 1f13892..554a42d 100644 +--- a/include/spdlog/sinks/hourly_file_sink.h ++++ b/include/spdlog/sinks/hourly_file_sink.h +@@ -161,7 +161,7 @@ private: + bool remove_init_file_; + }; + +-using hourly_file_sink_mt = hourly_file_sink; ++using hourly_file_sink_mt = hourly_file_sink; + using hourly_file_sink_st = hourly_file_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/kafka_sink.h b/include/spdlog/sinks/kafka_sink.h +index 91e9878..e845ef0 100644 +--- a/include/spdlog/sinks/kafka_sink.h ++++ b/include/spdlog/sinks/kafka_sink.h +@@ -87,7 +87,7 @@ private: + std::unique_ptr topic_ = nullptr; + }; + +-using kafka_sink_mt = kafka_sink; ++using kafka_sink_mt = kafka_sink; + using kafka_sink_st = kafka_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/mongo_sink.h b/include/spdlog/sinks/mongo_sink.h +index c5b38ab..917c0f3 100644 +--- a/include/spdlog/sinks/mongo_sink.h ++++ b/include/spdlog/sinks/mongo_sink.h +@@ -80,7 +80,7 @@ private: + + #include "spdlog/details/null_mutex.h" + #include +-using mongo_sink_mt = mongo_sink; ++using mongo_sink_mt = mongo_sink; + using mongo_sink_st = mongo_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/msvc_sink.h b/include/spdlog/sinks/msvc_sink.h +index 2e5f687..cee97ad 100644 +--- a/include/spdlog/sinks/msvc_sink.h ++++ b/include/spdlog/sinks/msvc_sink.h +@@ -56,7 +56,7 @@ protected: + bool check_debugger_present_ = true; + }; + +-using msvc_sink_mt = msvc_sink; ++using msvc_sink_mt = msvc_sink; + using msvc_sink_st = msvc_sink; + + using windebug_sink_mt = msvc_sink_mt; +diff --git a/include/spdlog/sinks/ostream_sink.h b/include/spdlog/sinks/ostream_sink.h +index 6af9dd0..ba365ab 100644 +--- a/include/spdlog/sinks/ostream_sink.h ++++ b/include/spdlog/sinks/ostream_sink.h +@@ -36,7 +36,7 @@ protected: + bool force_flush_; + }; + +-using ostream_sink_mt = ostream_sink; ++using ostream_sink_mt = ostream_sink; + using ostream_sink_st = ostream_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/qt_sinks.h b/include/spdlog/sinks/qt_sinks.h +index d319e84..9fd66a1 100644 +--- a/include/spdlog/sinks/qt_sinks.h ++++ b/include/spdlog/sinks/qt_sinks.h +@@ -228,9 +228,9 @@ protected: + #include "spdlog/details/null_mutex.h" + #include + +-using qt_sink_mt = qt_sink; ++using qt_sink_mt = qt_sink; + using qt_sink_st = qt_sink; +-using qt_color_sink_mt = qt_color_sink; ++using qt_color_sink_mt = qt_color_sink; + using qt_color_sink_st = qt_color_sink; + } // namespace sinks + +diff --git a/include/spdlog/sinks/ringbuffer_sink.h b/include/spdlog/sinks/ringbuffer_sink.h +index 6156c6a..72d7b5d 100644 +--- a/include/spdlog/sinks/ringbuffer_sink.h ++++ b/include/spdlog/sinks/ringbuffer_sink.h +@@ -59,7 +59,7 @@ private: + details::circular_q q_; + }; + +-using ringbuffer_sink_mt = ringbuffer_sink; ++using ringbuffer_sink_mt = ringbuffer_sink; + using ringbuffer_sink_st = ringbuffer_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/rotating_file_sink.h b/include/spdlog/sinks/rotating_file_sink.h +index cd43d34..f8855c4 100644 +--- a/include/spdlog/sinks/rotating_file_sink.h ++++ b/include/spdlog/sinks/rotating_file_sink.h +@@ -52,7 +52,7 @@ private: + details::file_helper file_helper_; + }; + +-using rotating_file_sink_mt = rotating_file_sink; ++using rotating_file_sink_mt = rotating_file_sink; + using rotating_file_sink_st = rotating_file_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/syslog_sink.h b/include/spdlog/sinks/syslog_sink.h +index a2df3b4..e05cafc 100644 +--- a/include/spdlog/sinks/syslog_sink.h ++++ b/include/spdlog/sinks/syslog_sink.h +@@ -76,7 +76,7 @@ private: + const std::string ident_; + }; + +-using syslog_sink_mt = syslog_sink; ++using syslog_sink_mt = syslog_sink; + using syslog_sink_st = syslog_sink; + } // namespace sinks + +diff --git a/include/spdlog/sinks/systemd_sink.h b/include/spdlog/sinks/systemd_sink.h +index d2cd55f..c99cef6 100644 +--- a/include/spdlog/sinks/systemd_sink.h ++++ b/include/spdlog/sinks/systemd_sink.h +@@ -100,7 +100,7 @@ protected: + void flush_() override {} + }; + +-using systemd_sink_mt = systemd_sink; ++using systemd_sink_mt = systemd_sink; + using systemd_sink_st = systemd_sink; + } // namespace sinks + +diff --git a/include/spdlog/sinks/tcp_sink.h b/include/spdlog/sinks/tcp_sink.h +index 2534964..312d311 100644 +--- a/include/spdlog/sinks/tcp_sink.h ++++ b/include/spdlog/sinks/tcp_sink.h +@@ -68,7 +68,7 @@ protected: + details::tcp_client client_; + }; + +-using tcp_sink_mt = tcp_sink; ++using tcp_sink_mt = tcp_sink; + using tcp_sink_st = tcp_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/udp_sink.h b/include/spdlog/sinks/udp_sink.h +index 4bff0fd..8d07543 100644 +--- a/include/spdlog/sinks/udp_sink.h ++++ b/include/spdlog/sinks/udp_sink.h +@@ -52,7 +52,7 @@ protected: + details::udp_client client_; + }; + +-using udp_sink_mt = udp_sink; ++using udp_sink_mt = udp_sink; + using udp_sink_st = udp_sink; + + } // namespace sinks +diff --git a/include/spdlog/sinks/win_eventlog_sink.h b/include/spdlog/sinks/win_eventlog_sink.h +index 2c9b582..5e641fc 100644 +--- a/include/spdlog/sinks/win_eventlog_sink.h ++++ b/include/spdlog/sinks/win_eventlog_sink.h +@@ -253,7 +253,7 @@ public: + + } // namespace win_eventlog + +-using win_eventlog_sink_mt = win_eventlog::win_eventlog_sink; ++using win_eventlog_sink_mt = win_eventlog::win_eventlog_sink; + using win_eventlog_sink_st = win_eventlog::win_eventlog_sink; + + } // namespace sinks +diff --git a/meson.build b/meson.build +index 86c59f8..fcd8253 100644 +--- a/meson.build ++++ b/meson.build +@@ -24,6 +24,11 @@ else + endif + endif + ++ ++if get_option('no_tls') ++ spdlog_compile_args += '-DSPDLOG_NO_TLS' ++endif ++ + if get_option('compile_library') + spdlog_compile_args += '-DSPDLOG_COMPILED_LIB' + if get_option('default_library') != 'static' +diff --git a/meson_options.txt b/meson_options.txt +index 76d46f5..223110f 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -3,3 +3,5 @@ option('tests', type: 'feature', description: 'Build the unit tests') + option('compile_library', type: 'boolean', value: false, description: 'Builds a static/shared lib for faster compile times') + option('external_fmt', type: 'feature', description: 'Builds with external fmt lib instead of internal') + option('std_format', type: 'feature', description: 'Use std::format instead of internal fmt lib') ++ ++option('no_tls', type: 'boolean', value: false, description: 'prevent spdlog from using thread local storage') +diff --git a/src/file_sinks.cpp b/src/file_sinks.cpp +index 04cb6c1..c957983 100644 +--- a/src/file_sinks.cpp ++++ b/src/file_sinks.cpp +@@ -12,9 +12,9 @@ + + #include + +-template class SPDLOG_API spdlog::sinks::basic_file_sink; ++template class SPDLOG_API spdlog::sinks::basic_file_sink; + template class SPDLOG_API spdlog::sinks::basic_file_sink; + + #include +-template class SPDLOG_API spdlog::sinks::rotating_file_sink; ++template class SPDLOG_API spdlog::sinks::rotating_file_sink; + template class SPDLOG_API spdlog::sinks::rotating_file_sink; +diff --git a/src/spdlog.cpp b/src/spdlog.cpp +index 9f8390b..fc13f9f 100644 +--- a/src/spdlog.cpp ++++ b/src/spdlog.cpp +@@ -24,5 +24,5 @@ + template SPDLOG_API spdlog::logger::logger(std::string name, + sinks_init_list::iterator begin, + sinks_init_list::iterator end); +-template class SPDLOG_API spdlog::sinks::base_sink; ++template class SPDLOG_API spdlog::sinks::base_sink; + template class SPDLOG_API spdlog::sinks::base_sink; diff --git a/subprojects/spdlog.wrap b/subprojects/spdlog.wrap index af00d5a7..7f955f50 100644 --- a/subprojects/spdlog.wrap +++ b/subprojects/spdlog.wrap @@ -9,5 +9,7 @@ patch_hash = ae878e732330ea1048f90d7e117c40c0cd2a6fb8ae5492c7955818ce3aaade6c source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.14.1-1/spdlog-1.14.1.tar.gz wrapdb_version = 1.14.1-1 +diff_files = spdlog-1.14.1_wii.diff + [provide] spdlog = spdlog_dep diff --git a/tools/dependencies/meson.build b/tools/dependencies/meson.build index 4e702877..36e124dc 100644 --- a/tools/dependencies/meson.build +++ b/tools/dependencies/meson.build @@ -1,7 +1,11 @@ only_allow_native_libs = false if meson.is_cross_build() - if host_machine.system() == 'switch' or host_machine.system() == '3ds' + if ( + host_machine.system() == 'switch' + or host_machine.system() == '3ds' + or host_machine.system() == 'wii' + ) # we do not link to code that was compiled with gcc 10.1 / gcc 7.1, the code we link with is all compiled with gcc 13.2 core_lib += { 'compile_args': [core_lib.get('compile_args'), '-Wno-psabi'], @@ -31,7 +35,11 @@ fmt_use_header_only = false if ( meson.is_cross_build() - and (host_machine.system() == 'switch' or host_machine.system() == '3ds') + and ( + host_machine.system() == 'switch' + or host_machine.system() == '3ds' + or host_machine.system() == 'wii' + ) ) fmt_use_header_only = true endif @@ -205,6 +213,28 @@ if build_application 'compile_args': [graphics_lib.get('compile_args'), sdl2_mixer_defines], } + + # on the wii the option to enable thread is '-fpthread' and not '-pthread' + if (meson.is_cross_build() and host_machine.system() == 'wii') + thread_dep = declare_dependency( + link_args: [ + ## '-fpthread', + ], + compile_args: [], + ) + + meson.override_dependency('threads', thread_dep) + + ## use single thread for spdlog loggers + + graphics_lib += { + 'compile_args': [ + graphics_lib.get('compile_args'), + '-DSPDLOG_THREAD_USAGE=1', + ], + } + endif + spdlog_dep = dependency( 'spdlog', required: true, @@ -214,9 +244,15 @@ if build_application 'deps': [graphics_lib.get('deps'), spdlog_dep], } - if (meson.is_cross_build() and host_machine.system() == '3ds') + # TODO: solve this in teh spdlog meson.build, not here! + # on the 3ds there is no thread local storage (TLS) + if (meson.is_cross_build() and (host_machine.system() == '3ds')) + ##TODO: use no_tls as option! graphics_lib += { - 'compile_args': [graphics_lib.get('compile_args'), '-DSPDLOG_NO_TLS'], + 'compile_args': [ + graphics_lib.get('compile_args'), + '-DSPDLOG_NO_TLS', + ], } endif @@ -227,6 +263,7 @@ if build_application and ( host_machine.system() == 'switch' or host_machine.system() == '3ds' + or host_machine.system() == 'wii' ) ) online_multiplayer_supported = false @@ -261,8 +298,8 @@ if build_application if build_installer if get_option('buildtype') != 'release' error( - 'buildtype needs to be \'release\', when building the installer, but was: ' - + get_option('buildtype'), + 'buildtype needs to be \'release\', when building the installer, but was: ' + + get_option('buildtype'), ) endif @@ -279,8 +316,7 @@ if build_application else # TODO: create a proper installer for macOS : https://mesonbuild.com/Creating-OSX-packages.html error( - 'unsuported system for building the installer: ' - + host_machine.system(), + 'unsuported system for building the installer: ' + host_machine.system(), ) endif @@ -342,3 +378,37 @@ if build_application graphic_application_deps += argparse_dep recordings_application_deps += argparse_dep endif + + + +if (meson.is_cross_build() and host_machine.system() == 'wii') + + ## ROMFS handling, this is special in the case of the wii + + APP_ROMFS = meson.get_external_property('APP_ROMFS', '') + + if APP_ROMFS != '' + fs = import('fs') + + if not fs.is_absolute(APP_ROMFS) + APP_ROMFS = meson.project_source_root() / APP_ROMFS + endif + + if not fs.exists(APP_ROMFS) + error('APP_ROMFS should exist, but doesn\'t: \'' + APP_ROMFS + '\'') + endif + + libromfs_dep = dependency( + 'libromfs', + required: true, + allow_fallback: true, + native: false, + default_options: {'romfs_dir': APP_ROMFS}, + ) + + graphics_lib += { + 'deps': [graphics_lib.get('deps'), libromfs_dep], + } + endif + +endif diff --git a/tools/install/meson.build b/tools/install/meson.build index 69d8f1b3..de22ebe1 100644 --- a/tools/install/meson.build +++ b/tools/install/meson.build @@ -5,7 +5,11 @@ if build_application install_subdir( meson.project_source_root() / 'assets', install_dir: 'share/oopetris', - exclude_files: ['oopetris.desktop.in', 'OOPetris.svg', 'recordings.magic'], + exclude_files: [ + 'oopetris.desktop.in', + 'OOPetris.svg', + 'recordings.magic', + ], exclude_directories: ['icon'], ) @@ -14,8 +18,9 @@ if build_application app_name = 'com.github.mgerhold.OOPetris' endif - conf = configuration_data() - conf.set('APP_NAME', app_name) + conf = configuration_data( + {'DESCRIPTION': oopetris_desc, 'APP_NAME': app_name}, + ) datadir = get_option('prefix') / get_option('datadir') @@ -25,7 +30,9 @@ if build_application magic_dir = datadir / 'misc' magic_file = magic_dir / 'magic' - oopetris_magic_file = (meson.project_source_root() / 'assets' / 'recordings.magic') + oopetris_magic_file = ( + meson.project_source_root() / 'assets' / 'recordings.magic' + ) if fs.exists(magic_file) diff --git a/tools/options/meson.build b/tools/options/meson.build index 77687208..6b0aee36 100644 --- a/tools/options/meson.build +++ b/tools/options/meson.build @@ -1,5 +1,6 @@ oopetris_author = 'Coder2k' oopetris_name = 'OOPetris' +oopetris_desc = 'A Tetris clone in OOP' core_lib = { 'inc_dirs': [],