CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/Data/Random/Rng.h
Views: 1401
1
#pragma once
2
3
#include <cstdint>
4
#include "Common/Swap.h"
5
6
// George Marsaglia-style random number generator.
7
class GMRng {
8
public:
9
GMRng() {
10
m_w = 0x23E866ED;
11
m_z = 0x80FD5AF2;
12
}
13
void Init(int seed) {
14
m_w = seed ^ (seed << 16);
15
if (!m_w) m_w = 1337;
16
m_z = ~seed;
17
if (!m_z) m_z = 31337;
18
}
19
uint32_t R32() {
20
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
21
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
22
return (m_z << 16) + m_w;
23
}
24
float F() {
25
return (float)R32() / (float)(0xFFFFFFFF);
26
}
27
28
// public for easy save/load. Yes a bit ugly but better than moving DoState into native.
29
uint32_t m_w;
30
uint32_t m_z;
31
};
32
33
34
// Data must consist only of the index and the twister array. This matches the PSP
35
// MT context exactly.
36
class MersenneTwister {
37
public:
38
MersenneTwister(uint32_t seed) : index_(0) {
39
mt_[0] = seed;
40
for (uint32_t i = 1; i < MT_SIZE; i++)
41
mt_[i] = (1812433253UL * (mt_[i - 1] ^ (mt_[i - 1] >> 30)) + i);
42
}
43
44
uint32_t R32() {
45
if (index_ == 0)
46
gen();
47
uint32_t y = mt_[index_];
48
y ^= y >> 11;
49
y ^= (y << 7) & 2636928640UL;
50
y ^= (y << 15) & 4022730752UL;
51
y ^= y >> 18;
52
index_ = (index_ + 1) % MT_SIZE;
53
return y;
54
}
55
56
private:
57
enum {
58
MT_SIZE = 624,
59
};
60
61
u32_le index_;
62
u32_le mt_[MT_SIZE];
63
64
void gen() {
65
for(uint32_t i = 0; i < MT_SIZE; i++){
66
uint32_t y = (mt_[i] & 0x80000000) + (mt_[(i + 1) % MT_SIZE] & 0x80000000);
67
mt_[i] = mt_[(i + 397) % MT_SIZE] ^ (y >> 1);
68
if (y % 2) mt_[i] ^= 2567483615UL;
69
}
70
return;
71
}
72
};
73
74