play with CMakeLists.txt compile flags, change from using DEBUG to NDEBUG (the way...
[supertux.git] / src / supertux / title_screen.cpp
1 //  SuperTux
2 //  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
3 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
4 //
5 //  This program is free software: you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation, either version 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 #include "supertux/title_screen.hpp"
19
20 #include "audio/sound_manager.hpp"
21 #include "gui/menu_manager.hpp"
22 #include "lisp/parser.hpp"
23 #include "object/camera.hpp"
24 #include "object/player.hpp"
25 #include "supertux/fadeout.hpp"
26 #include "supertux/gameconfig.hpp"
27 #include "supertux/globals.hpp"
28 #include "supertux/screen_manager.hpp"
29 #include "supertux/menu/addon_menu.hpp"
30 #include "supertux/menu/contrib_world_menu.hpp"
31 #include "supertux/menu/contrib_menu.hpp"
32 #include "supertux/menu/main_menu.hpp"
33 #include "supertux/resources.hpp"
34 #include "supertux/sector.hpp"
35 #include "supertux/textscroller.hpp"
36 #include "supertux/world.hpp"
37 #include "util/file_system.hpp"
38 #include "util/gettext.hpp"
39 #include "util/reader.hpp"
40 #include "video/drawing_context.hpp"
41
42 #include <version.h>
43
44 TitleScreen::TitleScreen() :
45   main_menu(),
46   contrib_menu(),
47   contrib_world_menu(),
48   addons_menu(),
49   main_world(),
50   contrib_worlds(),
51   current_world(),
52   frame(),
53   controller(),
54   titlesession()
55 {
56   controller.reset(new CodeController());
57   titlesession.reset(new GameSession("levels/misc/menu.stl"));
58
59   Player* player = titlesession->get_current_sector()->player;
60   player->set_controller(controller.get());
61   player->set_speedlimit(230); //MAX_WALK_XM
62
63   generate_main_menu();
64
65   frame = std::auto_ptr<Surface>(new Surface("images/engine/menu/frame.png"));
66 }
67
68 std::string
69 TitleScreen::get_level_name(const std::string& filename)
70 {
71   try {
72     lisp::Parser parser;
73     const lisp::Lisp* root = parser.parse(filename);
74
75     const lisp::Lisp* level = root->get_lisp("supertux-level");
76     if(!level)
77       return "";
78
79     std::string name;
80     level->get("name", name);
81     return name;
82   } catch(std::exception& e) {
83     log_warning << "Problem getting name of '" << filename << "': "
84                 << e.what() << std::endl;
85     return "";
86   }
87 }
88
89 void
90 TitleScreen::check_levels_contrib_menu()
91 {
92   current_world = contrib_menu->get_current_world();
93   
94   if (current_world)
95   {
96     if (!current_world->is_levelset) 
97     {
98       start_game();
99     }
100     else 
101     {
102       contrib_world_menu.reset(new ContribWorldMenu(*current_world));
103       MenuManager::push_current(contrib_world_menu.get());
104     }
105   }
106 }
107
108 void
109 TitleScreen::make_tux_jump()
110 {
111   static bool jumpWasReleased = true;
112   Sector* sector  = titlesession->get_current_sector();
113   Player* tux = sector->player;
114
115   controller->update();
116   controller->press(Controller::RIGHT);
117
118   // Check if we should press the jump button
119   Rect lookahead = tux->get_bbox();
120   lookahead.p2.x += 96;
121   bool pathBlocked = !sector->is_free_of_statics(lookahead);
122   if ((pathBlocked && jumpWasReleased) || !tux->on_ground()) {
123     controller->press(Controller::JUMP);
124     jumpWasReleased = false;
125   } else {
126     jumpWasReleased = true;
127   }
128
129   // Wrap around at the end of the level back to the beginning
130   if(sector->get_width() - 320 < tux->get_pos().x) {
131     sector->activate("main");
132     sector->camera->reset(tux->get_pos());
133   }
134 }
135
136 void
137 TitleScreen::generate_main_menu()
138 {
139   main_menu.reset(new MainMenu());
140 }
141
142 TitleScreen::~TitleScreen()
143 {
144 }
145
146 void
147 TitleScreen::setup()
148 {
149   player_status->reset();
150
151   Sector* sector = titlesession->get_current_sector();
152   if(Sector::current() != sector) {
153     sector->play_music(LEVEL_MUSIC);
154     sector->activate(sector->player->get_pos());
155   }
156
157   MenuManager::set_current(main_menu.get());
158 }
159
160 void
161 TitleScreen::leave()
162 {
163   Sector* sector = titlesession->get_current_sector();
164   sector->deactivate();
165   MenuManager::set_current(NULL);
166 }
167
168 void
169 TitleScreen::draw(DrawingContext& context)
170 {
171   Sector* sector  = titlesession->get_current_sector();
172   sector->draw(context);
173
174   // FIXME: Add something to scale the frame to the resolution of the screen
175   context.draw_surface(frame.get(), Vector(0,0),LAYER_FOREGROUND1);
176
177   context.draw_text(Resources::small_font, "SuperTux " PACKAGE_VERSION "\n",
178                     Vector(5, SCREEN_HEIGHT - 50), ALIGN_LEFT, LAYER_FOREGROUND1);
179   context.draw_text(Resources::small_font,
180                     _(
181                       "Copyright (c) 2007 SuperTux Devel Team\n"
182                       "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to\n"
183                       "redistribute it under certain conditions; see the file COPYING for details.\n"
184                       ),
185                     Vector(5, SCREEN_HEIGHT - 50 + Resources::small_font->get_height() + 5),
186                     ALIGN_LEFT, LAYER_FOREGROUND1);
187 }
188
189 void
190 TitleScreen::update(float elapsed_time)
191 {
192   g_screen_manager->set_speed(0.6f);
193   Sector* sector  = titlesession->get_current_sector();
194   sector->update(elapsed_time);
195
196   make_tux_jump();
197
198   Menu* menu = MenuManager::current();
199   if(menu) {
200     if(menu == main_menu.get()) {
201       switch (main_menu->check()) {
202         case MNID_STARTGAME:
203           // Start Game, ie. goto the slots menu
204           if(main_world.get() == NULL) {
205             main_world.reset(new World());
206             main_world->load("levels/world1/info");
207           }
208           current_world = main_world.get();
209           start_game();
210           break;
211
212         case MNID_LEVELS_CONTRIB:
213           // Contrib Menu
214           contrib_menu.reset(new ContribMenu());
215           MenuManager::push_current(contrib_menu.get());
216           break;
217
218         case MNID_ADDONS:
219           // Add-ons Menu
220           addons_menu.reset(new AddonMenu());
221           MenuManager::push_current(addons_menu.get());
222           break;
223
224         case MNID_CREDITS:
225           MenuManager::set_current(NULL);
226           g_screen_manager->push_screen(new TextScroller("credits.txt"),
227                                    new FadeOut(0.5));
228           break;
229
230         case MNID_QUITMAINMENU:
231           g_screen_manager->quit(new FadeOut(0.25));
232           sound_manager->stop_music(0.25);
233           break;
234       }
235     } else if(menu == contrib_menu.get()) {
236       check_levels_contrib_menu();
237     } else if(menu == addons_menu.get()) {
238       addons_menu->check_menu();
239     } else if (menu == contrib_world_menu.get()) {
240       contrib_world_menu->check_menu();
241     }
242   }
243
244   // reopen menu if user closed it (so that the app doesn't close when user
245   // accidently hit ESC)
246   if(MenuManager::current() == 0 && g_screen_manager->has_no_pending_fadeout()) {
247     generate_main_menu();
248     MenuManager::set_current(main_menu.get());
249   }
250 }
251
252 void
253 TitleScreen::start_game()
254 {
255   MenuManager::set_current(NULL);
256   std::string basename = current_world->get_basedir();
257   basename = basename.substr(0, basename.length()-1);
258   std::string worlddirname = FileSystem::basename(basename);
259   std::ostringstream stream;
260   stream << "profile" << g_config->profile << "/" << worlddirname << ".stsg";
261   std::string slotfile = stream.str();
262
263   try {
264     current_world->set_savegame_filename(slotfile);
265     current_world->run();
266   } catch(std::exception& e) {
267     log_fatal << "Couldn't start world: " << e.what() << std::endl;
268   }
269 }
270
271 /* EOF */