[Add] Now we can use mersenne twister instead of rand(), you are welcome. :)
This commit is contained in:
parent
f63605d605
commit
8808864e56
@ -1,6 +1,8 @@
|
|||||||
# OPTIONS.
|
# OPTIONS.
|
||||||
DEBUG = 1
|
DEBUG = 1
|
||||||
APPNAME = Lephisto
|
|
||||||
|
OS := LINUX
|
||||||
|
#OS := WIN32
|
||||||
|
|
||||||
# VERSION.
|
# VERSION.
|
||||||
VMAJOR = 0
|
VMAJOR = 0
|
||||||
@ -22,7 +24,7 @@ CTTF = $(shell freetype-config --cflags)
|
|||||||
CAL = -lopenal
|
CAL = -lopenal
|
||||||
CVORBIS =
|
CVORBIS =
|
||||||
CGL =
|
CGL =
|
||||||
CFLAGS = $(CLUA) $(CSDL) $(CXML) $(CTTF) $(CGL) $(CAL) $(CVORBIS) $(VERSION)
|
CFLAGS = $(CLUA) $(CSDL) $(CXML) $(CTTF) $(CGL) $(CAL) $(CVORBIS) $(VERSION) -D$(OS)
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CFLAGS += -W -Wall -g3 -DDEBUG -DLUA_USE_APICHECK -std=c99
|
CFLAGS += -W -Wall -g3 -DDEBUG -DLUA_USE_APICHECK -std=c99
|
||||||
else
|
else
|
||||||
|
106
src/rng.c
106
src/rng.c
@ -1,8 +1,112 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#ifdef LINUX
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
// Mersenne twister state.
|
||||||
|
static uint32_t MT[624];
|
||||||
|
static uint32_t mt_y;
|
||||||
|
static int mt_pos = 0; // Current number.
|
||||||
|
|
||||||
|
static uint32_t rng_timeEntropy(void);
|
||||||
|
// Mersenne twister.
|
||||||
|
static void mt_initArray(uint32_t seed);
|
||||||
|
static void mt_genArray(void);
|
||||||
|
static uint32_t mt_getInt(void);
|
||||||
|
|
||||||
void rng_init(void) {
|
void rng_init(void) {
|
||||||
srand(getpid() + SDL_GetTicks());
|
uint32_t i;
|
||||||
|
|
||||||
|
#ifdef LINUX
|
||||||
|
int fd; char buf[4];
|
||||||
|
fd = open("/dev/random", O_RDONLY);
|
||||||
|
if(fd != -1) {
|
||||||
|
if(read(fd, buf, 4) < 4)
|
||||||
|
memcpy(&i, buf, 4);
|
||||||
|
else
|
||||||
|
i = rng_timeEntropy();
|
||||||
|
close(fd);
|
||||||
|
} else
|
||||||
|
i = rng_timeEntropy();
|
||||||
|
#else
|
||||||
|
i = rng_timeEntropy();
|
||||||
|
#endif
|
||||||
|
mt_initArray(i);
|
||||||
|
for(i = 0; i < 10; i++)
|
||||||
|
// Generate numbers to get away from poor initial values.
|
||||||
|
mt_genArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the time as source of entropy.
|
||||||
|
static uint32_t rng_timeEntropy(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
struct _timeb tb;
|
||||||
|
_ftime(&tb);
|
||||||
|
i = tb.time * 1000 + tb.millitm;
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
i = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||||
|
#endif
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates the initial mersenne twister based on seed.
|
||||||
|
static void mt_initArray(uint32_t seed) {
|
||||||
|
int i;
|
||||||
|
MT[0] = seed;
|
||||||
|
for(i = 1; i < 624; i++)
|
||||||
|
MT[i] = 1812433253 * (MT[i-1] ^ (((MT[i-1])) + i) >> 30);
|
||||||
|
mt_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate an array of numbers.
|
||||||
|
static void mt_genArray(void) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < 624; i++) {
|
||||||
|
mt_y = (MT[i] & 0x80000000) + ((MT[i] % 624) & 0x7FFFFFFF);
|
||||||
|
if(mt_y % 2)
|
||||||
|
// Odd.
|
||||||
|
MT[i] = (MT[(i+397) % 624] ^ (mt_y >> 1)) ^ 2567483615;
|
||||||
|
else
|
||||||
|
// Even.
|
||||||
|
MT[i] = MT[(i+397) % 624] ^ (mt_y >> 1);
|
||||||
|
}
|
||||||
|
mt_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next int.
|
||||||
|
static uint32_t mt_getInt(void) {
|
||||||
|
if(mt_pos >= 624) mt_genArray();
|
||||||
|
|
||||||
|
mt_y = MT[mt_pos++];
|
||||||
|
mt_y ^= mt_y >> 11;
|
||||||
|
mt_y ^= (mt_y << 7) & 2636928640;
|
||||||
|
mt_y ^= (mt_y << 15) & 4022730752;
|
||||||
|
mt_y ^= (mt_y >> 18);
|
||||||
|
|
||||||
|
return mt_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a random int.
|
||||||
|
unsigned int randint(void) {
|
||||||
|
return mt_getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a random double.
|
||||||
|
static double m_div = (double)(0xFFFFFFFF) + 1.;
|
||||||
|
double randfp(void) {
|
||||||
|
double m = (double)mt_getInt();
|
||||||
|
return m / m_div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdlib.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * (rand()/(RAND_MAX+1.))))
|
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * (randfp()))
|
||||||
#define RNGF() (rand()/(RAND_MAX+1.))
|
#define RNGF() (randfp())
|
||||||
|
|
||||||
void rng_init(void);
|
void rng_init(void);
|
||||||
|
unsigned int randint(void);
|
||||||
|
double randfp(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user