1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
/* -- Return a random value between 0 and range - 1 */
#include <sys/time.h>
static unsigned long randomSeed;
void SeedRandom(unsigned long Seed)
{
struct timeval tv;
#ifdef SERIOUS_DEBUG
printf("SeedRandom(%lu)\n", Seed);
#endif
if ( ! Seed ) {
gettimeofday(&tv, (struct timezone*)NULL);
randomSeed = ((tv.tv_usec<<16)|((tv.tv_sec^tv.tv_usec)&0xFFFF));
return;
}
randomSeed = Seed;
}
unsigned long GetRandSeed(void)
{
return(randomSeed);
}
/* This magic is wholly the result of Andrew Welch, not me. :-) */
short FastRandom(short range)
{
short result;
register unsigned long calc;
register unsigned long regD0;
register unsigned long regD1;
register unsigned long regD2;
#ifdef SERIOUS_DEBUG
printf("FastRandom(%hd) Seed in: %lu ", range, randomSeed);
#endif
calc = randomSeed;
regD0 = 0x41A7;
regD2 = regD0;
regD0 *= calc & 0x0000FFFF;
regD1 = regD0;
regD1 = regD1 >> 16;
regD2 *= calc >> 16;
regD2 += regD1;
regD1 = regD2;
regD1 += regD1;
regD1 = regD1 >> 16;
regD0 &= 0x0000FFFF;
regD0 -= 0x7FFFFFFF;
regD2 &= 0x00007FFF;
regD2 = (regD2 << 16) + (regD2 >> 16);
regD2 += regD1;
regD0 += regD2;
/* An unsigned value < 0 is always 0 */
/*************************************
Not compiled:
if (regD0 < 0)
regD0 += 0x7FFFFFFF;
*************************************/
randomSeed = regD0;
#ifdef SERIOUS_DEBUG
printf("Seed out: %lu ", randomSeed);
#endif
if ((regD0 & 0x0000FFFF) == 0x8000)
regD0 &= 0xFFFF0000;
/* -- Now that we have our pseudo random number, pin it to the range we want */
regD1 = range;
regD1 *= (regD0 & 0x0000FFFF);
regD1 = (regD1 >> 16);
result = regD1;
#ifdef SERIOUS_DEBUG
printf("Result: %hu\n", result);
#endif
return result;
}
|