Merge remote-tracking branch 'upstream/master' into stage3

Conflicts:
	src/global.c
	src/global.h
This commit is contained in:
Andrew "Akari" Alexeyew 2012-07-27 21:59:24 +03:00
commit 769c240e03
15 changed files with 204 additions and 49 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,14 +79,6 @@ void fade_out(float f) {
glColor4f(1,1,1,1);
}
inline double frand() {
return rand()/(double)RAND_MAX;
}
inline double nfrand() {
return frand() * 2 - 1;
}
inline double psin(double x) {
return 0.5 + 0.5 * sin(x);
}

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();
double nfrand();
double psin();
double min(double, double);
double max(double, double);

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

@ -287,6 +287,7 @@ float laser_charge(Laser *l, int t, float charge, float width) {
void static_laser(Laser *l, int t) {
if(t == EVENT_BIRTH) {
l->width = 0;
l->speed = 0;
l->timeshift = l->timespan;
return;

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;
}

85
src/random.c Normal file
View file

@ -0,0 +1,85 @@
/*
* 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 algorithm
*/
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);
}
inline double frand(void) {
return tsrand()/(double)TSRAND_MAX;
}
inline double nfrand() {
return frand() * 2 - 1;
}
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
}

44
src/random.h Normal file
View file

@ -0,0 +1,44 @@
/*
* 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);
inline double frand();
inline double nfrand();
#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

@ -17,11 +17,11 @@
#include "menu/savereplay.h"
StageInfo stages[] = {
{1, stage0_loop, False, "Stage 1", "Misty Lake"},
{2, stage1_loop, False, "Stage 2", "Walk Along the Border"},
{3, stage2_loop, False, "Stage 3", "Through the Tunnel of Light"},
{4, stage3_loop, False, "Stage 4", "Forgotten Mansion"},
{5, stage4_loop, False, "Stage 5", "Climbing the Tower of Babel"},
{1, stage0_loop, False, "Stage 1", "Misty Lake", {1, 1, 1}},
{2, stage1_loop, False, "Stage 2", "Walk Along the Border", {1, 1, 1}},
{3, stage2_loop, False, "Stage 3", "Through the Tunnel of Light", {0, 0, 0}},
{4, stage3_loop, False, "Stage 4", "Forgotten Mansion", {0, 0, 0}},
{5, stage4_loop, False, "Stage 5", "Climbing the Tower of Babel", {1, 1, 1}},
{0, NULL, False, NULL, NULL}
};
@ -170,7 +170,7 @@ void draw_hud() {
draw_texture(VIEWPORT_X+creal(global.boss->pos), 590, "boss_indicator");
}
void stage_draw(StageRule bgdraw, ShaderRule *shaderrules, int time) {
void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int time) {
if(!tconfig.intval[NO_SHADER]) {
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[0].fbo);
if(!global.menu)
@ -236,22 +236,24 @@ void stage_draw(StageRule bgdraw, ShaderRule *shaderrules, int time) {
draw_projectiles(global.particles);
draw_enemies(global.enemies);
draw_lasers();
if(global.boss)
draw_boss(global.boss);
if(global.dialog)
draw_dialog(global.dialog);
draw_stage_title(info);
if(!tconfig.intval[NO_SHADER]) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0,RESX,RESY);
glPushMatrix();
if(global.plr.cha == Marisa && global.plr.shot == MarisaLaser && global.frames - global.plr.recovery < 0)
glTranslatef(8*sin(global.frames),8*sin(global.frames+3),0);
// glColor4f(1,1,1,0.2);
draw_fbo_viewport(&resources.fsec);
// glColor4f(1,1,1,1);
glPopMatrix();
}
@ -435,7 +437,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);
@ -445,7 +447,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;
@ -459,6 +461,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();
@ -469,8 +472,10 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
stage_logic(endtime);
calc_fps(&global.fps);
stage_draw(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);
@ -482,7 +487,7 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
if(REPLAY_ASKSAVE) {
global.menu = create_saverpy_menu();
while(global.menu) {
stage_draw(draw, shaderrules, endtime);
stage_draw(info, draw, shaderrules, endtime);
ingame_menu_logic(&global.menu);
if(!global.menu)
@ -500,11 +505,25 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
end();
stage_end();
tsrand_switch(&global.rand_visual);
}
void draw_stage_title(int t, int dur, char *stage, char *subtitle) {
if(t < 0 || t > dur)
void draw_stage_title(StageInfo *info) {
int t = global.timer;
int i;
float f = 0;
if(t < 30 || t > 220)
return;
draw_text(AL_Center, VIEWPORT_W/2, VIEWPORT_H/2, stage, _fonts.mainmenu);
if((i = abs(t-135)) >= 50) {
i -= 50;
f = 1/35.0*i;
}
glColor4f(info->titleclr.r,info->titleclr.g,info->titleclr.b,1.0-f);
draw_text(AL_Center, VIEWPORT_W/2, VIEWPORT_H/2-40, info->title, _fonts.mainmenu);
draw_text(AL_Center, VIEWPORT_W/2, VIEWPORT_H/2, info->subtitle, _fonts.standard);
glColor4f(1,1,1,1);
}

View file

@ -17,6 +17,8 @@
*
*/
#include <projectile.h>
#define TIMER(ptr) int *__timep = ptr; int _i = 0, _ni = 0; _i = _ni = _i;
#define AT(t) if(*__timep == t)
#define FROM_TO(start,end,step) _ni = _ni; _i = (*__timep - (start))/(step); if(*__timep >= (start) && *__timep <= (end) && !((*__timep - (start)) % (step)))
@ -37,6 +39,8 @@ typedef struct StageInfo {
// reserved for draw_stage_title when/if it's used
char *title;
char *subtitle;
Color titleclr;
} StageInfo;
extern StageInfo stages[];
@ -45,7 +49,8 @@ StageInfo* stage_get(int);
void stage_loop(StageInfo *info, StageRule start, StageRule end, StageRule draw, StageRule event, ShaderRule *shaderrules, int endtime);
void apply_bg_shaders(ShaderRule *shaderrules);
void draw_stage_title(int t, int dur, char *stage, char *subtitle);
void draw_stage_title(StageInfo *info);
void stage0_loop();
void stage1_loop();

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);
}
}

