diff --git a/pkgs/by-name/to/torzu/fix-debugger.patch b/pkgs/by-name/to/torzu/fix-debugger.patch new file mode 100644 index 0000000000000..87d4e0cc118fd --- /dev/null +++ b/pkgs/by-name/to/torzu/fix-debugger.patch @@ -0,0 +1,53 @@ +diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp +index e86aae8460..a4dca23770 100644 +--- a/src/core/debugger/debugger.cpp ++++ b/src/core/debugger/debugger.cpp +@@ -5,7 +5,13 @@ + #include + #include + +-#include ++// Use basic asio functionality only ++#define BOOST_ASIO_STANDALONE ++#include ++#include ++#include ++#include ++ + #include + + #include "common/logging/log.h" +@@ -21,17 +27,22 @@ + + template + static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) { +- static_assert(std::is_trivial_v); +- auto boost_buffer{boost::asio::buffer(&buffer, sizeof(Buffer))}; +- r.async_read_some( +- boost_buffer, [&, c](const boost::system::error_code& error, size_t bytes_read) { +- if (!error.failed()) { +- const u8* buffer_start = reinterpret_cast(&buffer); +- std::span received_data{buffer_start, buffer_start + bytes_read}; +- c(received_data); +- AsyncReceiveInto(r, buffer, c); +- } +- }); ++ try { ++ static_assert(std::is_trivial_v); ++ auto boost_buffer{boost::asio::buffer(&buffer, sizeof(Buffer))}; ++ r.async_read_some( ++ boost_buffer, ++ [&, c](const boost::system::error_code& error, size_t bytes_read) { ++ if (!error) { ++ const u8* buffer_start = reinterpret_cast(&buffer); ++ std::span received_data{buffer_start, buffer_start + bytes_read}; ++ c(received_data); ++ AsyncReceiveInto(r, buffer, c); ++ } ++ }); ++ } catch (const std::exception& e) { ++ LOG_ERROR(Debug_GDBStub, "AsyncReceiveInto error: {}", e.what()); ++ } + } + + template diff --git a/pkgs/by-name/to/torzu/fix-udp-client.patch b/pkgs/by-name/to/torzu/fix-udp-client.patch new file mode 100644 index 0000000000000..103b1001ee2a4 --- /dev/null +++ b/pkgs/by-name/to/torzu/fix-udp-client.patch @@ -0,0 +1,30 @@ +diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp +index 60821b31a6..8f9c047218 100644 +--- a/src/input_common/drivers/udp_client.cpp ++++ b/src/input_common/drivers/udp_client.cpp +@@ -2,7 +2,15 @@ + // SPDX-License-Identifier: GPL-2.0-or-later + + #include +-#include ++// Include only needed asio components ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include + + #include "common/logging/log.h" +@@ -113,7 +121,7 @@ private: + } + + SocketCallback callback; +- boost::asio::io_service io_service; ++ boost::asio::io_context io_service; + boost::asio::basic_waitable_timer timer; + udp::socket socket; + diff --git a/pkgs/by-name/to/torzu/fix-udp-protocol.patch b/pkgs/by-name/to/torzu/fix-udp-protocol.patch new file mode 100644 index 0000000000000..65c4862825fc5 --- /dev/null +++ b/pkgs/by-name/to/torzu/fix-udp-protocol.patch @@ -0,0 +1,13 @@ +diff --git a/src/input_common/helpers/udp_protocol.h b/src/input_common/helpers/udp_protocol.h +index db08fc62c5..ea223ea937 100644 +--- a/src/input_common/helpers/udp_protocol.h ++++ b/src/input_common/helpers/udp_protocol.h +@@ -69,7 +69,7 @@ Message CreateMessage(const u32 magic, const T data, const u32 sender_id) { + }; + Message message{header, data}; + crc.process_bytes(&message, sizeof(Message)); +- message.header.crc = crc.checksum(); ++ message.header.crc = static_cast(crc.checksum()); + return message; + } + diff --git a/pkgs/by-name/to/torzu/package.nix b/pkgs/by-name/to/torzu/package.nix new file mode 100644 index 0000000000000..06cd23badc4e6 --- /dev/null +++ b/pkgs/by-name/to/torzu/package.nix @@ -0,0 +1,244 @@ +{ + lib, + stdenv, + SDL2, + autoconf, + boost, + catch2_3, + cmake, + fetchFromGitHub, + cpp-jwt, + cubeb, + discord-rpc, + enet, + fetchgit, + fetchurl, + ffmpeg-headless, + fmt, + glslang, + libopus, + libusb1, + libva, + lz4, + python3, + unzip, + nix-update-script, + nlohmann_json, + nv-codec-headers-12, + pkg-config, + qt6, + vulkan-headers, + vulkan-loader, + yasm, + simpleini, + zlib, + vulkan-memory-allocator, + zstd, +}: + +let + inherit (qt6) + qtbase + qtmultimedia + qtwayland + wrapQtAppsHook + qttools + qtwebengine + ; + + compat-list = stdenv.mkDerivation { + pname = "yuzu-compatibility-list"; + version = "unstable-2024-02-26"; + + src = fetchFromGitHub { + owner = "flathub"; + repo = "org.yuzu_emu.yuzu"; + rev = "9c2032a3c7e64772a8112b77ed8b660242172068"; + hash = "sha256-ITh/W4vfC9w9t+TJnPeTZwWifnhTNKX54JSSdpgaoBk="; + }; + + buildCommand = '' + cp $src/compatibility_list.json $out + ''; + }; + + nx_tzdb = stdenv.mkDerivation rec { + pname = "nx_tzdb"; + version = "221202"; + + src = fetchurl { + url = "https://github.com/lat9nq/tzdb_to_nx/releases/download/${version}/${version}.zip"; + hash = "sha256-mRzW+iIwrU1zsxHmf+0RArU8BShAoEMvCz+McXFFK3c="; + }; + + nativeBuildInputs = [ unzip ]; + + buildCommand = '' + unzip $src -d $out + ''; + + }; + +in + +stdenv.mkDerivation (finalAttrs: { + pname = "torzu"; + version = "unstable-2024-12-15"; + + src = fetchgit { + url = "https://notabug.org/litucks/torzu"; + rev = "02cfee3f184e6fdcc3b483ef399fb5d2bb1e8ec7"; + hash = "sha256-hAWMFzTNJGFcrXov5LKMdW9YWhsu7wueATmiuS7EVkI="; + fetchSubmodules = true; + }; + + patches = [ + # Remove coroutines from debugger to fix boost::asio compatibility issues + ./fix-debugger.patch + # Add explicit cast for CRC checksum value + ./fix-udp-protocol.patch + # Use specific boost::asio includes and update to modern io_context + ./fix-udp-client.patch + ]; + + nativeBuildInputs = [ + cmake + glslang + pkg-config + python3 + qttools + wrapQtAppsHook + ]; + + buildInputs = [ + # vulkan-headers must come first, so the older propagated versions + # don't get picked up by accident + vulkan-headers + + boost + catch2_3 + cpp-jwt + cubeb + discord-rpc + # intentionally omitted: dynarmic - prefer vendored version for compatibility + enet + + # ffmpeg deps (also includes vendored) + # we do not use internal ffmpeg because cuda errors + autoconf + yasm + libva # for accelerated video decode on non-nvidia + nv-codec-headers-12 # for accelerated video decode on nvidia + ffmpeg-headless + # end ffmpeg deps + + fmt + # intentionally omitted: gamemode - loaded dynamically at runtime + # intentionally omitted: httplib - upstream requires an older version than what we have + libopus + libusb1 + # intentionally omitted: LLVM - heavy, only used for stack traces in the debugger + lz4 + nlohmann_json + qtbase + qtmultimedia + qtwayland + qtwebengine + # intentionally omitted: renderdoc - heavy, developer only + SDL2 + # intentionally omitted: stb - header only libraries, vendor uses git snapshot + vulkan-memory-allocator + # intentionally omitted: xbyak - prefer vendored version for compatibility + zlib + zstd + ]; + + # This changes `ir/opt` to `ir/var/empty` in `externals/dynarmic/src/dynarmic/CMakeLists.txt` + # making the build fail, as that path does not exist + dontFixCmake = true; + + cmakeFlags = [ + # actually has a noticeable performance impact + (lib.cmakeBool "YUZU_ENABLE_LTO" true) + (lib.cmakeBool "YUZU_TESTS" false) + + (lib.cmakeBool "ENABLE_QT6" true) + (lib.cmakeBool "ENABLE_QT_TRANSLATION" true) + + # use system libraries + # NB: "external" here means "from the externals/ directory in the source", + # so "off" means "use system" + (lib.cmakeBool "YUZU_USE_EXTERNAL_SDL2" false) + (lib.cmakeBool "YUZU_USE_EXTERNAL_VULKAN_HEADERS" true) + "-DVulkan_INCLUDE_DIRS=${vulkan-headers}/include" + + # # don't use system ffmpeg, suyu uses internal APIs + # (lib.cmakeBool "YUZU_USE_BUNDLED_FFMPEG" true) + + # don't check for missing submodules + (lib.cmakeBool "YUZU_CHECK_SUBMODULES" false) + + # enable some optional features + (lib.cmakeBool "YUZU_USE_QT_WEB_ENGINE" true) + (lib.cmakeBool "YUZU_USE_QT_MULTIMEDIA" true) + (lib.cmakeBool "USE_DISCORD_PRESENCE" true) + + # We dont want to bother upstream with potentially outdated compat reports + (lib.cmakeBool "YUZU_ENABLE_COMPATIBILITY_REPORTING" false) + (lib.cmakeBool "ENABLE_COMPATIBILITY_LIST_DOWNLOAD" false) # We provide this deterministically + ]; + + env = { + # Does some handrolled SIMD + NIX_CFLAGS_COMPILE = lib.optionalString stdenv.hostPlatform.isx86_64 "-msse4.1"; + }; + + qtWrapperArgs = [ + # Fixes vulkan detection. + # FIXME: patchelf --add-rpath corrupts the binary for some reason, investigate + "--prefix LD_LIBRARY_PATH : ${vulkan-loader}/lib" + ]; + + # Setting this through cmakeFlags does not work. + # https://github.com/NixOS/nixpkgs/issues/114044 + preConfigure = lib.concatStringsSep "\n" [ + '' + cmakeFlagsArray+=( + "-DTITLE_BAR_FORMAT_IDLE=${finalAttrs.pname} | ${finalAttrs.version} (nixpkgs) {}" + "-DTITLE_BAR_FORMAT_RUNNING=${finalAttrs.pname} | ${finalAttrs.version} (nixpkgs) | {}" + ) + '' + # provide pre-downloaded tz data + '' + mkdir -p build/externals/nx_tzdb + ln -s ${nx_tzdb} build/externals/nx_tzdb/nx_tzdb + '' + ]; + + postConfigure = '' + ln -sf ${compat-list} ./dist/compatibility_list/compatibility_list.json + ''; + + postInstall = " + install -Dm444 $src/dist/72-yuzu-input.rules $out/lib/udev/rules.d/72-yuzu-input.rules + "; + + meta = { + description = "Fork of yuzu, an open-source Nintendo Switch emulator"; + homepage = "https://notabug.org/litucks/torzu"; + mainProgram = "yuzu"; + platforms = lib.platforms.linux; + badPlatforms = [ + # Several conversion errors, probably caused by the update to GCC 14 + "aarch64-linux" + ]; + maintainers = with lib.maintainers; [ liberodark ]; + license = with lib.licenses; [ + gpl3Plus + # Icons + asl20 + mit + cc0 + ]; + }; +})