2280fbff56b3efc83a18ed341b3ab4888f25fb24
[supertux.git] / src / title.cpp
1 /*
2   title.c
3   
4   Super Tux - Title Screen
5   
6   by Bill Kendrick
7   bill@newbreedsoftware.com
8   http://www.newbreedsoftware.com/supertux/
9   
10   April 11, 2000 - March 15, 2004
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <SDL.h>
19 #include <SDL_image.h>
20
21 #ifndef WIN32
22 #include <sys/types.h>
23 #include <ctype.h>
24 #endif
25
26 #include "defines.h"
27 #include "globals.h"
28 #include "title.h"
29 #include "screen.h"
30 #include "high_scores.h"
31 #include "menu.h"
32 #include "texture.h"
33 #include "timer.h"
34 #include "setup.h"
35 #include "level.h"
36 #include "gameloop.h"
37 #include "leveleditor.h"
38
39 static texture_type bkg_title, img_choose_subset, anim1, anim2;
40 static SDL_Event event;
41 static SDLKey key;
42 static int quit, frame, pict, i;
43
44 void display_credits();
45
46 void draw_background()
47 {
48   /* Draw the title background: */
49
50   texture_draw_bg(&bkg_title, NO_UPDATE);
51
52   /* Animate title screen: */
53
54   pict = (frame / 5) % 3;
55
56   if (pict == 0)
57     texture_draw_part(&bkg_title, 560, 270, 560, 270, 80, 75, NO_UPDATE);
58   else if (pict == 1)
59     texture_draw(&anim1, 560, 270, NO_UPDATE);
60   else if (pict == 2)
61     texture_draw(&anim2, 560, 270, NO_UPDATE);
62 }
63
64 /* --- TITLE SCREEN --- */
65
66 int title(void)
67 {
68   int done;
69   char str[80];
70   string_list_type level_subsets;
71   st_subset subset;
72   level_subsets = dsubdirs("/levels", "info");
73
74   /* Reset menu variables */
75   menu_reset();
76   menu_set_current(&main_menu);
77
78   clearscreen(0, 0, 0);
79   updatescreen();
80
81   /* Load images: */
82
83   texture_load(&bkg_title,datadir + "/images/title/title.png", IGNORE_ALPHA);
84   texture_load(&anim1,datadir + "/images/title/title-anim2.png", IGNORE_ALPHA);
85   texture_load(&anim2,datadir + "/images/title/title-anim1.png", IGNORE_ALPHA);
86   texture_load(&img_choose_subset,datadir + "/images/status/choose-level-subset.png", USE_ALPHA);
87
88   /* --- Main title loop: --- */
89
90   done = 0;
91   quit = 0;
92   show_menu = 1;
93   frame = 0;
94
95   /* Draw the title background: */
96   texture_draw_bg(&bkg_title, NO_UPDATE);
97
98   load_hs();
99
100   while (!done && !quit)
101     {
102       /* Handle events: */
103
104       while (SDL_PollEvent(&event))
105         {
106           if (event.type == SDL_QUIT)
107             {
108               /* Quit event - quit: */
109               quit = 1;
110             }
111           else if (event.type == SDL_KEYDOWN)
112             {
113               /* Keypress... */
114
115               key = event.key.keysym.sym;
116
117               /* Check for menu events */
118               menu_event(&event.key.keysym);
119
120               if (key == SDLK_ESCAPE)
121                 {
122                   /* Escape: Quit: */
123
124                   quit = 1;
125                 }
126             }
127           else if (event.type == SDL_JOYAXISMOTION && event.jaxis.axis == JOY_Y)
128             {
129               if (event.jaxis.value > 1024)
130                 menuaction = MN_DOWN;
131               else if (event.jaxis.value < -1024)
132                 menuaction = MN_UP;
133             }
134           else if (event.type == SDL_JOYBUTTONDOWN)
135             {
136               /* Joystick button: Continue: */
137
138               menuaction = MN_HIT;
139             }
140         }
141
142       /* Draw the background: */
143       draw_background();
144
145       /* Draw the high score: */
146       sprintf(str, "High score: %d", hs_score);
147       text_drawf(&gold_text, str, 0, -40, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
148       sprintf(str, "by %s", hs_name);
149       text_drawf(&gold_text, str, 0, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
150
151       /* Don't draw menu, if quit is true */
152       if(show_menu && !quit)
153         menu_process_current();
154
155       if(current_menu == &main_menu)
156         {
157           switch (menu_check(&main_menu))
158             {
159             case 2:
160               done = 0;
161               i = 0;
162               if(level_subsets.num_items != 0)
163                 {
164                   subset.load(level_subsets.item[0]);
165                   while(!done)
166                     {
167                       texture_draw(&img_choose_subset,(screen->w - img_choose_subset.w) / 2, 0, NO_UPDATE);
168                       if(level_subsets.num_items != 0)
169                         {
170                           texture_draw(&subset.image,(screen->w - subset.image.w) / 2 + 25,78,NO_UPDATE);
171                           if(level_subsets.num_items > 1)
172                             {
173                               if(i > 0)
174                                 texture_draw(&arrow_left,(screen->w / 2) - ((subset.title.length()+2)*16)/2,20,NO_UPDATE);
175                               if(i < level_subsets.num_items-1)
176                                 texture_draw(&arrow_right,(screen->w / 2) + ((subset.description.length())*16)/2,20,NO_UPDATE);
177                             }
178                           text_drawf(&gold_text, subset.title.c_str(), 0, 20, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
179                           text_drawf(&gold_text, subset.description.c_str(), 20, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
180                         }
181                       updatescreen();
182                       SDL_Delay(50);
183                       while(SDL_PollEvent(&event) && !done)
184                         {
185                           switch(event.type)
186                             {
187                             case SDL_QUIT:
188                               done = 1;
189                               quit = 1;
190                               break;
191                             case SDL_KEYDOWN:           // key pressed
192                               /* Keypress... */
193
194                               key = event.key.keysym.sym;
195
196                               if(key == SDLK_LEFT)
197                                 {
198                                   if(i > 0)
199                                     {
200                                       --i;
201                                       subset.free();
202                                       subset.load(level_subsets.item[i]);
203                                     }
204                                 }
205                               else if(key == SDLK_RIGHT)
206                                 {
207                                   if(i < level_subsets.num_items -1)
208                                     {
209                                       ++i;
210                                       subset.free();
211                                       subset.load(level_subsets.item[i]);
212                                     }
213                                 }
214                               else if(key == SDLK_SPACE || key == SDLK_RETURN)
215                                 {
216                                   done = YES;
217                                   quit = gameloop(subset.name.c_str(),1,ST_GL_PLAY);
218                                   subset.free();
219                                 }
220                               else if(key == SDLK_ESCAPE)
221                                 {
222                                   done = YES;
223                                 }
224                               break;
225                             default:
226                               break;
227                             }
228                         }
229                     }
230                 }
231               break;
232             case 3:
233               update_load_save_game_menu(&load_game_menu, YES);
234               break;
235             case 5:
236               done = 1;
237               quit = leveleditor(1);
238               break;
239             case 6:
240               display_credits();
241               break;
242             case 8:
243               quit = 1;
244               break;
245             }
246         }
247       else if(current_menu == &options_menu)
248         {
249           process_options_menu();
250         }
251       else if(current_menu == &load_game_menu)
252         {
253           process_save_load_game_menu(NO);
254         }
255
256       flipscreen();
257
258       /* Pause: */
259       frame++;
260       SDL_Delay(50);
261
262     }
263   /* Free surfaces: */
264
265   texture_free(&bkg_title);
266   texture_free(&anim1);
267   texture_free(&anim2);
268   string_list_free(&level_subsets);
269
270   /* Return to main! */
271
272   return(quit);
273 }
274
275 #define MAX_VEL 10
276 #define SPEED   1
277 #define SCROLL  60
278
279 void display_credits()
280 {
281   int done;
282   int scroll, speed;
283   timer_type timer;
284   int n,d;
285   int length;
286   FILE* fi;
287   char temp[1024];
288   string_list_type names;
289   char filename[1024];
290   string_list_init(&names);
291   sprintf(filename,"%s/CREDITS", datadir.c_str());
292   if((fi = fopen(filename,"r")) != NULL)
293     {
294       while(fgets(temp, sizeof(temp), fi) != NULL)
295         {
296           temp[strlen(temp)-1]='\0';
297           string_list_add_item(&names,temp);
298         }
299       fclose(fi);
300     }
301   else
302     {
303       string_list_add_item(&names,"Credits were not found!");
304       string_list_add_item(&names,"Shame on the guy, who");
305       string_list_add_item(&names,"forgot to include them");
306       string_list_add_item(&names,"in your SuperTux distribution.");
307     }
308
309
310   timer_init(&timer, SDL_GetTicks());
311   timer_start(&timer, 50);
312
313   scroll = 0;
314   speed = 2;
315   done = 0;
316
317   n = d = 0;
318
319   length = names.num_items;
320
321   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
322
323   while(done == 0)
324     {
325       /* in case of input, exit */
326       while(SDL_PollEvent(&event))
327         switch(event.type)
328           {
329           case SDL_KEYDOWN:
330             switch(event.key.keysym.sym)
331               {
332               case SDLK_UP:
333                 speed -= SPEED;
334                 break;
335               case SDLK_DOWN:
336                 speed += SPEED;
337                 break;
338               case SDLK_SPACE:
339               case SDLK_RETURN:
340                 if(speed >= 0)
341                   scroll += SCROLL;
342                 break;
343               case SDLK_ESCAPE:
344                 done = 1;
345                 break;
346               default:
347                 break;
348               }
349             break;
350           case SDL_QUIT:
351             done = 1;
352             break;
353           default:
354             break;
355           }
356
357       if(speed > MAX_VEL)
358         speed = MAX_VEL;
359       else if(speed < -MAX_VEL)
360         speed = -MAX_VEL;
361
362       /* draw the credits */
363
364       draw_background();
365
366       text_drawf(&white_big_text, "- Credits -", 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
367
368       for(i = 0, n = 0, d = 0; i < length; i++,n++,d++)
369         {
370           if(names.item[i] == "")
371             n--;
372           else
373             {
374               if(names.item[i][0] == ' ')
375                 text_drawf(&white_small_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll-10, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
376               else if(names.item[i][0] == '     ')
377                 text_drawf(&white_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
378               else if(names.item[i+1][0] == '-' || names.item[i][0] == '-')
379                 text_drawf(&white_big_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 3, NO_UPDATE);
380               else
381                 text_drawf(&blue_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
382             }
383         }
384
385
386       texture_draw_part(&bkg_title, 0, 0, 0, 0, 640, 130, NO_UPDATE);
387
388       flipscreen();
389
390       if(60+screen->h+(n*18)+(d*18)-scroll < 0 && 20+60+screen->h+(n*18)+(d*18)-scroll < 0)
391         done = 1;
392
393       scroll += speed;
394       if(scroll < 0)
395         scroll = 0;
396
397       SDL_Delay(35);
398
399       if(timer_get_left(&timer) < 0)
400         {
401           frame++;
402           timer_start(&timer, 50);
403         }
404     }
405   string_list_free(&names);
406
407   SDL_EnableKeyRepeat(0, 0);    // disables key repeating
408   show_menu = 1;
409   menu_set_current(&main_menu);
410 }