View file

@ -28,7 +28,7 @@ int stage4_greeter(Enemy *e, int t) {
e->moving = 1;
e->dir = creal(e->args[0]) < 0;
if((t < 100 && creal(e->pos) > VIEWPORT_W-100) || t > 200)
if(t < 50 || t > 200)
e->pos += e->args[0];
FROM_TO(100, 180, 20) {
@ -116,7 +116,7 @@ int stage4_laserfairy(Enemy *e, int t) {
e->pos -= e->args[0];
FROM_TO(100, 700, (7-global.diff)*(1+(int)creal(e->args[1]))) {
complex n = cexp(I*carg(global.plr.pos-e->pos)+(0.2-0.02*global.diff)*I*_i-M_PI/2*I);
complex n = cexp(I*carg(global.plr.pos-e->pos)+(0.2-0.02*global.diff)*I*_i);
float fac = (0.5+0.2*global.diff);
create_lasercurve2c(e->pos, 100, 300, rgb(0.7, 0.3, 1), las_accel, fac*4*n, fac*0.05*n);
create_projectile2c("plainball", e->pos, rgb(0.7, 0.3, 1), accelerated, fac*4*n, fac*0.05*n)->draw = ProjDrawAdd;
@ -460,10 +460,7 @@ Boss *create_iku() {
void stage4_events() {
TIMER(&global.timer);
AT(0)
global.timer = 5000;
FROM_TO(60, 120, 10)
create_enemy1c(VIEWPORT_W+70I+50*_i*I, 300, Fairy, stage4_greeter, -3);
@ -476,14 +473,17 @@ void stage4_events() {
FROM_TO(700, 800, 10)
create_enemy3c(VIEWPORT_W+200I*frand(), 500, Swirl, stage4_swirl, -4+frand()*I, 70+20*frand()+200I, cexp(0.05I));
FROM_TO(870, 1200, 50)
FROM_TO(870, 1000, 50)
create_enemy1c(VIEWPORT_W/4+VIEWPORT_W/2*(_i&1), 2000, BigFairy, stage4_limiter, I);
AT(1000)
create_enemy1c(VIEWPORT_W/2, 6000, BigFairy, stage4_laserfairy, 2I);
create_enemy1c(VIEWPORT_W/2, 9000, BigFairy, stage4_laserfairy, 2I);
FROM_TO(1500, 2200, 40)
FROM_TO(1900, 2200, 40)
create_enemy1c(VIEWPORT_W+200I*frand(), 500, Swirl, stage4_miner, -3+2I*frand());
FROM_TO(1500, 2400, 80)
create_enemy1c(VIEWPORT_W*(_i&1)+100I, 300, Fairy, stage4_greeter, 3-6*(_i&1));
FROM_TO(2200, 2600, 40)
create_enemy1c(VIEWPORT_W/10*_i, 200, Swirl, stage4_miner, 3I);