diff --git a/util/bits/bits.cpp b/util/bits/bits.cpp new file mode 100644 index 0000000000..5267078abe --- /dev/null +++ b/util/bits/bits.cpp @@ -0,0 +1,40 @@ +#include "util/bits/bits.h" + +namespace bits { + +// See http://graphics.stanford.edu/~seander/bithacks.html + +static const unsigned char BitsSetTable256[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int CountBits8(uint8 v) { + return BitsSetTable256[v]; +} + +int CountBits16(uint16 v) { + return BitsSetTable256[v & 0xFF] + BitsSetTable256[v >> 8]; +} + +int CountBits32(uint32 v) { + v = v - ((v >> 1) & 0x55555555); // reuse input as temporary + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp + return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count +} + +} // namespace bits diff --git a/util/bits/varint.cpp b/util/bits/varint.cpp new file mode 100644 index 0000000000..8cd94d052c --- /dev/null +++ b/util/bits/varint.cpp @@ -0,0 +1,35 @@ +#include "util/bits/varint.h" + +namespace varint { + +void Encode32(uint32 value, char **dest) { + // Simple varint + char *p = *dest; + while (value > 127) { + *p++ = (value & 127); + value >>= 7; + } + *p++ = value | 0x80; + *dest = p; +} + +uint32 Decode32(const char **ptr) { + uint32 value = 0; + const char *p = *ptr; + while (true) { + uint8 b = *p++; + if (b & 0x80) { + *ptr = p; + return value | (b & 0x7F); + } else { + value |= *p++; + value <<= 7; + } + } + *ptr = p; + return value; +} + +} // namespace varint + + diff --git a/util/hash/hash.cpp b/util/hash/hash.cpp new file mode 100644 index 0000000000..264450dabe --- /dev/null +++ b/util/hash/hash.cpp @@ -0,0 +1,65 @@ +#include "base/base.h" +#include "util/hash/hash.h" + +namespace hash { + +// uint32_t +// WARNING - may read one more byte! +// Implementation from Wikipedia. +uint32 HashFletcher(const uint8 *data_uint8, size_t length) { + const uint16 *data = (const uint16 *)data_uint8; + size_t len = (length + 1) / 2; + uint32 sum1 = 0xffff, sum2 = 0xffff; + + while (len) { + size_t tlen = len > 360 ? 360 : len; + len -= tlen; + + do { + sum1 += *data++; + sum2 += sum1; + } while (--tlen); + + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + } + + /* Second reduction step to reduce sums to 16 bits */ + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + return sum2 << 16 | sum1; +} + +// Implementation from Wikipedia +// Slightly slower than Fletcher above, but slighly more reliable. +#define MOD_ADLER 65521 +// data: Pointer to the data to be summed; len is in bytes +uint32 HashAdler32(const uint8 *data, size_t len) { + uint32 a = 1, b = 0; + while (len) { + size_t tlen = len > 5550 ? 5550 : len; + len -= tlen; + do { + a += *data++; + b += a; + } while (--tlen); + + a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); + b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); + } + + // It can be shown that a <= 0x1013a here, so a single subtract will do. + if (a >= MOD_ADLER) { + a -= MOD_ADLER; + } + + // It can be shown that b can reach 0xfff87 here. + b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); + + if (b >= MOD_ADLER) { + b -= MOD_ADLER; + } + return (b << 16) | a; +} + +} // namespace hash diff --git a/util/random/perlin.cpp b/util/random/perlin.cpp new file mode 100644 index 0000000000..d0ee8a9fa4 --- /dev/null +++ b/util/random/perlin.cpp @@ -0,0 +1,72 @@ +#include "util/random/perlin.h" + +#include + +// This should go in the const section of the binary. +static const int p[512] = { + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, +}; + +inline float fade(float t) { + return t * t * t * (t * (t * 6 - 15) + 10); +} + +inline float lerp(float t, float a, float b) { + return a + t * (b - a); +} + +inline float grad(int hash, float x, float y, float z) { + int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + float u = h < 8 ? x : y; // INTO 12 GRADIENT DIRECTIONS. + float v = h < 4 ? y : (h == 12 || h == 14 ? x : z); + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); +} + +float Noise(double z, double y, double x) { + double fx = floor(x), fy = floor(y), fz = floor(z); + int X = (int)fx & 255, // FIND UNIT CUBE THAT + Y = (int)fy & 255, // CONTAINS POINT. + Z = (int)fz & 255; + x -= fx; // FIND RELATIVE X,Y,Z + y -= fy; // OF POINT IN CUBE. + z -= fz; + float u = fade(x); // COMPUTE FADE CURVES + float v = fade(y); // FOR EACH OF X,Y,Z. + float w = fade(z); + int A = p[X ]+Y, B = p[X+1]+Y; + int AA = p[A]+Z, AB = p[A+1]+Z; // HASH COORDINATES OF + int BA = p[B]+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS, + return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD + grad(p[BA ], x-1, y , z )), // BLENDED + lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS + grad(p[BB ], x-1, y-1, z ))), // FROM 8 + lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS + grad(p[BA+1], x-1, y , z-1 )), // OF CUBE + lerp(u, grad(p[AB+1], x , y-1, z-1 ), + grad(p[BB+1], x-1, y-1, z-1 )))); +}