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_text_file(char *filename);
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,
83 contrib_subset_menu, i+1);
84 contrib_subsets.push_back(subset);
87 contrib_menu->additem(MN_HL,"",0,0);
88 contrib_menu->additem(MN_BACK,"Back",0,0);
90 string_list_free(&level_subsets);
93 void check_contrib_menu()
95 static int current_subset = -1;
97 int index = contrib_menu->check();
101 if (index >= 0 && index <= int(contrib_subsets.size()))
103 if (current_subset != index)
105 current_subset = index;
106 // FIXME: This shouln't be busy looping
107 st_subset& subset = contrib_subsets[index];
109 current_contrib_subset = subset.name;
111 std::cout << "Updating the contrib subset menu..." << subset.levels << std::endl;
113 contrib_subset_menu->clear();
115 contrib_subset_menu->additem(MN_LABEL, subset.title, 0,0);
116 contrib_subset_menu->additem(MN_HL,"",0,0);
117 for (int i = 1; i <= subset.levels; ++i)
120 level.load(subset.name, i);
121 contrib_subset_menu->additem(MN_ACTION, level.name, 0, 0, i);
123 contrib_subset_menu->additem(MN_HL,"",0,0);
124 contrib_subset_menu->additem(MN_BACK, "Back", 0, 0);
134 void check_contrib_subset_menu()
136 int index = contrib_subset_menu->check();
139 if (contrib_subset_menu->get_item_by_id(index).kind == MN_ACTION)
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();
163 session->get_world()->play_music(LEVEL_MUSIC);
166 // update particle systems
167 std::vector<ParticleSystem*>::iterator p;
168 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
170 (*p)->simulate(frame_ratio);
173 // Draw particle systems (background)
174 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
176 (*p)->draw(scroll_x, 0, 0);
180 // Draw interactive tiles:
181 for (int y = 0; y < 15; ++y)
183 for (int x = 0; x < 21; ++x)
185 Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
186 plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
190 global_frame_counter++;
191 tux->key_event((SDLKey) keymap.right,DOWN);
193 if(random_timer.check())
196 tux->key_event((SDLKey) keymap.jump,UP);
198 tux->key_event((SDLKey) keymap.jump,DOWN);
202 random_timer.start(rand() % 3000 + 3000);
206 // Wrap around at the end of the level back to the beginnig
207 if(plevel->width * 32 - 320 < tux->base.x)
209 tux->base.x = tux->base.x - (plevel->width * 32 - 640);
210 scroll_x = tux->base.x - 320;
213 float last_tux_x_pos = tux->base.x;
214 tux->action(frame_ratio);
216 // Jump if tux stays in the same position for one loop, ie. if he is
217 // stuck behind a wall
218 if (last_tux_x_pos == tux->base.x)
224 /* --- TITLE SCREEN --- */
228 random_timer.init(true);
232 st_pause_ticks_init();
234 GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME);
236 clearscreen(0, 0, 0);
240 bkg_title = new Surface(datadir + "/images/title/background.jpg", IGNORE_ALPHA);
241 logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA);
242 img_choose_subset = new Surface(datadir + "/images/status/choose-level-subset.png", USE_ALPHA);
244 /* --- Main title loop: --- */
247 /* Draw the title background: */
248 bkg_title->draw_bg();
250 update_time = st_get_ticks();
251 random_timer.start(rand() % 2000 + 2000);
253 Menu::set_current(main_menu);
254 while (Menu::current())
256 // if we spent to much time on a menu entry
257 if( (update_time - last_update_time) > 1000)
258 update_time = last_update_time = st_get_ticks();
260 // Calculate the movement-factor
261 double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
262 if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
263 frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
264 /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */
268 while (SDL_PollEvent(&event))
272 Menu::current()->event(event);
274 // FIXME: QUIT signal should be handled more generic, not locally
275 if (event.type == SDL_QUIT)
276 Menu::set_current(0);
279 /* Draw the background: */
281 draw_demo(&session, frame_ratio);
283 if (Menu::current() == main_menu)
284 logo->draw( 160, 30);
286 white_small_text->draw(" SuperTux " VERSION "\n"
287 "Copyright (c) 2003 SuperTux Devel Team\n"
288 "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
289 "are welcome to redistribute it under certain conditions; see the file COPYING\n"
293 /* Don't draw menu, if quit is true */
294 Menu* menu = Menu::current();
300 if(menu == main_menu)
302 switch (main_menu->check())
305 // Start Game, ie. goto the slots menu
306 update_load_save_game_menu(load_game_menu);
310 puts("Entering contrib menu");
311 generate_contrib_menu();
313 case MNID_LEVELEDITOR:
315 Menu::set_current(main_menu);
318 display_text_file("CREDITS");
319 Menu::set_current(main_menu);
321 case MNID_QUITMAINMENU:
322 Menu::set_current(0);
326 else if(menu == options_menu)
328 process_options_menu();
330 else if(menu == load_game_menu)
332 if (process_load_game_menu())
334 // FIXME: shouldn't be needed if GameSession doesn't relay on global variables
337 //titletux.level_begin();
338 update_time = st_get_ticks();
341 else if(menu == contrib_menu)
343 check_contrib_menu();
345 else if (menu == contrib_subset_menu)
347 check_contrib_subset_menu();
351 mouse_cursor->draw();
355 /* Set the time of the last update and the time of the current update */
356 last_update_time = update_time;
357 update_time = st_get_ticks();
372 #define ITEMS_SPACE 4
374 void display_text_file(char *file)
383 string_list_type names;
385 string_list_init(&names);
386 sprintf(filename,"%s/%s", datadir.c_str(), file);
387 if((fi = fopen(filename,"r")) != NULL)
389 while(fgets(temp, sizeof(temp), fi) != NULL)
391 temp[strlen(temp)-1]='\0';
392 string_list_add_item(&names,temp);
398 string_list_add_item(&names,"Credits were not found!");
399 string_list_add_item(&names,"Shame on the guy, who");
400 string_list_add_item(&names,"forgot to include them");
401 string_list_add_item(&names,"in your SuperTux distribution.");
405 timer.init(SDL_GetTicks());
412 length = names.num_items;
414 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
418 /* in case of input, exit */
420 while(SDL_PollEvent(&event))
424 switch(event.key.keysym.sym)
453 else if(speed < -MAX_VEL)
456 /* draw the credits */
460 if (strcmp(file, "CREDITS") == 0)
461 white_big_text->drawf("- SuperTux " VERSION " -",
462 0, screen->h-scroll, A_HMIDDLE, A_TOP, 2);
465 for(int i = 0; i < length; i++)
467 switch(names.item[i][0])
470 white_small_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
471 y += white_small_text->h+ITEMS_SPACE;
474 white_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
475 y += white_text->h+ITEMS_SPACE;
478 white_big_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 3);
479 y += white_big_text->h+ITEMS_SPACE;
482 blue_text->drawf(names.item[i], 0, 60+screen->h+y-scroll, A_HMIDDLE, A_TOP, 1);
483 y += blue_text->h+ITEMS_SPACE;
490 if(60+screen->h+y-scroll < 0 && 20+60+screen->h+y-scroll < 0)
499 if(timer.get_left() < 0)
505 string_list_free(&names);
507 SDL_EnableKeyRepeat(0, 0); // disables key repeating
508 Menu::set_current(main_menu);