Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/DLSSUpdater/Core/AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ public void Save()
[JsonSerializable(typeof(NrVersion))]
[JsonSerializable(typeof(AddonBuild))]
[JsonSerializable(typeof(HdrBuild))]
[JsonSerializable(typeof(LumaBuild))]
[JsonSerializable(typeof(TechOverride))]
[JsonSerializable(typeof(LimiterBuild))]
[JsonSerializable(typeof(ReShadeBuild))]
Expand Down
4 changes: 3 additions & 1 deletion src/DLSSUpdater/Core/BuildLibrary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace DLSSUpdater.Core;
/// Every library of kept builds: the downloaded OptiScaler and GITC Uplift releases, the imported add-ons and the NR runtime.
/// Each keeps several builds side by side; settings choose a default and each game may choose its own.
/// </summary>
public enum LibraryKind { OptiScaler, Uplift, Lecram, RenoDx, Dfc, DlssNr, RenoDxHdr, ReShade, FrameLimiter, Feeder, Dxvk }
public enum LibraryKind { OptiScaler, Uplift, Lecram, RenoDx, Dfc, DlssNr, RenoDxHdr, ReShade, FrameLimiter, Feeder, Dxvk, Luma }

/// <summary>
/// One kept build as the lists and the cleanup see it. <see cref="Id"/> is what settings, game picks and install records name
Expand Down Expand Up @@ -174,6 +174,7 @@ public sealed partial class ComponentStore
LibraryKind.OptiScaler => ReleaseBuilds(Component.OptiScaler),
LibraryKind.Uplift => ReleaseBuilds(Component.Uplift),
LibraryKind.RenoDxHdr => HdrLibraryBuilds(),
LibraryKind.Luma => LumaLibraryBuilds(),
LibraryKind.FrameLimiter => LimiterLibraryBuilds(),
LibraryKind.ReShade => ReShadeBuilds.Select(b => new LibraryBuild(kind, b.Id, b.Label, b.Version, b.Added, ReShadeBuildDir(b), Downloaded: b.Downloaded)).ToList(),
LibraryKind.Feeder => FeederLibrary.Builds(),
Expand Down Expand Up @@ -574,6 +575,7 @@ public long RunCleanup(IEnumerable<CleanupItem> items)
ReleasesChanged();
foreach (var kind in Enum.GetValues<AddonKind>()) ForgetAddons(kind);
ForgetHdr();
ForgetLuma();
ForgetLimiters();
ForgetReShade();
if (count > 0) Log.Info($"Cleanup freed {BuildCleanup.FormatBytes(freed)} ({count} item(s))");
Expand Down
71 changes: 71 additions & 0 deletions src/DLSSUpdater/Core/CatalogLuma.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace DLSSUpdater.Core;

/// <summary>
/// The catalog's <c>luma</c> section: the Luma Framework (Filoppi/Luma-Framework) mods the wiki lists, the generic Unreal Engine mod
/// with its game table, and the pinned release zips. The licence is NOASSERTION, so the files are the author's own URLs plus a hash.
/// </summary>
public sealed class CatalogLuma
{
public string? Updated { get; set; }
/// <summary>The upstream release tag the zips come from ("latest-755").</summary>
public string Release { get; set; } = "";
public List<CatalogLumaPackage> Packages { get; set; } = [];
public List<CatalogLumaMod> Mods { get; set; } = [];
/// <summary>Id of the package that is the generic Unreal Engine mod.</summary>
public string UnrealPackage { get; set; } = "Unreal_Engine";
public List<CatalogLumaUnrealGame> UnrealGames { get; set; } = [];

public CatalogLumaPackage? PackageOf(string? id) =>
id is null ? null : Packages.FirstOrDefault(p => p.Id.Equals(id, StringComparison.OrdinalIgnoreCase));
}

/// <summary>One release zip: a file per bitness (<c>x64</c> = Luma-&lt;id&gt;.zip, <c>x86</c> = Luma-&lt;id&gt;-x32.zip).</summary>
public sealed class CatalogLumaPackage
{
public string Id { get; set; } = "";
public List<CatalogBinary> Files { get; set; } = [];

/// <summary>
/// The file for a game of <paramref name="bits"/> (32, 64, or 0 when the exe couldn't be read: x64 first, else x86). Only files with
/// a hash count.
/// </summary>
public CatalogBinary? FileFor(int bits)
{
var usable = Files.Where(f => f.IsInstallable).ToList();
CatalogBinary? Of(string arch) => usable.FirstOrDefault(f => f.Arch.Equals(arch, StringComparison.OrdinalIgnoreCase));
return bits switch { 32 => Of("x86"), 64 => Of("x64"), _ => Of("x64") ?? Of("x86") };
}
}

