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++) | |||
| { | |||
| if(Welded[j] == -1) | |||
| m_vert[i].m_coord *= 1.0f + RandF(r); | |||
| m_vert[i].m_coord *= 1.0f + rand(r); | |||
| else | |||
| m_vert[i].m_coord = m_vert[Welded[j]].m_coord; | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| // | |||
| // 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 | |||
| // modify it under the terms of the Do What The Fuck You Want To | |||
| // Public License, Version 2, as published by Sam Hocevar. See | |||
| @@ -22,23 +22,77 @@ | |||
| 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. */ | |||
| 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++) | |||
| { | |||
| 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[j] = tmp; | |||
| } | |||
| @@ -185,7 +185,7 @@ void *TickerData::GameThreadMain(void * /* p */) | |||
| data->frame++; | |||
| /* Ensure some randomness */ | |||
| (void)std::rand(); | |||
| rand<int>(); | |||
| /* If recording with fixed framerate, set deltatime to a fixed value */ | |||
| if (data->recording && data->fps) | |||
| @@ -37,11 +37,11 @@ void bench_half(int mode) | |||
| { | |||
| case 1: | |||
| for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++) | |||
| ph[i] = half::makebits(rand()); | |||
| ph[i] = half::makebits(rand<uint16_t>()); | |||
| break; | |||
| case 2: | |||
| 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; | |||
| } | |||
| @@ -51,15 +51,15 @@ void bench_trig(int mode) | |||
| { | |||
| case 1: | |||
| for (size_t i = 0; i < TRIG_TABLE_SIZE; i++) | |||
| pf[i] = RandF(-1e5f, 1e5f); | |||
| pf[i] = rand(-1e5f, 1e5f); | |||
| break; | |||
| case 2: | |||
| 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; | |||
| case 3: | |||
| 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; | |||
| } | |||
| @@ -39,7 +39,7 @@ void bench_matrix(int mode) | |||
| for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++) | |||
| for (int j = 0; j < 4; j++) | |||
| 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; | |||
| } | |||
| @@ -157,32 +157,32 @@ public: | |||
| { | |||
| case 0: | |||
| { | |||
| RandValue = (int)(lol::RandF() * (SphereLimit - 1)); | |||
| RandValue = rand(SphereLimit); | |||
| break; | |||
| } | |||
| case 1: | |||
| { | |||
| RandValue = SphereLimit + (int)(lol::RandF() * ((ConeLimit - SphereLimit) - 1)); | |||
| RandValue = rand(SphereLimit, ConeLimit); | |||
| break; | |||
| } | |||
| case 2: | |||
| { | |||
| RandValue = ConeLimit + (int)(lol::RandF() * ((CylLimit - ConeLimit) - 1)); | |||
| RandValue = rand(ConeLimit, CylLimit); | |||
| break; | |||
| } | |||
| case 3: | |||
| { | |||
| RandValue = CylLimit + (int)(lol::RandF() * ((CapsLimit - CylLimit) - 1)); | |||
| RandValue = rand(CylLimit, CapsLimit); | |||
| break; | |||
| } | |||
| case 4: | |||
| { | |||
| RandValue = CapsLimit + (int)(lol::RandF() * ((MeshRand.Count() - CapsLimit) - 1)); | |||
| RandValue = rand(CapsLimit, MeshRand.Count()); | |||
| break; | |||
| } | |||
| default: | |||
| { | |||
| RandValue = (int)(lol::RandF() * (MeshRand.Count() - 1)); | |||
| RandValue = rand(MeshRand.Count()); | |||
| } | |||
| } | |||
| @@ -132,7 +132,7 @@ LOLUNIT_FIXTURE(BuildTest) | |||
| { | |||
| double x, y; | |||
| y = x = 1.0 + RandF(0.1f, 0.2f); | |||
| y = x = 1.0 + rand(0.1f, 0.2f); | |||
| y += 4503599627370496.0; | |||
| /* The compiler should optimise this away */ | |||
| y -= 4503599627370496.0; | |||
| @@ -145,7 +145,7 @@ LOLUNIT_FIXTURE(BuildTest) | |||
| { | |||
| double x, y; | |||
| y = x = 1.0 + RandF(0.1f, 0.2f); | |||
| y = x = 1.0 + rand(0.1f, 0.2f); | |||
| y += 4503599627370496.0; | |||
| FP_USE(y); | |||
| /* The compiler should not optimise this away */ | |||