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. this.Vmm = Vmm;
  14. this.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. }