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

Conflicts:
	src/enemy.c
	src/global.c
This commit is contained in:
Andrew "Akari" Alexeyew 2012-07-29 09:19:58 +03:00
commit c7886ac0ae
22 changed files with 307 additions and 63 deletions

BIN
gfx/stage2/wspellbg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 KiB

BIN
gfx/stage2/wspellclouds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

BIN
gfx/stage2/wspellswarm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View file

@ -34,6 +34,7 @@ set(SRCs
vbo.c
stageutils.c
matrix.c
video.c
menu/menu.c
menu/mainmenu.c
menu/options.c

View file

@ -37,7 +37,10 @@ enum {
NO_STAGEBG,
NO_STAGEBG_FPSLIMIT,
SAVE_RPY
SAVE_RPY,
VID_WIDTH,
VID_HEIGHT,
};
void parse_config(char *filename);

View file

@ -41,6 +41,9 @@
"save_rpy" { yylval = SAVE_RPY; return tSAVE_RPY; }
"vid_width" { yylval = VID_WIDTH; return tVID_WIDTH; }
"vid_height" { yylval = VID_HEIGHT; return tVID_HEIGHT; }
"shift" { yylval = SDLK_LSHIFT; return SKEY; }
"ctrl" { yylval = SDLK_LCTRL; return SKEY; }
"return" { yylval = SDLK_RETURN; return SKEY; }

View file

@ -7,6 +7,7 @@
%{
#include "config.h"
#include "global.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -51,6 +52,9 @@
%token tNO_STAGEBG_FPSLIMIT
%token tSAVE_RPY
%token tVID_WIDTH
%token tVID_HEIGHT
%token SKEY
%token NUMBER
@ -90,6 +94,8 @@ key_key : tKEY_UP
| tFULLSCREEN
| tNO_STAGEBG
| tNO_STAGEBG_FPSLIMIT
| tVID_WIDTH
| tVID_HEIGHT
| tSAVE_RPY;
nl : LB { lineno++; };
@ -144,6 +150,9 @@ void config_preset() {
tconfig.intval[NO_STAGEBG_FPSLIMIT] = 40;
tconfig.intval[SAVE_RPY] = 2;
tconfig.intval[VID_WIDTH] = RESX;
tconfig.intval[VID_HEIGHT] = RESY;
}
int config_sym2key(int sym) {

View file

@ -13,7 +13,7 @@
#include "projectile.h"
#include "list.h"
void create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
complex a1, complex a2, complex a3, complex a4) {
Enemy *e = (Enemy *)create_element((void **)enemies, sizeof(Enemy));
e->moving = 0;
@ -25,6 +25,7 @@ void create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rul
e->hp = hp;
e->alpha = 1.0;
e->unbombable = 0;
e->logic_rule = logic_rule;
e->draw_rule = draw_rule;
@ -35,6 +36,8 @@ void create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rul
e->args[3] = a4;
e->logic_rule(e, EVENT_BIRTH);
return e;
}
void _delete_enemy(void **enemies, void* enemy) {

View file

@ -40,6 +40,7 @@ struct Enemy {
EnemyDrawRule draw_rule;
int hp;
int unbombable;
complex args[RULE_ARGC];
float alpha;
@ -50,7 +51,7 @@ struct Enemy {
#define create_enemy2c(p,h,d,l,a1,a2) create_enemy_p(&global.enemies,p,h,d,l,a1,a2,0,0)
#define create_enemy1c(p,h,d,l,a1) create_enemy_p(&global.enemies,p,h,d,l,a1,0,0,0)
void create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
complex a1, complex a2, complex a3, complex a4);
void delete_enemy(Enemy **enemies, Enemy* enemy);
void draw_enemies(Enemy *enemies);

View file

@ -6,6 +6,7 @@
*/
#include "global.h"
#include "video.h"
#include <SDL/SDL.h>
#include <time.h>
#include <stdio.h>
@ -91,19 +92,6 @@ inline double min(double a, double b) {
return (a < b)? a : b;
}
extern SDL_Surface *display;
void toggle_fullscreen()
{
int newflags = display->flags;
newflags ^= SDL_FULLSCREEN;
tconfig.intval[FULLSCREEN] = newflags & SDL_FULLSCREEN;
SDL_FreeSurface(display);
if((display = SDL_SetVideoMode(RESX, RESY, 32, newflags)) == NULL)
errx(-1, "Error opening screen: %s", SDL_GetError());
}
void take_screenshot()
{
FILE *out;
@ -177,6 +165,6 @@ void global_processevent(SDL_Event *event)
if(sym == tconfig.intval[KEY_SCREENSHOT])
take_screenshot();
if((sym == SDLK_RETURN && (keys[SDLK_LALT] || keys[SDLK_RALT])) || sym == tconfig.intval[KEY_FULLSCREEN])
toggle_fullscreen();
video_toggle_fullscreen();
}
}

View file

@ -35,7 +35,8 @@
#define FILE_PREFIX PREFIX "/share/taisei/"
#define CONFIG_FILE "config"
enum {
enum {
// defaults
RESX = 800,
RESY = 600,
@ -128,7 +129,6 @@ void calc_fps(FPSCounter *fps);
void set_ortho();
void fade_out(float f);
void toggle_fullscreen();
void global_processevent(SDL_Event*);
void take_screenshot();

View file

@ -125,7 +125,7 @@ void draw_laser_curve(Laser *laser) {
float wq = ((float)tex->w)/tex->truew;
float hq = ((float)tex->h)/tex->trueh;
glScalef(s*tex->w*wq,s*laser->width*hq,s);
glScalef(tex->w*wq*0.5*cabs(last-pos),s*laser->width*hq,s);
draw_quad();
last = pos;

View file

@ -12,12 +12,11 @@
#include "taisei_err.h"
#include "global.h"
#include "video.h"
#include "stage.h"
#include "menu/mainmenu.h"
#include "paths/native.h"
SDL_Surface *display;
void init_gl() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
@ -35,7 +34,7 @@ void taisei_shutdown() {
free_resources();
SDL_FreeSurface(display);
video_shutdown();
SDL_Quit();
printf("-- Good Bye.\n");
}
@ -63,17 +62,9 @@ int main(int argc, char** argv) {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
int flags = SDL_OPENGL;
if(tconfig.intval[FULLSCREEN])
flags |= SDL_FULLSCREEN;
if((display = SDL_SetVideoMode(RESX, RESY, 32, flags)) == NULL)
errx(-1, "Error opening screen: %s", SDL_GetError());
video_init();
printf("-- SDL viewport\n");
SDL_WM_SetCaption("TaiseiProject", NULL);
init_gl();
printf("-- GL\n");

View file

@ -10,6 +10,7 @@
#include "menu.h"
#include "options.h"
#include "global.h"
#include "video.h"
#include "paths/native.h"
#include "taisei_err.h"
@ -90,6 +91,26 @@ OptionBinding* bind_keybinding(MenuData *m, char *optname, int cfgentry)
return bind;
}
// Super-special binding type for the resolution setting
OptionBinding* bind_resolution(MenuData *m) {
OptionBinding *bind;
bind = allocate_binding(m);
bind->enabled = True;
bind->type = BT_Resolution;
bind->valcount = video.mcount;
bind->selected = -1;
int i; for(i = 0; i < video.mcount; ++i) {
VideoMode *m = &(video.modes[i]);
if(m->width == video.intended.width && m->height == video.intended.height)
bind->selected = i;
}
return bind;
}
// Returns a pointer to the first found binding that blocks input. If none found, returns NULL.
OptionBinding* get_input_blocking_binding(MenuData *m)
{
@ -119,14 +140,20 @@ void bind_setvaluerange(OptionBinding *b, int vmin, int vmax) {
// Called to select a value of a BT_IntValue type binding by index
int bind_setvalue(OptionBinding *b, int v)
{
return b->selected = b->setter(b, v);
if(b->setter)
return b->selected = b->setter(b, v);
else
return b->selected = v;
}
// Called to get the selected value of a BT_IntValue type binding by index
int bind_getvalue(OptionBinding *b)
{
// query AND update
return b->selected = b->getter(b);
if(b->getter)
// query AND update
return b->selected = b->getter(b);
else
return b->selected;
}
// Selects the next to current value of a BT_IntValue type binding
@ -207,7 +234,7 @@ int bind_common_onoffset_inverted(void *b, int v)
int bind_fullscreen_set(void *b, int v)
{
toggle_fullscreen();
video_toggle_fullscreen();
return bind_common_onoffset(b, v);
}
@ -313,6 +340,11 @@ void menu_save_config(MenuData *m, char *filename)
fprintf(out, "%s = K%i\n", bind->optname, tconfig.intval[bind->configentry]);
break;
case BT_Resolution:
// at this point, the intended resolution is what the user has picked
fprintf(out, "vid_width = %i\nvid_height = %i\n", video.intended.width, video.intended.height);
break;
default:
printf("FIXME: unhandled BindingType %i, option '%s' will NOT be saved!\n", bind->type, bind->optname);
}
@ -327,6 +359,19 @@ void menu_save_config(MenuData *m, char *filename)
void destroy_options_menu(void *menu)
{
MenuData *m = (MenuData*)menu;
OptionBinding *binds = (OptionBinding*)m->context;
int i;
for(i = 0; i < m->ecount; ++i) {
if(binds[i].type == BT_Resolution) {
if(binds[i].selected != -1) {
VideoMode *m = &(video.modes[binds[i].selected]);
video_setmode(m->width, m->height, tconfig.intval[FULLSCREEN]);
}
break;
}
}
menu_save_config(m, CONFIG_FILE);
free_bindings(menu);
}
@ -348,6 +393,9 @@ void create_options_menu(MenuData *m) {
#define bind_onoff(b) bind_addvalue(b, "on"); bind_addvalue(b, "off")
add_menu_entry(m, "Video Mode", do_nothing, NULL);
b = bind_resolution(m);
add_menu_entry(m, "Fullscreen", do_nothing, NULL);
b = bind_option(m, "fullscreen", FULLSCREEN, bind_common_onoffget, bind_fullscreen_set);
bind_onoff(b);
@ -357,7 +405,7 @@ void create_options_menu(MenuData *m) {
bind_noaudio_set);
bind_onoff(b);
add_menu_entry(m, "Shader", do_nothing, NULL);
add_menu_entry(m, "Shaders", do_nothing, NULL);
b = bind_option(m, "disable_shader", NO_SHADER, bind_common_onoffget_inverted,
bind_noshader_set);
bind_onoff(b);
@ -519,6 +567,24 @@ void draw_options_menu(MenuData *menu) {
else
draw_text(AL_Right, origin, 20*i, SDL_GetKeyName(tconfig.intval[bind->configentry]), _fonts.standard);
break;
case BT_Resolution: {
char tmp[16];
int w, h;
if(bind->selected == -1) {
w = video.intended.width;
h = video.intended.height;
} else {
VideoMode *m = &(video.modes[bind->selected]);
w = m->width;
h = m->height;
}
snprintf(tmp, 16, "%dx%d", w, h);
draw_text(AL_Right, origin, 20*i, tmp, _fonts.standard);
break;
}
}
}
}
@ -582,24 +648,22 @@ static void options_key_action(MenuData *menu, int sym) {
if(bind->enabled) switch(bind->type)
{
case BT_IntValue: bind_setnext(bind); break;
case BT_KeyBinding: bind->blockinput = True; break;
}
else
menu->quit = 1;
case BT_IntValue: case BT_Resolution: bind_setnext(bind); break;
case BT_KeyBinding: bind->blockinput = True; break;
} else menu->quit = 1;
} else if(sym == tconfig.intval[KEY_LEFT] || sym == SDLK_LEFT) {
menu->selected = menu->cursor;
OptionBinding *binds = (OptionBinding*)menu->context;
OptionBinding *bind = &(binds[menu->selected]);
if(bind->enabled && bind->type == BT_IntValue)
if(bind->enabled && (bind->type == BT_IntValue || bind->type == BT_Resolution))
bind_setprev(bind);
} else if(sym == tconfig.intval[KEY_RIGHT] || sym == SDLK_RIGHT) {
menu->selected = menu->cursor;
OptionBinding *binds = (OptionBinding*)menu->context;
OptionBinding *bind = &(binds[menu->selected]);
if(bind->enabled && bind->type == BT_IntValue)
if(bind->enabled && (bind->type == BT_IntValue || bind->type == BT_Resolution))
bind_setnext(bind);
} else if(sym == SDLK_ESCAPE) {
menu->quit = 1;

View file

@ -22,7 +22,8 @@ typedef int (*BindingDependence)();
typedef enum BindingType {
BT_IntValue,
BT_KeyBinding
BT_KeyBinding,
BT_Resolution
} BindingType;
typedef struct OptionBinding {

View file

@ -155,12 +155,19 @@ void player_logic(Player* plr) {
if(global.frames - plr->recovery < 0) {
Enemy *en;
for(en = global.enemies; en; en = en->next)
en->hp -= 300;
if(!en->unbombable)
en->hp -= 300;
Projectile *p;
for(p = global.projs; p; p = p->next)
if(p->type >= FairyProj)
p->type = DeadProj;
if(global.boss && global.boss->current) {
AttackType at = global.boss->current->type;
if(at != AT_Move && at != AT_SurvivalSpell)
global.boss->dmg += 30;
}
}
}

View file

@ -339,12 +339,6 @@ int master_spark(Enemy *e, int t) {
if(t > creal(e->args[0]))
return ACTION_DESTROY;
if(global.projs && global.projs->type != PlrProj)
global.projs->type = DeadProj;
if(global.boss)
global.boss->dmg++;
return 1;
}

View file

@ -10,6 +10,7 @@
#include <SDL/SDL.h>
#include <time.h>
#include "global.h"
#include "video.h"
#include "replay.h"
#include "config.h"
#include "player.h"
@ -247,7 +248,7 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
if(!tconfig.intval[NO_SHADER]) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0,RESX,RESY);
glViewport(0, 0, video.current.width, video.current.height);
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);

View file

@ -343,9 +343,6 @@ void kurumi_spell_bg(Boss *b, int time) {
}
void kurumi_outro(Boss *b, int time) {
if(time < 0)
return;
b->pos += -5-I;
}
@ -401,9 +398,6 @@ int stage3_supercard(Enemy *e, int t) {
}
void kurumi_boss_intro(Boss *b, int t) {
if(t < 0)
return;
TIMER(&t);
GO_TO(b, VIEWPORT_W/2.0+200I, 0.01);
@ -698,7 +692,7 @@ void kurumi_danmaku(Boss *b, int time) {
Boss *create_kurumi() {
Boss* b = create_boss("Kurumi", "kurumi", -400I);
boss_add_attack(b, AT_Move, "Introduction", 9, 0, kurumi_boss_intro, NULL);
boss_add_attack(b, AT_Move, "Introduction", 4, 0, kurumi_boss_intro, NULL);
boss_add_attack(b, AT_Normal, "Sin Breaker", 20, 20000, kurumi_sbreaker, NULL);
boss_add_attack(b, AT_Spellcard, global.diff < D_Hard ? "Limit ~ Animate Wall" : "Summoning ~ Demon Wall", 30, 40000, kurumi_aniwall, kurumi_spell_bg);
boss_add_attack(b, AT_Normal, "Cold Breaker", 20, 20000, kurumi_breaker, NULL);

View file

@ -17,6 +17,28 @@ Dialog *stage4_post_mid_dialog() {
return d;
}
Dialog *stage4_boss_dialog() {
Dialog *d = create_dialog(global.plr.cha == Marisa ? "dialog/marisa" : "dialog/youmu", "masterspark");
dadd_msg(d, Left, "Finally!");
dadd_msg(d, Right, "Stop following me!");
dadd_msg(d, Left, "Why? You aren't involved in this, are you?");
dadd_msg(d, Right, "I don't have time for your suspicions now.");
dadd_msg(d, Left, "Sounds very suspecious, actually.");
dadd_msg(d, Right, "Ok, let's finish this quickly.");
return d;
}
Dialog *stage4_post_boss_dialog() {
Dialog *d = create_dialog(global.plr.cha == Marisa ? "dialog/marisa" : "dialog/youmu", NULL);
dadd_msg(d, Left, "I can see the top!");
dadd_msg(d, Left, "Hopefully climbing all those stairs\nwas worth it.");
return d;
}
int stage4_greeter(Enemy *e, int t) {
TIMER(&t)
@ -231,6 +253,9 @@ int stage4_superbullet(Enemy *e, int t) {
void iku_intro(Boss *b, int t) {
GO_TO(b, VIEWPORT_W/2+300I, 0.01);
if(t == 100)
global.dialog = stage4_boss_dialog();
}
void iku_bolts(Boss *b, int time) {
@ -276,7 +301,7 @@ void iku_atmospheric(Boss *b, int time) {
int i;
int c = 10;
for(i = -c*0.5; i <= c*0.5; i++) {
create_projectile2c("ball", p1+(p2-p1)/c*i, rgb(1/(1+fabs(0.3*i)), 1, 1), accelerated, 0, (0.005+0.001*global.diff)*cexp(I*carg(p2-p1)+I*M_PI/2+0.2I*i))->draw = ProjDrawAdd;
}
@ -460,7 +485,7 @@ Boss *create_iku() {
void stage4_events() {
TIMER(&global.timer);
FROM_TO(60, 120, 10)
create_enemy1c(VIEWPORT_W+70I+50*_i*I, 300, Fairy, stage4_greeter, -3);
@ -512,4 +537,7 @@ void stage4_events() {
AT(5300)
global.boss = create_iku();
AT(5320)
global.dialog = stage4_post_boss_dialog();
}

123
src/video.c Normal file
View file

@ -0,0 +1,123 @@
/*
* 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 "global.h"
#include "video.h"
#include "taisei_err.h"
#include <stdlib.h>
static VideoMode common_modes[] = {
{RESX, RESY},
{640, 480},
{800, 600},
{1024, 768},
{1280, 960},
{1152, 864},
{1400, 1050},
{1440, 1080},
{0, 0},
};
static void video_add_mode(int width, int height) {
if(video.modes) {
int i; for(i = 0; i < video.mcount; ++i) {
VideoMode *m = &(video.modes[i]);
if(m->width == width && m->height == height)
return;
}
}
video.modes = (VideoMode*)realloc(video.modes, (++video.mcount) * sizeof(VideoMode));
video.modes[video.mcount-1].width = width;
video.modes[video.mcount-1].height = height;
}
static int video_compare_modes(const void *a, const void *b) {
VideoMode *va = (VideoMode*)a;
VideoMode *vb = (VideoMode*)b;
return va->width * va->height - vb->width * vb->height;
}
static void _video_setmode(int w, int h, int fs, int fallback) {
int flags = SDL_OPENGL;
if(fs) flags |= SDL_FULLSCREEN;
if(!fallback) {
video.intended.width = w;
video.intended.height = h;
}
if(display)
SDL_FreeSurface(display);
if(!(display = SDL_SetVideoMode(w, h, 32, flags))) {
if(fallback) {
errx(-1, "video_setmode(): error opening screen: %s", SDL_GetError());
return;
}
warnx("video_setmode(): setting %dx%d failed, falling back to %dx%d", w, h, RESX, RESY);
_video_setmode(RESX, RESY, fs, True);
}
const SDL_VideoInfo *info = SDL_GetVideoInfo();
video.current.width = info->current_w;
video.current.height = info->current_h;
glViewport(0, 0, video.current.width, video.current.height);
}
void video_setmode(int w, int h, int fs) {
_video_setmode(w, h, fs, False);
}
int video_isfullscreen(void) {
return !!(display->flags & SDL_FULLSCREEN);
}
void video_toggle_fullscreen(void) {
video_setmode(video.intended.width, video.intended.height, !video_isfullscreen());
}
void video_init(void) {
SDL_Rect **modes;
int i;
memset(&video, 0, sizeof(video));
// First register all resolutions that are available in fullscreen
modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
if(!modes) {
warnx("video_init(): no available fullscreen modes");
tconfig.intval[FULLSCREEN] = False;
} else if(modes == (SDL_Rect**)-1) {
warnx("video_init(): you seem to have a weird video driver");
} else {
for(i = 0; modes[i]; ++i) {
video_add_mode(modes[i]->w, modes[i]->h);
}
}
// Then, add some common 4:3 modes for the windowed mode if they are not there yet.
// This is required for some multihead setups.
for(i = 0; common_modes[i].width; ++i)
video_add_mode(common_modes[i].width, common_modes[i].height);
// sort it, mainly for the options menu
qsort(video.modes, video.mcount, sizeof(VideoMode), video_compare_modes);
video_setmode(tconfig.intval[VID_WIDTH], tconfig.intval[VID_HEIGHT], tconfig.intval[FULLSCREEN]);
SDL_WM_SetCaption("TaiseiProject", NULL);
}
void video_shutdown(void) {
SDL_FreeSurface(display);
free(video.modes);
}

33
src/video.h Normal file
View file

@ -0,0 +1,33 @@
/*
* 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 VIDEO_H
#define VIDEO_H
typedef struct VideoMode {
unsigned int width;
unsigned int height;
} VideoMode;
typedef struct {
VideoMode *modes;
int mcount;
VideoMode intended;
VideoMode current;
} Video;
Video video;
SDL_Surface *display;
void video_init(void);
void video_shutdown(void);
void video_setmode(int w, int h, int fs);
int video_isfullscreen(void);
void video_toggle_fullscreen(void);
#endif