diff --git a/pkgs/applications/emulators/citra/default.nix b/pkgs/applications/emulators/citra/default.nix new file mode 100644 index 0000000000000..b1bacedb5729e --- /dev/null +++ b/pkgs/applications/emulators/citra/default.nix @@ -0,0 +1,103 @@ +# NOTICE: The company behind Citra was SLAPPed to death and was forced to nuke +# the upstream repos. This package is therefore without an active upstream and +# may break at any time. If you maintain a dependency of this package and yuzu +# broke because of a change in your package, please notify us maintainers and +# pay no further attention. + +{ branch +, qt6Packages +, fetchFromGitHub +, fetchurl +}: + +let + # Fetched from https://api.citra-emu.org/gamedb + # Please make sure to update this when updating citra! + compat-list = fetchurl { + name = "citra-compat-list"; + url = "https://web.archive.org/web/20231111133415/https://api.citra-emu.org/gamedb"; + hash = "sha256-J+zqtWde5NgK2QROvGewtXGRAWUTNSKHNMG6iu9m1fU="; + }; +in { + nightly = qt6Packages.callPackage ./generic.nix rec { + pname = "citra-nightly"; + version = "2088"; + + src = fetchFromGitHub { + owner = "PabloMK7"; + repo = "citra"; + rev = "480604ec72433f8cde3a8f6d22d3f8c86bea402f"; + sha256 = "0l9w4i0zbafcv2s6pd1zqb11vh0i7gzwbqnzlz9al6ihwbsgbj3k"; + fetchSubmodules = false; # We do fetch these but must substitute mirror URLs beforehand + leaveDotGit = true; + + # We must use mirrors because upstream yuzu got nuked. + # Sadly, the regular nix-prefetch-git doesn't support changing submodule urls. + # This substitutes mirrors and fetches the submodules manually. + postFetch = '' + pushd $out + # Git won't allow working on submodules otherwise... + git restore --staged . + + cp .gitmodules{,.bak} + + substituteInPlace .gitmodules \ + --replace-fail yuzu-emu yuzu-emu-mirror \ + --replace-fail citra-emu PabloMK7 \ + --replace-fail merryhime yuzu-mirror \ + + git submodule update --init --recursive -j ''${NIX_BUILD_CORES:-1} --progress --depth 1 --checkout --force + + mv .gitmodules{.bak,} + + # Remove .git dirs + find . -name .git -type f -exec rm -rf {} + + rm -rf .git/ + popd + ''; + }; + + inherit branch compat-list; + }; + + canary = qt6Packages.callPackage ./generic.nix rec { + pname = "citra-canary"; + version = "2766"; + + src = fetchFromGitHub { + owner = "alessiot89"; + repo = "citrus-canary"; + rev = "canary-${version}"; + sha256 = "1gm3ajphpzwhm3qnchsx77jyl51za8yw3r0j0h8idf9y1ilcjvi4"; + fetchSubmodules = false; # We do fetch these but must substitute mirror URLs beforehand + leaveDotGit = true; + + # We must use mirrors because upstream yuzu got nuked. + # Sadly, the regular nix-prefetch-git doesn't support changing submodule urls. + # This substitutes mirrors and fetches the submodules manually. + postFetch = '' + pushd $out + # Git won't allow working on submodules otherwise... + git restore --staged . + + cp .gitmodules{,.bak} + + substituteInPlace .gitmodules \ + --replace-fail yuzu-emu yuzu-emu-mirror \ + --replace-fail citra-emu PabloMK7 \ + --replace-fail merryhime yuzu-mirror \ + + git submodule update --init --recursive -j ''${NIX_BUILD_CORES:-1} --progress --depth 1 --checkout --force + + mv .gitmodules{.bak,} + + # Remove .git dirs + find . -name .git -type f -exec rm -rf {} + + rm -rf .git/ + popd + ''; + }; + + inherit branch compat-list; + }; +}.${branch} diff --git a/pkgs/applications/emulators/citra/generic.nix b/pkgs/applications/emulators/citra/generic.nix new file mode 100644 index 0000000000000..01b3b90ddf00d --- /dev/null +++ b/pkgs/applications/emulators/citra/generic.nix @@ -0,0 +1,150 @@ +{ pname +, version +, src +, branch +, compat-list + +, lib +, stdenv +, cmake +, boost +, pkg-config +, catch2_3 +, cpp-jwt +, cryptopp +, enet +, ffmpeg +, fmt +, gamemode +, glslang +, httplib +, inih +, libusb1 +, nlohmann_json +, openal +, openssl +, SDL2 +, soundtouch +, spirv-tools +, zstd +, vulkan-headers +, vulkan-loader +, enableSdl2Frontend ? true +, enableQt ? true, qtbase, qtmultimedia, qtwayland, wrapQtAppsHook +, enableQtTranslation ? enableQt, qttools +, enableWebService ? true +, enableCubeb ? true, cubeb +, useDiscordRichPresence ? false, rapidjson +}: +stdenv.mkDerivation { + inherit pname version src; + + nativeBuildInputs = [ + cmake + pkg-config + ffmpeg + glslang + ] ++ lib.optionals enableQt [ wrapQtAppsHook ]; + + buildInputs = [ + boost + catch2_3 + cpp-jwt + cryptopp + # intentionally omitted: dynarmic - prefer vendored version for compatibility + enet + fmt + httplib + inih + libusb1 + nlohmann_json + openal + openssl + SDL2 + soundtouch + spirv-tools + vulkan-headers + # intentionally omitted: xbyak - prefer vendored version for compatibility + zstd + ] ++ lib.optionals enableQt [ qtbase qtmultimedia qtwayland ] + ++ lib.optional enableQtTranslation qttools + ++ lib.optional enableCubeb cubeb + ++ lib.optional useDiscordRichPresence rapidjson; + + cmakeFlags = [ + (lib.cmakeBool "USE_SYSTEM_LIBS" true) + + (lib.cmakeBool "DISABLE_SYSTEM_DYNARMIC" true) + (lib.cmakeBool "DISABLE_SYSTEM_GLSLANG" true) # The following imported targets are referenced, but are missing: SPIRV-Tools-opt + (lib.cmakeBool "DISABLE_SYSTEM_LODEPNG" true) # Not packaged in nixpkgs + (lib.cmakeBool "DISABLE_SYSTEM_VMA" true) + (lib.cmakeBool "DISABLE_SYSTEM_XBYAK" true) + + # We don't want to bother upstream with potentially outdated compat reports + (lib.cmakeBool "CITRA_ENABLE_COMPATIBILITY_REPORTING" true) + (lib.cmakeBool "ENABLE_COMPATIBILITY_LIST_DOWNLOAD" false) # We provide this deterministically + + (lib.cmakeBool "ENABLE_SDL2_FRONTEND" enableSdl2Frontend) + (lib.cmakeBool "ENABLE_QT" enableQt) + (lib.cmakeBool "ENABLE_QT_TRANSLATION" enableQtTranslation) + (lib.cmakeBool "ENABLE_WEB_SERVICE" enableWebService) + (lib.cmakeBool "ENABLE_CUBEB" enableCubeb) + (lib.cmakeBool "USE_DISCORD_PRESENCE" useDiscordRichPresence) + ]; + + # causes redefinition of _FORTIFY_SOURCE + hardeningDisable = [ "fortify3" ]; + + postPatch = let + branchCaptialized = (lib.toUpper (lib.substring 0 1 branch) + lib.substring 1 (-1) branch); + in '' + # Fix file not found when looking in var/empty instead of opt + mkdir externals/dynarmic/src/dynarmic/ir/var + ln -s ../opt externals/dynarmic/src/dynarmic/ir/var/empty + + # Prep compatibilitylist + ln -s ${compat-list} ./dist/compatibility_list/compatibility_list.json + + # We already know the submodules are present + substituteInPlace CMakeLists.txt \ + --replace "check_submodules_present()" "" + + # Add versions + echo 'set(BUILD_FULLNAME "${branchCaptialized} ${version}")' >> CMakeModules/GenerateBuildInfo.cmake + + # Add gamemode + substituteInPlace externals/gamemode/include/gamemode_client.h --replace "libgamemode.so.0" "${lib.getLib gamemode}/lib/libgamemode.so.0" + ''; + + postInstall = let + libs = lib.makeLibraryPath [ vulkan-loader ]; + in lib.optionalString enableSdl2Frontend '' + wrapProgram "$out/bin/citra" \ + --prefix LD_LIBRARY_PATH : ${libs} + '' + lib.optionalString enableQt '' + qtWrapperArgs+=( + --prefix LD_LIBRARY_PATH : ${libs} + ) + ''; + + meta = with lib; { + broken = (stdenv.isLinux && stdenv.isAarch64); + homepage = "https://citra-emu.org"; + description = "The ${branch} branch of an open-source emulator for the Nintendo 3DS"; + longDescription = '' + A Nintendo 3DS Emulator written in C++ + Using the nightly branch is recommended for general usage. + Using the canary branch is recommended if you would like to try out + experimental features, with a cost of stability. + ''; + mainProgram = if enableQt then "citra-qt" else "citra"; + platforms = platforms.linux; + license = licenses.gpl2Plus; + maintainers = with maintainers; [ + abbradar + ashley + atemu # Maintains citra until a new fork is established + ivar + ]; + }; +} diff --git a/pkgs/applications/emulators/yuzu/compat-list.nix b/pkgs/applications/emulators/yuzu/compat-list.nix new file mode 100644 index 0000000000000..79b56948aeab0 --- /dev/null +++ b/pkgs/applications/emulators/yuzu/compat-list.nix @@ -0,0 +1,18 @@ +{ stdenv, fetchFromGitHub, unstableGitUpdater }: +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 + ''; + + passthru.updateScript = unstableGitUpdater {}; +} diff --git a/pkgs/applications/emulators/yuzu/default.nix b/pkgs/applications/emulators/yuzu/default.nix new file mode 100644 index 0000000000000..6852da378650f --- /dev/null +++ b/pkgs/applications/emulators/yuzu/default.nix @@ -0,0 +1,12 @@ +{ qt6Packages, makeScopeWithSplicing', generateSplicesForMkScope }: + +makeScopeWithSplicing' { + otherSplices = generateSplicesForMkScope "yuzuPackages"; + f = self: qt6Packages // { + compat-list = self.callPackage ./compat-list.nix {}; + nx_tzdb = self.callPackage ./nx_tzdb.nix {}; + + mainline = self.callPackage ./mainline.nix {}; + early-access = self.callPackage ./early-access {}; + }; +} diff --git a/pkgs/applications/emulators/yuzu/early-access/default.nix b/pkgs/applications/emulators/yuzu/early-access/default.nix new file mode 100644 index 0000000000000..f2ad5197d0bba --- /dev/null +++ b/pkgs/applications/emulators/yuzu/early-access/default.nix @@ -0,0 +1,37 @@ +{ mainline, fetchzip, fetchgit, runCommand, gnutar }: +# The mirror repo for early access builds is missing submodule info, +# but the Windows distributions include a source tarball, which in turn +# includes the full git metadata. So, grab that and rehydrate it. +# This has the unfortunate side effect of requiring two FODs, one +# for the Windows download and one for the full repo with submodules. +let + sources = import ./sources.nix; + + zip = fetchzip { + name = "yuzu-ea-windows-dist"; + url = "https://github.com/pineappleEA/pineapple-src/releases/download/EA-${sources.version}/Windows-Yuzu-EA-${sources.version}.zip"; + hash = sources.distHash; + }; + + gitSrc = runCommand "yuzu-ea-dist-unpacked" { + src = zip; + nativeBuildInputs = [ gnutar ]; + } + '' + mkdir $out + tar xf $src/*.tar.xz --directory=$out --strip-components=1 + ''; + + rehydratedSrc = fetchgit { + name = "yuzu-ea-rehydrated"; + url = gitSrc; + fetchSubmodules = true; + hash = sources.fullHash; + }; +in mainline.overrideAttrs(old: { + pname = "yuzu-early-access"; + version = sources.version; + src = rehydratedSrc; + passthru.updateScript = ./update.sh; + meta = old.meta // { description = old.meta.description + " - early access branch"; }; +}) diff --git a/pkgs/applications/emulators/yuzu/early-access/sources.nix b/pkgs/applications/emulators/yuzu/early-access/sources.nix new file mode 100644 index 0000000000000..c7653444a2e51 --- /dev/null +++ b/pkgs/applications/emulators/yuzu/early-access/sources.nix @@ -0,0 +1,7 @@ +# Generated by ./update.sh - do not update manually! +# Last updated: 2024-02-27 +{ + version = "4174"; + distHash = "sha256:1hzwfsm4m2q29a2ihipk0ij0qakn4730283d6gwbrgr8lzmj8q49"; + fullHash = "sha256:1ayn7y595iz4smbxq10jjgip04ss35v4vrn8pa1mpnrmyikv79l9"; +} diff --git a/pkgs/applications/emulators/yuzu/early-access/update.sh b/pkgs/applications/emulators/yuzu/early-access/update.sh new file mode 100755 index 0000000000000..f7ea2ca34a412 --- /dev/null +++ b/pkgs/applications/emulators/yuzu/early-access/update.sh @@ -0,0 +1,44 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i bash -p nix nix-prefetch-git gnutar curl jq unzip + +set -euo pipefail + +cd "$(dirname "$(readlink -f "$0")")" + +log() { + tput bold + echo "#" "$@" + tput sgr0 +} + +oldVersion="$(nix --experimental-features nix-command eval -f sources.nix --raw version)" +newVersion="$(curl "https://api.github.com/repos/pineappleEA/pineapple-src/releases?per_page=1" | jq -r '.[0].tag_name' | cut -d"-" -f2)" + +if [ "$oldVersion" == "$newVersion" ]; then + log "Already up to date" + exit 0 +fi + +fetched="$(nix-prefetch-url --unpack --print-path "https://github.com/pineappleEA/pineapple-src/releases/download/EA-${newVersion}/Windows-Yuzu-EA-${newVersion}.zip")" + +eaDistHash="$(echo "${fetched}" | head -n1)" +eaDist="$(echo "${fetched}" | tail -n1)" + +eaDistUnpacked="$(mktemp -d)" +trap 'rm -rf "$eaDistUnpacked"' EXIT + +log "Unpacking dist..." +tar xf "$eaDist"/*.tar.xz --directory="$eaDistUnpacked" --strip-components=1 + +log "Rehydrating..." +eaFullHash="$(nix-prefetch-git --fetch-submodules --quiet "$eaDistUnpacked" | jq -r '.sha256')" + +cat >sources.nix <