189 lines
4.5 KiB
Nix
189 lines
4.5 KiB
Nix
{ lib, config, pkgs, ... }:
|
|
let
|
|
t = v: builtins.trace v v;
|
|
filterAttrs' = l: lib.filterAttrs (v: _: builtins.elem v l);
|
|
cfg = config.retronix.emulationstation;
|
|
|
|
attrToXml = attrs: lib.concatLines (lib.mapAttrsToList (k: v: "<${k}>${builtins.toString v}</${k}>") attrs);
|
|
|
|
gameTemplate = args: let
|
|
attr = [
|
|
"path"
|
|
"name"
|
|
"desc"
|
|
"image"
|
|
"thumbnail"
|
|
"video"
|
|
"rating"
|
|
"releasedate"
|
|
"developer"
|
|
"publisher"
|
|
"genre"
|
|
"players"
|
|
"sortname"
|
|
];
|
|
in ''
|
|
<game>
|
|
${attrToXml (filterAttrs' attr args)}
|
|
</game>
|
|
'';
|
|
|
|
systemTemplate = args: let
|
|
attr = [
|
|
"name"
|
|
"fullname"
|
|
"path"
|
|
"extension"
|
|
"command"
|
|
"platform"
|
|
"theme"
|
|
];
|
|
in ''
|
|
<system>
|
|
${attrToXml (filterAttrs' attr args)}
|
|
</system>
|
|
'';
|
|
|
|
mkSystemPath = name: games: let
|
|
gamelist = ''
|
|
<?xml version="1.0"?>
|
|
<gameList>
|
|
${lib.concatLines (builtins.map gameTemplate games)}
|
|
</gameList>
|
|
'';
|
|
symlinkCommands = builtins.map (
|
|
v: "ln -s ${v.src} $out/${v.filename}"
|
|
) games;
|
|
|
|
in pkgs.runCommand "${name}-roms" {
|
|
inherit gamelist symlinkCommands;
|
|
passAsFile = [
|
|
"gamelist"
|
|
];
|
|
} ''
|
|
mkdir -p $out
|
|
cp $gamelistPath $out/gamelist.xml
|
|
substituteInPlace $out/gamelist.xml --subst-var out
|
|
|
|
${lib.concatLines symlinkCommands}
|
|
'';
|
|
|
|
sectionOptions = lib.types.submodule ({config, name, ...}: {
|
|
freeformType = with lib.types; attrsOf str;
|
|
options = {
|
|
name = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = name;
|
|
};
|
|
fullname = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = name;
|
|
};
|
|
path = lib.mkOption { # TODO: check it works
|
|
type = lib.types.path;
|
|
};
|
|
command = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "echo \"Hello world !\"";
|
|
};
|
|
extension = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = ".zip";
|
|
};
|
|
games = lib.mkOption {
|
|
type = lib.types.listOf gameOptions;
|
|
description = "Takes attributes of `games` tag in gamelist.xml";
|
|
};
|
|
};
|
|
config = {
|
|
path = mkSystemPath config.name config.games;
|
|
};
|
|
});
|
|
|
|
gameOptions = lib.types.submodule ({config, name, ... }: {
|
|
freeformType = with lib.types; attrsOf str;
|
|
options = {
|
|
src = lib.mkOption {
|
|
type = lib.types.path;
|
|
};
|
|
name = lib.mkOption {
|
|
type = lib.types.str;
|
|
};
|
|
desc = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "";
|
|
};
|
|
path = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "@out@/${config.filename}";
|
|
};
|
|
filename = lib.mkOption {
|
|
type = lib.types.str;
|
|
};
|
|
};
|
|
});
|
|
in {
|
|
options = {
|
|
retronix.emulationstation = {
|
|
systems = lib.mkOption {
|
|
type = lib.types.attrsOf (sectionOptions);
|
|
default = {};
|
|
};
|
|
systemCfgFile = lib.mkOption {
|
|
type = lib.types.path;
|
|
};
|
|
inputCfgFile = lib.mkOption {
|
|
type = lib.types.path;
|
|
};
|
|
systemsDir = lib.mkOption {
|
|
internal = true;
|
|
type = lib.types.path;
|
|
description = "Directory containing the symlinks to roms and gamelists.xml files";
|
|
};
|
|
themesDir = lib.mkOption {
|
|
type = lib.types.path;
|
|
};
|
|
inputCfg = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "";
|
|
};
|
|
homeDir = lib.mkOption {
|
|
internal = true;
|
|
type = lib.types.path;
|
|
};
|
|
extraConfigFiles = lib.mkOption {
|
|
type = with lib.types; listOf path;
|
|
default = [];
|
|
description = ''
|
|
Must be store paths.
|
|
Directory structure will be merged.
|
|
Must contain .emulationstation folder
|
|
'';
|
|
};
|
|
cli = lib.mkOption {
|
|
type = lib.types.str;
|
|
};
|
|
};
|
|
};
|
|
config = {
|
|
|
|
retronix.emulationstation = {
|
|
systemCfgFile = writeESDir "es_systems.cfg" ''
|
|
<?xml version="1.0"?>
|
|
<systemList>
|
|
${lib.concatLines (lib.mapAttrsToList (_: systemTemplate) cfg.systems)}
|
|
</systemList>
|
|
'';
|
|
inputCfgFile = lib.mkDefault (writeTextDir "es_input.cfg" cfg.inputCfg);
|
|
homeDir = pkgs.symlinkJoinSubDir {
|
|
name = "es-config-dir";
|
|
paths = [
|
|
cfg.systemCfgFile
|
|
cfg.inputCfgFile
|
|
] ++ cfg.extraConfigFiles;
|
|
};
|
|
cli = t "${pkgs.emulationstation}/bin/emulationstation --home ${cfg.homeDir}";
|
|
};
|
|
};
|
|
|
|
}
|