From 52e82b0b04df1abc6f612ba7ef2ecd95eb69a356 Mon Sep 17 00:00:00 2001 From: WheelsForReals Date: Sat, 28 Jun 2025 15:54:06 -0500 Subject: [PATCH] parallel-launcher: init at 8.2.0 --- .../pa/parallel-launcher/fix-paths.patch | 71 ++++++++ .../fix-version-checks.patch | 92 ++++++++++ pkgs/by-name/pa/parallel-launcher/package.nix | 164 ++++++++++++++++++ .../parallel-launcher/parallel-n64-next.nix | 75 ++++++++ pkgs/by-name/pa/parallel-launcher/update.sh | 26 +++ 5 files changed, 428 insertions(+) create mode 100644 pkgs/by-name/pa/parallel-launcher/fix-paths.patch create mode 100644 pkgs/by-name/pa/parallel-launcher/fix-version-checks.patch create mode 100644 pkgs/by-name/pa/parallel-launcher/package.nix create mode 100644 pkgs/by-name/pa/parallel-launcher/parallel-n64-next.nix create mode 100755 pkgs/by-name/pa/parallel-launcher/update.sh diff --git a/pkgs/by-name/pa/parallel-launcher/fix-paths.patch b/pkgs/by-name/pa/parallel-launcher/fix-paths.patch new file mode 100644 index 000000000000..26dc04767845 --- /dev/null +++ b/pkgs/by-name/pa/parallel-launcher/fix-paths.patch @@ -0,0 +1,71 @@ +diff --git a/src/core/retroarch.cpp b/src/core/retroarch.cpp +index c2a2c47..97fa782 100644 +--- a/src/core/retroarch.cpp ++++ b/src/core/retroarch.cpp +@@ -102,7 +102,7 @@ static void loadConfig( std::map &configs ) { + + const fs::path basePath = RetroArch::getBasePath(); + configs["system_directory"] = (basePath / _NFS("system")).u8string(); +- configs["libretro_directory"] = (basePath / _NFS("cores")).u8string(); ++ configs["libretro_directory"] = "@retroArchCoresPath@"; + configs["savefile_directory"] = (basePath / _NFS("saves")).u8string(); + configs["savestate_directory"] = (basePath / _NFS("states")).u8string(); + configs["libretro_info_path"] = (basePath / _NFS("info")).u8string(); +@@ -110,7 +110,7 @@ static void loadConfig( std::map &configs ) { + #if defined(FLATPAK_VERSION) + configs["assets_directory"] = "/app/share/libretro/assets/"; + #elif defined(__linux__) +- configs["assets_directory"] = (BaseDir::data() / "retro-data" / "assets").u8string(); ++ configs["assets_directory"] = "@retroArchAssetsPath@";; + configs["osk_overlay_directory"] = (BaseDir::data() / "retro-data" / "overlays" / "keyboards").u8string(); + configs["overlay_directory"] = (BaseDir::data() / "retro-data" / "overlays").u8string(); + configs["audio_filter_dir"] = (BaseDir::data() / "retro-data" / "filters" / "audio").u8string(); +@@ -845,13 +845,7 @@ fs::path RetroArch::getBasePath() { + } + + fs::path RetroArch::getCorePath() { +-#if defined(_WIN32) +- return RetroArch::getBasePath() / L"cores" / L"parallel_n64_next_libretro.dll"; +-#elif defined(__APPLE__) +- return RetroArch::getBasePath() / "cores" / "parallel_n64_next_libretro.dylib"; +-#else +- return RetroArch::getBasePath() / "cores" / "parallel_n64_next_libretro.so"; +-#endif ++ return "@parallelN64CorePath@"; + } + + fs::path RetroArch::getConfigPath() { +@@ -866,7 +860,7 @@ fs::path RetroArch::getExePath() { + #elif defined(FLATPAK_VERSION) + return BaseDir::program() / "retroarch"; + #else +- return BaseDir::data() / "appimage" / "RetroArch-Linux-x86_64.AppImage"; ++ return "@retroArchExePath@"; + #endif + } + +diff --git a/src/main.cpp b/src/main.cpp +index 3ca39b2..f3c14ba 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -200,6 +200,7 @@ int main( int argc, char **argv ) { + fs::path( "/usr/local/share/parallel-launcher/translations/" ), + fs::path( "/usr/share/parallel-launcher/translations/" ) + #else ++ fs::read_symlink( "/proc/self/exe" ).parent_path().parent_path() / "share/parallel-launcher/translations/", + fs::path( "/usr/share/parallel-launcher/translations/" ), + fs::path( "/usr/local/share/parallel-launcher/translations/" ), + BaseDir::program() / "lang" +diff --git a/src/polyfill/base-directory.cpp b/src/polyfill/base-directory.cpp +index 720a754..db607ca 100644 +--- a/src/polyfill/base-directory.cpp ++++ b/src/polyfill/base-directory.cpp +@@ -134,7 +134,7 @@ static Locations getLocations() { + #if defined(FLATPAK_VERSION) + fs::path( "/app/share/parallel-launcher" ) + #elif defined(__linux__) +- fs::path( "/usr/share/parallel-launcher" ) ++ fs::read_symlink( "/proc/self/exe" ).parent_path().parent_path() / "share/parallel-launcher" + #endif + }; + } diff --git a/pkgs/by-name/pa/parallel-launcher/fix-version-checks.patch b/pkgs/by-name/pa/parallel-launcher/fix-version-checks.patch new file mode 100644 index 000000000000..92c9974a27dc --- /dev/null +++ b/pkgs/by-name/pa/parallel-launcher/fix-version-checks.patch @@ -0,0 +1,92 @@ +diff --git a/src/core/updates.cpp b/src/core/updates.cpp +index 403290b..f7d6547 100644 +--- a/src/core/updates.cpp ++++ b/src/core/updates.cpp +@@ -30,8 +30,8 @@ + #endif + + const InstalledVersionsInfo InstalledVersionsInfo::Default { +- /* retroArchVersion */ RetroArchVersion{ Version{ 0, 0, 0 }, false }, +- /* parallelVersion */ Version{ 0, 0, 0 }, ++ /* retroArchVersion */ RetroArchVersion{ Version{ @retroArchVersion@ }, true }, ++ /* parallelVersion */ Version{ @parallelN64CoreVersion@ }, + /* lastUpdateCheck */ 0 + }; + +@@ -47,15 +47,7 @@ template<> void JsonSerializer::serialize( JsonWriter &jw, con + } + + template<> RetroArchVersion JsonSerializer::parse( const Json &json ) { +- Version version = Version{ 0, 0, 0 }; +- if( json[P_VERSION].exists() ) { +- version = parse( json[P_VERSION] ); +- } +- +- return RetroArchVersion { +- version, +- json[P_LOCK].getOrDefault( false ) +- }; ++ return InstalledVersionsInfo::Default.retroArchVersion; + } + + static constexpr char P_RETROARCH[] = "retroarch"; +@@ -73,47 +65,14 @@ template<> void JsonSerializer::serialize( JsonWriter &jw + } + + template<> InstalledVersionsInfo JsonSerializer::parse( const Json &json ) { +- Version parallelVersion; +- try { +- parallelVersion = parse( json[P_PARALLEL] ); +- } catch( ... ) { +- parallelVersion = { 0, 0, 0 }; +- } +- +- RetroArchVersion retroVersion; +- try { +- retroVersion = parse( json[P_RETROARCH] ); +- } catch( ... ) { +- retroVersion = RetroArchVersion{ Version{ 0, 0, 0 }, false }; +- } +- +- return InstalledVersionsInfo { +- retroVersion, +- parallelVersion, +- json[P_LAST_CHECKED].get() +- }; ++ return InstalledVersionsInfo::Default; + } + + template<> ParallelCoreVersion JsonSerializer::parse( const Json &json ) { +-#if defined(__linux__) +- const Json &vjson = json["linux_x64"]; +-#elif defined(_WIN32) +- #ifdef _WIN64 +- const Json &vjson = json["windows_x64"]; +- #else +- const Json &vjson = json["windows_x86"]; +- #endif +-#elif defined(__APPLE__) +- const Json &vjson = AppleUtil::shouldUseArmCore() ? json["macos_arm64"] : json["macos_x64"]; +-#else +- const Json &vjson = json; +- static_assert( false ); +-#endif +- + return ParallelCoreVersion{ +- JsonSerializer::parse( vjson["version"] ), +- vjson["sha1"].get(), +- vjson["url"].get() ++ InstalledVersionsInfo::Default.parallelVersion, ++ "", ++ "" + }; + } + +@@ -178,6 +137,7 @@ void RetroUpdater::checkForUpdates( + bool waitForCoreUpdates, + bool forceUpdate + ) { ++ return; + InstalledVersionsInfo installedVersions = FileController::loadInstalledVersions(); + + if( forceUpdate || checkSchedule( installedVersions ) ) { diff --git a/pkgs/by-name/pa/parallel-launcher/package.nix b/pkgs/by-name/pa/parallel-launcher/package.nix new file mode 100644 index 000000000000..e73bd73c266c --- /dev/null +++ b/pkgs/by-name/pa/parallel-launcher/package.nix @@ -0,0 +1,164 @@ +{ + lib, + stdenv, + callPackage, + fetchFromGitLab, + replaceVars, + qt5, + SDL2, + discord-rpc, + libgcrypt, + sqlite, + findutils, + xdg-utils, + coreutils, + dosfstools, + vulkan-loader, + wrapRetroArch, + retroarch-assets, + parallel-launcher, + # Allow overrides for the RetroArch core and declarative settings + parallel-n64-core ? parallel-launcher.passthru.parallel-n64-core, + extraRetroArchSettings ? { }, +}: +let + # Converts a version string like x.y.z to vx.y-z + reformatVersion = v: "v${lib.versions.majorMinor v}-${lib.versions.patch v}"; + + # Converts a version string like x.y.z to x, y, z + reformatVersion' = lib.replaceStrings [ "." ] [ ", " ]; + + retroArchAssetsPath = "${retroarch-assets}/share/retroarch/assets"; +in +stdenv.mkDerivation ( + finalAttrs: + let + retroarch' = wrapRetroArch { + cores = [ + parallel-n64-core + ]; + + # These settings take precedence over those supplied by user config files + settings = { + # Override the wrapper's libretro_info_path because that path doesn't + # have any information about Parallel Launcher's parallel-n64 core fork. + # Upstream provides this information in their own *.info files in $src/data. + # Save states with the parallel-n64 core will not work without this. + libretro_info_path = "${finalAttrs.src}/data"; + assets_directory = retroArchAssetsPath; + } // extraRetroArchSettings; + }; + in + { + pname = "parallel-launcher"; + version = "8.2.0"; # Check ./parallel-n64-next.nix for updates when updating, too + + src = fetchFromGitLab { + owner = "parallel-launcher"; + repo = "parallel-launcher"; + tag = reformatVersion finalAttrs.version; + hash = "sha256-G1ob2Aq/PE12jNO2YnlCdL9SWELj0Mf/vmr7dzNv550="; + }; + + patches = + let + retroArchCoresPath = "${retroarch'}/lib/retroarch/cores"; + suffix = stdenv.hostPlatform.extensions.sharedLibrary; + in + [ + # Fix FHS path assumptions + (replaceVars ./fix-paths.patch { + inherit retroArchAssetsPath retroArchCoresPath; + retroArchExePath = lib.getExe retroarch'; + parallelN64CorePath = "${retroArchCoresPath}/parallel_n64_next_libretro${suffix}"; + }) + # Bypass update checks and hardcode internal version checks to ours + (replaceVars ./fix-version-checks.patch { + retroArchVersion = reformatVersion' (lib.getVersion retroarch'); + parallelN64CoreVersion = reformatVersion' (lib.getVersion parallel-n64-core); + }) + ]; + + nativeBuildInputs = [ + qt5.wrapQtAppsHook + qt5.qttools + qt5.qmake + ]; + + buildInputs = [ + SDL2 + discord-rpc + libgcrypt + sqlite + qt5.qtbase + qt5.qtsvg + ]; + + qtWrapperArgs = [ + "--prefix PATH : ${ + lib.makeBinPath [ + findutils + xdg-utils + coreutils + dosfstools + ] + }" + "--prefix LD_LIBRARY_PATH : ${ + lib.makeLibraryPath [ + vulkan-loader + ] + }" + ]; + + # Our patches result in unused params. + # Ignoring the warning is easier to maintain than more invasive patching. + env.NIX_CFLAGS_COMPILE = "-Wno-error=unused-parameter"; + + preConfigure = '' + lrelease app.pro + ''; + + installPhase = '' + runHook preInstall + + # Taken from pkg/arch/PKGBUILD + install -D parallel-launcher -t $out/bin + install -D ca.parallel_launcher.ParallelLauncher.desktop -t $out/share/applications + install -D ca.parallel_launcher.ParallelLauncher.metainfo.xml -t $out/share/metainfo + install -D data/appicon.svg $out/share/icons/hicolor/scalable/apps/ca.parallel_launcher.ParallelLauncher.svg + install -D bps-mime.xml parallel-launcher-{lsjs,sdl-relay} -t $out/share/parallel-launcher + install -D lang/*.qm -t $out/share/parallel-launcher/translations + + runHook postInstall + ''; + + passthru = { + parallel-n64-core = callPackage ./parallel-n64-next.nix { }; + updateScript = { + command = ./update.sh; + supportedFeatures = [ "commit" ]; + }; + }; + + meta = { + description = "Modern N64 Emulator"; + longDescription = '' + Parallel Launcher is an emulator launcher that aims to make playing N64 games, + both retail and homebrew, as simple and as accessible as possible. Parallel + Launcher uses the RetroArch emulator, but replaces its confusing menus and + controller setup with a much simpler user interface. It also features optional + integration with romhacking.com. + ''; + homepage = "https://parallel-launcher.ca"; + changelog = "https://gitlab.com/parallel-launcher/parallel-launcher/-/releases/${finalAttrs.src.tag}"; + # Theoretically, platforms should be the intersection of what upstream supports, + # what nixpkgs RetroArch supports, and what the RetroArch core supports + platforms = [ "x86_64-linux" ]; + license = lib.licenses.gpl3Plus; + maintainers = with lib.maintainers; [ + WheelsForReals + ]; + mainProgram = "parallel-launcher"; + }; + } +) diff --git a/pkgs/by-name/pa/parallel-launcher/parallel-n64-next.nix b/pkgs/by-name/pa/parallel-launcher/parallel-n64-next.nix new file mode 100644 index 000000000000..00a4a5d8ef1c --- /dev/null +++ b/pkgs/by-name/pa/parallel-launcher/parallel-n64-next.nix @@ -0,0 +1,75 @@ +{ + lib, + stdenv, + fetchFromGitLab, + pkg-config, + libGLU, + libGL, + libpng, + libretro, +}: +let + # Converts a version string like x.y.z to vx.y-z + reformatVersion = v: "v${lib.versions.majorMinor v}-${lib.versions.patch v}"; +in +# Based on the libretro parallel-n64 derivation with slight tweaks +libretro.mkLibretroCore (finalAttrs: { + core = "parallel-n64-next"; + version = "2.24.1"; + + src = fetchFromGitLab { + owner = "parallel-launcher"; + repo = "parallel-n64"; + tag = reformatVersion finalAttrs.version; + hash = "sha256-BeeKX78zozxx72cmJ3HI0nH/STvkltMBZs2+mb4ukM0="; + }; + + extraNativeBuildInputs = [ + pkg-config + ]; + + extraBuildInputs = [ + libGLU + libGL + libpng + ]; + + makefile = "Makefile"; + + makeFlags = [ + "HAVE_PARALLEL=1" + "HAVE_PARALLEL_RSP=1" + "HAVE_THR_AL=1" + "SYSTEM_LIBPNG=1" + "SYSTEM_ZLIB=1" + "ARCH=${stdenv.hostPlatform.parsed.cpu.name}" + ]; + + postPatch = lib.optionalString stdenv.hostPlatform.isAarch64 '' + sed -i -e '1 i\CPUFLAGS += -DARM_FIX -DNO_ASM -DARM_ASM -DDONT_WANT_ARM_OPTIMIZATIONS -DARM64' Makefile \ + && sed -i -e 's,CPUFLAGS :=,,g' Makefile + ''; + + preInstall = + let + suffix = stdenv.hostPlatform.extensions.sharedLibrary; + in + '' + mv parallel_n64_libretro${suffix} parallel_n64_next_libretro${suffix} + ''; + + passthru.updateScript = { }; + + meta = { + description = "Fork of libretro's parallel-n64 core designed to be used with Parallel Launcher."; + homepage = "https://gitlab.com/parallel-launcher/parallel-n64"; + license = lib.licenses.gpl3Only; + teams = [ ]; + maintainers = with lib.maintainers; [ + WheelsForReals + ]; + badPlatforms = [ + "aarch64-linux" + ]; + }; +}) diff --git a/pkgs/by-name/pa/parallel-launcher/update.sh b/pkgs/by-name/pa/parallel-launcher/update.sh new file mode 100755 index 000000000000..0821a87454a7 --- /dev/null +++ b/pkgs/by-name/pa/parallel-launcher/update.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p curl jq gnused common-updater-scripts + +set -euo pipefail + +nixpkgs=$(git rev-parse --show-toplevel) +packageDir="$nixpkgs/pkgs/by-name/pa/parallel-launcher" + +getLatestVersion() { + curl -s "https://gitlab.com/api/v4/projects/parallel-launcher%2F$1/repository/tags" \ + | jq -r '.[0] | select(.) | .name' \ + | sed 's|v||' \ + | sed 's|-|.|' +} + +updateSourceVersion() { + update-source-version "$1" "$2" --file="$3" --print-changes +} + +latestLauncherVersion=$(getLatestVersion parallel-launcher) +latestCoreVersion=$(getLatestVersion parallel-n64) + +launcherUpdate=$(updateSourceVersion parallel-launcher "$latestLauncherVersion" "$packageDir/package.nix") +coreUpdate=$(updateSourceVersion parallel-launcher.parallel-n64-core "$latestCoreVersion" "$packageDir/parallel-n64-next.nix") + +echo '[]' | jq ". += $launcherUpdate + $coreUpdate"