/** * @file intro.c * * @brief Handle the introduction sequence. * * @todo Allow handling of images and other fancy things once we get them. */ #include #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; }