From: Matthew Mondor Date: Tue, 9 Jan 2007 01:49:10 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: pgsql-branch-merge~35 X-Git-Url: http://git.pulsar-zone.net/?a=commitdiff_plain;h=260ee5766fdfd6ccf95e3c9f155d98472f082add;p=mmondor.git *** empty log message *** --- diff --git a/mmsoftware/paradise_adventure/src/main.c b/mmsoftware/paradise_adventure/src/main.c index 9a90954..312c4be 100644 --- a/mmsoftware/paradise_adventure/src/main.c +++ b/mmsoftware/paradise_adventure/src/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.9 2007/01/08 11:46:57 mmondor Exp $ */ +/* $Id: main.c,v 1.10 2007/01/09 01:49:10 mmondor Exp $ */ /* * Copyright (c) 2006, Matthew Mondor @@ -30,9 +30,13 @@ #define FADEOUT_DELAY 1000 +#define TEXT_WIDTH 185 +#define TEXT_LINE_SIZE 256 + struct scene { const char *img, *mus; int vol; + const char *text; }; struct font { @@ -41,6 +45,12 @@ struct font { TTF_Font *fnt; }; +typedef struct text { + TTF_Font *fnt; + int numlines, alloclines; + char **lines; +} text_t; + /* PRIVATE PROTOTYPES */ @@ -48,12 +58,16 @@ struct font { int main(int, char **); static void screen_draw(void); -static void scene_switch(const char *, const char *, int); +static void scene_switch(const char *, const char *, int, + const char *); static void scene_next(void); static void fonts_load(void); static TTF_Font *font_next(void); +static text_t *text_create(TTF_Font *, const char *); +static void text_free(text_t *); + /* PUBLIC GLOBALS */ @@ -72,12 +86,23 @@ static Mix_Music *music = NULL; static char *painting_file = NULL, *music_file = NULL; static const struct scene scenes[] = { - { "gardens_smallbridge", "adventure1", 128 }, - { "forest_entry", "forest", 128 }, - { "dungeon_deadend", "cavern", 128 }, - { "gardens_house", "castle", 128 }, - { "mountains_landscape", "aria_prima", 85 }, - { NULL, NULL } + { "gardens_smallbridge", "adventure1", 128, + "The water is calm. Far ahead can be seen a bridge at the " + "right." + }, + { "forest_entry", "forest", 128, + "You are at the entrance of a deep forest." + }, + { "dungeon_deadend", "cavern", 128, + "You reached a deadly dungeon dead-end!" + }, + { "gardens_house", "castle", 128, + "Here can be seen a quiet asian-style castle." + }, + { "mountains_landscape", "aria_prima", 85, + "What a great mountain landscape!" + }, + { NULL, NULL, 0, NULL } }; static int curscene = 0; @@ -209,14 +234,15 @@ screen_draw(void) } static void -scene_switch(const char *img, const char *mus, int vol) +scene_switch(const char *img, const char *mus, int vol, const char *text) { SDL_Surface *s = NULL; Mix_Music *m = NULL; char path[1024], *str = NULL; int music_new = 0; + text_t *txt; - ASSERT(img != NULL && mus != NULL); + ASSERT(img != NULL && mus != NULL && text != NULL); /* * Because redrawing a lot while the music is just starting appears @@ -255,9 +281,33 @@ scene_switch(const char *img, const char *mus, int vol) r = (SDL_Rect){ 16, 16, 0, 0 }; (void) SDL_BlitSurface(img_painting, NULL, screen_surface, &r); - (void) SDL_Flip(screen_surface); } + /* Draw text */ + if ((txt = text_create(font_next(), text)) != NULL) { + SDL_Rect r; + SDL_Surface *s; + int i, y, h; + + r = (SDL_Rect){ 798, 16, 0, 0 }; + (void) SDL_BlitSurface(img_textarea, NULL, screen_surface, &r); + + h = TTF_FontHeight(txt->fnt); + y = 32; + for (i = 0; i < txt->numlines; i++, y += h) { + if ((s = TTF_RenderText_Blended(txt->fnt, + txt->lines[i], fontcol)) != NULL) { + r = (SDL_Rect){ 815, y, 0, 0 }; + (void) SDL_BlitSurface(s, NULL, screen_surface, + &r); + SDL_FreeSurface(s); + } + } + text_free(txt); + } + + (void) SDL_Flip(screen_surface); + /* Load new music track if necessary and start it */ if (music_new) { (void) snprintf(path, 1023, "mus/%s.ogg", mus); @@ -286,25 +336,13 @@ scene_switch(const char *img, const char *mus, int vol) static void scene_next(void) { - SDL_Surface *s; if (scenes[curscene].img == NULL) curscene = 0; scene_switch(scenes[curscene].img, scenes[curscene].mus, - scenes[curscene].vol); + scenes[curscene].vol, scenes[curscene].text); curscene++; - - if ((s = TTF_RenderText_Blended(font_next(), "A Paradise Adventure!", - fontcol)) != NULL) { - SDL_Rect r; - - r = (SDL_Rect){ 798, 16, 0, 0 }; - (void) SDL_BlitSurface(img_textarea, NULL, screen_surface, &r); - r = (SDL_Rect){ 832, 32, 0, 0 }; - (void) SDL_BlitSurface(s, NULL, screen_surface, &r); - SDL_FreeSurface(s); - } } static void @@ -338,3 +376,95 @@ font_next(void) return fonts[curfont++].fnt; } + +static text_t * +text_create(TTF_Font *font, const char *string) +{ + text_t *text; + char *str, *ptr, *olptr, *lptr; + + /* + * Since not performance-critical, and that we could be supplied + * a read-only string, let's duplicate the supplied string. + */ + if ((str = strdup(string)) == NULL) + return NULL; + + if ((text = malloc(sizeof(text_t))) == NULL) + goto err; + text->numlines = 0; + if ((text->lines = malloc(sizeof(char *) * 16)) == NULL) + goto err; + text->alloclines = 16; + text->fnt = font; + + /* Allocate an initial line */ + if ((olptr = malloc(sizeof(char) * TEXT_LINE_SIZE)) == NULL) + goto err; + lptr = text->lines[text->numlines++] = olptr; + + /* + * Populate line with words until it exceeds the allowed width, + * in which case we delete the last word from it and create a new + * line, adding it to it. + */ + for (ptr = strtok(str, " \t"); ptr != NULL; + ptr = strtok(NULL, " \t")) { + int l, w; + + l = strlen(ptr); +again: + (void) memcpy(lptr, ptr, l); + lptr[l] = ' '; + lptr[l + 1] = '\0'; + if (TTF_SizeText(font, olptr, &w, NULL) == -1) + goto err; + if (w < TEXT_WIDTH) { + lptr += l + 1; + continue; + } + + /* + * We need to allocate a new line and reiterate. + * First discard last word we appended to current line. + */ + *lptr = '\0'; + if (text->numlines == text->alloclines) { + /* Grow strings array buffer */ + char **a; + + if ((a = malloc(sizeof(char *) * + (text->alloclines * 2))) == NULL) + goto err; + text->lines = a; + } + if ((olptr = malloc(sizeof(char) * TEXT_LINE_SIZE)) == NULL) + goto err; + lptr = text->lines[text->numlines++] = olptr; + goto again; + } + + free(str); + return text; + +err: + if (str != NULL) + free(str); + text_free(text); + return NULL; +} + +static void +text_free(text_t *text) +{ + int i; + + if (text != NULL) { + if (text->lines != NULL) { + for (i = 0; i < text->numlines; i++) + free(text->lines[i]); + free(text->lines); + } + free(text); + } +}