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 */ | ||||