Unverified Commit ef4e5545 authored by Matteo Pacini's avatar Matteo Pacini Committed by GitHub
Browse files

duckstation: revert removal and update to latest version (#444821)

parents 1842aa40 58d04541
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@

- `spidermonkey_91` has been removed, as it has been EOL since September 2022.

- The license of duckstation has changed from `gpl3Only` to `cc-by-nc-nd-40` making it unfree in newer releases. The `duckstation` package has been overhauled to support the new releases and `duckstation-bin` has been aliased to `duckstation` to support darwin binary builds.

- `hiawata` has been removed, due to lack of active development upstream, lack of maintainership downstream and upcoming security issues.

- `forgejo` main program has been renamed to `bin/forgejo` from the previous `bin/gitea`.
+317 −0
Original line number Diff line number Diff line
{
  lib,
  llvmPackages,
  stdenvNoCC,
  fetchFromGitHub,
  cmake,
  pkg-config,
  ninja,
  extra-cmake-modules,
  wayland-scanner,
  makeBinaryWrapper,
  qt6,
  sdl3,
  zstd,
  libwebp,
  zlib,
  libpng,
  libjpeg,
  freetype,
  plutosvg,
  cpuinfo,
  soundtouch,
  rapidjson,
  libzip,
  curl,
  libX11,
  wayland,
  shaderc,
  spirv-cross,
  udev,
  libbacktrace,
  ffmpeg-headless,
  alsa-lib,
  libjack2,
  libpulseaudio,
  pipewire,
  fetchurl,
  zip,
  unzip,
}:

let
  passthru = {
    updateScript = ./update.sh;
  };

  meta = {
    description = "Fast PlayStation 1 emulator for x86-64/AArch32/AArch64/RV64";
    longDescription = ''
      # DISCLAIMER
      This is an **unofficial** package, do not report any issues to
      duckstation developers. Instead, please report them to
      <https://github.com/NixOS/nixpkgs> or use the officially
      supported platform build at <https://duckstation.org> or other
      upstream-approved distribution mechanism not listed here. We
      (nixpkgs) do not endorse or condone any action taken on your own
      accord in regards to this package.

      The SDL audio backend must be used as cubeb support is currently
      non-functional without patches.
    '';
    homepage = "https://duckstation.org";
    license = lib.licenses.cc-by-nc-nd-40;
    maintainers = with lib.maintainers; [
      normalcea
      matteopacini
    ];
  };

  pkgSources = lib.importJSON ./sources.json;

  linuxDrv = llvmPackages.stdenv.mkDerivation (finalAttrs: {
    pname = "duckstation";
    version = pkgSources.duckstation.version;

    src = fetchFromGitHub {
      owner = "stenzek";
      repo = "duckstation";
      tag = "v${finalAttrs.version}";
      hash = pkgSources.duckstation.hash_linux;
    };

    vendorDiscordRPC = llvmPackages.stdenv.mkDerivation {
      pname = "discord-rpc-duckstation";
      inherit (finalAttrs) version;
      src = fetchFromGitHub {
        owner = "stenzek";
        repo = "discord-rpc";
        inherit (pkgSources.discord_rpc) rev hash;
      };
      nativeBuildInputs = [ cmake ];
      buildInputs = [ rapidjson ];
      meta = {
        license = lib.licenses.mit;
        platforms = lib.platforms.linux;
      };
    };

    vendorShaderc = shaderc.overrideAttrs (oldAttrs: {
      pname = "shaderc-duckstation";
      inherit (finalAttrs) version;
      src = fetchFromGitHub {
        owner = "stenzek";
        repo = "shaderc";
        inherit (pkgSources.shaderc) rev hash;
      };

      patches = (oldAttrs.patches or [ ]);
      cmakeFlags = (oldAttrs.cmakeFlags or [ ]) ++ [
        (lib.cmakeBool "SHADERC_SKIP_EXAMPLES" true)
        (lib.cmakeBool "SHADERC_SKIP_TESTS" true)
      ];
      outputs = [
        "out"
        "lib"
        "dev"
      ];
      postFixup = null;
    });

    soundtouch = llvmPackages.stdenv.mkDerivation {
      inherit (soundtouch)
        pname
        version
        src
        meta
        ;
      nativeBuildInputs = [ cmake ];
      postPatch = ''
        substituteInPlace CMakeLists.txt \
          --replace-fail "\''${prefix}/''${CMAKE_INSTALL_LIBDIR}" \
                         "''${CMAKE_INSTALL_FULL_LIBDIR}"
      '';

      cmakeFlags = [
        (lib.cmakeBool "SOUNDTOUCH_DLL" true)
      ];
    };

    chtdb = stdenvNoCC.mkDerivation {
      pname = "chtdb-duckstation";
      version = "0-unstable-${pkgSources.chtdb.date}";

      src = fetchFromGitHub {
        owner = "duckstation";
        repo = "chtdb";
        inherit (pkgSources.chtdb) rev hash;
      };

      nativeBuildInputs = [
        zip
      ];

      buildPhase = ''
        runHook preBuild

        pushd cheats
        zip -r cheats.zip *.cht
        popd
        pushd patches
        zip -r patches.zip *.cht
        popd

        runHook postBuild
      '';

      installPhase = ''
        runHook preInstall

        install -Dm644 cheats/cheats.zip -t $out/lib/duckstation
        install -Dm644 patches/patches.zip -t $out/lib/duckstation

        install -Dm644 LICENSE -t $out/share/doc/duckstation
        install -Dm644 README.md -t $out/share/doc/duckstation

        runHook postInstall
      '';

      meta = {
        description = "Collection of cheats and patches for PSX games";
        longDescription = ''
          Collection of cheats and patches for PSX games, primarily intended for
          use with the DuckStation emulator, but can also be used by other
          emulators that support GameShark codes.

          Patches show in the UI in a separate section to cheats, and are
          intended for modifications to the game that do not provide any
          "advantage" to the player, including:

          - Improving performance.
          - Fixing game-breaking bugs.
          - Unlocking the frame rate (e.g. "60 FPS patches").
          - Widescreen rendering where the built-in widescreen rendering rendering is insufficient.
        '';
        license = lib.licenses.mit;
        inherit (meta) maintainers;
        platforms = lib.platforms.all;
      };
    };

    preConfigure = ''
      cp ${finalAttrs.chtdb}/lib/duckstation/cheats.zip data/resources
      cp ${finalAttrs.chtdb}/lib/duckstation/patches.zip data/resources
    '';

    nativeBuildInputs = [
      cmake
      pkg-config
      ninja
      extra-cmake-modules
      wayland-scanner
      makeBinaryWrapper
      qt6.wrapQtAppsHook
      qt6.qttools
    ];

    buildInputs = [
      sdl3
      zstd
      libwebp
      zlib
      libpng
      libjpeg
      freetype
      plutosvg
      cpuinfo
      libzip
      curl
      libX11
      wayland
      spirv-cross
      qt6.qtbase
      udev
      libbacktrace
      ffmpeg-headless
      alsa-lib
      libjack2
      pipewire
      libpulseaudio
    ]
    ++ [
      finalAttrs.vendorDiscordRPC
      finalAttrs.vendorShaderc
      finalAttrs.soundtouch
    ];

    cmakeFlags = [
      (lib.cmakeBool "ALLOW_INSTALL" true)
      (lib.cmakeFeature "CMAKE_INSTALL_PREFIX" "${placeholder "out"}/lib/duckstation")
    ];

    postInstall = ''
      makeWrapper $out/lib/duckstation/duckstation-qt $out/bin/duckstation-qt

      mkdir -p $out/share/applications
      ln -s $out/lib/duckstation/resources/org.duckstation.DuckStation.desktop \
            $out/share/applications

      mkdir -p $out/share/icons/hicolor/512x512/apps
      ln -s $out/lib/duckstation/resources/org.duckstation.DuckStation.png \
            $out/share/icons/hicolor/512x512/apps

      pushd ..
      install -Dm644 LICENSE -t $out/share/doc/duckstation
      install -Dm644 README.* -t $out/share/doc/duckstation
      install -Dm644 CONTRIBUTORS.md -t $out/share/doc/duckstation
      popd
    '';

    inherit passthru;

    meta = meta // {
      mainProgram = "duckstation-qt";
      platforms = lib.platforms.linux;
    };
  });

  darwinDrv = stdenvNoCC.mkDerivation (finalAttrs: {
    pname = "duckstation";
    version = pkgSources.duckstation.version;

    src = fetchurl {
      url = "https://github.com/stenzek/duckstation/releases/download/v${finalAttrs.version}/duckstation-mac-release.zip";
      hash = pkgSources.duckstation.hash_darwin;
    };

    nativeBuildInputs = [ unzip ];

    dontPatch = true;
    dontConfigure = true;
    dontBuild = true;

    sourceRoot = ".";

    installPhase = ''
      runHook preInstall

      mkdir -p $out/Applications
      cp -r DuckStation.app $out/Applications/DuckStation.app

      runHook postInstall
    '';

    inherit passthru;

    meta = meta // {
      sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
      platforms = lib.platforms.darwin;
    };
  });
