This commit is contained in:
mjallen18
2026-03-15 19:40:42 -05:00
parent 2fbb4d1f1b
commit 3c54fd5412
4 changed files with 793 additions and 152 deletions

View File

@@ -12,9 +12,28 @@ let
cfg = config.programs.steam-rom-manager;
# Single source of truth for built-in emulator metadata (package, romFolder,
# fileTypes). options.nix imports the same file so both files stay in sync.
# fileTypes, executableArgs, steamCategory, parserInputs).
# options.nix imports the same file so both files stay in sync.
knownEmulators = import ./emulators.nix pkgs;
# Parser types that do not scan ROM files and have no executable path.
platformParserTypes = [
"Epic"
"Legendary"
"GOG Galaxy"
"Amazon Games"
"UPlay"
"itch.io"
"UWP"
"EA Desktop"
"Battle.net"
"Non-SRM Shortcuts"
"Steam"
"Manual"
];
isPlatformParser = type: builtins.elem type platformParserTypes;
# ---------------------------------------------------------------------------
# Build an ordered JSON object for one parser entry.
# SRM requires keys in a specific order; builtins.toJSON does not guarantee
@@ -27,24 +46,50 @@ let
name: emu:
let
known = knownEmulators.${name} or null;
parserType = emu.parserType;
platform = isPlatformParser parserType;
romFolder =
if emu.romFolder != "" then
emu.romFolder
else if known != null then
else if known != null && known ? romFolder then
known.romFolder
else
lib.warn "steam-rom-manager: unknown emulator '${name}', romFolder not set" "";
fileTypes =
if emu.fileTypes != [ ] then
emu.fileTypes
else if known != null then
else if known != null && known ? fileTypes then
known.fileTypes
else
lib.warn "steam-rom-manager: unknown emulator '${name}', fileTypes not set" [ ];
parserType = emu.parserType;
[ ];
# lib.getExe resolves the primary binary without IFD path probing.
exePath = lib.getExe emu.package;
# For platform parsers there is no executable; use empty string.
exePath =
if platform then
""
else if emu.package != null then
lib.getExe emu.package
else
"";
# Build parserInputs: for Glob/Glob-regex parsers always include the
# generated glob key; merge any extra user-supplied inputs on top.
globKey =
if parserType == "Glob" then
"glob"
else if parserType == "Glob-regex" then
"glob-regex"
else
null;
globPattern =
if globKey != null && fileTypes != [ ] then
{ ${globKey} = "\${title}@(${lib.concatStringsSep "|" fileTypes})"; }
else
{ };
resolvedParserInputs = globPattern // emu.parserInputs;
orderedConfig = [
{
@@ -61,7 +106,7 @@ let
}
{
name = "romDirectory";
value = "${cfg.environmentVariables.romsDirectory}/${romFolder}";
value = if platform then "" else "${cfg.environmentVariables.romsDirectory}/${romFolder}";
}
{
name = "steamCategories";
@@ -69,7 +114,7 @@ let
}
{
name = "executableArgs";
value = emu.extraArgs;
value = if platform then "" else emu.extraArgs;
}
{
name = "executableModifier";
@@ -77,15 +122,15 @@ let
}
{
name = "startInDirectory";
value = "${cfg.environmentVariables.romsDirectory}/${romFolder}";
value = if platform then "" else "${cfg.environmentVariables.romsDirectory}/${romFolder}";
}
{
name = "titleModifier";
value = emu.titleModifier;
}
# fetchControllerTemplatesButton / removeControllersButton are UI-only
# action triggers in SRM; they have no meaningful config value and must
# be present as null for schema compatibility.
# action triggers in SRM; they carry no config value and must be null
# for schema compatibility.
{
name = "fetchControllerTemplatesButton";
value = null;
@@ -122,9 +167,7 @@ let
}
{
name = "parserInputs";
value = {
glob = "\${title}@(${lib.concatStringsSep "|" fileTypes})";
};
value = resolvedParserInputs;
}
{
name = "executable";
@@ -192,6 +235,10 @@ let
icon = "";
};
}
{
name = "disabled";
value = emu.disabled;
}
{
name = "parserId";
value = name;
@@ -239,6 +286,10 @@ let
} "$@"
'';
# Collect only enabled emulators that have a non-null package (i.e. not
# pure platform parsers like Epic/GOG that need no extra Nix package).
enabledEmulatorsWithPackage = lib.filterAttrs (_: v: v.enable && v.package != null) cfg.emulators;
in
{
imports = [ ./options.nix ];
@@ -249,7 +300,7 @@ in
pkgs.appimage-run
steam-rom-manager-appimage
]
++ lib.mapAttrsToList (_: v: v.package) (lib.filterAttrs (_: v: v.enable) cfg.emulators);
++ lib.mapAttrsToList (_: v: v.package) enabledEmulatorsWithPackage;
xdg.dataFile."icons/hicolor/scalable/apps/steam-rom-manager.svg".source = steam-rom-manager-icon;