mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +00:00
73 lines
1.5 KiB
C++
73 lines
1.5 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include "Common/Swap.h"
|
|
|
|
// George Marsaglia-style random number generator.
|
|
class GMRng {
|
|
public:
|
|
GMRng() {
|
|
m_w = 0x23E866ED;
|
|
m_z = 0x80FD5AF2;
|
|
}
|
|
void Init(int seed) {
|
|
m_w = seed ^ (seed << 16);
|
|
if (!m_w) m_w = 1337;
|
|
m_z = ~seed;
|
|
if (!m_z) m_z = 31337;
|
|
}
|
|
uint32_t R32() {
|
|
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
|
|
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
|
|
return (m_z << 16) + m_w;
|
|
}
|
|
float F() {
|
|
return (float)R32() / (float)(0xFFFFFFFF);
|
|
}
|
|
|
|
// public for easy save/load. Yes a bit ugly but better than moving DoState into native.
|
|
uint32_t m_w;
|
|
uint32_t m_z;
|
|
};
|
|
|
|
|
|
// Data must consist only of the index and the twister array. This matches the PSP
|
|
// MT context exactly.
|
|
class MersenneTwister {
|
|
public:
|
|
MersenneTwister(uint32_t seed) : index_(0) {
|
|
mt_[0] = seed;
|
|
for (uint32_t i = 1; i < MT_SIZE; i++)
|
|
mt_[i] = (1812433253UL * (mt_[i - 1] ^ (mt_[i - 1] >> 30)) + i);
|
|
}
|
|
|
|
uint32_t R32() {
|
|
if (index_ == 0)
|
|
gen();
|
|
uint32_t y = mt_[index_];
|
|
y ^= y >> 11;
|
|
y ^= (y << 7) & 2636928640UL;
|
|
y ^= (y << 15) & 4022730752UL;
|
|
y ^= y >> 18;
|
|
index_ = (index_ + 1) % MT_SIZE;
|
|
return y;
|
|
}
|
|
|
|
private:
|
|
enum {
|
|
MT_SIZE = 624,
|
|
};
|
|
|
|
u32_le index_;
|
|
u32_le mt_[MT_SIZE];
|
|
|
|
void gen() {
|
|
for(uint32_t i = 0; i < MT_SIZE; i++){
|
|
uint32_t y = (mt_[i] & 0x80000000) + (mt_[(i + 1) % MT_SIZE] & 0x80000000);
|
|
mt_[i] = mt_[(i + 397) % MT_SIZE] ^ (y >> 1);
|
|
if (y % 2) mt_[i] ^= 2567483615UL;
|
|
}
|
|
return;
|
|
}
|
|
};
|