Lephisto/src/intro.c

186 lines
4.2 KiB
C

/**
* @file intro.c
*
* @brief Handle the introduction sequence.
*
* @todo Allow handling of images and other fancy things once we get them.
*/
#include <string.h>
#include "SDL.h"
#include "lephisto.h"
#include "log.h"
#include "ldata.h"
#include "font.h"
#include "music.h"
#include "lstd.h"
#include "intro.h"
#define INTRO_FONT_SIZE 18. /**< Intro text font size. */
#define INTRO_SPEED 30. /**< Speed of text in characters / seconds. */
/* Intro text lines. */
static char** intro_lines = NULL; /**< Introduction text lines. */
static int intro_nlines = 0; /**< Number of introduction text lines. */
static int intro_length = 0; /**< Length of the text. */
static glFont intro_font; /** Introduction font. */
static int intro_load(void);
static void intro_cleanup(void);
static int intro_load(void) {
uint32_t intro_size;
char* intro_buf;
int i, p, n;
int mem;
intro_buf = ldata_read("../dat/intro", &intro_size);
intro_length = intro_size; /* Length aproximation! */
/* Create intro font. */
gl_fontInit(&intro_font, NULL, INTRO_FONT_SIZE);
/* Load lines. */
p = 0;
n = 0;
mem = 0;
while((uint32_t)p < intro_size) {
/* Get the length. */
i = gl_printWidthForText(&intro_font, &intro_buf[p], SCREEN_W - 200.);
/* Copy the line. */
if(n+1 > mem) {
mem += 128;
intro_lines = realloc(intro_lines, sizeof(char*) * mem);
}
intro_lines[n] = malloc(i+1);
strncpy(intro_lines[n], &intro_buf[p], i);
intro_lines[n][i] = '\0';
p += i + 1; /* Move pointer. */
n++; /* New line. */
}
/* Clean up. */
free(intro_buf);
intro_nlines = n;
return 0;
}
/**
* @brief Cleans up the intro crap!
*/
static void intro_cleanup(void) {
int i;
/* Free memory. */
for(i = 0; i < intro_nlines; i++)
free(intro_lines[i]);
free(intro_lines);
gl_freeFont(&intro_font);
/* Set default. */
intro_lines = NULL;
intro_nlines = 0;
}
/**
* @brief Display the introduction sequence.
*/
int intro_display(void) {
int i, max;
unsigned int tcur, tlast;
double dt;
double x, y, vel;
double offset;
double density;
SDL_Event event;
/* Load the introduction. */
if(intro_load() < 0)
return -1;
/* Calculate velocity. */
density = ((double)intro_length / (double)intro_nlines); /* char / line. */
density /= (double)intro_font.h; /* char / pixel. */
vel = INTRO_SPEED / density; /* (char / s) * (pixel / char) = pixel / s */
/* Change music to intro music. */
music_load("intro");
music_play();
/* Prepare for intro loop. */
x = 100.;
y = 0.;
tlast = SDL_GetTicks();
offset = 0.;
/*offset = -(intro_font.h + 5.);*/
max = intro_nlines + SCREEN_H / ((intro_font.h + 5.));
while(1) {
/* Get delta tick in seconds! */
tcur = SDL_GetTicks();
dt = (double)(tcur - tlast) / 1000.;
tlast = tcur;
/* Handle events. */
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
/* Skip the boring intro we saw a million times already! */
if(event.key.keysym.sym == SDLK_ESCAPE)
offset = max * (intro_font.h + 5.);
/* Only handle space from here down. */
else if(!lstd_isspace(event.key.keysym.sym))
break;
/* Purpose fallthrough. */
case SDL_JOYBUTTONDOWN:
offset += 250.;
default:
break;
}
}
/* Increment position. */
offset += vel * dt;
/* Clear stuff. */
glClear(GL_COLOR_BUFFER_BIT);
/* Draw text! */
i = (int)(offset / (intro_font.h + 5.));
if(i > max) /* Out of lines. */
break;
y = offset - (i+1) * (intro_font.h + 5.);
while(i >= 0) {
/* Skip in line isn't valid. */
if(i >= intro_nlines) {
i--;
y += intro_font.h + 5.;
continue;
}
gl_print(&intro_font, x, y, &cConsole, intro_lines[i]);
/* Increment line and position. */
i--;
y += intro_font.h + 5.;
}
/* Display our sh*t. */
SDL_GL_SwapBuffers();
SDL_Delay(10); /* No need to go burning our CPU now! */
}
/* Stops music, normal music will start shortly after. */
music_stop();
/* Cleanup our mess. */
intro_cleanup();
return 0;
}