- fixed file extension, removed pwd.h header
[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 #ifdef JOY_YES
128           else if (event.type == SDL_JOYAXISMOTION && event.jaxis.axis == JOY_Y)
129             {
130               if (event.jaxis.value > 1024)
131                 menuaction = MN_DOWN;
132               else if (event.jaxis.value < -1024)
133                 menuaction = MN_UP;
134             }
135           else if (event.type == SDL_JOYBUTTONDOWN)
136             {
137               /* Joystick button: Continue: */
138
139               menuaction = MN_HIT;
140             }
141 #endif
142
143         }
144
145       /* Draw the background: */
146       draw_background();
147
148       /* Draw the high score: */
149       sprintf(str, "High score: %d", hs_score);
150       text_drawf(&gold_text, str, 0, -40, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
151       sprintf(str, "by %s", hs_name);
152       text_drawf(&gold_text, str, 0, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
153
154       /* Don't draw menu, if quit is true */
155       if(show_menu && !quit)
156         menu_process_current();
157
158       if(current_menu == &main_menu)
159         {
160           switch (menu_check(&main_menu))
161             {
162             case 2:
163               done = 0;
164               i = 0;
165               if(level_subsets.num_items != 0)
166                 {
167                   subset.load(level_subsets.item[0]);
168                   while(!done)
169                     {
170                       texture_draw(&img_choose_subset,(screen->w - img_choose_subset.w) / 2, 0, NO_UPDATE);
171                       if(level_subsets.num_items != 0)
172                         {
173                           texture_draw(&subset.image,(screen->w - subset.image.w) / 2 + 25,78,NO_UPDATE);
174                           if(level_subsets.num_items > 1)
175                             {
176                               if(i > 0)
177                                 texture_draw(&arrow_left,(screen->w / 2) - ((subset.title.length()+2)*16)/2,20,NO_UPDATE);
178                               if(i < level_subsets.num_items-1)
179                                 texture_draw(&arrow_right,(screen->w / 2) + ((subset.description.length())*16)/2,20,NO_UPDATE);
180                             }
181                           text_drawf(&gold_text, subset.title.c_str(), 0, 20, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
182                           text_drawf(&gold_text, subset.description.c_str(), 20, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
183                         }
184                       updatescreen();
185                       SDL_Delay(50);
186                       while(SDL_PollEvent(&event) && !done)
187                         {
188                           switch(event.type)
189                             {
190                             case SDL_QUIT:
191                               done = 1;
192                               quit = 1;
193                               break;
194                             case SDL_KEYDOWN:           // key pressed
195                               /* Keypress... */
196
197                               key = event.key.keysym.sym;
198
199                               if(key == SDLK_LEFT)
200                                 {
201                                   if(i > 0)
202                                     {
203                                       --i;
204                                       subset.free();
205                                       subset.load(level_subsets.item[i]);
206                                     }
207                                 }
208                               else if(key == SDLK_RIGHT)
209                                 {
210                                   if(i < level_subsets.num_items -1)
211                                     {
212                                       ++i;
213                                       subset.free();
214                                       subset.load(level_subsets.item[i]);
215                                     }
216                                 }
217                               else if(key == SDLK_SPACE || key == SDLK_RETURN)
218                                 {
219                                   done = YES;
220                                   quit = gameloop(subset.name.c_str(),1,ST_GL_PLAY);
221                                   subset.free();
222                                 }
223                               else if(key == SDLK_ESCAPE)
224                                 {
225                                   done = YES;
226                                 }
227                               break;
228                             default:
229                               break;
230                             }
231                         }
232                     }
233                 }
234               break;
235             case 3:
236               update_load_save_game_menu(&load_game_menu, YES);
237               break;
238             case 5:
239               done = 1;
240               quit = leveleditor(1);
241               break;
242             case 6:
243               display_credits();
244               break;
245             case 8:
246               quit = 1;
247               break;
248             }
249         }
250       else if(current_menu == &options_menu)
251         {
252           process_options_menu();
253         }
254       else if(current_menu == &load_game_menu)
255         {
256           process_save_load_game_menu(NO);
257         }
258
259       flipscreen();
260
261       /* Pause: */
262       frame++;
263       SDL_Delay(50);
264
265     }
266   /* Free surfaces: */
267
268   texture_free(&bkg_title);
269   texture_free(&anim1);
270   texture_free(&anim2);
271   string_list_free(&level_subsets);
272
273   /* Return to main! */
274
275   return(quit);
276 }
277
278 #define MAX_VEL 10
279 #define SPEED   1
280 #define SCROLL  60
281
282 void display_credits()
283 {
284   int done;
285   int scroll, speed;
286   timer_type timer;
287   int n,d;
288   int length;
289   FILE* fi;
290   char temp[1024];
291   string_list_type names;
292   char filename[1024];
293   string_list_init(&names);
294   sprintf(filename,"%s/CREDITS", datadir.c_str());
295   if((fi = fopen(filename,"r")) != NULL)
296     {
297       while(fgets(temp, sizeof(temp), fi) != NULL)
298         {
299           temp[strlen(temp)-1]='\0';
300           string_list_add_item(&names,temp);
301         }
302       fclose(fi);
303     }
304   else
305     {
306       string_list_add_item(&names,"Credits were not found!");
307       string_list_add_item(&names,"Shame on the guy, who");
308       string_list_add_item(&names,"forgot to include them");
309       string_list_add_item(&names,"in your SuperTux distribution.");
310     }
311
312
313   timer_init(&timer, SDL_GetTicks());
314   timer_start(&timer, 50);
315
316   scroll = 0;
317   speed = 2;
318   done = 0;
319
320   n = d = 0;
321
322   length = names.num_items;
323
324   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
325
326   while(done == 0)
327     {
328       /* in case of input, exit */
329       while(SDL_PollEvent(&event))
330         switch(event.type)
331           {
332           case SDL_KEYDOWN:
333             switch(event.key.keysym.sym)
334               {
335               case SDLK_UP:
336                 speed -= SPEED;
337                 break;
338               case SDLK_DOWN:
339                 speed += SPEED;
340                 break;
341               case SDLK_SPACE:
342               case SDLK_RETURN:
343                 if(speed >= 0)
344                   scroll += SCROLL;
345                 break;
346               case SDLK_ESCAPE:
347                 done = 1;
348                 break;
349               default:
350                 break;
351               }
352             break;
353           case SDL_QUIT:
354             done = 1;
355             break;
356           default:
357             break;
358           }
359
360       if(speed > MAX_VEL)
361         speed = MAX_VEL;
362       else if(speed < -MAX_VEL)
363         speed = -MAX_VEL;
364
365       /* draw the credits */
366
367       draw_background();
368
369       text_drawf(&white_big_text, "- Credits -", 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
370
371       for(i = 0, n = 0, d = 0; i < length; i++,n++,d++)
372         {
373           if(names.item[i] == "")
374             n--;
375           else
376             {
377               if(names.item[i][0] == ' ')
378                 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);
379               else if(names.item[i][0] == '     ')
380                 text_drawf(&white_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
381               else if(names.item[i+1][0] == '-' || names.item[i][0] == '-')
382                 text_drawf(&white_big_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 3, NO_UPDATE);
383               else
384                 text_drawf(&blue_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
385             }
386         }
387
388
389       texture_draw_part(&bkg_title, 0, 0, 0, 0, 640, 130, NO_UPDATE);
390
391       flipscreen();
392
393       if(60+screen->h+(n*18)+(d*18)-scroll < 0 && 20+60+screen->h+(n*18)+(d*18)-scroll < 0)
394         done = 1;
395
396       scroll += speed;
397       if(scroll < 0)
398         scroll = 0;
399
400       SDL_Delay(35);
401
402       if(timer_get_left(&timer) < 0)
403         {
404           frame++;
405           timer_start(&timer, 50);
406         }
407     }
408   string_list_free(&names);
409
410   SDL_EnableKeyRepeat(0, 0);    // disables key repeating
411   show_menu = 1;
412   menu_set_current(&main_menu);
413 }