OpenBarnyard
 
Loading...
Searching...
No Matches
TRandom.cpp
Go to the documentation of this file.
1#include "ToshiPCH.h"
2#include "TRandom.h"
3
4#ifdef USE_PORTABLE
5# define cut( a ) ( (a)&0xffffffff ) /* Cut the integer down to 32bits */
6#else
7# define cut( a ) ( a ) /* A no-op */
8#endif
9
10#define ind( mm, x ) ( ( mm )[ ( x >> 2 ) & ( RANDSIZ - 1 ) ] )
11/* the call to cut() is a macro defined in standard.h */
12#define rngstep( mix, a, b, mm, m, m2, r, x ) \
13 { \
14 x = *m; \
15 a = cut( ( a ^ ( mix ) ) + *( m2++ ) ); \
16 *( m++ ) = y = cut( ind( mm, x ) + a + b ); \
17 *( r++ ) = b = cut( ind( mm, y >> RANDSIZL ) + x ); \
18 }
19
20#define mix( a, b, c, d, e, f, g, h ) \
21 { \
22 a ^= b << 11; \
23 d += a; \
24 b += c; \
25 b ^= c >> 2; \
26 e += b; \
27 c += d; \
28 c ^= d << 8; \
29 f += c; \
30 d += e; \
31 d ^= e >> 16; \
32 g += d; \
33 e += f; \
34 e ^= f << 10; \
35 h += e; \
36 f += g; \
37 f ^= g >> 4; \
38 a += f; \
39 g += h; \
40 g ^= h << 8; \
41 b += g; \
42 h += a; \
43 h ^= a >> 9; \
44 c += h; \
45 a += b; \
46 }
47
48#define shuffle( a, b, mm, m, m2, r, x ) \
49 { \
50 rngstep( a << 13, a, b, mm, m, m2, r, x ); \
51 rngstep( a >> 6, a, b, mm, m, m2, r, x ); \
52 rngstep( a << 2, a, b, mm, m, m2, r, x ); \
53 rngstep( a >> 16, a, b, mm, m, m2, r, x ); \
54 }
55
57
58// $Barnyard: FUNCTION 006b5ca0
60{
61 THPTimer timer = THPTimer();
62 SetSeed( timer.GetRaw32() );
63}
64
65// $Barnyard: FUNCTION 006b5850
66void TRandom::Isaac()
67{
68 TUINT a, b, x, y, *m, *mm, *m2, *r, *mend;
69 mm = m_pRandmem;
70 r = m_pRandrsl;
71 a = m_uiRandA;
72 b = cut( m_uiRandB + ( ++m_uiRandC ) );
73
74 m = mm;
75 mend = m2 = m + ( RANDSIZ / 2 );
76 while ( m < mend )
77 {
78 shuffle( a, b, mm, m, m2, r, x );
79 }
80
81 m2 = mm;
82 while ( m2 < mend )
83 {
84 shuffle( a, b, mm, m, m2, r, x );
85 }
86
87 m_uiRandA = a;
88 m_uiRandB = b;
89}
90
91// $Barnyard: FUNCTION 006b5af0
92void TRandom::RandInit()
93{
94 TUINT32 a, b, c, d, e, f, g, h;
95 TINT i;
96
97 m_uiRandA = m_uiRandB = m_uiRandC = 0;
98
99 /* Initialize a to h with the golden ratio and seed */
100 a = b = c = d = e = f = g = h = 0x9e3779b9 + m_uiSeed;
101
102 /* scramble it */
103 for ( i = 0; i < RANDSIZL; i++ )
104 {
105 mix( a, b, c, d, e, f, g, h );
106 }
107
108 TUINT32* m = m_pRandmem;
109 TUINT32* r = m_pRandrsl;
110
111 /* initialize using the contents of r[] as the seed */
112 for ( i = 0; i < RANDSIZ; i += 8 )
113 {
114 a += r[ i ];
115 b += r[ i + 1 ];
116 c += r[ i + 2 ];
117 d += r[ i + 3 ];
118 e += r[ i + 4 ];
119 f += r[ i + 5 ];
120 g += r[ i + 6 ];
121 h += r[ i + 7 ];
122
123 mix( a, b, c, d, e, f, g, h );
124
125 m[ i ] = a;
126 m[ i + 1 ] = b;
127 m[ i + 2 ] = c;
128 m[ i + 3 ] = d;
129 m[ i + 4 ] = e;
130 m[ i + 5 ] = f;
131 m[ i + 6 ] = g;
132 m[ i + 7 ] = h;
133 }
134
135 /* do a second pass to make all of the seed affect all of m */
136 for ( i = 0; i < RANDSIZ; i += 8 )
137 {
138 a += m[ i ];
139 b += m[ i + 1 ];
140 c += m[ i + 2 ];
141 d += m[ i + 3 ];
142 e += m[ i + 4 ];
143 f += m[ i + 5 ];
144 g += m[ i + 6 ];
145 h += m[ i + 7 ];
146
147 mix( a, b, c, d, e, f, g, h );
148
149 m[ i ] = a;
150 m[ i + 1 ] = b;
151 m[ i + 2 ] = c;
152 m[ i + 3 ] = d;
153 m[ i + 4 ] = e;
154 m[ i + 5 ] = f;
155 m[ i + 6 ] = g;
156 m[ i + 7 ] = h;
157 }
158
159 Isaac();
160 m_uiRndCnt = RANDSIZ;
161}
162
163TINT TRandom::GetInt( TUINT32 a_iLower, TUINT32 a_iUpper )
164{
165 TASSERT( a_iUpper > a_iLower, "a_iLower can't be higher than a_iUpper" );
166
167 unsigned long long rand = RandRaw();
168 unsigned long long range = a_iUpper - a_iLower;
169 return a_iLower + ( range * rand >> 32 );
170}
171
172// $Barnyard: FUNCTION 006b5ce0
174{
175 return GetInt( 0, a_iUpper );
176}
177
179{
180 return RandRaw();
181}
182
184{
185 return ( RandRaw() >> 1 ) * 4.6566129E-10f;
186}
187
188// $Barnyard: FUNCTION 00401080
190{
191 return (TFLOAT)( RandRaw() >> 1 ) * 4.6566129E-10f * ( a_fUpper - a_fLower ) + a_fLower;
192}
193
195{
196 return ( RandRaw() >> 1 ) * 9.3132257E-10f * -1.0f;
197}
198
199void TRandom::SetSeed( TUINT a_uiSeed )
200{
201 m_uiSeed = a_uiSeed;
202 RandInit();
203}
204
206{
207 if ( ( m_uiRndCnt-- ) != 0 )
208 {
209 return m_pRandrsl[ m_uiRndCnt ];
210 }
211
212 Isaac();
213 m_uiRndCnt = RANDSIZ - 1;
214 return m_pRandrsl[ RANDSIZ - 1 ];
215}
216
#define shuffle(a, b, mm, m, m2, r, x)
Definition TRandom.cpp:48
#define cut(a)
Definition TRandom.cpp:7
#define mix(a, b, c, d, e, f, g, h)
Definition TRandom.cpp:20
#define RANDSIZL
Definition TRandom.h:14
#define RANDSIZ
Definition TRandom.h:15
#define TASSERT(X,...)
Definition Defines.h:138
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
unsigned int TUINT
Definition Typedefs.h:8
float TFLOAT
Definition Typedefs.h:4
uint32_t TUINT32
Definition Typedefs.h:13
int TINT
Definition Typedefs.h:7
TFLOAT GetFloat2()
Definition TRandom.cpp:194
TINT GetInt()
Definition TRandom.cpp:178
TRandom()
Definition TRandom.cpp:59
void SetSeed(TUINT a_uiSeed)
Definition TRandom.cpp:199
TFLOAT GetFloat()
Definition TRandom.cpp:183
TUINT32 RandRaw()
Definition TRandom.cpp:205
TFLOAT GetFloatMinMax(TFLOAT a_fLower, TFLOAT a_fUpper)
Definition TRandom.cpp:189
TUINT32 GetRaw32()