2024-07-26 20:49:10 +05:00

81 lines
2.0 KiB
C#

using System.Diagnostics;
namespace SoulstormReplayReader.Core.Utils;
internal sealed class NativeDowRandom
{
public uint Seed { get; set; }
public uint Index { get; set; }
public uint IterLimit { get; set; }
public int Lock { get; set; }
public NativeDowRandom(uint iterLimit = 4u)
{
IterLimit = iterLimit;
}
public NativeDowRandom SetSeed(uint seed)
{
Seed = seed;
Index = 0;
return this;
}
public int GetMax(uint num)
{
if (num == 0) return 0;
var res = (int)(HashRandom() % num);
Debug.WriteLine($"{num} {res}");
return res;
}
public int GetMax(int num) => GetMax((uint)num);
#region Dow decompiled code
private uint HashRandom()
{
var result = Index;
Index++;
var seed = Seed;
if (IterLimit == 0) return result;
for (var ind = 0; ind < IterLimit; ind++)
{
var s4 = result ^ s_arr1[ind];
var s5 = result;
var s6 = (ushort)s4;
s4 >>= 16;
var s7 = s_arr2[ind] ^ RotateLeft4((uint)(s6 * s6 + ~(s4 * s4)), '\x10');
result = (seed ^ (s6 * s4 + s7));
seed = s5;
}
return result;
}
private static uint RotateLeft4(uint x, char n) => (x << n) | (x >> (32 - n));
private static readonly uint[] s_arr1 =
{
3131664519, 504877868, 62708796, 255054258, 1990609181,
3312506973, 3816993251, 2027635554, 1949936084, 2632616645,
2303949916, 629732701, 1096506909, 560872853, 2244371175,
1586148200, 1051053196, 3530166132, 4087947819, 1219155940,
0, 0, 0, 0
};
private static readonly uint[] s_arr2 =
{
1259289432, 3899977923, 1767228838, 1437059654, 1301978502,
4264075669, 2982836325, 1797478225, 2593749601, 2859374024,
2863238881, 1526273356, 4237173347, 957308556, 1493161986,
2886360762, 2890429686, 2849966355, 2260618356, 3979088443,
0, 0, 0, 0
};
#endregion
}