Dialogs! conversational~

fun fact: taisei might build with -Wall -Werror now.
This commit is contained in:
laochailan 2011-05-08 13:48:25 +02:00
parent b16df91ad5
commit d9fdc2aa0e
23 changed files with 1353 additions and 72 deletions

BIN
gfx/dialog/youmu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 496 KiB

After

Width:  |  Height:  |  Size: 544 KiB

View file

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

View file

@ -10,6 +10,7 @@
#include "list.h"
#include <assert.h>
#include <err.h>
Animation *init_animation(char *filename) {
Animation *buf = create_element((void **)&global.animations, sizeof(Animation));

View file

@ -8,6 +8,7 @@
#include "audio.h"
#include "global.h"
#include "list.h"
#include <err.h>
Sound *load_sound(char *filename) {
ALuint sound;

View file

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

119
src/dialog.c Normal file
View file

@ -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 <laochailan@web.de>
*/
#include "dialog.h"
#include "global.h"
#include "font.h"
#include <stdlib.h>
#include <string.h>
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++;
}
}

46
src/dialog.h Normal file
View file

@ -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 <laochailan@web.de>
*/
#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

View file

@ -10,6 +10,10 @@
#include "animation.h"
#include <complex.h>
#undef complex
#define complex double _Complex
#include <stdarg.h>
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 {

View file

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

View file

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

View file

@ -8,6 +8,7 @@
#include "global.h"
#include <SDL/SDL.h>
#include <time.h>
#include <err.h>
#include "font.h"
Global global;

View file

@ -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];

View file

@ -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

View file

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

View file

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

View file

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

View file

@ -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

View file

@ -67,5 +67,7 @@ int main(int argc, char** argv) {
stage0_loop();
shutdown();
shutdown();
return 1;
}

View file

@ -9,6 +9,7 @@
#include "global.h"
#include "list.h"
#include <stdio.h>
#include <err.h>
void print_info_log(GLuint shader) {
int len, alen;

View file

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

View file

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

View file

@ -11,6 +11,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <png.h>
#include <err.h>
#include "audio.h"
#include "shader.h"
#include "list.h"