that lets us draw integer random values too.legacy
@@ -1212,7 +1212,7 @@ void EasyMesh::RadialJitter(float r) | |||||
for (i = m_cursors.Last().m1, j = 0; i < m_vert.Count(); i++, j++) | for (i = m_cursors.Last().m1, j = 0; i < m_vert.Count(); i++, j++) | ||||
{ | { | ||||
if(Welded[j] == -1) | if(Welded[j] == -1) | ||||
m_vert[i].m_coord *= 1.0f + RandF(r); | |||||
m_vert[i].m_coord *= 1.0f + rand(r); | |||||
else | else | ||||
m_vert[i].m_coord = m_vert[Welded[j]].m_coord; | m_vert[i].m_coord = m_vert[Welded[j]].m_coord; | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | // This program is free software; you can redistribute it and/or | ||||
// modify it under the terms of the Do What The Fuck You Want To | // modify it under the terms of the Do What The Fuck You Want To | ||||
// Public License, Version 2, as published by Sam Hocevar. See | // Public License, Version 2, as published by Sam Hocevar. See | ||||
@@ -22,23 +22,77 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
/* Random float value */ | |||||
static inline float RandF() | |||||
/* Random number generators */ | |||||
template<typename T> static inline T rand(); | |||||
template<typename T> static inline T rand(T a); | |||||
template<typename T> static inline T rand(T a, T b); | |||||
/* One-value random number generators */ | |||||
template<typename T> static inline T rand(T a) | |||||
{ | { | ||||
using namespace std; | |||||
return (float)std::rand() / RAND_MAX; | |||||
return rand<T>() % a; | |||||
} | } | ||||
static inline float RandF(float val) | |||||
template<> | |||||
inline half rand<half>(half a) { return a * std::rand() / RAND_MAX; } | |||||
template<> | |||||
inline float rand<float>(float a) { return a * std::rand() / RAND_MAX; } | |||||
template<> | |||||
inline double rand<double>(double a) { return a * std::rand() / RAND_MAX; } | |||||
template<> | |||||
inline ldouble rand<ldouble>(ldouble a) { return a * std::rand() / RAND_MAX; } | |||||
/* Two-value random number generator -- no need for specialisation */ | |||||
template<typename T> static inline T rand(T a, T b) | |||||
{ | { | ||||
return RandF() * val; | |||||
return a + rand<T>(b - a); | |||||
} | } | ||||
static inline float RandF(float min, float max) | |||||
/* Default random number generator */ | |||||
template<typename T> static inline T rand() | |||||
{ | { | ||||
return min + RandF() * (max - min); | |||||
switch (sizeof(T)) | |||||
{ | |||||
case 1: | |||||
return static_cast<T>(std::rand() & 0xff); | |||||
case 2: | |||||
if (RAND_MAX >= 0xffff) | |||||
return static_cast<T>(std::rand()); | |||||
else | |||||
return static_cast<T>((std::rand() << 8) ^ std::rand()); | |||||
case 4: | |||||
if (RAND_MAX >= 0xffff) | |||||
return static_cast<T>((std::rand() << 16) ^ std::rand()); | |||||
else | |||||
return static_cast<T>((std::rand() << 24) ^ (std::rand() << 16) | |||||
^ (std::rand() << 8) ^ std::rand()); | |||||
case 8: | |||||
if (RAND_MAX >= 0xffff) | |||||
return static_cast<T>(((uint64_t)std::rand() << 48) | |||||
^ ((uint64_t)std::rand() << 32) | |||||
^ ((uint64_t)std::rand() << 16) | |||||
^ ((uint64_t)std::rand())); | |||||
else | |||||
return static_cast<T>(((uint64_t)std::rand() << 56) | |||||
^ ((uint64_t)std::rand() << 48) | |||||
^ ((uint64_t)std::rand() << 40) | |||||
^ ((uint64_t)std::rand() << 32) | |||||
^ ((uint64_t)std::rand() << 24) | |||||
^ ((uint64_t)std::rand() << 16) | |||||
^ ((uint64_t)std::rand() << 8) | |||||
^ ((uint64_t)std::rand())); | |||||
default: | |||||
ASSERT(false, "rand() doesn’t support types of size %d\n", | |||||
(int)sizeof(T)); | |||||
} | |||||
} | } | ||||
template<> inline half rand<half>() { return rand<half>(1.f); } | |||||
template<> inline float rand<float>() { return rand<float>(1.f); } | |||||
template<> inline double rand<double>() { return rand<double>(1.0); } | |||||
template<> inline ldouble rand<ldouble>() { return rand<ldouble>(1.0); } | |||||
/* Next power of two. */ | /* Next power of two. */ | ||||
template <typename T> static inline T PotUp(T val) | template <typename T> static inline T PotUp(T val) | ||||
{ | { | ||||
@@ -216,7 +216,7 @@ void Scene::Render() // XXX: rename to Blit() | |||||
for (int i = 0; i < data->m_tiles.Count(); i++) | for (int i = 0; i < data->m_tiles.Count(); i++) | ||||
{ | { | ||||
Tile tmp = data->m_tiles[i]; | Tile tmp = data->m_tiles[i]; | ||||
int j = std::rand() % data->m_tiles.Count(); | |||||
int j = rand<int>() % data->m_tiles.Count(); | |||||
data->m_tiles[i] = data->m_tiles[j]; | data->m_tiles[i] = data->m_tiles[j]; | ||||
data->m_tiles[j] = tmp; | data->m_tiles[j] = tmp; | ||||
} | } | ||||
@@ -185,7 +185,7 @@ void *TickerData::GameThreadMain(void * /* p */) | |||||
data->frame++; | data->frame++; | ||||
/* Ensure some randomness */ | /* Ensure some randomness */ | ||||
(void)std::rand(); | |||||
rand<int>(); | |||||
/* If recording with fixed framerate, set deltatime to a fixed value */ | /* If recording with fixed framerate, set deltatime to a fixed value */ | ||||
if (data->recording && data->fps) | if (data->recording && data->fps) | ||||
@@ -37,11 +37,11 @@ void bench_half(int mode) | |||||
{ | { | ||||
case 1: | case 1: | ||||
for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++) | for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++) | ||||
ph[i] = half::makebits(rand()); | |||||
ph[i] = half::makebits(rand<uint16_t>()); | |||||
break; | break; | ||||
case 2: | case 2: | ||||
for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++) | for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++) | ||||
ph[i] = RandF(-2.0f, 2.0f); | |||||
ph[i] = rand(-2.0f, 2.0f); | |||||
break; | break; | ||||
} | } | ||||
@@ -51,15 +51,15 @@ void bench_trig(int mode) | |||||
{ | { | ||||
case 1: | case 1: | ||||
for (size_t i = 0; i < TRIG_TABLE_SIZE; i++) | for (size_t i = 0; i < TRIG_TABLE_SIZE; i++) | ||||
pf[i] = RandF(-1e5f, 1e5f); | |||||
pf[i] = rand(-1e5f, 1e5f); | |||||
break; | break; | ||||
case 2: | case 2: | ||||
for (size_t i = 0; i < TRIG_TABLE_SIZE; i++) | for (size_t i = 0; i < TRIG_TABLE_SIZE; i++) | ||||
pf[i] = RandF(-M_PI, M_PI); | |||||
pf[i] = rand(-M_PI, M_PI); | |||||
break; | break; | ||||
case 3: | case 3: | ||||
for (size_t i = 0; i < TRIG_TABLE_SIZE; i++) | for (size_t i = 0; i < TRIG_TABLE_SIZE; i++) | ||||
pf[i] = RandF(-1e-2f, 1e-2f); | |||||
pf[i] = rand(-1e-2f, 1e-2f); | |||||
break; | break; | ||||
} | } | ||||
@@ -39,7 +39,7 @@ void bench_matrix(int mode) | |||||
for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++) | for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++) | ||||
for (int j = 0; j < 4; j++) | for (int j = 0; j < 4; j++) | ||||
for (int k = 0; k < 4; k++) | for (int k = 0; k < 4; k++) | ||||
pm[i][j][k] = RandF(-2.0f, 2.0f); | |||||
pm[i][j][k] = rand(-2.0f, 2.0f); | |||||
break; | break; | ||||
} | } | ||||
@@ -157,32 +157,32 @@ public: | |||||
{ | { | ||||
case 0: | case 0: | ||||
{ | { | ||||
RandValue = (int)(lol::RandF() * (SphereLimit - 1)); | |||||
RandValue = rand(SphereLimit); | |||||
break; | break; | ||||
} | } | ||||
case 1: | case 1: | ||||
{ | { | ||||
RandValue = SphereLimit + (int)(lol::RandF() * ((ConeLimit - SphereLimit) - 1)); | |||||
RandValue = rand(SphereLimit, ConeLimit); | |||||
break; | break; | ||||
} | } | ||||
case 2: | case 2: | ||||
{ | { | ||||
RandValue = ConeLimit + (int)(lol::RandF() * ((CylLimit - ConeLimit) - 1)); | |||||
RandValue = rand(ConeLimit, CylLimit); | |||||
break; | break; | ||||
} | } | ||||
case 3: | case 3: | ||||
{ | { | ||||
RandValue = CylLimit + (int)(lol::RandF() * ((CapsLimit - CylLimit) - 1)); | |||||
RandValue = rand(CylLimit, CapsLimit); | |||||
break; | break; | ||||
} | } | ||||
case 4: | case 4: | ||||
{ | { | ||||
RandValue = CapsLimit + (int)(lol::RandF() * ((MeshRand.Count() - CapsLimit) - 1)); | |||||
RandValue = rand(CapsLimit, MeshRand.Count()); | |||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
{ | { | ||||
RandValue = (int)(lol::RandF() * (MeshRand.Count() - 1)); | |||||
RandValue = rand(MeshRand.Count()); | |||||
} | } | ||||
} | } | ||||
@@ -132,7 +132,7 @@ LOLUNIT_FIXTURE(BuildTest) | |||||
{ | { | ||||
double x, y; | double x, y; | ||||
y = x = 1.0 + RandF(0.1f, 0.2f); | |||||
y = x = 1.0 + rand(0.1f, 0.2f); | |||||
y += 4503599627370496.0; | y += 4503599627370496.0; | ||||
/* The compiler should optimise this away */ | /* The compiler should optimise this away */ | ||||
y -= 4503599627370496.0; | y -= 4503599627370496.0; | ||||
@@ -145,7 +145,7 @@ LOLUNIT_FIXTURE(BuildTest) | |||||
{ | { | ||||
double x, y; | double x, y; | ||||
y = x = 1.0 + RandF(0.1f, 0.2f); | |||||
y = x = 1.0 + rand(0.1f, 0.2f); | |||||
y += 4503599627370496.0; | y += 4503599627370496.0; | ||||
FP_USE(y); | FP_USE(y); | ||||
/* The compiler should not optimise this away */ | /* The compiler should not optimise this away */ | ||||