Exclude end sequence from focus lose code
[supertux.git] / contrib / supertux-coop.diff
1 Index: src/control/joystickkeyboardcontroller.cpp\r
2 ===================================================================\r
3 --- src/control/joystickkeyboardcontroller.cpp  (revision 6139)\r
4 +++ src/control/joystickkeyboardcontroller.cpp  (working copy)\r
5 @@ -479,11 +479,12 @@\r
6    KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
7  
8    // if console key was pressed: toggle console
9 -  if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
10 +  // only main controller does console
11 +  if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE) && (this == g_main_controller)) {
12      if (event.type == SDL_KEYDOWN) 
13        Console::instance->toggle();
14    } else {
15 -    if (Console::instance->hasFocus()) {
16 +    if (Console::instance->hasFocus() && (this == g_main_controller)) {
17        // if console is open: send key there
18        process_console_key_event(event);
19      } else if (MenuManager::current()) {
20 Index: src/object/player.cpp\r
21 ===================================================================\r
22 --- src/object/player.cpp       (revision 6139)\r
23 +++ src/object/player.cpp       (working copy)\r
24 @@ -152,7 +152,7 @@\r
25    climbing(0)
26  {
27    this->name = name;
28 -  controller = g_main_controller;
29 +  controller = (name == "Penny") ? g_secondary_controller : g_main_controller;
30    scripting_controller.reset(new CodeController());
31    sprite = sprite_manager->create("images/creatures/tux/tux.sprite");
32    airarrow = Surface::create("images/engine/hud/airarrow.png");
33 @@ -1015,6 +1015,16 @@\r
34    else
35      sa_postfix = "-right";
36  
37 +  // two-player hack: draw Penny in a different color
38 +  if (name == "Penny") {
39 +    sprite->set_color(Color(1.0f, 1.0f, 0.5f, 1.0f));
40 +  } else {
41 +    sprite->set_color(Color(1.0f, 1.0f, 1.0f, 1.0f));
42 +  }
43 +  // if/when we have complete penny gfx, we can
44 +  // load those instead of Tux's sprite in the
45 +  // constructor
46 +
47    /* Set Tux sprite action */
48    if(dying) {
49      sprite->set_action("gameover");
50 @@ -1177,6 +1187,11 @@\r
51      return FORCE_MOVE;
52    }
53  
54 +  Player* player = dynamic_cast<Player*> (&other);
55 +  if(player) {
56 +    return ABORT_MOVE;
57 +  }
58 +
59    if(hit.left || hit.right) {
60      try_grab(); //grab objects right now, in update it will be too late
61    }
62 @@ -1276,8 +1291,11 @@\r
63      dying_timer.start(3.0);
64      set_group(COLGROUP_DISABLED);
65  
66 -    Sector::current()->effect->fade_out(3.0);
67 -    sound_manager->stop_music(3.0);
68 +    // Two-player hack: ignore Penny's death
69 +    if (name != "Penny") {
70 +      Sector::current()->effect->fade_out(3.0);
71 +      sound_manager->stop_music(3.0);
72 +    }
73    }
74  }
75  
76 Index: src/supertux/game_session.cpp\r
77 ===================================================================\r
78 --- src/supertux/game_session.cpp       (revision 6139)\r
79 +++ src/supertux/game_session.cpp       (working copy)\r
80 @@ -93,6 +93,7 @@\r
81    end_sequence = 0;
82  
83    g_main_controller->reset();
84 +  g_secondary_controller->reset();
85  
86    currentsector = 0;
87  
88 @@ -434,6 +435,22 @@\r
89      game_pause = false;
90    }
91  
92 +  // two-player hack: resurrect Penny when she dies
93 +  Player* tux = currentsector->player;
94 +  for(std::vector<GameObject*>::iterator i = currentsector->gameobjects.begin(); i != currentsector->gameobjects.end(); ++i) {
95 +    Player* p = dynamic_cast<Player*>(*i);
96 +    if (!p) continue;
97 +    if (p == tux) continue;
98 +    if (p->is_dead()) {
99 +      p->remove_me();
100 +      static PlayerStatus* ps = new PlayerStatus();
101 +      p = new Player(ps, "Penny");
102 +      currentsector->add_object(p);
103 +      p->move(tux->get_pos());
104 +      p->safe_timer.start(TUX_SAFE_TIME);
105 +    }
106 +  }
107 +
108    check_end_conditions();
109  
110    // respawning in new sector?
111 Index: src/supertux/gameconfig.cpp\r
112 ===================================================================\r
113 --- src/supertux/gameconfig.cpp (revision 6139)\r
114 +++ src/supertux/gameconfig.cpp (working copy)\r
115 @@ -94,6 +94,11 @@\r
116      g_main_controller->read(*config_control_lisp);
117    }
118  
119 +  const lisp::Lisp* config_control_p2_lisp = config_lisp->get_lisp("control-p2");
120 +  if(config_control_p2_lisp && g_secondary_controller) {
121 +    g_secondary_controller->read(*config_control_p2_lisp);
122 +  }
123 +
124    const lisp::Lisp* config_addons_lisp = config_lisp->get_lisp("addons");
125    if(config_addons_lisp) {
126      AddonManager::get_instance().read(*config_addons_lisp);
127 @@ -138,6 +143,12 @@\r
128      writer.end_list("control");
129    }
130  
131 +  if(g_secondary_controller) {
132 +    writer.start_list("control-p2");
133 +    g_secondary_controller->write(writer);
134 +    writer.end_list("control-p2");
135 +  }
136 +
137    writer.start_list("addons");
138    AddonManager::get_instance().write(writer);
139    writer.end_list("addons");
140 Index: src/supertux/globals.cpp\r
141 ===================================================================\r
142 --- src/supertux/globals.cpp    (revision 6139)\r
143 +++ src/supertux/globals.cpp    (working copy)\r
144 @@ -19,6 +19,7 @@\r
145  
146  SDL_Surface* g_screen;
147  JoystickKeyboardController* g_main_controller = 0;
148 +JoystickKeyboardController* g_secondary_controller = 0;
149  tinygettext::DictionaryManager* dictionary_manager = 0;
150  
151  int SCREEN_WIDTH;
152 Index: src/supertux/globals.hpp\r
153 ===================================================================\r
154 --- src/supertux/globals.hpp    (revision 6139)\r
155 +++ src/supertux/globals.hpp    (working copy)\r
156 @@ -41,6 +41,7 @@\r
157  
158  // global variables
159  extern JoystickKeyboardController* g_main_controller;
160 +extern JoystickKeyboardController* g_secondary_controller;
161  
162  extern SDL_Surface* g_screen;
163  
164 @@ -64,6 +65,7 @@\r
165  
166  // global player state
167  extern PlayerStatus* player_status;
168 +extern PlayerStatus* second_player_status;
169  
170  extern SpriteManager* sprite_manager;
171  
172 Index: src/supertux/main.cpp\r
173 ===================================================================\r
174 --- src/supertux/main.cpp       (revision 6139)\r
175 +++ src/supertux/main.cpp       (working copy)\r
176 @@ -541,6 +541,7 @@\r
177  
178      timelog("controller");
179      g_main_controller = new JoystickKeyboardController();
180 +    g_secondary_controller = new JoystickKeyboardController();
181  
182      timelog("config");
183      init_config();
184 @@ -629,6 +630,8 @@\r
185    g_config = NULL;
186    delete g_main_controller;
187    g_main_controller = NULL;
188 +  delete g_secondary_controller;
189 +  g_secondary_controller = NULL;
190    delete Console::instance;
191    Console::instance = NULL;
192    scripting::exit_squirrel();
193 Index: src/supertux/menu/menu_storage.cpp\r
194 ===================================================================\r
195 --- src/supertux/menu/menu_storage.cpp  (revision 6139)\r
196 +++ src/supertux/menu/menu_storage.cpp  (working copy)\r
197 @@ -26,6 +26,8 @@\r
198  ProfileMenu*  MenuStorage::profile_menu = 0;
199  KeyboardMenu* MenuStorage::key_options_menu = 0;
200  JoystickMenu* MenuStorage::joystick_options_menu = 0;
201 +KeyboardMenu* MenuStorage::key_options_p2_menu = 0;
202 +JoystickMenu* MenuStorage::joystick_options_p2_menu = 0;
203  
204  OptionsMenu*
205  MenuStorage::get_options_menu()
206 @@ -63,4 +65,26 @@\r
207    return joystick_options_menu;
208  }
209  
210 +KeyboardMenu*
211 +MenuStorage::get_key_options_p2_menu()
212 +{
213 +  if (!key_options_p2_menu)
214 +  { // FIXME: this in never freed
215 +    key_options_p2_menu = new KeyboardMenu(g_secondary_controller);
216 +  }
217 +
218 +  return key_options_p2_menu;
219 +}
220 +
221 +JoystickMenu*
222 +MenuStorage::get_joystick_options_p2_menu()
223 +{
224 +  if (!joystick_options_p2_menu)
225 +  { // FIXME: this in never freed
226 +    joystick_options_p2_menu = new JoystickMenu(g_secondary_controller);
227 +  }
228 +
229 +  return joystick_options_p2_menu;
230 +}
231 +
232  /* EOF */
233 Index: src/supertux/menu/menu_storage.hpp\r
234 ===================================================================\r
235 --- src/supertux/menu/menu_storage.hpp  (revision 6139)\r
236 +++ src/supertux/menu/menu_storage.hpp  (working copy)\r
237 @@ -32,12 +32,16 @@\r
238    static ProfileMenu*  get_profile_menu();
239    static KeyboardMenu* get_key_options_menu();
240    static JoystickMenu* get_joystick_options_menu();
241 +  static KeyboardMenu* get_key_options_p2_menu();
242 +  static JoystickMenu* get_joystick_options_p2_menu();
243  
244  private:
245    static OptionsMenu*  options_menu;
246    static ProfileMenu*  profile_menu;
247    static KeyboardMenu* key_options_menu;
248    static JoystickMenu* joystick_options_menu;
249 +  static KeyboardMenu* key_options_p2_menu;
250 +  static JoystickMenu* joystick_options_p2_menu;
251  
252  private:
253    MenuStorage(const MenuStorage&);
254 Index: src/supertux/menu/options_menu.cpp\r
255 ===================================================================\r
256 --- src/supertux/menu/options_menu.cpp  (revision 6139)\r
257 +++ src/supertux/menu/options_menu.cpp  (working copy)\r
258 @@ -161,6 +161,13 @@\r
259  
260    add_submenu(_("Setup Joystick"), MenuStorage::get_joystick_options_menu())
261      ->set_help(_("Configure joystick control-action mappings"));
262 +
263 +  add_submenu(_("Setup P2 Keyboard"), MenuStorage::get_key_options_p2_menu())
264 +    ->set_help(_("Configure key-action mappings"));
265 +
266 +  add_submenu(_("Setup P2 Joystick"), MenuStorage::get_joystick_options_p2_menu())
267 +    ->set_help(_("Configure joystick control-action mappings"));
268 +
269    add_hl();
270    add_back(_("Back"));
271  }
272 Index: src/supertux/player_status.cpp\r
273 ===================================================================\r
274 --- src/supertux/player_status.cpp      (revision 6139)\r
275 +++ src/supertux/player_status.cpp      (working copy)\r
276 @@ -30,6 +30,7 @@\r
277  static const int MAX_COINS = 9999;
278  
279  PlayerStatus* player_status = 0;
280 +PlayerStatus* second_player_status = 0;
281  
282  PlayerStatus::PlayerStatus() :
283    coins(START_COINS),
284 Index: src/supertux/resources.cpp\r
285 ===================================================================\r
286 --- src/supertux/resources.cpp  (revision 6139)\r
287 +++ src/supertux/resources.cpp  (working copy)\r
288 @@ -48,6 +48,7 @@\r
289    sprite_manager = new SpriteManager();
290  
291    player_status = new PlayerStatus();
292 +  second_player_status = new PlayerStatus();
293  }
294  
295  /* Free shared data: */
296 @@ -67,6 +68,9 @@\r
297  
298    delete player_status;
299    player_status = NULL;
300 +
301 +  delete second_player_status;
302 +  second_player_status = NULL;
303  }
304  
305  /* EOF */
306 Index: src/supertux/screen_manager.cpp\r
307 ===================================================================\r
308 --- src/supertux/screen_manager.cpp     (revision 6139)\r
309 +++ src/supertux/screen_manager.cpp     (working copy)\r
310 @@ -190,11 +190,13 @@\r
311  ScreenManager::process_events()
312  {
313    g_main_controller->update();
314 +  g_secondary_controller->update();
315    Uint8* keystate = SDL_GetKeyState(NULL);
316    SDL_Event event;
317    while(SDL_PollEvent(&event)) 
318    {
319      g_main_controller->process_event(event);
320 +    g_secondary_controller->process_event(event);
321  
322      if(MenuManager::current() != NULL)
323        MenuManager::current()->event(event);
324 Index: src/supertux/sector.cpp\r
325 ===================================================================\r
326 --- src/supertux/sector.cpp     (revision 6139)\r
327 +++ src/supertux/sector.cpp     (working copy)\r
328 @@ -84,6 +84,7 @@\r
329    effect(0)
330  {
331    add_object(new Player(player_status, "Tux"));
332 +  add_object(new Player(second_player_status, "Penny"));
333    add_object(new DisplayEffect("Effect"));
334    add_object(new TextObject("Text"));
335  
336 @@ -572,19 +573,27 @@\r
337    }
338    try_expose_me();
339  
340 -  // spawn smalltux below spawnpoint
341 -  if (!player->is_big()) {
342 -    player->move(player_pos + Vector(0,32));
343 -  } else {
344 -    player->move(player_pos);
345 -  }
346  
347 -  // spawning tux in the ground would kill him
348 -  if(!is_free_of_tiles(player->get_bbox())) {
349 -    log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
350 -    Vector npos = player->get_bbox().p1;
351 -    npos.y-=32;
352 -    player->move(npos);
353 +  // two-player hack: move other players to main player's position
354 +  for(GameObjects::iterator i = gameobjects.begin();
355 +      i != gameobjects.end(); ++i) {
356 +    Player* p = dynamic_cast<Player*>(*i);
357 +    if (!p) continue;
358 +
359 +    // spawn smalltux below spawnpoint
360 +    if (!p->is_big()) {
361 +      p->move(player_pos + Vector(0,32));
362 +    } else {
363 +      p->move(player_pos);
364 +    }
365 +
366 +    // spawning tux in the ground would kill him
367 +    if(!is_free_of_tiles(p->get_bbox())) {
368 +      log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
369 +      Vector npos = p->get_bbox().p1;
370 +      npos.y-=32;
371 +      p->move(npos);
372 +    }
373    }
374  
375    camera->reset(player->get_pos());
376 @@ -645,7 +654,13 @@\r
377  void
378  Sector::update(float elapsed_time)
379  {
380 -  player->check_bounds(camera);
381 +  // keep players in bounds
382 +  for(GameObjects::iterator i = gameobjects.begin();
383 +      i != gameobjects.end(); ++i) {
384 +    Player* p = dynamic_cast<Player*>(*i);
385 +    if (!p) continue;
386 +    p->check_bounds(camera);
387 +  }
388  
389    /* update objects */
390    for(GameObjects::iterator i = gameobjects.begin();
391 @@ -741,10 +756,11 @@\r
392    Player* player = dynamic_cast<Player*> (object);
393    if(player != NULL) {
394      if(this->player != 0) {
395 -      log_warning << "Multiple players added. Ignoring" << std::endl;
396 -      return false;
397 +//      log_warning << "Multiple players added. Ignoring" << std::endl;
398 +//      return false;
399 +    } else {
400 +      this->player = player;
401      }
402 -    this->player = player;
403    }
404  
405    DisplayEffect* effect = dynamic_cast<DisplayEffect*> (object);