Added a custom random generator

This commit is contained in:
Andrew "Akari" Alexeyew 2012-07-27 20:11:45 +03:00
parent 577f0ef204
commit 5a7f17a240
12 changed files with 154 additions and 21 deletions

View file

@ -17,6 +17,7 @@ ADD_FLEX_BISON_DEPENDENCY(cfgscanner cfgparser)
set(SRCs
main.c
random.c
stage.c
replay.c
global.c

View file

@ -19,8 +19,11 @@ Global global;
void init_global() {
memset(&global, 0, sizeof(global));
srand(time(0));
tsrand_seed_p(&global.rand_game, time(0));
tsrand_seed_p(&global.rand_visual, time(0));
tsrand_switch(&global.rand_visual);
memset(&resources, 0, sizeof(Resources));
load_resources();
printf("- fonts:\n");
@ -76,10 +79,6 @@ void fade_out(float f) {
glColor4f(1,1,1,1);
}
inline double frand() {
return rand()/(double)RAND_MAX;
}
extern SDL_Surface *display;
void toggle_fullscreen()

View file

@ -30,6 +30,7 @@
#include "vbo.h"
#include "resource/resource.h"
#include "replay.h"
#include "random.h"
#define FILE_PREFIX PREFIX "/share/taisei/"
#define CONFIG_FILE "config"
@ -112,6 +113,9 @@ typedef struct {
Replay replay;
int replaymode;
RandomState rand_game;
RandomState rand_visual;
} Global;
extern Global global;
@ -128,8 +132,6 @@ void toggle_fullscreen();
void global_processevent(SDL_Event*);
void take_screenshot();
double frand();
// this is used by both player and replay code
enum {
EV_PRESS,

View file

@ -127,7 +127,7 @@ int collision_item(Item *i) {
}
inline void spawn_item(complex pos, Type type) {
create_item(pos, 5*cexp(I*rand()/frand()*M_PI*2), type);
create_item(pos, 5*cexp(I*tsrand()/frand()*M_PI*2), type);
}
void spawn_items(complex pos, int point, int power, int bomb, int life) {
@ -143,4 +143,4 @@ void spawn_items(complex pos, int point, int power, int bomb, int life) {
for(i = 0; i < life; i++)
spawn_item(pos, Life);
}
}

View file

@ -47,6 +47,9 @@ void taisei_shutdown() {
#endif
int main(int argc, char** argv) {
if(tsrand_test())
return 0;
MKDIR(get_config_path());
MKDIR(get_screenshots_path());
MKDIR(get_replays_path());

View file

@ -220,7 +220,7 @@ void player_death(Player *plr) {
if(plr->deathtime == -1 && global.frames - abs(plr->recovery) > 0) {
int i;
for(i = 0; i < 20; i++)
create_particle2c("flare", plr->pos, NULL, Shrink, timeout_linear, 40, (3+frand()*7)*cexp(I*rand()));
create_particle2c("flare", plr->pos, NULL, Shrink, timeout_linear, 40, (3+frand()*7)*cexp(I*tsrand()));
create_particle2c("blast", plr->pos, rgb(1,0.5,0.3), GrowFade, timeout, 35, 2.4);
plr->deathtime = global.frames + DEATHBOMB_TIME;
}

81
src/random.c Normal file
View file

@ -0,0 +1,81 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
#include "random.h"
#include <stdio.h>
#include <stdlib.h>
/*
* Multiply-with-carry algorythm
*/
static RandomState *tsrand_current;
void tsrand_switch(RandomState *rnd) {
tsrand_current = rnd;
}
void tsrand_seed_p(RandomState *rnd, uint32_t seed) {
// might be not the best way to seed this
rnd->w = (seed >> 16u) + TSRAND_W_SEED_COEFF * (seed & 0xFFFFu);
rnd->z = (seed >> 16u) + TSRAND_Z_SEED_COEFF * (seed & 0xFFFFu);
}
int tsrand_p(RandomState *rnd) {
rnd->w = (rnd->w >> 16u) + TSRAND_W_COEFF * (rnd->w & 0xFFFFu);
rnd->z = (rnd->z >> 16u) + TSRAND_Z_COEFF * (rnd->z & 0xFFFFu);
return (uint32_t)((rnd->z << 16u) + rnd->w) % TSRAND_MAX;
}
inline void tsrand_seed(uint32_t seed) {
tsrand_seed_p(tsrand_current, seed);
}
inline int tsrand(void) {
return tsrand_p(tsrand_current);
}
double frand(void) {
return tsrand()/(double)TSRAND_MAX;
}
int tsrand_test(void) {
#if defined(TSRAND_FLOATTEST)
RandomState rnd;
tsrand_switch(&rnd);
tsrand_seed(time(0));
FILE *fp;
int i;
fp = fopen("/tmp/rand_test", "w");
for(i = 0; i < 10000; ++i)
fprintf(fp, "%f\n", frand());
return 1;
#elif defined(TSRAND_SEEDTEST)
RandomState rnd;
tsrand_switch(&rnd);
int seed = 1337, i, j;
printf("SEED: %d\n", seed);
for(i = 0; i < 5; ++i) {
printf("RUN #%i\n", i);
tsrand_seed(seed);
for(j = 0; j < 5; ++j) {
printf("-> %i\n", tsrand());
}
}
return 1;
#else
return 0;
#endif
}

43
src/random.h Normal file
View file

@ -0,0 +1,43 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
#ifndef TSRAND_H
#define TSRAND_H
#include <stdint.h>
typedef struct RandomState {
uint32_t w;
uint32_t z;
} RandomState;
int tsrand_test(void);
void tsrand_switch(RandomState *rnd);
void tsrand_seed_p(RandomState *rnd, uint32_t seed);
int tsrand_p(RandomState *rnd);
inline void tsrand_seed(uint32_t seed);
inline int tsrand(void);
double frand();
#define TSRAND_MAX INT32_MAX
#define srand USE_tsrand_seed_INSTEAD_OF_srand
#define rand USE_tsrand_INSTEAD_OF_rand
/*
* These have to be distinct 16-bit constants k, for which both k*2^16-1 and k*2^15-1 are prime numbers
*/
#define TSRAND_W_COEFF 30963
#define TSRAND_W_SEED_COEFF 19164
#define TSRAND_Z_COEFF 29379
#define TSRAND_Z_SEED_COEFF 31083
#endif

View file

@ -418,7 +418,7 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
}
int seed = time(0);
srand(seed);
tsrand_seed_p(&global.rand_game, seed);
if(global.replaymode == REPLAY_RECORD) {
replay_destroy(&global.replay);
@ -428,7 +428,7 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
} else {
printf("REPLAY_PLAY mode: %d events\n", global.replay.ecount);
srand(global.replay.seed);
tsrand_seed_p(&global.rand_game, global.replay.seed);
printf("Random seed: %d\n", global.replay.seed);
global.diff = global.replay.diff;
@ -442,6 +442,7 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
global.plr.power = global.replay.plr_power;
}
tsrand_switch(&global.rand_game);
stage_start();
start();
@ -452,8 +453,10 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
stage_logic(endtime);
calc_fps(&global.fps);
stage_draw(info, draw, shaderrules, endtime);
tsrand_switch(&global.rand_visual);
stage_draw(info, draw, shaderrules, endtime);
tsrand_switch(&global.rand_game);
SDL_GL_SwapBuffers();
frame_rate(&global.lasttime);
@ -483,6 +486,7 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
end();
stage_end();
tsrand_switch(&global.rand_visual);
}
void draw_stage_title(StageInfo *info) {

View file

@ -161,9 +161,9 @@ void cirno_perfect_freeze(Boss *c, int time) {
float g = frand();
float b = frand();
create_projectile2c("ball", c->pos, rgb(r, g, b), cirno_pfreeze_frogs, 4*cexp(I*rand()), add_ref(global.boss));
create_projectile2c("ball", c->pos, rgb(r, g, b), cirno_pfreeze_frogs, 4*cexp(I*tsrand()), add_ref(global.boss));
if(global.diff > D_Normal)
create_projectile2c("ball", c->pos, rgb(r, g, b), cirno_pfreeze_frogs, 4*cexp(I*rand()), add_ref(global.boss));
create_projectile2c("ball", c->pos, rgb(r, g, b), cirno_pfreeze_frogs, 4*cexp(I*tsrand()), add_ref(global.boss));
}
GO_AT(c, 160, 190, 2 + 1I);

View file

@ -321,7 +321,7 @@ void hina_bad_pick(Boss *h, int time) {
}
AT(200) {
int win = rand()%5;
int win = tsrand()%5;
for(i = 0; i < 5; i++) {
if(i == win)
continue;
@ -448,4 +448,4 @@ void stage1_events() {
AT(5100) {
global.boss = create_hina();
}
}
}

View file

@ -88,7 +88,7 @@ void stage4_draw() {
stagedata.light_strength *= 0.98;
if(frand() < 0.01) // TODO: this will desync replays, so we need our own rand();
if(frand() < 0.01)
stagedata.light_strength = 5+5*frand();
}
@ -140,4 +140,4 @@ void stage4_end() {
void stage4_loop() {
// ShaderRule shaderrules[] = { stage3_fog, NULL };
stage_loop(stage_get(5), stage4_start, stage4_end, stage4_draw, stage4_events, NULL, 5700);
}
}