4 // Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
5 // Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 #include <SDL_image.h>
32 #include <sys/types.h>
40 #include "high_scores.h"
47 #include "leveleditor.h"
52 #include "resources.h"
54 static Surface* bkg_title;
56 static Surface* img_choose_subset;
59 static Timer random_timer;
62 static unsigned int last_update_time;
63 static unsigned int update_time;
65 void display_credits();
67 std::vector<st_subset> contrib_subsets;
68 std::string current_contrib_subset;
70 void generate_contrib_menu()
72 string_list_type level_subsets = dsubdirs("/levels", "info");
74 contrib_menu->clear();
75 contrib_menu->additem(MN_LABEL,"Contrib Levels",0,0);
76 contrib_menu->additem(MN_HL,"",0,0);
78 for (int i = 0; i < level_subsets.num_items; ++i)
81 subset.load(level_subsets.item[i]);
82 contrib_menu->additem(MN_GOTO, subset.title.c_str(), i, contrib_subset_menu);
83 contrib_subsets.push_back(subset);
86 contrib_menu->additem(MN_HL,"",0,0);
87 contrib_menu->additem(MN_BACK,"Back",0,0);
89 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 if (contrib_subset_menu->get_item(index).kind == MN_ACTION)
140 index -= 1; // FIXME: Hack
141 std::cout << "Sarting level: " << index << std::endl;
142 GameSession session(current_contrib_subset, index, ST_GL_PLAY);
144 Menu::set_current(main_menu);
149 void draw_background()
151 /* Draw the title background: */
153 bkg_title->draw_bg();
156 void draw_demo(GameSession* session, double frame_ratio)
158 World::set_current(session->get_world());
159 //World* world = session->get_world();
160 Level* plevel = session->get_level();
161 Player* tux = session->get_world()->get_tux();
164 // update particle systems
165 std::vector<ParticleSystem*>::iterator p;
166 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
168 (*p)->simulate(frame_ratio);
171 // Draw particle systems (background)
172 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
174 (*p)->draw(scroll_x, 0, 0);
178 // Draw interactive tiles:
179 for (int y = 0; y < 15; ++y)
181 for (int x = 0; x < 21; ++x)
183 Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
184 plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
188 global_frame_counter++;
189 tux->key_event(SDLK_RIGHT,DOWN);
191 if(random_timer.check())
194 tux->key_event(SDLK_UP,UP);
196 tux->key_event(SDLK_UP,DOWN);
200 random_timer.start(rand() % 3000 + 3000);
204 // Wrap around at the end of the level back to the beginnig
205 if(plevel->width * 32 - 320 < tux->base.x)
207 tux->base.x = tux->base.x - (plevel->width * 32 - 640);
208 scroll_x = tux->base.x - 320;
211 float last_tux_x_pos = tux->base.x;
212 tux->action(frame_ratio);
214 // Jump if tux stays in the same position for one loop, ie. if he is
215 // stuck behind a wall
216 if (last_tux_x_pos == tux->base.x)
222 /* --- TITLE SCREEN --- */
226 random_timer.init(true);
230 st_pause_ticks_init();
232 GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME);
234 clearscreen(0, 0, 0);
238 bkg_title = new Surface(datadir + "/images/title/background.jpg", IGNORE_ALPHA);
239 logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA);
240 img_choose_subset = new Surface(datadir + "/images/status/choose-level-subset.png", USE_ALPHA);
242 /* --- Main title loop: --- */
245 /* Draw the title background: */
246 bkg_title->draw_bg();
248 update_time = st_get_ticks();
249 random_timer.start(rand() % 2000 + 2000);
251 Menu::set_current(main_menu);
252 while (Menu::current())
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. */
262 while (SDL_PollEvent(&event))
266 Menu::current()->event(event);
268 // FIXME: QUIT signal should be handled more generic, not locally
269 if (event.type == SDL_QUIT)
270 Menu::set_current(0);
273 /* Draw the background: */
275 draw_demo(&session, frame_ratio);
277 if (Menu::current() == main_menu)
278 logo->draw( 160, 30);
280 white_small_text->draw(" SuperTux " VERSION "\n"
281 "Copyright (c) 2003 SuperTux Devel Team\n"
282 "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
283 "are welcome to redistribute it under certain conditions; see the file COPYING\n"
287 /* Don't draw menu, if quit is true */
288 Menu* menu = Menu::current();
294 if(menu == main_menu)
296 switch (main_menu->check())
299 // Start Game, ie. goto the slots menu
300 update_load_save_game_menu(load_game_menu);
304 puts("Entering contrib menu");
305 generate_contrib_menu();
309 Menu::set_current(main_menu);
313 Menu::set_current(main_menu);
316 Menu::set_current(0);
320 else if(menu == options_menu)
322 process_options_menu();
324 else if(menu == load_game_menu)
326 if (process_load_game_menu())
328 // FIXME: shouldn't be needed if GameSession doesn't relay on global variables
331 //titletux.level_begin();
332 update_time = st_get_ticks();
335 else if(menu == contrib_menu)
337 check_contrib_menu();
339 else if (menu == contrib_subset_menu)
341 check_contrib_subset_menu();
345 mouse_cursor->draw();
349 /* Set the time of the last update and the time of the current update */
350 last_update_time = update_time;
351 update_time = st_get_ticks();
367 #define ITEMS_SPACE 4
369 void display_credits()
378 string_list_type names;
380 string_list_init(&names);
381 sprintf(filename,"%s/CREDITS", datadir.c_str());
382 if((fi = fopen(filename,"r")) != NULL)
384 while(fgets(temp, sizeof(temp), fi) != NULL)
386 temp[strlen(temp)-1]='\0';
387 string_list_add_item(&names,temp);
393 string_list_add_item(&names,"Credits were not found!");
394 string_list_add_item(&names,"Shame on the guy, who");
395 string_list_add_item(&names,"forgot to include them");
396 string_list_add_item(&names,"in your SuperTux distribution.");
400 timer.init(SDL_GetTicks());
407 length = names.num_items;
409 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
413 /* in case of input, exit */
415 while(SDL_PollEvent(&event))
419 switch(event.key.keysym.sym)
448 else if(speed < -MAX_VEL)
451 /* draw the credits */
455 white_big_text->drawf("- Credits -", 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2);
458 for(int i = 0; i < length; i++)
460 switch(names.item[i][0])
463 white_small_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
464 y += white_small_text->h+ITEMS_SPACE;
467 white_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
468 y += white_text->h+ITEMS_SPACE;
471 white_big_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 3);
472 y += white_big_text->h+ITEMS_SPACE;
475 blue_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
476 y += blue_text->h+ITEMS_SPACE;
483 if(60+screen->h+y-scroll < 0 && 20+60+screen->h+y-scroll < 0)
492 if(timer.get_left() < 0)
498 string_list_free(&names);
500 SDL_EnableKeyRepeat(0, 0); // disables key repeating
501 Menu::set_current(main_menu);