-
Notifications
You must be signed in to change notification settings - Fork 8
/
fastrand.cpp
93 lines (71 loc) · 1.7 KB
/
fastrand.cpp
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 <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "SDL_types.h"
static Uint32 randomSeed;
void SeedRandom(Uint32 Seed)
{
#ifdef SERIOUS_DEBUG
fprintf(stderr, "SeedRandom(%lu)\n", Seed);
#endif
if ( ! Seed ) {
srand((unsigned int)time(NULL));
Seed = (((rand()%0xFFFF)<<16)|(rand()%0xFFFF));
}
randomSeed = Seed;
}
Uint32 GetRandSeed(void)
{
return(randomSeed);
}
/* This magic is wholly the result of Andrew Welch, not me. :-) */
Uint16 FastRandom(Uint16 range)
{
Uint16 result;
register Uint32 calc;
register Uint32 regD0;
register Uint32 regD1;
register Uint32 regD2;
#ifdef SERIOUS_DEBUG
fprintf(stderr, "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
fprintf(stderr, "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
fprintf(stderr, "Result: %hu\n", result);
#endif
return result;
}