diff --git a/src/Ryujinx.Common/Configuration/DirtyHacks.cs b/src/Ryujinx.Common/Configuration/DirtyHacks.cs
index 12f6b019b..d874b226c 100644
--- a/src/Ryujinx.Common/Configuration/DirtyHacks.cs
+++ b/src/Ryujinx.Common/Configuration/DirtyHacks.cs
@@ -13,13 +13,13 @@ namespace Ryujinx.Common.Configuration
public record EnabledDirtyHack(DirtyHacks Hack, int Value)
{
- private static readonly byte[] _packedFormat = [8, 32];
+ public static readonly byte[] PackedFormat = [8, 32];
- public ulong Pack() => BitTricks.PackBitFields([(uint)Hack, (uint)Value], _packedFormat);
+ public ulong Pack() => BitTricks.PackBitFields([(uint)Hack, (uint)Value], PackedFormat);
public static EnabledDirtyHack FromPacked(ulong packedHack)
{
- var unpackedFields = BitTricks.UnpackBitFields(packedHack, _packedFormat);
+ var unpackedFields = BitTricks.UnpackBitFields(packedHack, PackedFormat);
if (unpackedFields is not [var hack, var value])
throw new ArgumentException(nameof(packedHack));
@@ -45,6 +45,15 @@ namespace Ryujinx.Common.Configuration
}
}
+ public ulong[] PackEntries() =>
+ this
+ .Select(it =>
+ BitTricks.PackBitFields([(uint)it.Key, (uint)it.Value], EnabledDirtyHack.PackedFormat))
+ .ToArray();
+
+ public static implicit operator DirtyHackCollection(EnabledDirtyHack[] hacks) => new(hacks);
+ public static implicit operator DirtyHackCollection(ulong[] packedHacks) => new(packedHacks);
+
public new int this[DirtyHacks hack] => TryGetValue(hack, out var value) ? value : -1;
public bool IsEnabled(DirtyHacks hack) => ContainsKey(hack);
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml
index a32fecfcb..b4e3437ff 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml
@@ -42,7 +42,7 @@
VerticalAlignment="Center"
Text="Xenoblade Chronicles 2 Menu Softlock Fix" />
-
+
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
index b0664e1b6..812092688 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
@@ -752,7 +752,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
Hacks.ShowDirtyHacks.Value = configurationFileFormat.ShowDirtyHacks;
{
- EnabledDirtyHack[] hacks = configurationFileFormat.DirtyHacks.Select(EnabledDirtyHack.FromPacked).ToArray();
+ EnabledDirtyHack[] hacks = (configurationFileFormat.DirtyHacks ?? []).Select(EnabledDirtyHack.FromPacked).ToArray();
Hacks.Xc2MenuSoftlockFix.Value = hacks.Any(it => it.Hack == DirtyHacks.Xc2MenuSoftlockFix);
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
index 53192618e..ef3d565da 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
@@ -10,6 +10,7 @@ using Ryujinx.Common.Logging;
using Ryujinx.HLE;
using System.Collections.Generic;
using System.Linq;
+using RyuLogger = Ryujinx.Common.Logging.Logger;
namespace Ryujinx.Ava.Utilities.Configuration
{
@@ -644,9 +645,20 @@ namespace Ryujinx.Ava.Utilities.Configuration
private void HackChanged(object sender, ReactiveEventArgs rxe)
{
- Ryujinx.Common.Logging.Logger.Info?.Print(LogClass.Configuration, $"EnabledDirtyHacks set to: [{EnabledHacks.Select(x => x.Hack).JoinToString(", ")}]", "LogValueChange");
+ var newHacks = EnabledHacks.Select(x => x.Hack)
+ .JoinToString(", ");
+
+ if (newHacks != _lastHackCollection)
+ {
+ RyuLogger.Info?.Print(LogClass.Configuration,
+ $"EnabledDirtyHacks set to: [{_lastHackCollection}]", "LogValueChange");
+
+ _lastHackCollection = newHacks;
+ }
}
+ private static string _lastHackCollection;
+
public EnabledDirtyHack[] EnabledHacks
{
get