#include "random.h"

uint32 random_in[4] = {0,0,0,0};
uint32 random_t[16];
int random_pos = 0;

#define ROTATE(x,b) x = (((x) << (b)) | ((x) >> (32 - (b))))

uint32 random_fill()
{
  register uint32 y, x = 0, sum = 0;
  int rounds = 10;
  y=random_in[0]; random_t[1] =random_t[2] =random_t[3] =0; random_t[0] =y;
  y=random_in[1]; random_t[5] =random_t[6] =random_t[7] =0; random_t[4] =y;
  y=random_in[2]; random_t[9] =random_t[10]=random_t[11]=0; random_t[8] =y;
  y=random_in[3]; random_t[13]=random_t[14]=random_t[15]=0; random_t[12]=y;
  do {
    sum += 0x9e3779b9; y=x; y+=sum;
    ROTATE(x,5);  x^=y; y=random_t[0];  x+=y; y=sum; random_t[0] =x; y+=x;
    ROTATE(x,7);  x^=y; y=random_t[1];  x+=y; y=sum; random_t[1] =x; y+=x;
    ROTATE(x,9);  x^=y; y=random_t[2];  x+=y; y=sum; random_t[2] =x; y+=x;
    ROTATE(x,13); x^=y; y=random_t[3];  x+=y; y=sum; random_t[3] =x; y+=x;
    ROTATE(x,5);  x^=y; y=random_t[4];  x+=y; y=sum; random_t[4] =x; y+=x;
    ROTATE(x,7);  x^=y; y=random_t[5];  x+=y; y=sum; random_t[5] =x; y+=x;
    ROTATE(x,9);  x^=y; y=random_t[6];  x+=y; y=sum; random_t[6] =x; y+=x;
    ROTATE(x,13); x^=y; y=random_t[7];  x+=y; y=sum; random_t[7] =x; y+=x;
    ROTATE(x,5);  x^=y; y=random_t[8];  x+=y; y=sum; random_t[8] =x; y+=x;
    ROTATE(x,7);  x^=y; y=random_t[9];  x+=y; y=sum; random_t[9] =x; y+=x;
    ROTATE(x,9);  x^=y; y=random_t[10]; x+=y; y=sum; random_t[10]=x; y+=x;
    ROTATE(x,13); x^=y; y=random_t[11]; x+=y; y=sum; random_t[11]=x; y+=x;
    ROTATE(x,5);  x^=y; y=random_t[12]; x+=y; y=sum; random_t[12]=x; y+=x;
    ROTATE(x,7);  x^=y; y=random_t[13]; x+=y; y=sum; random_t[13]=x; y+=x;
    ROTATE(x,9);  x^=y; y=random_t[14]; x+=y; y=sum; random_t[14]=x; y+=x;
    ROTATE(x,13); x^=y; y=random_t[15]; x+=y;
    random_t[15] = x;
  } while (--rounds);
  if (!++random_in[0]) if (!++random_in[1]) if (!++random_in[2]) ++random_in[3];
  random_pos = 15;
  return random_t[15];
}
