2018-12-03 03:38:47 +01:00
|
|
|
using Ryujinx.Graphics.Memory;
|
|
|
|
using System;
|
|
|
|
|
|
|
|
namespace Ryujinx.Graphics.Vic
|
|
|
|
{
|
|
|
|
class StructUnpacker
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
private NvGpuVmm _vmm;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private long _position;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private ulong _buffer;
|
|
|
|
private int _buffPos;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public StructUnpacker(NvGpuVmm vmm, long position)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_vmm = vmm;
|
|
|
|
_position = position;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
_buffPos = 64;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public int Read(int bits)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
if ((uint)bits > 32)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
throw new ArgumentOutOfRangeException(nameof(bits));
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int value = 0;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
while (bits > 0)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
|
|
|
RefillBufferIfNeeded();
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int readBits = bits;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int maxReadBits = 64 - _buffPos;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
if (readBits > maxReadBits)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
readBits = maxReadBits;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
value <<= readBits;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
value |= (int)(_buffer >> _buffPos) & (int)(0xffffffff >> (32 - readBits));
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
_buffPos += readBits;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
bits -= readBits;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
return value;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private void RefillBufferIfNeeded()
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
if (_buffPos >= 64)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_buffer = _vmm.ReadUInt64(_position);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
_position += 8;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
_buffPos = 0;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|