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;
53 static unsigned int last_update_time;
54 static unsigned int update_time;
56 void display_credits();
58 std::vector<st_subset> contrib_subsets;
59 std::string current_contrib_subset;
61 void update_contrib_menu()
63 // FIXME: Hack to update only once
64 static bool up_to_date = false;
68 string_list_type level_subsets = dsubdirs("/levels", "info");
70 contrib_menu->clear();
71 contrib_menu->additem(MN_LABEL,"Contrib Levels",0,0);
72 contrib_menu->additem(MN_HL,"",0,0);
74 for (int i = 0; i < level_subsets.num_items; ++i)
77 subset.load(level_subsets.item[i]);
78 contrib_menu->additem(MN_GOTO, subset.title.c_str(), i, contrib_subset_menu);
79 contrib_subsets.push_back(subset);
82 contrib_menu->additem(MN_HL,"",0,0);
83 contrib_menu->additem(MN_BACK,"Back",0,0);
85 string_list_free(&level_subsets);
90 void check_contrib_menu()
92 static int current_subset = -1;
94 int index = contrib_menu->check();
97 index -= 2; // FIXME: Hack
98 if (index >= 0 && index <= int(contrib_subsets.size()))
100 if (current_subset != index)
102 current_subset = index;
103 // FIXME: This shouln't be busy looping
104 st_subset& subset = contrib_subsets[index];
106 current_contrib_subset = subset.name;
108 std::cout << "Updating the contrib subset menu..." << subset.levels << std::endl;
110 contrib_subset_menu->clear();
112 contrib_subset_menu->additem(MN_LABEL, subset.title, 0,0);
113 contrib_subset_menu->additem(MN_HL,"",0,0);
114 for (int i = 1; i <= subset.levels; ++i)
117 level.load(subset.name, i);
118 contrib_subset_menu->additem(MN_ACTION, level.name, 0, 0);
120 contrib_subset_menu->additem(MN_HL,"",0,0);
121 contrib_subset_menu->additem(MN_BACK, "Back", 0, 0);
131 void check_contrib_subset_menu()
133 int index = contrib_subset_menu->check();
136 index -= 1; // FIXME: Hack
137 std::cout << "Sarting level: " << index << std::endl;
138 GameSession session(current_contrib_subset, index, ST_GL_PLAY);
140 Menu::set_current(main_menu);
144 void draw_background()
146 /* Draw the title background: */
148 bkg_title->draw_bg();
151 void draw_demo(GameSession* session, double frame_ratio)
153 World::set_current(session->get_world());
154 //World* world = session->get_world();
155 Level* plevel = session->get_level();
156 Player* tux = session->get_world()->get_tux();
159 // update particle systems
160 std::vector<ParticleSystem*>::iterator p;
161 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
163 (*p)->simulate(frame_ratio);
166 // Draw particle systems (background)
167 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
169 (*p)->draw(scroll_x, 0, 0);
173 // Draw interactive tiles:
174 for (int y = 0; y < 15; ++y)
176 for (int x = 0; x < 21; ++x)
178 Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
179 plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
183 global_frame_counter++;
184 tux->key_event(SDLK_RIGHT,DOWN);
186 if(random_timer.check())
189 tux->key_event(SDLK_UP,UP);
191 tux->key_event(SDLK_UP,DOWN);
195 random_timer.start(rand() % 3000 + 3000);
199 // Wrap around at the end of the level back to the beginnig
200 if(plevel->width * 32 - 320 < tux->base.x)
202 tux->base.x = tux->base.x - (plevel->width * 32 - 640);
203 scroll_x = tux->base.x - 320;
206 float last_tux_x_pos = tux->base.x;
207 tux->action(frame_ratio);
209 // Jump if tux stays in the same position for one loop, ie. if he is
210 // stuck behind a wall
211 if (last_tux_x_pos == tux->base.x)
217 /* --- TITLE SCREEN --- */
221 random_timer.init(true);
225 st_pause_ticks_init();
227 GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME);
229 clearscreen(0, 0, 0);
233 bkg_title = new Surface(datadir + "/images/title/background.jpg", IGNORE_ALPHA);
234 logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA);
235 img_choose_subset = new Surface(datadir + "/images/status/choose-level-subset.png", USE_ALPHA);
237 /* --- Main title loop: --- */
240 /* Draw the title background: */
241 bkg_title->draw_bg();
243 update_time = st_get_ticks();
244 random_timer.start(rand() % 2000 + 2000);
246 Menu::set_current(main_menu);
247 while (Menu::current())
249 // Calculate the movement-factor
250 double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
251 if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
252 frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
253 /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */
257 while (SDL_PollEvent(&event))
261 Menu::current()->event(event);
265 // FIXME: QUIT signal should be handled more generic, not locally
266 if (event.type == SDL_QUIT)
267 Menu::set_current(0);
271 /* Draw the background: */
273 draw_demo(&session, frame_ratio);
275 if (Menu::current() == main_menu)
276 logo->draw( 160, 30);
278 white_small_text->draw(" SuperTux " VERSION "\n"
279 "Copyright (c) 2003 SuperTux Devel Team\n"
280 "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
281 "are welcome to redistribute it under certain conditions; see the file COPYING\n"
285 /* Don't draw menu, if quit is true */
288 Menu::current()->action();
289 Menu::current()->draw();
292 if(Menu::current() == main_menu)
294 switch (main_menu->check())
297 // Start Game, ie. goto the slots menu
298 update_load_save_game_menu(load_game_menu);
302 update_contrib_menu();
306 Menu::set_current(main_menu);
310 Menu::set_current(main_menu);
313 Menu::set_current(0);
317 else if(Menu::current() == options_menu)
319 process_options_menu();
321 else if(Menu::current() == load_game_menu)
323 if (process_load_game_menu())
325 // FIXME: shouldn't be needed if GameSession doesn't relay on global variables
328 //titletux.level_begin();
329 update_time = st_get_ticks();
332 else if(Menu::current() == contrib_menu)
334 check_contrib_menu();
336 else if (Menu::current() == contrib_subset_menu)
338 check_contrib_subset_menu();
341 mouse_cursor->draw();
345 /* Set the time of the last update and the time of the current update */
346 last_update_time = update_time;
347 update_time = st_get_ticks();
364 void display_credits()
373 string_list_type names;
375 string_list_init(&names);
376 sprintf(filename,"%s/CREDITS", datadir.c_str());
377 if((fi = fopen(filename,"r")) != NULL)
379 while(fgets(temp, sizeof(temp), fi) != NULL)
381 temp[strlen(temp)-1]='\0';
382 string_list_add_item(&names,temp);
388 string_list_add_item(&names,"Credits were not found!");
389 string_list_add_item(&names,"Shame on the guy, who");
390 string_list_add_item(&names,"forgot to include them");
391 string_list_add_item(&names,"in your SuperTux distribution.");
395 timer.init(SDL_GetTicks());
404 length = names.num_items;
406 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
410 /* in case of input, exit */
412 while(SDL_PollEvent(&event))
416 switch(event.key.keysym.sym)
445 else if(speed < -MAX_VEL)
448 /* draw the credits */
452 white_big_text->drawf("- Credits -", 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2);
454 for(i = 0, n = 0, d = 0; i < length; i++,n++,d++)
456 if(names.item[i] == "")
460 if(names.item[i][0] == ' ')
461 white_small_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll-10, A_HMIDDLE, A_TOP, 1);
462 else if(names.item[i][0] == ' ')
463 white_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1);
464 else if(names.item[i+1][0] == '-' || names.item[i][0] == '-')
465 white_big_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 3);
467 blue_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1);
473 if(60+screen->h+(n*18)+(d*18)-scroll < 0 && 20+60+screen->h+(n*18)+(d*18)-scroll < 0)
482 if(timer.get_left() < 0)
488 string_list_free(&names);
490 SDL_EnableKeyRepeat(0, 0); // disables key repeating
491 Menu::set_current(main_menu);