sdlbomber/utils.c
2009-08-09 19:10:35 +02:00

241 lines
4.6 KiB
C

#include "bomber.h"
#include "utils.h"
#include "gfx.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int volatile hc=0;
char volatile interrupted=0;
static Uint32 cur_unique;
Uint32 network_unique;
Uint32 gtime(void) {
return SDL_GetTicks();
}
Uint32 longtime(void) {
return gtime()/1000;
}
/* surf random generator: x (Daniel J. Bernstein) */
#define ROT(x, b) (((x) << (b)) | ((x) >> (32-(b))))
#define MUSH(i, b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROT(x,b))
static void surf(Uint32 out[8], const Uint32 in[12], const Uint32 seed[32]) {
Uint32 t[12], x, sum = 0;
int r, i, loop;
for (i = 0; i < 12; ++i) t[i] = in[i] ^ seed[12 + i];
for (i = 0; i < 8; ++i) out[i] = seed[24 + i];
x = t[11];
for (loop = 0; loop < 2; ++loop) {
for (r = 0; r < 16; ++r) {
sum += 0x9e3779b9;
MUSH(0, 5); MUSH(1, 7); MUSH(2, 9); MUSH(3, 13);
MUSH(4, 5); MUSH(5, 7); MUSH(6, 9); MUSH(7, 13);
MUSH(8, 5); MUSH(9, 7); MUSH(10, 9); MUSH(11, 13);
}
for (i = 0; i < 8; ++i) out[i] ^= t[i+4];
}
}
#undef ROT
#undef MUSH
static Uint32 surf_seed[32];
static Uint32 surf_in[12], surf_out[8];
static int surf_left;
static Uint32 surf_init(void) {
Uint32 unique = 0;
int fd;
memset(surf_in, 0, sizeof(surf_in));
memset(surf_out, 0, sizeof(surf_out));
memset(surf_seed, 0, sizeof(surf_seed));
surf_left = 0;
fd = open("/dev/urandom", O_RDONLY);
if (-1 == fd) {
Uint32 genseed[4][8];
surf_seed[0] = surf_seed[1] = gtime();
surf_in[0]++; surf(genseed[0], surf_in, surf_seed);
surf_in[0]++; surf(genseed[1], surf_in, surf_seed);
surf_in[0]++; surf(genseed[2], surf_in, surf_seed);
surf_in[0]++; surf(genseed[3], surf_in, surf_seed);
memcpy(surf_seed, genseed[0], 32);
memcpy(surf_seed, genseed[1], 32);
memcpy(surf_seed, genseed[2], 32);
memcpy(surf_seed, genseed[3], 32);
surf_in[0] = gtime();
surf(genseed[0], surf_in, surf_seed);
surf_in[0] = 0;
unique = genseed[0][0];
} else {
read(fd, &unique, sizeof(unique));
read(fd, &surf_seed, sizeof(surf_seed));
close(fd);
}
return unique;
}
static Uint32 surf_random(void) {
if (surf_left == 0) {
int i;
for (i = 0; (i < 12) && !(++surf_in[i]); i++) ;
surf_left = 8;
surf(surf_out, surf_in, surf_seed);
}
return surf_out[--surf_left];
}
void read_seed_unique(unsigned char *buf) {
int i;
memset(surf_in, 0, sizeof(surf_in));
memset(surf_out, 0, sizeof(surf_out));
surf_left = 0;
memcpy(&surf_seed, buf, sizeof(surf_seed));
memcpy(&network_unique, buf+sizeof(surf_seed), sizeof(network_unique));
cur_unique = ntohl(network_unique);
for (i = 0; i < 32; i++) surf_seed[i] = ntohl(surf_seed[i]);
}
unsigned char* write_seed_unique(unsigned char *buf) {
int i;
for (i = 0; i < 32; i++) {
Uint32 l = htonl(surf_seed[i]);
memcpy(buf, &l, sizeof(l));
buf += sizeof(l);
}
memcpy(buf, &network_unique, sizeof(network_unique));
buf += sizeof(network_unique);
return buf;
}
void create_seed_unique(void) {
cur_unique = surf_init();
network_unique = htonl(cur_unique);
}
int myrand(void) {
return surf_random() & 0xffffu;
}
#if 0
/* random generator */
#define TAP1 250
#define TAP2 103
/*
#define TAP1 55
#define TAP2 31
*/
static unsigned char myrandblock[TAP1];
static int myrandtake;
static int myrand1(void) {
int i;
int val;
i=myrandtake-TAP2;
if(i<0) i+=TAP1;
val=myrandblock[myrandtake++]^=myrandblock[i];
if(myrandtake==TAP1) myrandtake=0;
return val;
}
int myrand(void) {
int v;
v=myrand1();
return (v<<8) | myrand1();
}
static void initmyrand(Uint32 unique) {
int i,j;
unsigned char *p;
int msb,msk;
myrandtake=0;
p=myrandblock;
j=12345 ^ unique;
i=TAP1;
while(i--) {
j=(j*1277)&0xffff;
*p++=j>>8;
}
p=myrandblock+14;
msk=0xff;
msb=0x80;
do {
*p&=msk;
*p|=msb;
p+=11;
msk>>=1;
msb>>=1;
} while(msk);
i=500;
while(i--) myrand();
}
void create_unique(void) {
set_unique(gtime());
}
void set_unique(Uint32 unique) {
cur_unique = unique;
network_unique = htonl(cur_unique);
initmyrand(cur_unique);
}
Uint32 get_unique(void) {
return cur_unique;
}
#endif
void nomem(char *str) {
printf("No memory!!![%s]\n",str);
exit(1);
}
int mypause(void) {
while(!interrupted) {
pollinput();
SDL_Delay(1);
}
interrupted=0;
return 1;
}
static Uint32 sdlhandler(Uint32 time) {
#if defined (SDL_LATENCY)
outmsgs();
#endif
interrupted=1;
hc++;
return time;
}
void pulseon(void) {
SDL_SetTimer(40,sdlhandler);
}
void hexdump(unsigned char *p, int len) {
int i;
for (i = 0; i < len; i++) {
if (15 == len % 16)
fprintf(stderr, "0x%X\n", p[i]);
else
fprintf(stderr, "0x%X ", p[i]);
}
if (i % 16)
fprintf(stderr, "\n");
}