diff --git a/gfx/dialog/youmu.png b/gfx/dialog/youmu.png
new file mode 100644
index 00000000..09629240
Binary files /dev/null and b/gfx/dialog/youmu.png differ
diff --git a/gfx/dialog/youmu.svg b/gfx/dialog/youmu.svg
index e5fe114b..a1278296 100644
--- a/gfx/dialog/youmu.svg
+++ b/gfx/dialog/youmu.svg
@@ -10,14 +10,731 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="1337"
- height="1664"
+ width="1087.3624"
+ height="1431.0938"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
- sodipodi:docname="youmu.svg">
+ sodipodi:docname="youmu.svg"
+ inkscape:export-filename="/tmp/vektoryoumu.png"
+ inkscape:export-xdpi="200"
+ inkscape:export-ydpi="200">
+ id="defs4">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ inkscape:window-maximized="1"
+ showguides="true"
+ inkscape:guide-bbox="true" />
@@ -56,9 +775,9 @@
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(179.92857,159.63782)"
+ transform="translate(-52.126629,120.00835)"
sodipodi:insensitive="true"
- style="display:inline">
+ style="display:none">
+ style="display:inline"
+ transform="translate(-232.05519,-39.629467)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+ d="m 667.71083,551.06445 c 0,7.67102 -9.7236,13.8896 -21.71828,13.8896 -11.99467,0 -21.71828,-6.21858 -21.71828,-13.8896 0,-7.67101 9.72361,-13.88959 21.71828,-13.88959 11.99468,0 21.71828,6.21858 21.71828,13.88959 z"
+ transform="matrix(1.0348837,0,0,1.5636364,-23.797316,-303.78143)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 81e29d20..e297982e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,6 +15,7 @@ set(SRCs
plrmodes.c
laser.c
shader.c
+ dialog.c
stages/stage0.c)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR})
diff --git a/src/animation.c b/src/animation.c
index 64644c0e..cec2c993 100644
--- a/src/animation.c
+++ b/src/animation.c
@@ -10,6 +10,7 @@
#include "list.h"
#include
+#include
Animation *init_animation(char *filename) {
Animation *buf = create_element((void **)&global.animations, sizeof(Animation));
diff --git a/src/audio.c b/src/audio.c
index 152733b5..56d5a4e2 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -8,6 +8,7 @@
#include "audio.h"
#include "global.h"
#include "list.h"
+#include
Sound *load_sound(char *filename) {
ALuint sound;
diff --git a/src/boss.c b/src/boss.c
index d62ee839..7f5aa6e7 100644
--- a/src/boss.c
+++ b/src/boss.c
@@ -113,7 +113,11 @@ void process_boss(Boss *boss) {
}
}
- boss->current->rule(boss, time);
+ if(time == 0)
+ boss->current->rule(boss, EVENT_BIRTH);
+ else
+ boss->current->rule(boss, time);
+
if(time > boss->current->timeout)
boss->dmg = boss->current->dmglimit + 1;
@@ -145,7 +149,6 @@ void free_attack(Attack *a) {
void start_attack(Boss *b, Attack *a) {
a->starttime = global.frames;
- a->rule(b, 0);
if(a->type == Spellcard || a->type == SurvivalSpell)
play_sound("charge_generic");
}
@@ -162,7 +165,6 @@ Attack *boss_add_attack(Boss *boss, AttackType type, char *name, float timeout,
strcpy(a->name, name);
a->timeout = timeout * FPS;
- int i;
int dmg = 0;
if(boss->acount > 1)
dmg = boss->attacks[boss->acount - 2].dmglimit;
diff --git a/src/dialog.c b/src/dialog.c
new file mode 100644
index 00000000..6a5e9028
--- /dev/null
+++ b/src/dialog.c
@@ -0,0 +1,119 @@
+/*
+ * This software is licensed under the terms of the MIT-License
+ * See COPYING for further information.
+ * ---
+ * Copyright (C) 2011, Lukas Weber
+ */
+
+#include "dialog.h"
+#include "global.h"
+#include "font.h"
+#include
+#include
+
+Dialog *create_dialog(char *left, char *right) {
+ Dialog *d = malloc(sizeof(Dialog));
+ memset(d, 0, sizeof(Dialog));
+
+ d->images[Left] = get_tex(left);
+ d->images[Right] = get_tex(right);
+
+ d->page_time = global.frames;
+ d->birthtime = global.frames;
+ return d;
+}
+
+void dset_image(Dialog *d, Side side, char *name) {
+ d->images[side] = get_tex(name);
+}
+
+void dadd_msg(Dialog *d, Side side, char *msg) {
+ d->messages = realloc(d->messages, (++d->count)*sizeof(DialogMessage));
+ d->messages[d->count-1].side = side;
+ d->messages[d->count-1].msg = malloc(strlen(msg) + 1);
+ strncpy(d->messages[d->count-1].msg, msg, strlen(msg) + 1);
+}
+
+void delete_dialog(Dialog *d) {
+ int i;
+ for(i = 0; i < d->count; i++)
+ free(d->messages[i].msg);
+
+ free(d->messages);
+ free(d);
+}
+
+void draw_dialog(Dialog *dialog) {
+ glPushMatrix();
+
+ glTranslatef(VIEWPORT_W/2.0, VIEWPORT_H*3.0/4.0, 0);
+
+ int i;
+ for(i = 0; i < 2; i++) {
+ glPushMatrix();
+ if(i == Left) {
+ glCullFace(GL_FRONT);
+ glScalef(-1,1,1);
+ }
+
+ if(global.frames - dialog->birthtime < 30)
+ glTranslatef(120 - (global.frames - dialog->birthtime)*4, 0, 0);
+
+ int cur = dialog->messages[dialog->pos].side;
+ int pre = 2;
+ if(dialog->pos > 0)
+ pre = dialog->messages[dialog->pos-1].side;
+
+ short dir = (1 - 2*(i == dialog->messages[dialog->pos].side));
+ if(global.frames - dialog->page_time < 10 && ((i != pre && i == cur) || (i == pre && i != cur))) {
+ int time = (global.frames - dialog->page_time) * dir;
+ glTranslatef(time, time, 0);
+ float clr = 1.0 - 0.07*time;
+ glColor3f(clr, clr, clr);
+ } else {
+ glTranslatef(dir*10, dir*10, 0);
+ glColor3f(1 - dir*0.7, 1 - dir*0.7, 1 - dir*0.7);
+ }
+
+ glTranslatef(VIEWPORT_W*7.0/18.0, 0, 0);
+ if(dialog->images[i])
+ draw_texture_p(0, 0, dialog->images[i]);
+ glPopMatrix();
+ }
+
+ glColor3f(1,1,1);
+
+ glCullFace(GL_BACK);
+ glPopMatrix();
+
+ glPushMatrix();
+ if(global.frames - dialog->birthtime < 25)
+ glTranslatef(0, 100-(global.frames-dialog->birthtime)*4, 0);
+ glColor4f(0,0,0,0.8);
+
+ glBegin(GL_QUADS);
+ glVertex3f(20, VIEWPORT_H-130, 0);
+ glVertex3f(20, VIEWPORT_H-20, 0);
+ glVertex3f(VIEWPORT_W-20, VIEWPORT_H-20, 0);
+ glVertex3f(VIEWPORT_W-20, VIEWPORT_H-130, 0);
+ glEnd();
+ glColor4f(1,1,1,1);
+
+ if(dialog->messages[dialog->pos].side == Right)
+ glColor3f(0.6,0.6,1);
+ draw_text(dialog->messages[dialog->pos].msg, VIEWPORT_W/2, VIEWPORT_H-110, _fonts.biolinum);
+
+ glColor4f(1,1,1,1);
+ glPopMatrix();
+}
+
+void page_dialog(Dialog **d) {
+ (*d)->pos++;
+ (*d)->page_time = global.frames;
+
+ if((*d)->pos >= (*d)->count) {
+ delete_dialog(*d);
+ *d = NULL;
+ global.timer++;
+ }
+}
\ No newline at end of file
diff --git a/src/dialog.h b/src/dialog.h
new file mode 100644
index 00000000..42e78bf7
--- /dev/null
+++ b/src/dialog.h
@@ -0,0 +1,46 @@
+/*
+ * This software is licensed under the terms of the MIT-License
+ * See COPYING for further information.
+ * ---
+ * Copyright (C) 2011, Lukas Weber
+ */
+
+#ifndef DIALOG_H
+#define DIALOG_H
+
+#include "texture.h"
+
+struct DialogMessage;
+struct DialogSpeaker;
+
+typedef enum {
+ Right,
+ Left
+} Side;
+
+typedef struct DialogMessage {
+ Side side;
+ char *msg;
+} DialogMessage;
+
+typedef struct Dialog {
+ DialogMessage *messages;
+ Texture *images[2];
+
+ int count;
+ int pos;
+
+ int page_time;
+
+ int birthtime;
+} Dialog;
+
+Dialog *create_dialog(char *left, char *right);
+void dset_image(Dialog *d, Side side, char *name);
+void dadd_msg(Dialog *d, Side side, char *msg);
+void delete_dialog(Dialog *d);
+
+void draw_dialog(Dialog *dialog);
+void page_dialog(Dialog **d);
+
+#endif
\ No newline at end of file
diff --git a/src/enemy.h b/src/enemy.h
index b18c3afb..86fa0e04 100644
--- a/src/enemy.h
+++ b/src/enemy.h
@@ -10,6 +10,10 @@
#include "animation.h"
#include
+
+#undef complex
+#define complex double _Complex
+
#include
struct Enemy;
@@ -17,7 +21,7 @@ typedef void (*EnemyLogicRule)(struct Enemy*, int t);
typedef EnemyLogicRule EnemyDrawRule;
enum {
- ENEMY_IMMUNE = -9000,
+ ENEMY_IMMUNE = -9000
};
typedef struct Enemy {
diff --git a/src/font.c b/src/font.c
index 49064791..3758249f 100644
--- a/src/font.c
+++ b/src/font.c
@@ -30,7 +30,17 @@ Texture *load_text(const char *text, TTF_Font *font) {
}
void draw_text(const char *text, int x, int y, TTF_Font *font) {
- Texture *tex = load_text(text, font);
+ char *nl;
+ char *buf = malloc(strlen(text));
+ strcpy(buf, text);
+
+ if((nl = strchr(buf, '\n')) != NULL && strlen(nl) > 1) {
+ draw_text(nl+1, x, y + 20, font);
+ *nl = '\0';
+ }
+
+ Texture *tex = load_text(buf, font);
draw_texture_p(x, y, tex);
free_texture(tex);
+ free(buf);
}
\ No newline at end of file
diff --git a/src/font.h b/src/font.h
index a2a8373e..de15ebe3 100644
--- a/src/font.h
+++ b/src/font.h
@@ -14,6 +14,7 @@
Texture *load_text(const char *text, TTF_Font *font);
void draw_text(const char *text, int x, int y, TTF_Font *font);
+void init_fonts();
struct Fonts {
TTF_Font *biolinum;
diff --git a/src/global.c b/src/global.c
index 56001004..714e4b01 100644
--- a/src/global.c
+++ b/src/global.c
@@ -8,6 +8,7 @@
#include "global.h"
#include
#include
+#include
#include "font.h"
Global global;
diff --git a/src/global.h b/src/global.h
index 3f5f3ba7..56b40f26 100644
--- a/src/global.h
+++ b/src/global.h
@@ -17,6 +17,7 @@
#include "boss.h"
#include "laser.h"
#include "shader.h"
+#include "dialog.h"
enum {
SCREEN_W = 800,
@@ -47,6 +48,7 @@ typedef struct {
Laser *lasers;
int frames;
+ int timer;
Texture *textures;
Animation *animations;
@@ -62,6 +64,7 @@ typedef struct {
} rtt;
Boss *boss;
+ Dialog *dialog;
ALuint sndsrc[SNDSRC_COUNT];
diff --git a/src/item.h b/src/item.h
index 31c9c721..179a60e0 100644
--- a/src/item.h
+++ b/src/item.h
@@ -25,7 +25,7 @@ typedef struct Item{
struct Item *next;
struct Item *prev;
- long birthtime;
+ int birthtime;
complex pos;
complex pos0;
@@ -40,7 +40,7 @@ void delete_item(Item *item);
void draw_items();
void delete_items();
-int collision(Item *p);
+int collision_item(Item *p);
void process_items();
#endif
diff --git a/src/laser.c b/src/laser.c
index 740f764b..39080f45 100644
--- a/src/laser.c
+++ b/src/laser.c
@@ -91,7 +91,7 @@ void draw_laser_curve(Laser *laser) {
if(t < 0)
t = 0;
- for(t; t < global.frames - laser->birthtime && t <= laser->deathtime; t+=0.5) {
+ for(; t < global.frames - laser->birthtime && t <= laser->deathtime; t+=0.5) {
complex pos = laser->rule(laser,t);
glPushMatrix();
@@ -181,7 +181,7 @@ int collision_laser_curve(Laser *l) {
if(t < 0)
t = 0;
- for(t; t < global.frames - l->birthtime && t <= l->deathtime; t+=2) {
+ for(; t < global.frames - l->birthtime && t <= l->deathtime; t+=2) {
complex pos = l->rule(l,t);
if(cabs(pos - global.plr.pos) < 5)
return 1;
diff --git a/src/laser.h b/src/laser.h
index e4fedc5a..e9e4f1d5 100644
--- a/src/laser.h
+++ b/src/laser.h
@@ -41,7 +41,7 @@ typedef struct Laser {
Laser *create_laser(LaserType type, complex pos, complex pos0, int time, int deathtime, Color *color, LaserRule rule, complex args, ...);
void draw_lasers();
-void free_lasers();
+void delete_lasers();
void process_lasers();
int collision_laser_line(Laser *l);
diff --git a/src/list.c b/src/list.c
index 21c1e40a..c9ec32c7 100644
--- a/src/list.c
+++ b/src/list.c
@@ -44,7 +44,7 @@ void delete_element(void **dest, void *e) {
free(e);
}
-void *delete_all_elements(void **dest, void (callback)(void **, void *)) {
+void delete_all_elements(void **dest, void (callback)(void **, void *)) {
void *e = *dest;
void *tmp;
diff --git a/src/list.h b/src/list.h
index 5e6fe4f1..bc93ca60 100644
--- a/src/list.h
+++ b/src/list.h
@@ -14,6 +14,6 @@
void *create_element(void **dest, int size);
void delete_element(void **dest, void *e);
-void *delete_all_elements(void **dest, void (callback)(void **, void *));
+void delete_all_elements(void **dest, void (callback)(void **, void *));
#endif
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index 531b2ccb..6245c05f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -67,5 +67,7 @@ int main(int argc, char** argv) {
stage0_loop();
- shutdown();
+ shutdown();
+
+ return 1;
}
\ No newline at end of file
diff --git a/src/shader.c b/src/shader.c
index 4fbe9bea..daff44f7 100644
--- a/src/shader.c
+++ b/src/shader.c
@@ -9,6 +9,7 @@
#include "global.h"
#include "list.h"
#include
+#include
void print_info_log(GLuint shader) {
int len, alen;
diff --git a/src/stage.c b/src/stage.c
index f8dfdc00..7c0c6715 100644
--- a/src/stage.c
+++ b/src/stage.c
@@ -15,6 +15,7 @@ SDL_Event event;
void stage_start() {
init_player(&global.plr, Youmu, YoumuHoming);
+ global.timer = 0;
}
void stage_input() {
@@ -25,10 +26,14 @@ void stage_input() {
global.plr.focus = 1;
break;
case SDLK_y:
- global.plr.fire = True;
+ if(!global.dialog)
+ global.plr.fire = True;
+ else
+ page_dialog(&global.dialog);
break;
case SDLK_x:
- plr_bomb(&global.plr);
+ if(!global.dialog)
+ plr_bomb(&global.plr);
break;
case SDLK_ESCAPE:
exit(1);
@@ -77,28 +82,8 @@ void stage_input() {
}
-void stage_draw() {
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, SCREEN_W, SCREEN_H, 0, -10, 10);
- glMatrixMode(GL_MODELVIEW);
- glDisable(GL_DEPTH_TEST);
-
- glPushMatrix();
- glTranslatef(VIEWPORT_X,VIEWPORT_Y,0);
- apply_bg_shaders();
- player_draw(&global.plr);
-
- draw_projectiles(global.projs);
- draw_enemies(global.enemies);
- draw_items();
- draw_lasers();
-
- if(global.boss)
- draw_boss(global.boss);
-
- glPopMatrix();
- draw_texture(SCREEN_W/2, SCREEN_H/2, "hud");
+void draw_hud() {
+ draw_texture(SCREEN_W/2, SCREEN_H/2, "hud");
char buf[16];
int i;
@@ -123,6 +108,34 @@ void stage_draw() {
glPopMatrix();
}
+void stage_draw() {
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, SCREEN_W, SCREEN_H, 0, -10, 10);
+ glMatrixMode(GL_MODELVIEW);
+ glDisable(GL_DEPTH_TEST);
+
+ glPushMatrix();
+ glTranslatef(VIEWPORT_X,VIEWPORT_Y,0);
+ apply_bg_shaders();
+ player_draw(&global.plr);
+
+ draw_projectiles(global.projs);
+ draw_enemies(global.enemies);
+ draw_items();
+ draw_lasers();
+
+ if(global.boss)
+ draw_boss(global.boss);
+
+ if(global.dialog)
+ draw_dialog(global.dialog);
+
+ glPopMatrix();
+
+ draw_hud();
+}
+
void apply_bg_shaders() {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
@@ -173,7 +186,11 @@ void stage_logic() {
global.boss = NULL;
}
}
+
global.frames++;
+
+ if(!global.dialog)
+ global.timer++;
if(SDL_GetTicks() > global.fpstime+1000) {
fprintf(stderr, "FPS: %d\n", global.fps);
@@ -189,6 +206,5 @@ void stage_end() {
delete_enemies(&global.enemies);
delete_items();
delete_lasers();
- global.frames = 0;
}
\ No newline at end of file
diff --git a/src/stages/stage0.c b/src/stages/stage0.c
index bc0ecf57..2db675d3 100644
--- a/src/stages/stage0.c
+++ b/src/stages/stage0.c
@@ -19,13 +19,23 @@ void simpleEnemy(Enemy *e, int t) {
return;
}
- if(!((global.frames - e->birthtime) % 50))
+ if(!(t % 50))
create_projectile("ball", e->pos, rgb(0,0,1), linear,3 + 2I);
e->moving = 1;
e->dir = creal(e->args[0]) < 0;
- e->pos = e->pos0 + e->args[0]*t + I*sin((global.frames - e->birthtime)/10.0f)*20; // TODO: do this way cooler.
+ e->pos = e->pos0 + e->args[0]*t + I*sin(t/10.0f)*20; // TODO: do this way cooler.
+}
+
+Dialog *test_dialog() {
+ Dialog *d = create_dialog("dialog/youmu", "dialog/youmu");
+
+ dadd_msg(d, Left, "Hello");
+ dadd_msg(d, Right, "Hello you");
+ dadd_msg(d, Right, "Uhm ... who are you?\nNew line.\nAnother longer line.");
+
+ return d;
}
void stage0_draw() {
@@ -103,13 +113,14 @@ void stage0_draw() {
}
void cirno_intro(Boss *c, int time) {
- if(time == 0) {
+ if(time == EVENT_BIRTH) {
boss_add_waypoint(c->current, VIEWPORT_W/2-100 + 30I, 100);
boss_add_waypoint(c->current, VIEWPORT_W/2+100 + 30I, 400);
+ return;
}
-// if(!(time % 50))
-// create_laser(LaserLine, c->pos, 10*cexp(I*carg(global.plr.pos - c->pos)), 30, 200, ((Color){1,0,0}), NULL, 0);
+ if(!(time % 50))
+ create_laser(LaserLine, c->pos, 10*cexp(I*carg(global.plr.pos - c->pos)+I*0.1), 30, 200, rgb(1,0,0), NULL, 0);
}
complex lolsin(Laser *l, float t) {
@@ -120,10 +131,11 @@ complex lolsin(Laser *l, float t) {
}
void cirno_test(Boss *c, int time) {
- if(time == 0) {
+ if(time == EVENT_BIRTH) {
boss_add_waypoint(c->current, 220 + 100I, 50);
boss_add_waypoint(c->current, 12 + 100I, 60);
boss_add_waypoint(c->current, 200 + 90I, 100);
+ return;
}
int i;
if(!(time % 50))
@@ -140,11 +152,15 @@ Boss *create_cirno() {
}
void stage0_events() {
- if(global.frames == 300 )
+ if(global.dialog)
+ return;
+ if(global.timer == 200)
+ global.dialog = test_dialog();
+ if(global.timer == 300)
global.boss = create_cirno();
- if(global.boss == NULL && !(global.frames % 100)) create_enemy(&global.enemies, Fairy, simpleEnemy, 0 + I*100, 3, NULL, 2);
+ if(global.boss == NULL && !(global.timer % 100)) create_enemy(&global.enemies, Fairy, simpleEnemy, 0 + I*100, 3, NULL, 2);
-// if(!(global.frames % 100))
+// if(!(global.timer % 100))
// create_laser(LaserCurve, 300, 300, 60, 500, ((ColorA){0.6,0.6,1,0.4}), lolsin, 0);
}
diff --git a/src/texture.c b/src/texture.c
index 6caf6fdd..60ab8b60 100644
--- a/src/texture.c
+++ b/src/texture.c
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include "audio.h"
#include "shader.h"
#include "list.h"