#include "platform.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #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>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>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>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>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); }