1#include "random/seadRandom.h"
2#include "time/seadTickTime.h"
3
4namespace sead
5{
6void Random::init()
7{
8 TickTime now;
9 init(seed: static_cast<u32>(now.toTicks()));
10}
11
12void Random::init(u32 seed)
13{
14 const u32 mt_constant = 0x6C078965;
15 mX = mt_constant * (seed ^ (seed >> 30u)) + 1;
16 mY = mt_constant * (mX ^ (mX >> 30u)) + 2;
17 mZ = mt_constant * (mY ^ (mY >> 30u)) + 3;
18 mW = mt_constant * (mZ ^ (mZ >> 30u)) + 4;
19}
20
21void Random::init(u32 seed_x, u32 seed_y, u32 seed_z, u32 seed_w)
22{
23 if ((seed_x | seed_y | seed_z | seed_w) == 0)
24 {
25 SEAD_ASSERT_MSG(false, "seeds must not be all zero.");
26 seed_w = 0x48077044;
27 seed_z = 0x714ACB41;
28 seed_y = 0x6C078967;
29 seed_x = 1;
30 }
31 mX = seed_x;
32 mY = seed_y;
33 mZ = seed_z;
34 mW = seed_w;
35}
36
37u32 Random::getU32()
38{
39 u32 x = mX ^ (mX << 11u);
40 mX = mY;
41 mY = mZ;
42 mZ = mW;
43 mW = mW ^ (mW >> 19u) ^ x ^ (x >> 8u);
44 return mW;
45}
46
47u64 Random::getU64()
48{
49 return u64(getU32()) << 32u | getU32();
50}
51
52void Random::getContext(u32* x, u32* y, u32* z, u32* w) const
53{
54 *x = mX;
55 *y = mY;
56 *z = mZ;
57 *w = mW;
58}
59} // namespace sead
60