Merge pull request #460 from VelocityRa/master

Use better random generator.
This commit is contained in:
YVT 2016-11-23 19:36:33 +09:00 committed by GitHub
commit 478a4460e8
17 changed files with 67 additions and 59 deletions

View File

@ -21,7 +21,6 @@
#include "ALDevice.h"
#include "ALFuncs.h"
#include <exception>
#include <stdio.h>
#include <Client/IAudioChunk.h>
#include <Core/IAudioStream.h>
#include <Core/FileManager.h>
@ -48,6 +47,8 @@ DEFINE_SPADES_SETTING(s_alPreciseErrorCheck, "1");
namespace spades {
namespace audio {
std::uniform_real_distribution<float> real_dist_audio(0, 1);
static Vector3 TransformVectorToAL(Vector3 v) {
return MakeVector3(v.x, v.y, v.z);
}
@ -56,7 +57,7 @@ namespace spades {
}
static float NextRandom() {
return (float)rand() /(float)RAND_MAX;
return real_dist_audio(mt_engine);
}
class ALAudioChunk: public client::IAudioChunk {
@ -560,7 +561,7 @@ namespace spades {
ALSrc *AllocChunk(){
SPADES_MARK_FUNCTION();
size_t start = rand() % srcs.size();
size_t start = mt_engine() % srcs.size();
for(size_t i = 0; i < srcs.size(); i++){
ALSrc *src = srcs[(i + start) % srcs.size()];
if(src->IsPlaying())
@ -568,7 +569,7 @@ namespace spades {
return src;
}
ALSrc *src = srcs[rand() % srcs.size()];
ALSrc *src = srcs[mt_engine() % srcs.size()];
src->Terminate();
return src;
}
@ -740,7 +741,7 @@ namespace spades {
for(size_t i = 0; i < srcs.size(); i++){
ALSrc *s = srcs[i];
if((rand() % 8 == 0) && s->IsPlaying())
if((mt_engine() % 8 == 0) && s->IsPlaying())
s->UpdateObstruction();
}
}

View File

@ -26,7 +26,6 @@
#include <Core/FileManager.h>
#include <Core/IAudioStream.h>
#include <Core/WavAudioStream.h>
#include <cstdlib>
#include "../Imports/SDL.h"
#include <Core/IStream.h>
@ -45,6 +44,7 @@ DEFINE_SPADES_SETTING(s_ysrDebug, "0");
namespace spades {
namespace audio {
static spades::DynamicLibrary *library = nullptr;
@ -524,9 +524,9 @@ namespace spades {
if(this->gameMap) this->gameMap->AddRef();
if(old) old->Release();
}
static float NextRandom() {
return (float)std::rand() /(float)RAND_MAX;
return real_dist(mt_engine);
}
void YsrDevice::Respatialize(const spades::Vector3 &eye,

View File

@ -65,6 +65,9 @@ DEFINE_SPADES_SETTING(cg_serverAlert, "1");
namespace spades {
namespace client {
std::random_device r_device_client;
std::mt19937_64 mt_engine_client(r_device_client()); // Seed Mersenne twister with non-deterministic 32-bit seed
Client::Client(IRenderer *r, IAudioDevice *audioDev,
const ServerAddress& host, std::string playerName):
@ -352,7 +355,7 @@ namespace spades {
mumbleLink.setContext(hostname.asString(false));
mumbleLink.setIdentity(playerName);
SPLog("Started connecting to '%s'", hostname.asString(true).c_str());
net.reset(new NetClient(this));
net->Connect(hostname);

View File

@ -63,7 +63,9 @@ namespace spades {
class ClientPlayer;
class ClientUI;
extern std::mt19937_64 mt_engine_client; // randomness generator
class Client: public IWorldListener, public gui::View {
friend class ScoreboardView;
friend class LimboView;
@ -118,7 +120,7 @@ namespace spades {
float timeSinceInit;
MumbleLink mumbleLink;
// view/drawing state for some world objects
std::vector<Handle<ClientPlayer>> clientPlayers;

View File

@ -1093,7 +1093,7 @@ namespace spades {
switch(player->GetWeapon()->GetWeaponType()){
case RIFLE_WEAPON:
model = renderer->RegisterModel("Models/Weapons/Rifle/Casing.kv6");
snd = (rand()&0x1000)?
snd = (mt_engine_client()&0x1000)?
audioDevice->RegisterSound("Sounds/Weapons/Rifle/ShellDrop1.wav"):
audioDevice->RegisterSound("Sounds/Weapons/Rifle/ShellDrop2.wav");
snd2 =
@ -1106,7 +1106,7 @@ namespace spades {
break;
case SMG_WEAPON:
model = renderer->RegisterModel("Models/Weapons/SMG/Casing.kv6");
snd = (rand()&0x1000)?
snd = (mt_engine_client()&0x1000)?
audioDevice->RegisterSound("Sounds/Weapons/SMG/ShellDrop1.wav"):
audioDevice->RegisterSound("Sounds/Weapons/SMG/ShellDrop2.wav");
snd2 =

View File

@ -20,7 +20,6 @@
*/
#include "Client.h"
#include <cstdlib>
#include <Core/ConcurrentDispatch.h>
#include <Core/Settings.h>
@ -48,7 +47,7 @@ DEFINE_SPADES_SETTING(cg_depthOfFieldAmount, "1");
DEFINE_SPADES_SETTING(cg_shake, "1");
static float nextRandom() {
return (float)rand() / (float)RAND_MAX;
return spades::real_dist(spades::client::mt_engine_client);
}
namespace spades {

View File

@ -20,7 +20,6 @@
*/
#include "Client.h"
#include <cstdlib>
#include <Core/ConcurrentDispatch.h>
#include <Core/Settings.h>
@ -498,7 +497,7 @@ namespace spades {
lastHurtTime = world->GetTime();
Handle<IAudioChunk> c;
switch((rand() >> 3) & 3){
switch((mt_engine_client() >> 3) & 3){
case 0:
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/FleshLocal1.wav");
break;
@ -619,14 +618,14 @@ namespace spades {
};
bool sprinting = clientPlayers[p->GetId()] ? clientPlayers[p->GetId()]->GetSprintState() > 0.5f : false;
Handle<IAudioChunk> c = p->GetWade() ?
audioDevice->RegisterSound(wsnds[(rand() >> 8) % 8]):
audioDevice->RegisterSound(snds[(rand() >> 8) % 8]);
audioDevice->RegisterSound(wsnds[(mt_engine_client() >> 8) % 8]):
audioDevice->RegisterSound(snds[(mt_engine_client() >> 8) % 8]);
audioDevice->Play(c, p->GetOrigin(),
AudioParam());
if(sprinting && !p->GetWade()) {
AudioParam param;
param.volume *= clientPlayers[p->GetId()]->GetSprintState();
c = audioDevice->RegisterSound(rsnds[(rand() >> 8) % 12]);
c = audioDevice->RegisterSound(rsnds[(mt_engine_client() >> 8) % 12]);
audioDevice->Play(c, p->GetOrigin(),
param);
}
@ -793,7 +792,7 @@ namespace spades {
if(victim != world->GetLocalPlayer()) {
if(!IsMuted()){
Handle<IAudioChunk> c;
switch(rand()%3){
switch(mt_engine_client()%3){
case 0:
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Flesh1.wav");
break;
@ -954,7 +953,7 @@ namespace spades {
AudioParam());
}else{
Handle<IAudioChunk> c;
switch((rand()>>6)%3){
switch((mt_engine_client()>>6)%3){
case 0:
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Flesh1.wav");
break;
@ -1010,7 +1009,7 @@ namespace spades {
Handle<IAudioChunk> c;
param.pitch = .9f + GetRandom() * 0.2f;
switch((rand() >> 6) & 3){
switch((mt_engine_client() >> 6) & 3){
case 0:
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Water1.wav");
break;
@ -1036,7 +1035,7 @@ namespace spades {
Handle<IAudioChunk> c;
switch((rand() >> 6) & 3) {
switch((mt_engine_client() >> 6) & 3) {
case 0:
case 1:
case 2:
@ -1049,7 +1048,7 @@ namespace spades {
param.pitch = .9f + GetRandom() * 0.2f;
param.volume = 2.f;
switch((rand() >> 6) & 3){
switch((mt_engine_client() >> 6) & 3){
case 0:
c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Ricochet1.wav");
break;
@ -1171,7 +1170,7 @@ namespace spades {
if(!IsMuted()){
Handle<IAudioChunk> c, cs;
switch((rand() >> 8) & 1){
switch((mt_engine_client() >> 8) & 1){
case 0:
c = audioDevice->RegisterSound("Sounds/Weapons/Grenade/Explode1.wav");
cs = audioDevice->RegisterSound("Sounds/Weapons/Grenade/ExplodeStereo1.wav");

View File

@ -32,11 +32,12 @@
namespace spades {
namespace client {
GameMap::GameMap():
listener(NULL){
SPADES_MARK_FUNCTION();
uint32_t rnd = (uint32_t)rand() ^ ((uint32_t)rand() << 16);
uint32_t rnd = mt_engine();
rnd ^= 0x7abd4513;
for(int x = 0; x < DefaultWidth; x++)
for(int y = 0; y < DefaultHeight; y++){

View File

@ -24,7 +24,6 @@
#include "Client.h"
#include "World.h"
#include "IAudioDevice.h"
#include <stdlib.h>
#include "ParticleSpriteEntity.h"
#include "IAudioChunk.h"
@ -112,7 +111,7 @@ namespace spades {
}
if(dist < 40.f * 40.f){
int splats = rand() % 3;
int splats = mt_engine_client() % 3;
Handle<IImage> img = client->GetRenderer()->RegisterImage("Gfx/White.tga");

View File

@ -35,6 +35,12 @@ namespace spades {
}
*/
std::random_device r_device;
std::mt19937_64 mt_engine(r_device()); // Seed Mersenne twister with non-deterministic 32-bit seed
std::uniform_real_distribution<float> real_dist(0, 1);
void Matrix4Multiply(const float a[16], const float b[16], float out[16]) {
out[ 0] = b[ 0]*a[ 0] + b[ 1]*a[ 4] + b[ 2]*a[ 8] + b[ 3]*a[12];
out[ 1] = b[ 0]*a[ 1] + b[ 1]*a[ 5] + b[ 2]*a[ 9] + b[ 3]*a[13];
@ -621,8 +627,7 @@ namespace spades {
}
float GetRandom() {
const double factor = 1.f / ((double)RAND_MAX + 1.);
return (float)((double)rand() * factor);
return real_dist(mt_engine);
}
float SmoothStep(float v){
return v * v * (3.f - 2.f * v);

View File

@ -25,6 +25,7 @@
#include <string>
#include <stdint.h> // uint32_t --> msvc
#include <algorithm> // std::max / std::min
#include <random>
#ifdef _MSC_VER
#define isnan _isnan
@ -34,6 +35,11 @@ static inline long lround(double num) { return (long)(num > 0 ? num + 0.5 : ceil
namespace spades {
// Make mt_engine and a real dist [0,1] accesible everywhere in the spades namespace
extern std::mt19937_64 mt_engine;
extern std::uniform_real_distribution<float> real_dist;
#pragma mark - Integer Vector
class IntVector3 {

View File

@ -381,7 +381,7 @@ namespace spades {
for(int i = 0; i < 8; i++){
if(numDirtyChunks <= 0)
break;
int idx = rand() % numDirtyChunks;
int idx = mt_engine() % numDirtyChunks;
Chunk& c = chunks[dirtyChunkIds[idx]];
// remove from list (fast)

View File

@ -29,7 +29,6 @@
#include "GLRenderer.h"
#include "../Core/Debug.h"
#include "GLImage.h"
#include <stdlib.h>
#include <Core/Settings.h>
SPADES_SETTING(r_hdr);
@ -157,7 +156,7 @@ namespace spades {
SPADES_MARK_FUNCTION();
noise.resize(128 * 128);
uint32_t rnd = (uint32_t)rand() ^ ((uint32_t)rand() << 16);
uint32_t rnd = mt_engine();
rnd ^= 0x7abd4513;
for(size_t i = 0; i < 128 * 128; i++) {
noise[i] = rnd;

View File

@ -508,7 +508,7 @@ namespace spades {
for(int i = 0; i < 8; i++){
if(numDirtyChunks <= 0)
break;
int idx = rand() % numDirtyChunks;
int idx = mt_engine() % numDirtyChunks;
Chunk& c = chunks[dirtyChunkIds[idx]];
// remove from list (fast)

View File

@ -227,7 +227,7 @@ namespace spades {
cell.magnitude = mag;
cell.phase = rand() | ((uint32_t)rand() << 16);
cell.phase = mt_engine();
cell.phasePerSecond = dist * 1.e+9f * 128 / Size;
}
@ -466,8 +466,8 @@ namespace spades {
int count = (int)floorf(dt * 600.f);
if(count > 400) count = 400;
for(int i = 0; i < count; i++){
int ox = rand() % (size - 2);
int oy = rand() % (size - 2);
int ox = mt_engine() % (size - 2);
int oy = mt_engine() % (size - 2);
static const float gauss[] = {
0.225610111284052f,
0.548779777431897f,

View File

@ -1144,7 +1144,7 @@ namespace spades {
renderStopwatch.Reset();
/*
{
uint32_t rdb = rand();
uint32_t rdb = mt_engine();
uint32_t *ptr = fb->GetPixels();
for(int pixels = fb->GetWidth() * fb->GetHeight() / 10;
pixels > 0; pixels--) {

View File

@ -19,9 +19,10 @@
*/
#include <Core/Math.h>
#include <stdlib.h>
#include "ScriptManager.h"
#include <new>
#include <random>
namespace spades {
@ -34,31 +35,24 @@ namespace spades {
case 1:
return 0;
case 2:
return rand() & 1;
return mt_engine() & 1;
case 4:
return rand() & 3;
return mt_engine() & 3;
case 8:
return rand() & 7;
return mt_engine() & 7;
case 16:
return rand() & 15;
return mt_engine() & 15;
case 32:
return rand() & 31;
return mt_engine() & 31;
case 64:
return rand() & 63;
return mt_engine() & 63;
}
unsigned int ret;
unsigned int mask = range;
for(unsigned int i = range - 1; i != 0; i >>= 1) {
mask |= i;
}
do {
ret = rand();
if(range - 1 > (unsigned int)RAND_MAX) {
ret += rand() * ((unsigned int)(RAND_MAX) + 1);
}
ret &= mask;
} while( ret >= range );
return ret;
// We can't directly use the engine here, we need a distribution
// range - 1 because it's inclusive and we want exclusive
std::uniform_int_distribution<unsigned int> int_dist(0, range - 1);
return int_dist(mt_engine);
}
static unsigned int GetRandomUIntRange(unsigned int a,
unsigned int b){