public sealed class CatalogLumaMod
{
public string Id { get; set; } = "";
public string Name { get; set; } = "";
public List<string> Authors { get; set; } = [];
/// <summary>"working", "in-progress", or null for a release zip the wiki doesn't list.</summary>
public string? Status { get; set; }
public string? Notes { get; set; }
public CatalogLinks? Links { get; set; }
/// <summary>The package the mod is in; null when the author publishes it elsewhere (Nexus Mods).</summary>
public string? Package { get; set; }
public bool RequiresDgVoodoo { get; set; }
public List<string> DgVoodooVersions { get; set; } = [];
public List<string> DgVoodooSetup { get; set; } = [];
public string? FeaturesUrl { get; set; }
}

/// <summary>A row of the wiki's generic Unreal Engine table.</summary>
public sealed class CatalogLumaUnrealGame
{
public string Name { get; set; } = "";
/// <summary>"yes", "blocked", "in-progress" or null (empty cell).</summary>
public string? Dlss { get; set; }
public string? Hdr { get; set; }
public string? UeVersion { get; set; }
public string? Notes { get; set; }
public List<CatalogEngineIniKey> EngineIni { get; set; } = [];
public List<string> LaunchArgs { get; set; } = [];

/// <summary>The wiki marks DLSS/FSR blocked and has no HDR for the game: the generic mod does nothing useful there.</summary>
public bool Blocked => Dlss == "blocked" && Hdr != "yes";
}
1 change: 1 addition & 0 deletions src/DLSSUpdater/Core/CatalogModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public sealed class CatalogSections
public CatalogNeural? Neural { get; set; }
/// <summary>ReLimiter and Display Commander add-on files (ReLimiter mirrored, Display Commander pinned to the author's URL).</summary>
public CatalogFrameLimiters? FrameLimiters { get; set; }
public CatalogLuma? Luma { get; set; }
}

public sealed class CatalogFrameLimiters
Expand Down
3 changes: 3 additions & 0 deletions src/DLSSUpdater/Core/CatalogState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public sealed class CatalogState(CatalogClient client)
public CatalogOrigin Origin { get; private set; } = CatalogOrigin.None;
public string? Note { get; private set; }
public HdrPicker? Picker { get; private set; }
/// <summary>The Luma mods of the catalog; null when the catalog has no luma section.</summary>
public LumaPicker? LumaPicker { get; private set; }

public event Action? Changed;

Expand All @@ -27,6 +29,7 @@ private void Apply(CatalogLoad load)
changed = Document?.Generated != load.Document?.Generated || (Document is null) != (load.Document is null);
Document = load.Document;
Picker = load.Document?.Sections.Renodx is { } renodx ? new HdrPicker(renodx) : null;
LumaPicker = load.Document?.Sections.Luma is { } luma ? new LumaPicker(luma) : null;
}
Origin = load.Origin;
Note = load.Note;
Expand Down
3 changes: 3 additions & 0 deletions src/DLSSUpdater/Core/ComponentRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public static class ComponentRegistry
public const string Feeder = "dlss5-feeder";
/// <summary>DXVK (Direct3D 8-11 over Vulkan): stable, development and the Lilium HDR fork; recorded the generic way (<see cref="DxvkLibrary"/>).</summary>
public const string Dxvk = "dxvk";
/// <summary>Luma Framework mods (Filoppi/Luma-Framework): a ReShade add-on plus its Luma\ folder, per game or the generic Unreal one (<see cref="LumaLibrary"/>).</summary>
public const string Luma = "luma";
/// <summary>Not a component with files: the per-game record of what the app wrote into the NVIDIA driver profile (<see cref="NvidiaRecord"/>).</summary>
public const string NvidiaDriver = "nvidia-driver";
/// <summary>The ReShade add-on frame limiters (ids match the catalog's <c>managedBy</c>) and the Unreal Engine.ini cap; one is active per game.</summary>
Expand Down Expand Up @@ -98,6 +100,7 @@ static ComponentRegistry()
});
Register(new(UnrealFrameCap, "Unreal frame cap") { Label = "UE frame cap" });
Register(new(Dxvk, "DXVK") { Library = LibraryKind.Dxvk, Label = "DXVK", OwnedFiles = [.. DxvkDlls.All, DxvkConf.FileName] });
Register(new(Luma, "Luma") { Library = LibraryKind.Luma, Label = "Luma", OwnedFiles = [LumaFiles.TreeDir + @"\*", "Luma-*.addon", "Luma-*.addon64", "Luma-*.addon32"] });
Register(new(Feeder, "DLSS5-Feeder") { Library = LibraryKind.Feeder, Label = "Feeder", OwnedFiles = FeederLibrary.OwnedFiles });
}

