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