mersenne.c
author peter1138
Sun, 01 Oct 2006 12:00:32 +0000
changeset 4694 c917a3ad0dd2
parent 2952 58522ed8f0f1
permissions -rw-r--r--
(svn r6601) - Codechange: Support cargo subtypes in the refit window. The refit window has been altered to support resizing and scrolling. Note that the cargo subtype isn't yet passed for actual refitting yet. (Based on mart3p's patch)
2186
db48cf29b983 (svn r2701) Insert Id tags into all source files
tron
parents: 2075
diff changeset
     1
/* $Id$ */
db48cf29b983 (svn r2701) Insert Id tags into all source files
tron
parents: 2075
diff changeset
     2
2075
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     3
#include "stdafx.h"
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     4
#include "openttd.h"
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     5
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     6
#ifdef MERSENNE_TWISTER
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     7
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     8
// Source code for Mersenne Twister.
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     9
// A Random number generator with much higher quality random numbers.
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    10
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    11
#define N              (624)                 // length of _mt_state vector
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    12
#define M              (397)                 // a period parameter
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    13
#define K              (0x9908B0DFU)         // a magic constant
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    14
#define hiBit(u)       ((u) & 0x80000000U)   // mask all but highest   bit of u
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    15
#define loBit(u)       ((u) & 0x00000001U)   // mask all but lowest    bit of u
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    16
#define loBits(u)      ((u) & 0x7FFFFFFFU)   // mask     the highest   bit of u
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    17
#define mixBits(u, v)  (hiBit(u)|loBits(v))  // move hi bit of u to hi bit of v
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    18
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    19
static uint32   _mt_state[N+1];     // _mt_state vector + 1 extra to not violate ANSI C
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    20
static uint32   *_mt_next;          // _mt_next random value is computed from here
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    21
static int      _mt_left = -1;      // can *_mt_next++ this many times before reloading
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    22
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    23
void SeedMT(uint32 seed)
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    24
{
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    25
    register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = _mt_state;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    26
    register int    j;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    27
2952
58522ed8f0f1 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    28
    for (_mt_left=0, *s++=x, j=N; --j;
2075
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    29
        *s++ = (x*=69069U) & 0xFFFFFFFFU);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    30
 }
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    31
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    32
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    33
static uint32 ReloadMT(void)
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    34
 {
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    35
    register uint32 *p0=_mt_state, *p2=_mt_state+2, *pM=_mt_state+M, s0, s1;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    36
    register int    j;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    37
2952
58522ed8f0f1 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    38
    if (_mt_left < -1)
2075
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    39
        SeedMT(4357U);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    40
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    41
    _mt_left=N-1, _mt_next=_mt_state+1;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    42
2952
58522ed8f0f1 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    43
    for (s0=_mt_state[0], s1=_mt_state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
2075
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    44
        *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    45
2952
58522ed8f0f1 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    46
    for (pM=_mt_state, j=M; --j; s0=s1, s1=*p2++)
2075
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    47
        *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    48
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    49
    s1=_mt_state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    50
    s1 ^= (s1 >> 11);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    51
    s1 ^= (s1 <<  7) & 0x9D2C5680U;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    52
    s1 ^= (s1 << 15) & 0xEFC60000U;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    53
    return(s1 ^ (s1 >> 18));
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    54
 }
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    55
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    56
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    57
uint32 RandomMT(void)
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    58
{
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    59
	uint32 y;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    60
2952
58522ed8f0f1 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    61
	if (--_mt_left < 0)
2075
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    62
		return ReloadMT();
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    63
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    64
	y  = *_mt_next++;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    65
	y ^= (y >> 11);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    66
	y ^= (y <<  7) & 0x9D2C5680U;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    67
	y ^= (y << 15) & 0xEFC60000U;
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    68
	return y ^ (y >> 18);
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    69
}
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    70
#else
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    71
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    72
void SeedMT(uint32 seed) {}
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    73
21d2986569d1 (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    74
#endif /* MERSENNE_TWISTER */