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);
142 Menu::set_current(main_menu);
146 void draw_background()
148 /* Draw the title background: */
150 bkg_title->draw_bg();
153 void draw_demo(GameSession* session, double frame_ratio)
155 World::set_current(session->get_world());
156 //World* world = session->get_world();
157 Level* plevel = session->get_level();
158 Player* tux = session->get_world()->get_tux();
161 // update particle systems
162 std::vector<ParticleSystem*>::iterator p;
163 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
165 (*p)->simulate(frame_ratio);
168 // Draw particle systems (background)
169 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
171 (*p)->draw(scroll_x, 0, 0);
175 // Draw interactive tiles:
176 for (int y = 0; y < 15; ++y)
178 for (int x = 0; x < 21; ++x)
180 Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
181 plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
185 global_frame_counter++;
186 tux->key_event(SDLK_RIGHT,DOWN);
188 if(random_timer.check())
191 tux->key_event(SDLK_UP,UP);
193 tux->key_event(SDLK_UP,DOWN);
197 random_timer.start(rand() % 3000 + 3000);
201 // Wrap around at the end of the level back to the beginnig
202 if(plevel->width * 32 - 320 < tux->base.x)
204 tux->base.x = tux->base.x - (plevel->width * 32 - 640);
205 scroll_x = tux->base.x - 320;
208 float last_tux_x_pos = tux->base.x;
209 tux->action(frame_ratio);
211 // Jump if tux stays in the same position for one loop, ie. if he is
212 // stuck behind a wall
213 if (last_tux_x_pos == tux->base.x)
219 /* --- TITLE SCREEN --- */
223 random_timer.init(true);
227 st_pause_ticks_init();
229 GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME);
231 clearscreen(0, 0, 0);
236 bkg_title = new Surface(datadir + "/images/title/background.jpg", IGNORE_ALPHA);
237 logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA);
238 img_choose_subset = new Surface(datadir + "/images/status/choose-level-subset.png", USE_ALPHA);
240 /* --- Main title loop: --- */
244 /* Draw the title background: */
245 bkg_title->draw_bg();
248 update_time = st_get_ticks();
249 random_timer.start(rand() % 2000 + 2000);
251 Menu::set_current(main_menu);
254 // Calculate the movement-factor
255 double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
256 if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
257 frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
258 /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */
263 while (SDL_PollEvent(&event))
265 if (event.type == SDL_QUIT)
269 else if (event.type == SDL_KEYDOWN)
272 key = event.key.keysym.sym;
276 Menu::current()->event(event);
279 if (!Menu::current())
287 /* Draw the background: */
289 draw_demo(&session, frame_ratio);
291 if (Menu::current() == main_menu)
292 logo->draw( 160, 30);
294 white_small_text->draw(" SuperTux " VERSION "\n"
295 "Copyright (c) 2003 SuperTux Devel Team\n"
296 "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
297 "are welcome to redistribute it under certain conditions; see the file COPYING\n"
301 /* Don't draw menu, if quit is true */
303 menu_process_current();
305 if(Menu::current() == main_menu)
307 switch (main_menu->check())
310 // Start Game, ie. goto the slots menu
311 update_load_save_game_menu(load_game_menu);
315 update_contrib_menu();
319 done = leveleditor(1);
320 Menu::set_current(main_menu);
330 else if(Menu::current() == options_menu)
332 process_options_menu();
334 else if(Menu::current() == load_game_menu)
336 if (process_load_game_menu())
338 // FIXME: shouldn't be needed if GameSession doesn't relay on global variables
341 //titletux.level_begin();
342 update_time = st_get_ticks();
345 else if(Menu::current() == contrib_menu)
347 check_contrib_menu();
349 else if (Menu::current() == contrib_subset_menu)
351 check_contrib_subset_menu();
354 mouse_cursor->draw();
358 /* Set the time of the last update and the time of the current update */
359 last_update_time = update_time;
360 update_time = st_get_ticks();
372 /* Return to main! */
380 void display_credits()
389 string_list_type names;
391 string_list_init(&names);
392 sprintf(filename,"%s/CREDITS", datadir.c_str());
393 if((fi = fopen(filename,"r")) != NULL)
395 while(fgets(temp, sizeof(temp), fi) != NULL)
397 temp[strlen(temp)-1]='\0';
398 string_list_add_item(&names,temp);
404 string_list_add_item(&names,"Credits were not found!");
405 string_list_add_item(&names,"Shame on the guy, who");
406 string_list_add_item(&names,"forgot to include them");
407 string_list_add_item(&names,"in your SuperTux distribution.");
411 timer.init(SDL_GetTicks());
420 length = names.num_items;
422 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
426 /* in case of input, exit */
427 while(SDL_PollEvent(&event))
431 switch(event.key.keysym.sym)
460 else if(speed < -MAX_VEL)
463 /* draw the credits */
467 white_big_text->drawf("- Credits -", 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2);
469 for(i = 0, n = 0, d = 0; i < length; i++,n++,d++)
471 if(names.item[i] == "")
475 if(names.item[i][0] == ' ')
476 white_small_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll-10, A_HMIDDLE, A_TOP, 1);
477 else if(names.item[i][0] == ' ')
478 white_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1);
479 else if(names.item[i+1][0] == '-' || names.item[i][0] == '-')
480 white_big_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 3);
482 blue_text->drawf(names.item[i], 0, 60+screen->h+(n*18)+(d*18)-scroll, A_HMIDDLE, A_TOP, 1);
488 if(60+screen->h+(n*18)+(d*18)-scroll < 0 && 20+60+screen->h+(n*18)+(d*18)-scroll < 0)
497 if(timer.get_left() < 0)
503 string_list_free(&names);
505 SDL_EnableKeyRepeat(0, 0); // disables key repeating
506 Menu::set_current(main_menu);