in
if stdenvNoCC.hostPlatform.isLinux then
  linuxDrv
else if stdenvNoCC.hostPlatform.isDarwin then
  darwinDrv
else
  throw "duckstation is not supported on ${stdenvNoCC.hostPlatform.system}."
+20 −0
Original line number Diff line number Diff line
{
  "duckstation": {
    "version": "0.1-9669",
    "hash_linux": "sha256-Q3vU4PaHMHzA8MTxLQbR++ND4L0iRMw6M7J74jyWBKI=",
    "hash_darwin": "sha256-qbY1xKqjYAoxU5EWSFRq8Quu3bZBHHsS8nqnLW3xT+k="
  },
  "discord_rpc": {
    "rev": "cc59d26d1d628fbd6527aac0ac1d6301f4978b92",
    "hash": "sha256-8xXcx5w36eiJqtWm6qQfhEHgchVJbhP/jR94eMNNjHU="
  },
  "shaderc": {
    "rev": "4daf9d466ad00897f755163dd26f528d14e1db44",
    "hash": "sha256-/o3LPYvMTlKhuvLQITnADmz8BTGXVaVR0aciOWVyFS8="
  },
  "chtdb": {
    "date": "2025-10-05",
    "rev": "eab12dde0ddfd03e1260d7111f2a0709144e047e",
    "hash": "sha256-wRk9BijV52BCcvpeq4CzhLsaWYYrt+vFvdMwlAixBvU="
  }
}
+77 −0
Original line number Diff line number Diff line
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p coreutils nix curl jq
# shellcheck shell=bash

