4 Super Tux - Title Screen
7 bill@newbreedsoftware.com
8 http://www.newbreedsoftware.com/supertux/
10 April 11, 2000 - March 15, 2004
20 #include <SDL_image.h>
23 #include <sys/types.h>
31 #include "high_scores.h"
38 #include "leveleditor.h"
43 #include "resources.h"
45 static Surface* bkg_title;
47 static Surface* img_choose_subset;
50 static Timer random_timer;
52 static SDL_Event event;
55 static unsigned int last_update_time;
56 static unsigned int update_time;
58 void display_credits();
60 std::vector<st_subset> contrib_subsets;
61 std::string current_contrib_subset;
63 void update_contrib_menu()
65 // FIXME: Hack to update only once
66 static bool up_to_date = false;
70 string_list_type level_subsets = dsubdirs("/levels", "info");
72 contrib_menu->clear();
73 contrib_menu->additem(MN_LABEL,"Contrib Levels",0,0);
74 contrib_menu->additem(MN_HL,"",0,0);
76 for (int i = 0; i < level_subsets.num_items; ++i)
79 subset.load(level_subsets.item[i]);
80 contrib_menu->additem(MN_GOTO, subset.title.c_str(), i, contrib_subset_menu);
81 contrib_subsets.push_back(subset);
84 contrib_menu->additem(MN_HL,"",0,0);
85 contrib_menu->additem(MN_BACK,"Back",0,0);
87 string_list_free(&level_subsets);
92 void check_contrib_menu()
94 static int current_subset = -1;
96 int index = contrib_menu->check();
99 index -= 2; // FIXME: Hack
100 if (index >= 0 && index <= int(contrib_subsets.size()))
102 if (current_subset != index)
104 current_subset = index;
105 // FIXME: This shouln't be busy looping
106 st_subset& subset = contrib_subsets[index];
108 current_contrib_subset = subset.name;
110 std::cout << "Updating the contrib subset menu..." << subset.levels << std::endl;
112 contrib_subset_menu->clear();
114 contrib_subset_menu->additem(MN_LABEL, subset.title, 0,0);
115 contrib_subset_menu->additem(MN_HL,"",0,0);
116 for (int i = 1; i <= subset.levels; ++i)
119 level.load(subset.name, i);
120 contrib_subset_menu->additem(MN_ACTION, level.name, 0, 0);
122 contrib_subset_menu->additem(MN_HL,"",0,0);
123 contrib_subset_menu->additem(MN_BACK, "Back", 0, 0);
133 void check_contrib_subset_menu()
135 int index = contrib_subset_menu->check();
138 index -= 1; // FIXME: Hack
139 std::cout << "Sarting level: " << index << std::endl;
140 GameSession session(current_contrib_subset, index, ST_GL_PLAY);
143 Menu::set_current(main_menu);
148 void draw_background()
150 /* Draw the title background: */
152 bkg_title->draw_bg();
155 void draw_demo(GameSession* session, double frame_ratio)
157 World::set_current(session->get_world());
158 //World* world = session->get_world();
159 Level* plevel = session->get_level();
160 Player* tux = session->get_world()->get_tux();
163 // update particle systems
164 std::vector<ParticleSystem*>::iterator p;
165 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
167 (*p)->simulate(frame_ratio);
170 // Draw particle systems (background)
171 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
173 (*p)->draw(scroll_x, 0, 0);
177 // Draw interactive tiles:
178 for (int y = 0; y < 15; ++y)
180 for (int x = 0; x < 21; ++x)
182 Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
183 plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
187 global_frame_counter++;
188 tux->key_event(SDLK_RIGHT,DOWN);
190 if(random_timer.check())
193 tux->key_event(SDLK_UP,UP);
195 tux->key_event(SDLK_UP,DOWN);
199 random_timer.start(rand() % 3000 + 3000);
203 // Wrap around at the end of the level back to the beginnig
204 if(plevel->width * 32 - 320 < tux->base.x)
206 tux->base.x = tux->base.x - (plevel->width * 32 - 640);
207 scroll_x = tux->base.x - 320;
212 float last_tux_x_pos = tux->base.x;
213 tux->action(frame_ratio);
215 // Jump if tux stays in the same position for one loop, ie. if he is
216 // stuck behind a wall
217 if (last_tux_x_pos == tux->base.x)
223 /* --- TITLE SCREEN --- */
227 random_timer.init(true);
231 st_pause_ticks_init();
233 GameSession session(datadir + "/levels/misc/menu.stl");
235 //FIXME:activate_particle_systems();
237 /* Reset menu variables */
239 Menu::set_current(main_menu);
241 clearscreen(0, 0, 0);
246 bkg_title = new Surface(datadir + "/images/title/background.jpg", IGNORE_ALPHA);
247 logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA);
248 img_choose_subset = new Surface(datadir + "/images/status/choose-level-subset.png", USE_ALPHA);
250 /* --- Main title loop: --- */
255 /* Draw the title background: */
256 bkg_title->draw_bg();
259 update_time = st_get_ticks();
260 random_timer.start(rand() % 2000 + 2000);
264 /* Calculate the movement-factor */
265 double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
266 if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
267 frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
268 /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */
273 while (SDL_PollEvent(&event))
275 current_menu->event(event);
276 if (event.type == SDL_QUIT)
280 else if (event.type == SDL_KEYDOWN)
283 key = event.key.keysym.sym;
285 /* Check for menu events */
288 if (key == SDLK_ESCAPE)
296 /* Draw the background: */
298 draw_demo(&session, frame_ratio);
300 if (current_menu == main_menu)
301 logo->draw( 160, 30);
303 text_draw(&white_small_text,
304 " SuperTux " VERSION "\n"
305 "Copyright (c) 2003 SuperTux Devel Team\n"
306 "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
307 "are welcome to redistribute it under certain conditions; see the file COPYING\n"
311 /* Draw the high score: */
313 sprintf(str, "High score: %d", hs_score);
314 text_drawf(&gold_text, str, 0, -40, A_HMIDDLE, A_BOTTOM, 1);
315 sprintf(str, "by %s", hs_name);
316 text_drawf(&gold_text, str, 0, -20, A_HMIDDLE, A_BOTTOM, 1);
319 /* Don't draw menu, if quit is true */
320 if(show_menu && !done)
321 menu_process_current();
323 if(current_menu == main_menu)
325 switch (main_menu->check())
329 string_list_type level_subsets;
330 level_subsets = dsubdirs("/levels", "info");
336 if(level_subsets.num_items != 0)
338 subset.load(level_subsets.item[0]);
341 img_choose_subset->draw((screen->w - img_choose_subset.w) / 2, 0);
342 if(level_subsets.num_items != 0)
344 subset.image->draw((screen->w - subset.image.w) / 2 + 25,78);
345 if(level_subsets.num_items > 1)
348 arrow_left->draw((screen->w / 2) - ((subset.title.length()+2)*16)/2,20);
349 if(i < level_subsets.num_items-1)
350 arrow_right->draw((screen->w / 2) + ((subset.description.length())*16)/2,20);
352 text_drawf(&gold_text, subset.title.c_str(), 0, 20, A_HMIDDLE, A_TOP, 1);
353 text_drawf(&gold_text, subset.description.c_str(), 20, -20, A_HMIDDLE, A_BOTTOM, 1);
357 while(SDL_PollEvent(&event) && !done)
364 case SDL_KEYDOWN: // key pressed
366 key = event.key.keysym.sym;
374 subset.load(level_subsets.item[i]);
377 else if(key == SDLK_RIGHT)
379 if(i < level_subsets.num_items -1)
383 subset.load(level_subsets.item[i]);
386 else if(key == SDLK_SPACE || key == SDLK_RETURN)
389 quit = gameloop(subset.name.c_str(),1,ST_GL_PLAY);
392 else if(key == SDLK_ESCAPE)
405 titletux.level_begin();
406 update_time = st_get_ticks();
410 // Start Game, ie. goto the slots menu
411 update_load_save_game_menu(load_game_menu, true);
415 update_contrib_menu();
419 done = leveleditor(1);
422 Menu::set_current(main_menu);
432 else if(current_menu == options_menu)
434 process_options_menu();
436 else if(current_menu == load_game_menu)
438 if (process_load_game_menu())
440 // FIXME: shouldn't be needed if GameSession doesn't relay on global variables
443 //titletux.level_begin();
444 update_time = st_get_ticks();
447 else if(current_menu == contrib_menu)
449 check_contrib_menu();
451 else if (current_menu == contrib_subset_menu)
453 check_contrib_subset_menu();
456 mouse_cursor->draw();
460 /* Set the time of the last update and the time of the current update */
461 last_update_time = update_time;
462 update_time = st_get_ticks();
474 /* Return to main! */
482 void display_credits()
491 string_list_type names;
493 string_list_init(&names);
494 sprintf(filename,"%s/CREDITS", datadir.c_str());
495 if((fi = fopen(filename,"r")) != NULL)
497 while(fgets(temp, sizeof(temp), fi) != NULL)
499 temp[strlen(temp)-1]='\0';
500 string_list_add_item(&names,temp);
506 string_list_add_item(&names,"Credits were not found!");
507 string_list_add_item(&names,"Shame on the guy, who");
508 string_list_add_item(&names,"forgot to include them");
509 string_list_add_item(&names,"in your SuperTux distribution.");
513 timer.init(SDL_GetTicks());
522 length = names.num_items;
524 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
528 /* in case of input, exit */
529 while(SDL_PollEvent(&event))
533 switch(event.key.keysym.sym)
562 else if(speed < -MAX_VEL)
565 /* draw the credits */
569 text_drawf(&white_big_text, "- Credits -", 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2);
571 for(i = 0, n = 0, d = 0; i < length; i++,n++,d++)
573 if(names.item[i] == "")
577 if(names.item[i][0] == ' ')
578 text_drawf(&white_small_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll-10, A_HMIDDLE, A_TOP, 1);
579 else if(names.item[i][0] == ' ')
580 text_drawf(&white_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1);
581 else if(names.item[i+1][0] == '-' || names.item[i][0] == '-')
582 text_drawf(&white_big_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 3);
584 text_drawf(&blue_text, names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1);
590 if(60+screen->h+(n*18)+(d*18)-scroll < 0 && 20+60+screen->h+(n*18)+(d*18)-scroll < 0)
599 if(timer.get_left() < 0)
605 string_list_free(&names);
607 SDL_EnableKeyRepeat(0, 0); // disables key repeating
609 Menu::set_current(main_menu);