Added a custom random generator
This commit is contained in:
parent
577f0ef204
commit
5a7f17a240
12 changed files with 154 additions and 21 deletions
|
@ -17,6 +17,7 @@ ADD_FLEX_BISON_DEPENDENCY(cfgscanner cfgparser)
|
|||
|
||||
set(SRCs
|
||||
main.c
|
||||
random.c
|
||||
stage.c
|
||||
replay.c
|
||||
global.c
|
||||
|
|
11
src/global.c
11
src/global.c
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
81
src/random.c
Normal 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
43
src/random.h
Normal 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
|
12
src/stage.c
12
src/stage.c
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue