--- deliantra/server/include/util.h 2007/01/07 02:39:14 1.26 +++ deliantra/server/include/util.h 2007/01/18 19:32:37 1.32 @@ -8,6 +8,7 @@ #endif #include +#include #include #include @@ -26,6 +27,62 @@ // most ugly macro I ever wrote #define declvar(type, name, value) if (type name = 0) { } else if (((name) = (value)), 1) +// in range including end +#define IN_RANGE_INC(val,beg,end) \ + ((unsigned int)(val) - (unsigned int)(beg) <= (unsigned int)(end) - (unsigned int)(beg)) + +// in range excluding end +#define IN_RANGE_EXC(val,beg,end) \ + ((unsigned int)(val) - (unsigned int)(beg) < (unsigned int)(end) - (unsigned int)(beg)) + +void fork_abort (const char *msg); + +template static inline T min (T a, U b) { return a < (T)b ? a : (T)b; } +template static inline T max (T a, U b) { return a > (T)b ? a : (T)b; } +template static inline T clamp (T v, U a, V b) { return v < (T)a ? a : v >(T)b ? b : v; } + +template static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; } + +// this is much faster than crossfires original algorithm +// on modern cpus +inline int +isqrt (int n) +{ + return (int)sqrtf ((float)n); +} + +// this is only twice as fast as naive sqrtf (dx*dy+dy*dy) +#if 0 +// and has a max. error of 6 in the range -100..+100. +#else +// and has a max. error of 9 in the range -100..+100. +#endif +inline int +idistance (int dx, int dy) +{ + unsigned int dx_ = abs (dx); + unsigned int dy_ = abs (dy); + +#if 0 + return dx_ > dy_ + ? (dx_ * 61685 + dy_ * 26870) >> 16 + : (dy_ * 61685 + dx_ * 26870) >> 16; +#else + return dx_ + dy_ - min (dx_, dy_) * 5 / 8; +#endif +} + +/* + * absdir(int): Returns a number between 1 and 8, which represent + * the "absolute" direction of a number (it actually takes care of + * "overflow" in previous calculations of a direction). + */ +inline int +absdir (int d) +{ + return ((d - 1) & 7) + 1; +} + // makes dynamically allocated objects zero-initialised struct zero_initialised { @@ -134,6 +191,37 @@ } }; +// P. L'Ecuyer, “Maximally Equidistributed Combined Tausworthe Generators”, Mathematics of Computation, 65, 213 (1996), 203–213. +// http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps +// http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps +struct tausworthe_random_generator +{ + uint32_t state [4]; + + tausworthe_random_generator (uint32_t seed); + uint32_t next (); + + uint32_t operator ()(uint32_t r_max) + { + return next () % r_max; + } + + // return a number within (min .. max) + int operator () (int r_min, int r_max) + { + return r_min + next () % max (r_max - r_min + 1, 1); + } + + double operator ()() + { + return next () / (double)0xFFFFFFFFU; + } +}; + +typedef tausworthe_random_generator rand_gen; + +extern rand_gen rndm; + template struct refptr { @@ -260,12 +348,6 @@ } }; -template static inline T min (T a, U b) { return a < (T)b ? a : (T)b; } -template static inline T max (T a, U b) { return a > (T)b ? a : (T)b; } -template static inline T clamp (T v, U a, V b) { return v < (T)a ? a : v >(T)b ? b : v; } - -template static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; } - // basically does what strncpy should do, but appends "..." to strings exceeding length void assign (char *dst, const char *src, int maxlen);