25 #include "textlines.h"
31 extern int32_t basic_seed
;
32 extern int mt_index
[MT_BUFFER_NUM
];
33 extern short mt_cur_buffer
;
34 extern short mt_virtual_buffer
;
35 extern uint32_t mt_buffer
[MT_BUFFER_NUM
][MT_LEN
];
37 //public domain RNG stuff by Michael Brundage
38 //with some modifications by me to handle more buffers
45 mt_buffer
[0][0]=GetTickCount();
49 //2010: better init line from wikipedia, ultimate source unknown
50 mt_buffer
[0][i
]=1812433253UL * (mt_buffer
[0][i
-1] ^ (mt_buffer
[0][i
-1]>>30)) + i
;
52 mt_index
[0]=MT_LEN
*sizeof(uint32_t);
55 for(j
=0;j
<20;j
++)trandom_twist();
59 #define MT_IB (MT_LEN - MT_IA)
60 #define UPPER_MASK 0x80000000
61 #define LOWER_MASK 0x7FFFFFFF
62 #define MATRIX_A 0x9908B0DF
63 #define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK)
64 #define MAGIC(s) (((s)&1)*MATRIX_A)
68 uint32_t * b
= mt_buffer
[mt_cur_buffer
];
69 int idx
= mt_index
[mt_cur_buffer
];
73 if (idx
== MT_LEN
*sizeof(uint32_t))
77 for (; i
< MT_IB
; i
++) {
79 b
[i
] = b
[i
+ MT_IA
] ^ (s
>> 1) ^ MAGIC(s
);
81 for (; i
< MT_LEN
-1; i
++) {
83 b
[i
] = b
[i
- MT_IB
] ^ (s
>> 1) ^ MAGIC(s
);
86 s
= TWIST(b
, MT_LEN
-1, 0);
87 b
[MT_LEN
-1] = b
[MT_IA
-1] ^ (s
>> 1) ^ MAGIC(s
);
89 mt_index
[mt_cur_buffer
] = idx
+ sizeof(uint32_t);
90 return *(uint32_t *)((unsigned char *)b
+ idx
);
95 uint32_t * b
= mt_buffer
[mt_cur_buffer
];
100 for (; i
< MT_IB
; i
++) {
101 s
= TWIST(b
, i
, i
+1);
102 b
[i
] = b
[i
+ MT_IA
] ^ (s
>> 1) ^ MAGIC(s
);
104 for (; i
< MT_LEN
-1; i
++) {
105 s
= TWIST(b
, i
, i
+1);
106 b
[i
] = b
[i
- MT_IB
] ^ (s
>> 1) ^ MAGIC(s
);
109 s
= TWIST(b
, MT_LEN
-1, 0);
110 b
[MT_LEN
-1] = b
[MT_IA
-1] ^ (s
>> 1) ^ MAGIC(s
);
113 //back to my crap - tarn
114 void pop_trandom_uniform_seed()
116 if(mt_virtual_buffer
>0)mt_virtual_buffer
--;
117 mt_cur_buffer
=mt_virtual_buffer
;
118 if(mt_cur_buffer
>=MT_BUFFER_NUM
)mt_cur_buffer
=MT_BUFFER_NUM
-1;
121 void push_trandom_uniform_seed(uint32_t newseed
)
124 mt_cur_buffer
=mt_virtual_buffer
;
125 if(mt_cur_buffer
>=MT_BUFFER_NUM
)
127 mt_cur_buffer
=MT_BUFFER_NUM
-1;
128 errorlog_string("Random Buffer Overload");
133 uint32_t * b
= mt_buffer
[mt_cur_buffer
];
136 for(i
=1;i
<MT_LEN
;i
++)
138 //2010: better init line from wikipedia, ultimate source unknown
139 b
[i
]=1812433253UL * (b
[i
-1] ^ (b
[i
-1]>>30)) + i
;
141 mt_index
[mt_cur_buffer
]=MT_LEN
*sizeof(uint32_t);
146 void push_trandom_double_seed(uint32_t newseed1
,uint32_t newseed2
)
149 mt_cur_buffer
=mt_virtual_buffer
;
150 if(mt_cur_buffer
>=MT_BUFFER_NUM
)
152 mt_cur_buffer
=MT_BUFFER_NUM
-1;
153 errorlog_string("Random Buffer Overload");
158 uint32_t * b
= mt_buffer
[mt_cur_buffer
];
160 b
[0]=newseed1
/2+newseed2
/2;
161 for(i
=0;i
<MT_LEN
;i
++)
163 b
[i
]=1812433253UL * (b
[i
-1] ^ (b
[i
-1]>>30)) + i
;
165 mt_index
[mt_cur_buffer
]=MT_LEN
*sizeof(uint32_t);
170 void push_trandom_triple_seed(uint32_t newseed1
,uint32_t newseed2
,uint32_t newseed3
)
173 mt_cur_buffer
=mt_virtual_buffer
;
174 if(mt_cur_buffer
>=MT_BUFFER_NUM
)
176 mt_cur_buffer
=MT_BUFFER_NUM
-1;
177 errorlog_string("Random Buffer Overload");
182 uint32_t * b
= mt_buffer
[mt_cur_buffer
];
184 b
[0]=newseed1
/3+newseed2
/3+newseed3
/3;
185 for(i
=0;i
<MT_LEN
;i
++)
187 b
[i
]=1812433253UL * (b
[i
-1] ^ (b
[i
-1]>>30)) + i
;
189 mt_index
[mt_cur_buffer
]=MT_LEN
*sizeof(uint32_t);
194 //picks a random number from 0 to max-1
195 int32_t basic_random(int32_t max
)
199 return (int32_t)((uint32_t)basic_seed
/((1073741824UL/(uint32_t)max
)+1UL));
202 //sets seed to a random number from 0 to 1 billion
205 basic_seed
=(int32_t)(((uint32_t)basic_seed
*907725UL+99979777UL)%1073741824UL);