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 std::vector<LevelSubset*> contrib_subsets;
66 std::string current_contrib_subset;
68 void free_contrib_menu()
70 for(std::vector<LevelSubset*>::iterator i = contrib_subsets.begin();
71 i != contrib_subsets.end(); ++i)
74 contrib_subsets.clear();
75 contrib_menu->clear();
78 void generate_contrib_menu()
80 string_list_type level_subsets = dsubdirs("/levels", "info");
84 contrib_menu->additem(MN_LABEL,"Contrib Levels",0,0);
85 contrib_menu->additem(MN_HL,"",0,0);
87 for (int i = 0; i < level_subsets.num_items; ++i)
89 LevelSubset* subset = new LevelSubset();
90 subset->load(level_subsets.item[i]);
91 contrib_menu->additem(MN_GOTO, subset->title.c_str(), i,
92 contrib_subset_menu, i+1);
93 contrib_subsets.push_back(subset);
96 contrib_menu->additem(MN_HL,"",0,0);
97 contrib_menu->additem(MN_BACK,"Back",0,0);
99 string_list_free(&level_subsets);
102 void check_contrib_menu()
104 static int current_subset = -1;
106 int index = contrib_menu->check();
110 if (index >= 0 && index <= int(contrib_subsets.size()))
112 if (current_subset != index)
114 current_subset = index;
115 // FIXME: This shouln't be busy looping
116 LevelSubset& subset = * (contrib_subsets[index]);
118 current_contrib_subset = subset.name;
120 std::cout << "Updating the contrib subset menu..." << subset.levels << std::endl;
122 contrib_subset_menu->clear();
124 contrib_subset_menu->additem(MN_LABEL, subset.title, 0,0);
125 contrib_subset_menu->additem(MN_HL,"",0,0);
126 for (int i = 1; i <= subset.levels; ++i)
129 level.load(subset.name, i);
130 contrib_subset_menu->additem(MN_ACTION, level.name, 0, 0, i);
132 contrib_subset_menu->additem(MN_HL,"",0,0);
133 contrib_subset_menu->additem(MN_BACK, "Back", 0, 0);
143 void check_contrib_subset_menu()
145 int index = contrib_subset_menu->check();
148 if (contrib_subset_menu->get_item_by_id(index).kind == MN_ACTION)
150 std::cout << "Sarting level: " << index << std::endl;
151 GameSession session(current_contrib_subset, index, ST_GL_PLAY);
153 Menu::set_current(main_menu);
158 void draw_background()
160 /* Draw the title background: */
162 bkg_title->draw_bg();
165 void draw_demo(GameSession* session, double frame_ratio)
167 World::set_current(session->get_world());
168 //World* world = session->get_world();
169 Level* plevel = session->get_level();
170 Player* tux = session->get_world()->get_tux();
172 session->get_world()->play_music(LEVEL_MUSIC);
175 // update particle systems
176 std::vector<ParticleSystem*>::iterator p;
177 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
179 (*p)->simulate(frame_ratio);
182 // Draw particle systems (background)
183 for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
185 (*p)->draw(scroll_x, 0, 0);
189 // Draw interactive tiles:
190 for (int y = 0; y < 15; ++y)
192 for (int x = 0; x < 21; ++x)
194 Tile::draw(32*x - fmodf(scroll_x, 32), y * 32,
195 plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
199 global_frame_counter++;
200 tux->key_event((SDLKey) keymap.right,DOWN);
202 if(random_timer.check())
205 tux->key_event((SDLKey) keymap.jump,UP);
207 tux->key_event((SDLKey) keymap.jump,DOWN);
211 random_timer.start(rand() % 3000 + 3000);
215 // Wrap around at the end of the level back to the beginnig
216 if(plevel->width * 32 - 320 < tux->base.x)
218 tux->base.x = tux->base.x - (plevel->width * 32 - 640);
219 scroll_x = tux->base.x - 320;
222 float last_tux_x_pos = tux->base.x;
223 tux->action(frame_ratio);
225 // Jump if tux stays in the same position for one loop, ie. if he is
226 // stuck behind a wall
227 if (last_tux_x_pos == tux->base.x)
233 /* --- TITLE SCREEN --- */
236 random_timer.init(true);
240 st_pause_ticks_init();
242 GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME);
244 clearscreen(0, 0, 0);
248 bkg_title = new Surface(datadir + "/images/title/background.jpg", IGNORE_ALPHA);
249 logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA);
250 img_choose_subset = new Surface(datadir + "/images/status/choose-level-subset.png", USE_ALPHA);
252 /* --- Main title loop: --- */
255 /* Draw the title background: */
256 bkg_title->draw_bg();
258 update_time = st_get_ticks();
259 random_timer.start(rand() % 2000 + 2000);
261 Menu::set_current(main_menu);
262 while (Menu::current())
264 // if we spent to much time on a menu entry
265 if( (update_time - last_update_time) > 1000)
266 update_time = last_update_time = st_get_ticks();
268 // Calculate the movement-factor
269 double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
270 if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
271 frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
272 /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */
276 while (SDL_PollEvent(&event))
280 Menu::current()->event(event);
282 // FIXME: QUIT signal should be handled more generic, not locally
283 if (event.type == SDL_QUIT)
284 Menu::set_current(0);
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 */
302 Menu* menu = Menu::current();
308 if(menu == main_menu)
310 switch (main_menu->check())
313 // Start Game, ie. goto the slots menu
314 update_load_save_game_menu(load_game_menu);
318 puts("Entering contrib menu");
319 generate_contrib_menu();
321 case MNID_LEVELEDITOR:
323 Menu::set_current(main_menu);
326 display_text_file("CREDITS", bkg_title, SCROLL_SPEED_CREDITS);
327 Menu::set_current(main_menu);
329 case MNID_QUITMAINMENU:
330 Menu::set_current(0);
334 else if(menu == options_menu)
336 process_options_menu();
338 else if(menu == load_game_menu)
340 if (process_load_game_menu())
342 // FIXME: shouldn't be needed if GameSession doesn't relay on global variables
345 //titletux.level_begin();
346 update_time = st_get_ticks();
349 else if(menu == contrib_menu)
351 check_contrib_menu();
353 else if (menu == contrib_subset_menu)
355 check_contrib_subset_menu();
359 mouse_cursor->draw();
363 /* Set the time of the last update and the time of the current update */
364 last_update_time = update_time;
365 update_time = st_get_ticks();
376 delete img_choose_subset;