aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Vic/StructUnpacker.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics/Vic/StructUnpacker.cs')
-rw-r--r--Ryujinx.Graphics/Vic/StructUnpacker.cs69
1 files changed, 69 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Vic/StructUnpacker.cs b/Ryujinx.Graphics/Vic/StructUnpacker.cs
new file mode 100644
index 00000000..62777aad
--- /dev/null
+++ b/Ryujinx.Graphics/Vic/StructUnpacker.cs
@@ -0,0 +1,69 @@
+using Ryujinx.Graphics.Memory;
+using System;
+
+namespace Ryujinx.Graphics.Vic
+{
+ class StructUnpacker
+ {
+ private NvGpuVmm Vmm;
+
+ private long Position;
+
+ private ulong Buffer;
+ private int BuffPos;
+
+ public StructUnpacker(NvGpuVmm Vmm, long Position)
+ {
+ this.Vmm = Vmm;
+ this.Position = Position;
+
+ BuffPos = 64;
+ }
+
+ public int Read(int Bits)
+ {
+ if ((uint)Bits > 32)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Bits));
+ }
+
+ int Value = 0;
+
+ while (Bits > 0)
+ {
+ RefillBufferIfNeeded();
+
+ int ReadBits = Bits;
+
+ int MaxReadBits = 64 - BuffPos;
+
+ if (ReadBits > MaxReadBits)
+ {
+ ReadBits = MaxReadBits;
+ }
+
+ Value <<= ReadBits;
+
+ Value |= (int)(Buffer >> BuffPos) & (int)(0xffffffff >> (32 - ReadBits));
+
+ BuffPos += ReadBits;
+
+ Bits -= ReadBits;
+ }
+
+ return Value;
+ }
+
+ private void RefillBufferIfNeeded()
+ {
+ if (BuffPos >= 64)
+ {
+ Buffer = Vmm.ReadUInt64(Position);
+
+ Position += 8;
+
+ BuffPos = 0;
+ }
+ }
+ }
+} \ No newline at end of file