Merge branch 'master' of git://github.com/BTAxis/naev into testmission
[naev.git] / src / intro.c
blob92a6149df4021c5c5bec90000a33afc13aa4912d
1 /*
2 * See Licensing and Copyright notice in naev.h
3 */
6 /**
7 * @file intro.c
9 * @brief Handles the introduction sequence.
11 * @todo Allow handling of images and other fancy things once we get them.
15 #include "intro.h"
17 #include "naev.h"
19 #include <string.h>
21 #include "SDL.h"
23 #include "log.h"
24 #include "ndata.h"
25 #include "font.h"
26 #include "music.h"
27 #include "nstd.h"
28 #include "toolkit.h"
29 #include "conf.h"
32 #define INTRO_FONT_SIZE 18. /**< Intro text font size. */
33 #define INTRO_SPEED 30. /**< Speed of text in characters / second. */
37 * Introduction text lines.
39 static char **intro_lines = NULL; /**< Introduction text lines. */
40 static int intro_nlines = 0; /**< Number of introduction text lines. */
41 static int intro_length = 0; /**< Length of the text. */
42 static glFont intro_font; /**< Introduction font. */
46 * Prototypes.
48 static int intro_load( const char *text );
49 static void intro_cleanup (void);
52 /**
53 * @brief Loads the intro stuff.
55 static int intro_load( const char *text )
57 uint32_t intro_size;
58 char *intro_buf;
59 int i, p, n;
60 int mem;
62 /* Load text. */
63 intro_buf = ndata_read( text, &intro_size );
64 intro_length = intro_size; /* Length aproximation. */
66 /* Create intro font. */
67 gl_fontInit( &intro_font, NULL, INTRO_FONT_SIZE );
69 /* Load lines. */
70 p = 0;
71 n = 0;
72 mem = 0;
73 while ((uint32_t)p < intro_size) {
74 /* Get the length. */
75 i = gl_printWidthForText( &intro_font, &intro_buf[p], SCREEN_W - 200. );
77 /* Copy the line. */
78 if (n+1 > mem) {
79 mem += 128;
80 intro_lines = realloc( intro_lines, sizeof(char*) * mem );
82 intro_lines[n] = malloc( i + 1 );
83 strncpy( intro_lines[n], &intro_buf[p], i );
84 intro_lines[n][i] = '\0';
86 p += i + 1; /* Move pointer. */
87 n++; /* New line. */
90 /* Clean up. */
91 free(intro_buf);
93 intro_nlines = n;
94 return 0;
98 /**
99 * @brief Cleans up the intro stuff.
101 static void intro_cleanup (void)
103 int i;
105 /* Free memory. */
106 for (i=0; i<intro_nlines; i++)
107 free(intro_lines[i]);
108 free(intro_lines);
109 gl_freeFont(&intro_font);
111 /* Set defaults. */
112 intro_lines = NULL;
113 intro_nlines = 0;
118 * @brief Displays the introduction sequence.
120 * @brief text Path of text file to use.
121 * @brief mus Type of music to use (run through music.lua).
122 * @return 0 on success.
124 int intro_display( const char *text, const char *mus )
126 int i, max, stop;
127 unsigned int tcur, tlast;
128 double dt;
129 double x, y, vel;
130 double offset;
131 double density;
132 SDL_Event event;
134 /* Load the introduction. */
135 if (intro_load(text) < 0)
136 return -1;
138 /* Calculate velocity. */
139 density = ((double)intro_length / (double)intro_nlines); /* char / line */
140 density /= (double)intro_font.h; /* char / pixel */
141 vel = INTRO_SPEED / density; /* (char / s) * (pixel / char) = pixel / s */
143 /* Change music to intro music. */
144 if (mus != NULL)
145 music_choose(mus);
147 /* We need to clear key repeat to avoid infinite loops. */
148 toolkit_clearKey();
150 /* Enable keyrepeat just for the intro. */
151 SDL_EnableKeyRepeat( conf.repeat_delay, conf.repeat_freq );
153 /* Prepare for intro loop. */
154 x = 100.;
155 y = 0.;
156 tlast = SDL_GetTicks();
157 offset = 0.;
158 max = intro_nlines + SCREEN_H / ((intro_font.h + 5.));
159 stop = 0;
160 while (!stop) {
162 /* Get delta tick in seconds. */
163 tcur = SDL_GetTicks();
164 dt = (double)(tcur - tlast) / 1000.;
165 tlast = tcur;
167 /* Handle events. */
168 while (SDL_PollEvent(&event)) {
169 switch (event.type) {
170 case SDL_KEYDOWN:
172 /* Escape skips directly. */
173 if (event.key.keysym.sym == SDLK_ESCAPE) {
174 stop = 1;
175 break;
178 /* Up arrow decreases speed. */
179 else if (event.key.keysym.sym == SDLK_UP) {
180 vel -= 12.;
181 break;
184 /* Down arrow increases speed. */
185 else if (event.key.keysym.sym == SDLK_DOWN) {
186 vel += 12.;
189 /* Pageup and backspace jump up. */
190 else if (event.key.keysym.sym == SDLK_PAGEUP || event.key.keysym.sym == SDLK_BACKSPACE ) {
191 offset -= 250.;
192 break;
195 /* Pagedown and space jump down. */
196 else if (event.key.keysym.sym == SDLK_PAGEDOWN || event.key.keysym.sym == SDLK_SPACE) {
197 offset += 250.;
198 break;
201 /* User is clearly flailing on keyboard. */
202 else {
203 vel = 30.;
206 /* Purpose fallthrough. */
207 case SDL_JOYBUTTONDOWN:
208 vel += 12.;
209 default:
210 break;
214 /* Increment position. */
215 offset += vel * dt;
217 /* Clear stuff. */
218 glClear(GL_COLOR_BUFFER_BIT);
220 /* Draw the text. */
221 i = (int)(offset / (intro_font.h + 5.));
222 if (i > max) /* Out of lines. */
223 break;
224 y = offset - (i+1) * (intro_font.h + 5.);
226 while (i >= 0) {
228 /* Skip in line isn't valid. */
229 if (i >= intro_nlines) {
230 i--;
231 y += intro_font.h + 5.;
232 continue;
235 gl_print( &intro_font, x, y, &cConsole, intro_lines[i] );
237 /* Increment line and position. */
238 i--;
239 y += intro_font.h + 5.;
242 /* Only thing we actually care about updating is music. */
243 music_update( 0. );
245 /* Display stuff. */
246 SDL_GL_SwapBuffers();
248 SDL_Delay(10); /* No need to burn CPU. */
251 /* Disable intro's key repeat. */
252 SDL_EnableKeyRepeat( 0, 0 );
254 /* Stop music, normal music will start shortly after. */
255 music_stop();
257 /* Clean up after the introduction. */
258 intro_cleanup();
260 return 0;