From b6f88514f9937f17eddc4df9efafaebc96fd1b10 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 30 Dec 2024 22:10:12 -0600 Subject: [PATCH] misc: Move BitTricks methods into BitUtils Cleanup DirtyHackCollection --- src/Ryujinx.Common/BitTricks.cs | 35 ---------------- .../Configuration/DirtyHacks.cs | 40 ++++++++----------- src/Ryujinx.Common/Utilities/BitUtils.cs | 30 ++++++++++++++ 3 files changed, 47 insertions(+), 58 deletions(-) delete mode 100644 src/Ryujinx.Common/BitTricks.cs diff --git a/src/Ryujinx.Common/BitTricks.cs b/src/Ryujinx.Common/BitTricks.cs deleted file mode 100644 index d0c689291..000000000 --- a/src/Ryujinx.Common/BitTricks.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace Ryujinx.Common -{ - public class BitTricks - { - // Never actually written bit packing logic before, so I looked it up. - // This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195 - - public static ulong PackBitFields(uint[] values, byte[] bitFields) - { - ulong retVal = values[0]; //we set the first value right away - for (int f = 1; f < values.Length; f++) - { - retVal <<= bitFields[f]; // we shift the previous value - retVal += values[f];// and add our current value - } - return retVal; - } - - public static uint[] UnpackBitFields(ulong packed, byte[] bitFields) - { - int fields = bitFields.Length - 1; // number of fields to unpack - uint[] retArr = new uint[fields + 1]; // init return array - int curPos = 0; // current field bit position (start) - int lastEnd; // position where last field ended - for (int f = fields; f >= 0; f--) // loop from last - { - lastEnd = curPos; // we store where the last value ended - curPos += bitFields[f]; // we get where the current value starts - int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion - retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic - } - return retArr; - } - } -} diff --git a/src/Ryujinx.Common/Configuration/DirtyHacks.cs b/src/Ryujinx.Common/Configuration/DirtyHacks.cs index 1015e95d1..e52c96cf1 100644 --- a/src/Ryujinx.Common/Configuration/DirtyHacks.cs +++ b/src/Ryujinx.Common/Configuration/DirtyHacks.cs @@ -1,4 +1,5 @@ -using System; +using Gommon; +using System; using System.Collections.Generic; using System.Linq; @@ -14,12 +15,14 @@ namespace Ryujinx.Common.Configuration public record EnabledDirtyHack(DirtyHacks Hack, int Value) { public static readonly byte[] PackedFormat = [8, 32]; - - public ulong Pack() => BitTricks.PackBitFields([(uint)Hack, (uint)Value], PackedFormat); + + private uint[] Raw => [(uint)Hack, (uint)Value.CoerceAtLeast(0)]; + + public ulong Pack() => Raw.PackBitFields(PackedFormat); public static EnabledDirtyHack Unpack(ulong packedHack) { - var unpackedFields = BitTricks.UnpackBitFields(packedHack, PackedFormat); + var unpackedFields = packedHack.UnpackBitFields(PackedFormat); if (unpackedFields is not [var hack, var value]) throw new ArgumentException(nameof(packedHack)); @@ -29,26 +32,17 @@ namespace Ryujinx.Common.Configuration public class DirtyHackCollection : Dictionary { - public DirtyHackCollection(EnabledDirtyHack[] hacks) - { - foreach ((DirtyHacks dirtyHacks, int value) in hacks) - { - Add(dirtyHacks, value); - } - } - - public DirtyHackCollection(ulong[] packedHacks) - { - foreach ((DirtyHacks dirtyHacks, int value) in packedHacks.Select(EnabledDirtyHack.Unpack)) - { - Add(dirtyHacks, value); - } - } + public DirtyHackCollection(IEnumerable hacks) + => hacks.ForEach(edh => Add(edh.Hack, edh.Value)); - public ulong[] PackEntries() => - this - .Select(it => - BitTricks.PackBitFields([(uint)it.Key, (uint)it.Value], EnabledDirtyHack.PackedFormat)) + public DirtyHackCollection(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {} + + public ulong[] PackEntries() + => Entries.Select(it => it.Pack()).ToArray(); + + public EnabledDirtyHack[] Entries + => this + .Select(it => new EnabledDirtyHack(it.Key, it.Value)) .ToArray(); public static implicit operator DirtyHackCollection(EnabledDirtyHack[] hacks) => new(hacks); diff --git a/src/Ryujinx.Common/Utilities/BitUtils.cs b/src/Ryujinx.Common/Utilities/BitUtils.cs index b9dae2e53..acbdde1f6 100644 --- a/src/Ryujinx.Common/Utilities/BitUtils.cs +++ b/src/Ryujinx.Common/Utilities/BitUtils.cs @@ -40,5 +40,35 @@ namespace Ryujinx.Common return (value >> 32) | (value << 32); } + + // Never actually written bit packing logic before, so I looked it up. + // This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195 + + public static ulong PackBitFields(this uint[] values, byte[] bitFields) + { + ulong retVal = values[0]; //we set the first value right away + for (int f = 1; f < values.Length; f++) + { + retVal <<= bitFields[f]; // we shift the previous value + retVal += values[f];// and add our current value + } + return retVal; + } + + public static uint[] UnpackBitFields(this ulong packed, byte[] bitFields) + { + int fields = bitFields.Length - 1; // number of fields to unpack + uint[] retArr = new uint[fields + 1]; // init return array + int curPos = 0; // current field bit position (start) + int lastEnd; // position where last field ended + for (int f = fields; f >= 0; f--) // loop from last + { + lastEnd = curPos; // we store where the last value ended + curPos += bitFields[f]; // we get where the current value starts + int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion + retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic + } + return retArr; + } } }