diff --git a/pkgs/overlay.nix b/pkgs/overlay.nix index cad8642..b849a7e 100644 --- a/pkgs/overlay.nix +++ b/pkgs/overlay.nix @@ -35,4 +35,7 @@ final: prev: { ''; roms = final.callPackage ./roms {}; + + wrapRetroarch' = { retroarch, cores ? [ ], settings ? { } }: + final.callPackage ./wrap-retroarch.nix { inherit retroarch cores settings; }; } diff --git a/pkgs/roms/atetris.nix b/pkgs/roms/atetris.nix index 723c181..8ced6b0 100644 --- a/pkgs/roms/atetris.nix +++ b/pkgs/roms/atetris.nix @@ -1,8 +1,10 @@ -{mkRetroarchRom}: +{mkRetroarchRom, settings ? {}}: mkRetroarchRom { name = "atetris"; src = ./bin/atetris; + inherit settings; + emulator = ""; filename = "atetris.zip"; diff --git a/pkgs/roms/build/mkRetroarchRom.nix b/pkgs/roms/build/mkRetroarchRom.nix index 0fcd40d..e7be293 100644 --- a/pkgs/roms/build/mkRetroarchRom.nix +++ b/pkgs/roms/build/mkRetroarchRom.nix @@ -1,15 +1,17 @@ -{ mkRom , retroarchFull }: +{ mkRom , lib, symlinkJoin, libretro, stdenv, retroarchBare, retroarchFull, wrapRetroarch' }: { name , src , emulator , filename -, settings ? {} +, settings , meta }: let - retroarch = retroarchFull.override (prev: { - settings = prev.settings // settings; - }); + retroarch = wrapRetroarch' { + retroarch = retroarchBare; + cores = retroarchFull.cores; + inherit settings; + }; in mkRom ({ runtimeInputs = [ retroarch ]; diff --git a/pkgs/roms/dkong.nix b/pkgs/roms/dkong.nix index 5f8ca8c..67decae 100644 --- a/pkgs/roms/dkong.nix +++ b/pkgs/roms/dkong.nix @@ -1,8 +1,10 @@ -{mkRetroarchRom}: +{mkRetroarchRom, settings ? {}}: mkRetroarchRom { name = "dkong"; src = ./bin/dkong; + inherit settings; + emulator = "fbneo"; filename = "dkong.zip"; diff --git a/pkgs/roms/mario.nix b/pkgs/roms/mario.nix index 8ea0174..ed7a73e 100644 --- a/pkgs/roms/mario.nix +++ b/pkgs/roms/mario.nix @@ -1,8 +1,10 @@ -{mkRetroarchRom}: +{mkRetroarchRom, settings ? {}}: mkRetroarchRom { name = "mario"; src = ./bin/mario; + inherit settings; + emulator = "fbneo"; filename = "mario.zip"; diff --git a/pkgs/roms/neopong.nix b/pkgs/roms/neopong.nix index 3262b28..8aaa69c 100644 --- a/pkgs/roms/neopong.nix +++ b/pkgs/roms/neopong.nix @@ -1,8 +1,10 @@ -{mkRetroarchRom}: +{mkRetroarchRom, settings ? {}}: mkRetroarchRom { name = "neopong"; src = ./bin/neopong; + inherit settings; + emulator = "fbneo"; filename = "neopong.zip"; diff --git a/pkgs/roms/pacman.nix b/pkgs/roms/pacman.nix index f6d1f05..6654edc 100644 --- a/pkgs/roms/pacman.nix +++ b/pkgs/roms/pacman.nix @@ -1,8 +1,10 @@ -{mkRetroarchRom}: +{mkRetroarchRom, settings ? {}}: mkRetroarchRom { name = "pacman"; src = ./bin/pacman; + inherit settings; + emulator = "fbneo"; filename = "pacman.zip"; diff --git a/pkgs/roms/spacedx.nix b/pkgs/roms/spacedx.nix index dd72506..e5af349 100644 --- a/pkgs/roms/spacedx.nix +++ b/pkgs/roms/spacedx.nix @@ -1,8 +1,10 @@ -{mkRetroarchRom}: +{mkRetroarchRom, settings ? {}}: mkRetroarchRom { name = "spacedx"; src = ./bin/spacedx; + inherit settings; + emulator = "fbneo"; filename = "spacedx.zip"; diff --git a/pkgs/wrap-retroarch.nix b/pkgs/wrap-retroarch.nix new file mode 100644 index 0000000..1abf718 --- /dev/null +++ b/pkgs/wrap-retroarch.nix @@ -0,0 +1,60 @@ +{ lib +, stdenv +, makeWrapper +, symlinkJoin +, runCommand +, retroarch +, cores ? [ ] +, settings ? { } +}: + +let + settings' = { libretro_directory = coresPath; } // settings; + settingsPath = runCommand "declarative-retroarch.cfg" + { + value = lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: "${n} = \"${v}\"") settings); + passAsFile = [ "value" ]; + } + '' + cp "$valuePath" "$out" + ''; + coresPath = let + path = assert + lib.assertMsg (builtins.length (map (c: c.libretroCore) cores) == 1) + "Libretro cores are not under the same paths"; + (builtins.head cores).libretroCore; + in + symlinkJoin { + name = "retroarch-cores"; + paths = cores; + } + path; + wrapperArgs = lib.strings.escapeShellArgs [ "--add-flags" "--config=${settingsPath}" ]; +in +symlinkJoin { + name = "retroarch-with-cores-${lib.getVersion retroarch}"; + + paths = [ retroarch ]; + + nativeBuildInputs = [ makeWrapper ]; + + passthru = { + inherit cores; + unwrapped = retroarch; + }; + + postBuild = '' + # wrap binary to load cores from the proper location(s) + wrapProgram $out/bin/retroarch ${wrapperArgs} + ''; + + meta = with retroarch.meta; { + inherit changelog description homepage license maintainers platforms; + longDescription = '' + RetroArch is the reference frontend for the libretro API. + '' + + lib.optionalString (cores != [ ]) '' + The following cores are included: ${lib.concatStringsSep ", " (map (c: c.core) cores)} + ''; + mainProgram = "retroarch"; + }; +}