StructUnpacker.cs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using Ryujinx.Graphics.Memory;
  2. using System;
  3. namespace Ryujinx.Graphics.Vic
  4. {
  5. class StructUnpacker
  6. {
  7. private NvGpuVmm _vmm;
  8. private long _position;
  9. private ulong _buffer;
  10. private int _buffPos;
  11. public StructUnpacker(NvGpuVmm vmm, long position)
  12. {
  13. _vmm = vmm;
  14. _position = position;
  15. _buffPos = 64;
  16. }
  17. public int Read(int bits)
  18. {
  19. if ((uint)bits > 32)
  20. {
  21. throw new ArgumentOutOfRangeException(nameof(bits));
  22. }
  23. int value = 0;
  24. while (bits > 0)
  25. {
  26. RefillBufferIfNeeded();
  27. int readBits = bits;
  28. int maxReadBits = 64 - _buffPos;
  29. if (readBits > maxReadBits)
  30. {
  31. readBits = maxReadBits;
  32. }
  33. value <<= readBits;
  34. value |= (int)(_buffer >> _buffPos) & (int)(0xffffffff >> (32 - readBits));
  35. _buffPos += readBits;
  36. bits -= readBits;
  37. }
  38. return value;
  39. }
  40. private void RefillBufferIfNeeded()
  41. {
  42. if (_buffPos >= 64)
  43. {
  44. _buffer = _vmm.ReadUInt64(_position);
  45. _position += 8;
  46. _buffPos = 0;
  47. }
  48. }
  49. }
  50. }