set -euo pipefail
location="$(dirname "${BASH_SOURCE[0]}")"

echo "checking for new tagged release (github:stenzek/duckstation)..."
old_version=$(nix --extra-experimental-features nix-command eval --raw -f . duckstation.src.tag)
new_version=$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} "https://api.github.com/repos/stenzek/duckstation/tags?per_page=1" | jq -r '.[0].name')

if [[ $old_version == "$new_version" ]]; then
  echo "'duckstation' is up-to-date ($old_version == $new_version)"
  exit 0
fi

echo "Updating duckstation from $old_version -> $new_version"
duckstation_linux_hash=$(nix --extra-experimental-features "nix-command flakes" flake prefetch github:stenzek/duckstation/"$new_version" --json | jq -r '.hash')
duckstation_darwin_hash=$(nix-hash --to-sri --type sha256 "$(nix-prefetch-url --type sha256 "https://github.com/stenzek/duckstation/releases/download/${new_version}/duckstation-mac-release.zip")")

echo "Vendor library update..."
duckstation_storepath=$(nix --extra-experimental-features "nix-command flakes" flake prefetch github:stenzek/duckstation/"$new_version" --json | jq -r '.storePath')
pinned_versions=$duckstation_storepath/scripts/deps/versions

echo "Using pinned discord_rpc..."
discord_rpc_rev=$(grep "DISCORD_RPC=" "$pinned_versions" | sed 's|.*=||g')
discord_rpc_hash=$(nix --extra-experimental-features "nix-command flakes" \
  flake prefetch github:stenzek/discord-rpc/"$discord_rpc_rev" --json |
  jq -r '.hash')

echo "Using pinned shaderc..."
shaderc_rev=$(grep "SHADERC=" "$pinned_versions" | sed 's|.*=||g')
shaderc_hash=$(nix --extra-experimental-features "nix-command flakes" flake prefetch github:stenzek/shaderc/"$shaderc_rev" --json | jq -r '.hash')

echo "Fetching latest chtdb commit..."
chtdb_json=$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} "https://api.github.com/repos/duckstation/chtdb/commits?per_page=1")
chtdb_rev=$(echo "$chtdb_json" | jq -r '.[0].sha')
chtdb_date=$(echo "$chtdb_json" | jq -r '.[0].commit.author.date')
chtdb_hash=$(nix --extra-experimental-features "nix-command flakes" \
  flake prefetch github:duckstation/chtdb/"$chtdb_rev" --json |
  jq -r '.hash')

echo "Regenerating '""$location""/sources.json'"
JSON=$(
  jq --null-input \
    --arg new_version "${new_version:1}" \
    --arg duckstation_linux_hash "$duckstation_linux_hash" \
    --arg duckstation_darwin_hash "$duckstation_darwin_hash" \
    --arg discord_rpc_rev "$discord_rpc_rev" \
    --arg discord_rpc_hash "$discord_rpc_hash" \
    --arg shaderc_rev "$shaderc_rev" \
    --arg shaderc_hash "$shaderc_hash" \
    --arg chtdb_rev "$chtdb_rev" \
    --arg chtdb_date "${chtdb_date::10}" \
    --arg chtdb_hash "$chtdb_hash" \
    '{ "duckstation": {
             "version": $new_version,
             "hash_linux": $duckstation_linux_hash,
             "hash_darwin": $duckstation_darwin_hash
           },
           "discord_rpc": {
             "rev": $discord_rpc_rev,
             "hash": $discord_rpc_hash
           },
           "shaderc": {
             "rev": $shaderc_rev,
             "hash": $shaderc_hash
           },
           "chtdb": {
             "date": $chtdb_date,
             "rev": $chtdb_rev,
             "hash": $chtdb_hash
           }
        }'
)

echo "$JSON" | jq >"$location"/sources.json
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ stdenv.mkDerivation (finalAttrs: {
    python3
  ];

  cmakeFlags = lib.optionals stdenv.hostPlatform.isLinux [
    (lib.cmakeBool "SPIRV_CROSS_SHARED" true)
  ];

  postFixup = ''
    substituteInPlace $out/lib/pkgconfig/*.pc \
      --replace '=''${prefix}//' '=/'
Loading