~ppsspp/ppsspp/ppsspp-1.1.1

« back to all changes in this revision

Viewing changes to ext/native/util/random/rng.h

  • Committer: Sérgio Benjamim
  • Date: 2015-10-17 01:37:55 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20151017013755-avrlz2pt37kwt43x
PPSSPP 1.1.1 source.

Show diffs side-by-side

added added

removed removed

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