File: fastrand.cpp

package info (click to toggle)
maelstrom 1.4.3-L2.0.6-13
  • links: PTS
  • area: non-free
  • in suites: potato
  • size: 4,352 kB
  • ctags: 2,231
  • sloc: cpp: 22,044; ansic: 1,853; sh: 242; makefile: 223
file content (93 lines) | stat: -rw-r--r-- 1,756 bytes parent folder | download
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;
}