forked from Mirror/Ryujinx
69 lines
1.4 KiB
C#
69 lines
1.4 KiB
C#
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|