summaryrefslogtreecommitdiff
path: root/g_src/random.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'g_src/random.cpp')
-rwxr-xr-xg_src/random.cpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/g_src/random.cpp b/g_src/random.cpp
new file mode 100755
index 0000000..1059cb9
--- /dev/null
+++ b/g_src/random.cpp
@@ -0,0 +1,206 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "basics.h"
+
+#include "random.h"
+
+extern int32_t basic_seed;
+extern int mt_index[MT_BUFFER_NUM];
+extern short mt_cur_buffer;
+extern short mt_virtual_buffer;
+extern uint32_t mt_buffer[MT_BUFFER_NUM][MT_LEN];
+
+//public domain RNG stuff by Michael Brundage
+ //with some modifications by me to handle more buffers
+
+void mt_init()
+{
+ mt_cur_buffer=0;
+ mt_virtual_buffer=0;
+
+ mt_buffer[0][0]=GetTickCount();
+ int i;
+ for(i=1;i<MT_LEN;i++)
+ {
+ //2010: better init line from wikipedia, ultimate source unknown
+ mt_buffer[0][i]=1812433253UL * (mt_buffer[0][i-1] ^ (mt_buffer[0][i-1]>>30)) + i;
+ }
+ mt_index[0]=MT_LEN*sizeof(uint32_t);
+
+ int32_t j;
+ for(j=0;j<20;j++)trandom_twist();
+}
+
+#define MT_IA 397
+#define MT_IB (MT_LEN - MT_IA)
+#define UPPER_MASK 0x80000000
+#define LOWER_MASK 0x7FFFFFFF
+#define MATRIX_A 0x9908B0DF
+#define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK)
+#define MAGIC(s) (((s)&1)*MATRIX_A)
+
+uint32_t mt_trandom()
+{
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+ int idx = mt_index[mt_cur_buffer];
+ uint32_t s;
+ int i;
+
+ if (idx == MT_LEN*sizeof(uint32_t))
+ {
+ idx = 0;
+ i = 0;
+ for (; i < MT_IB; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s);
+ }
+ for (; i < MT_LEN-1; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s);
+ }
+
+ s = TWIST(b, MT_LEN-1, 0);
+ b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s);
+ }
+ mt_index[mt_cur_buffer] = idx + sizeof(uint32_t);
+ return *(uint32_t *)((unsigned char *)b + idx);
+}
+
+void trandom_twist()
+{
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+ uint32_t s;
+ int i;
+
+ i = 0;
+ for (; i < MT_IB; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s);
+ }
+ for (; i < MT_LEN-1; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s);
+ }
+
+ s = TWIST(b, MT_LEN-1, 0);
+ b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s);
+}
+
+//back to my crap - tarn
+void pop_trandom_uniform_seed()
+{
+ if(mt_virtual_buffer>0)mt_virtual_buffer--;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)mt_cur_buffer=MT_BUFFER_NUM-1;
+}
+
+void push_trandom_uniform_seed(uint32_t newseed)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed;
+ for(i=1;i<MT_LEN;i++)
+ {
+ //2010: better init line from wikipedia, ultimate source unknown
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+void push_trandom_double_seed(uint32_t newseed1,uint32_t newseed2)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed1/2+newseed2/2;
+ for(i=1;i<MT_LEN;i++)
+ {
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+void push_trandom_triple_seed(uint32_t newseed1,uint32_t newseed2,uint32_t newseed3)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed1/3+newseed2/3+newseed3/3;
+ for(i=1;i<MT_LEN;i++)
+ {
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+//picks a random number from 0 to max-1
+int32_t basic_random(int32_t max)
+{
+ r_num();
+
+ return (int32_t)((uint32_t)basic_seed/((1073741824UL/(uint32_t)max)+1UL));
+}
+
+//sets seed to a random number from 0 to 1 billion
+void r_num()
+{
+ basic_seed=(int32_t)(((uint32_t)basic_seed*907725UL+99979777UL)%1073741824UL);
+} \ No newline at end of file