Expand Down
10 changes: 10 additions & 0 deletions src/DLSSUpdater/Core/ComponentSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ public void SetHdrUeExtended(bool? on) =>
public void SetEngineIniPath(string? path) =>
Components = ComponentPicks.SetOption(Components, ComponentRegistry.RenoDxHdr, "engine-ini", string.IsNullOrWhiteSpace(path) ? null : path.Trim());

/// <summary>The Luma mod the user picked by hand for this game: a catalog mod id, <see cref="LumaPicker.UnrealId"/>, or <see cref="LumaManual.CustomMod"/> (an imported zip, whose library id is the build pick); null = automatic.</summary>
public string? LumaMod => ComponentPicks.GetOption(Components, ComponentRegistry.Luma, "mod");

public void SetLumaMod(string? mod) => Components = ComponentPicks.SetOption(Components, ComponentRegistry.Luma, "mod", mod);

/// <summary>HDR output for Luma in this game: true = on, false = off, null = leave it to Luma (it sets it from the display on first start).</summary>
public bool? LumaHdr => ComponentPicks.GetOption(Components, ComponentRegistry.Luma, "hdr") switch { "on" => true, "off" => false, _ => null };

public void SetLumaHdr(bool? on) => Components = ComponentPicks.SetOption(Components, ComponentRegistry.Luma, "hdr", on is null ? null : on.Value ? "on" : "off");

/// <summary>Replaces this game's option values for a component in the map; null or empty removes them.</summary>
public void SetPickOptions(string id, Dictionary<string, string>? options) => Components = ComponentPicks.SetOptions(Components, id, options);
}
Expand Down
5 changes: 3 additions & 2 deletions src/DLSSUpdater/Core/HdrInstall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public sealed class HdrService(ComponentStore store, Installer installer, Catalo
/// OptiScaler, where the user decides about ReShade.
/// </summary>
public async Task<HdrInstallResult> InstallAsync(GameInfo game, string targetDir, HdrChoice choice, int? peakNits, string? engineIniHint,
HdrReShade? reshade, IProgress<TransferProgress>? progress, CancellationToken ct, IReadOnlyList<HdrIniEdit>? userEdits = null)
HdrReShade? reshade, IProgress<TransferProgress>? progress, CancellationToken ct, IReadOnlyList<HdrIniEdit>? userEdits = null, bool lumaClashConfirmed = false)
{
if (game.AntiCheat is { } ac) throw new InvalidOperationException($"{game.Name} has {ac} anti-cheat: no add-on is installed in games with anti-cheat.");
if (!choice.IsOffered) throw new InvalidOperationException(choice.Reason);
Expand All @@ -172,7 +172,8 @@ public async Task<HdrInstallResult> InstallAsync(GameInfo game, string targetDir
var plan = HdrPlanner.Build(game, targetDir, choice, build, ComponentStore.HdrPathOf(build), peakNits, engineIniHint, existing, userEdits);
foreach (var w in plan.Warnings) Log.Warn($"{game.Name}: {w}");
progress?.Report(new TransferProgress($"Installing {choice.Title} to {game.Name}", null));
var undo = await installer.InstallComponentAsync(game, targetDir, plan.Plan, ct);
var component = plan.Plan with { Extras = LumaConflict.WithMark(plan.Plan.Extras, lumaClashConfirmed) };
var undo = await installer.InstallComponentAsync(game, targetDir, component, ct);
return new HdrInstallResult(build, plan, undo);
}

Expand Down
Loading