update supertux-coop.diff
authormathnerd314 <mathnerd314@837edb03-e0f3-0310-88ca-d4d4e8b29345>
Fri, 27 Nov 2009 20:11:55 +0000 (20:11 +0000)
committermathnerd314 <mathnerd314@837edb03-e0f3-0310-88ca-d4d4e8b29345>
Fri, 27 Nov 2009 20:11:55 +0000 (20:11 +0000)
git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@6140 837edb03-e0f3-0310-88ca-d4d4e8b29345

contrib/supertux-coop.diff

index 7313aeb..f2c08b3 100644 (file)
@@ -1,76 +1,91 @@
-#
-#  SuperTux -coop patch
-#  Copyright (C) 2007,2008 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# -----------------------------------------------------------------------------
-#
-#  This patch allows two players to cooperatively jump and run through 
-#  SuperTux' levels.
-#
-#  Note that this is more or less a friendly hack. Most objects and all levels
-#  of SuperTux were not designed to work with two players. Expect lots of bugs.
-#
-#  Installing the patch should be pretty straightforward. Simply run the
-#  following command prior to running jam:
-#
-#  patch -p1 < contrib/supertux-coop.diff
-#
-#  This patch works for revision 5236. It may break for later revisions.
-#
-# -----------------------------------------------------------------------------
-diff --git a/src/control/joystickkeyboardcontroller.cpp b/src/control/joystickkeyboardcontroller.cpp
-index c0ca307..93cbb7c 100644
---- a/src/control/joystickkeyboardcontroller.cpp
-+++ b/src/control/joystickkeyboardcontroller.cpp
-@@ -30,6 +30,7 @@
- #include "game_session.hpp"
- #include "console.hpp"
- #include "gameconfig.hpp"
-+#include "main.hpp"
- namespace{
-   const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
-@@ -502,11 +503,11 @@ JoystickKeyboardController::process_key_event(const SDL_Event& event)
+Index: src/control/joystickkeyboardcontroller.cpp\r
+===================================================================\r
+--- src/control/joystickkeyboardcontroller.cpp (revision 6139)\r
++++ src/control/joystickkeyboardcontroller.cpp (working copy)\r
+@@ -479,11 +479,12 @@\r
    KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
  
    // if console key was pressed: toggle console
 -  if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
-+  if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE) && (this == main_controller)) {
++  // only main controller does console
++  if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE) && (this == g_main_controller)) {
      if (event.type == SDL_KEYDOWN) 
        Console::instance->toggle();
    } else {
 -    if (Console::instance->hasFocus()) {
-+    if (Console::instance->hasFocus() && (this == main_controller)) {
++    if (Console::instance->hasFocus() && (this == g_main_controller)) {
        // if console is open: send key there
        process_console_key_event(event);
-     } else if (Menu::current()) {
-diff --git a/src/game_session.cpp b/src/game_session.cpp
-index f6cf505..93f85da 100644
---- a/src/game_session.cpp
-+++ b/src/game_session.cpp
-@@ -126,6 +126,7 @@ GameSession::restart_level()
+     } else if (MenuManager::current()) {
+Index: src/object/player.cpp\r
+===================================================================\r
+--- src/object/player.cpp      (revision 6139)\r
++++ src/object/player.cpp      (working copy)\r
+@@ -152,7 +152,7 @@\r
+   climbing(0)
+ {
+   this->name = name;
+-  controller = g_main_controller;
++  controller = (name == "Penny") ? g_secondary_controller : g_main_controller;
+   scripting_controller.reset(new CodeController());
+   sprite = sprite_manager->create("images/creatures/tux/tux.sprite");
+   airarrow = Surface::create("images/engine/hud/airarrow.png");
+@@ -1015,6 +1015,16 @@\r
+   else
+     sa_postfix = "-right";
++  // two-player hack: draw Penny in a different color
++  if (name == "Penny") {
++    sprite->set_color(Color(1.0f, 1.0f, 0.5f, 1.0f));
++  } else {
++    sprite->set_color(Color(1.0f, 1.0f, 1.0f, 1.0f));
++  }
++  // if/when we have complete penny gfx, we can
++  // load those instead of Tux's sprite in the
++  // constructor
++
+   /* Set Tux sprite action */
+   if(dying) {
+     sprite->set_action("gameover");
+@@ -1177,6 +1187,11 @@\r
+     return FORCE_MOVE;
+   }
++  Player* player = dynamic_cast<Player*> (&other);
++  if(player) {
++    return ABORT_MOVE;
++  }
++
+   if(hit.left || hit.right) {
+     try_grab(); //grab objects right now, in update it will be too late
+   }
+@@ -1276,8 +1291,11 @@\r
+     dying_timer.start(3.0);
+     set_group(COLGROUP_DISABLED);
+-    Sector::current()->effect->fade_out(3.0);
+-    sound_manager->stop_music(3.0);
++    // Two-player hack: ignore Penny's death
++    if (name != "Penny") {
++      Sector::current()->effect->fade_out(3.0);
++      sound_manager->stop_music(3.0);
++    }
+   }
+ }
+Index: src/supertux/game_session.cpp\r
+===================================================================\r
+--- src/supertux/game_session.cpp      (revision 6139)\r
++++ src/supertux/game_session.cpp      (working copy)\r
+@@ -93,6 +93,7 @@\r
    end_sequence = 0;
  
-   main_controller->reset();
-+  secondary_controller->reset();
+   g_main_controller->reset();
++  g_secondary_controller->reset();
  
    currentsector = 0;
  
-@@ -506,6 +507,22 @@ GameSession::update(float elapsed_time)
+@@ -434,6 +435,22 @@\r
      game_pause = false;
    }
  
@@ -93,223 +108,298 @@ index f6cf505..93f85da 100644
    check_end_conditions();
  
    // respawning in new sector?
-diff --git a/src/gameconfig.cpp b/src/gameconfig.cpp
-index 289b6a2..65e8ce2 100644
---- a/src/gameconfig.cpp
-+++ b/src/gameconfig.cpp
-@@ -108,6 +108,10 @@ Config::load()
-   if(config_control_lisp && main_controller) {
-     main_controller->read(*config_control_lisp);
+Index: src/supertux/gameconfig.cpp\r
+===================================================================\r
+--- src/supertux/gameconfig.cpp        (revision 6139)\r
++++ src/supertux/gameconfig.cpp        (working copy)\r
+@@ -94,6 +94,11 @@\r
+     g_main_controller->read(*config_control_lisp);
    }
-+  const lisp::Lisp* config_control_lisp2 = config_lisp->get_lisp("control-p2");
-+  if(config_control_lisp2 && secondary_controller) {
-+    secondary_controller->read(*config_control_lisp2);
-+  }
  
++  const lisp::Lisp* config_control_p2_lisp = config_lisp->get_lisp("control-p2");
++  if(config_control_p2_lisp && g_secondary_controller) {
++    g_secondary_controller->read(*config_control_p2_lisp);
++  }
++
    const lisp::Lisp* config_addons_lisp = config_lisp->get_lisp("addons");
    if(config_addons_lisp) {
-@@ -152,6 +156,11 @@ Config::save()
-     main_controller->write(writer);
+     AddonManager::get_instance().read(*config_addons_lisp);
+@@ -138,6 +143,12 @@\r
      writer.end_list("control");
    }
-+  if(secondary_controller) {
++  if(g_secondary_controller) {
 +    writer.start_list("control-p2");
-+    secondary_controller->write(writer);
++    g_secondary_controller->write(writer);
 +    writer.end_list("control-p2");
 +  }
++
    writer.start_list("addons");
-   AddonManager::get_instance().write_config(writer);
-diff --git a/src/main.cpp b/src/main.cpp
-index fedbe0c..af6dfb6 100644
---- a/src/main.cpp
-+++ b/src/main.cpp
-@@ -65,6 +65,7 @@ namespace supertux_apple {
- namespace { DrawingContext *context_pointer; }
- SDL_Surface *screen;
- JoystickKeyboardController* main_controller = 0;
-+JoystickKeyboardController* secondary_controller = 0;
- TinyGetText::DictionaryManager dictionary_manager;
+   AddonManager::get_instance().write(writer);
+   writer.end_list("addons");
+Index: src/supertux/globals.cpp\r
+===================================================================\r
+--- src/supertux/globals.cpp   (revision 6139)\r
++++ src/supertux/globals.cpp   (working copy)\r
+@@ -19,6 +19,7 @@\r
+ SDL_Surface* g_screen;
+ JoystickKeyboardController* g_main_controller = 0;
++JoystickKeyboardController* g_secondary_controller = 0;
+ tinygettext::DictionaryManager* dictionary_manager = 0;
  
  int SCREEN_WIDTH;
-@@ -541,6 +542,7 @@ int main(int argc, char** argv)
+Index: src/supertux/globals.hpp\r
+===================================================================\r
+--- src/supertux/globals.hpp   (revision 6139)\r
++++ src/supertux/globals.hpp   (working copy)\r
+@@ -41,6 +41,7 @@\r
+ // global variables
+ extern JoystickKeyboardController* g_main_controller;
++extern JoystickKeyboardController* g_secondary_controller;
+ extern SDL_Surface* g_screen;
+@@ -64,6 +65,7 @@\r
+ // global player state
+ extern PlayerStatus* player_status;
++extern PlayerStatus* second_player_status;
+ extern SpriteManager* sprite_manager;
+Index: src/supertux/main.cpp\r
+===================================================================\r
+--- src/supertux/main.cpp      (revision 6139)\r
++++ src/supertux/main.cpp      (working copy)\r
+@@ -541,6 +541,7 @@\r
  
      timelog("controller");
-     main_controller = new JoystickKeyboardController();
-+    secondary_controller = new JoystickKeyboardController();
+     g_main_controller = new JoystickKeyboardController();
++    g_secondary_controller = new JoystickKeyboardController();
  
      timelog("config");
      init_config();
-@@ -629,7 +631,9 @@ int main(int argc, char** argv)
-   delete config;
-   config = NULL;
-   delete main_controller;
-+  delete secondary_controller;
-   main_controller = NULL;
-+  secondary_controller = NULL;
+@@ -629,6 +630,8 @@\r
+   g_config = NULL;
+   delete g_main_controller;
+   g_main_controller = NULL;
++  delete g_secondary_controller;
++  g_secondary_controller = NULL;
    delete Console::instance;
    Console::instance = NULL;
-   Scripting::exit_squirrel();
-diff --git a/src/main.hpp b/src/main.hpp
-index 92c1752..917c7f2 100644
---- a/src/main.hpp
-+++ b/src/main.hpp
-@@ -36,5 +36,6 @@ extern int SCREEN_HEIGHT;
- // global variables
- class  JoystickKeyboardController;
- extern JoystickKeyboardController* main_controller;
-+extern JoystickKeyboardController* secondary_controller;
- #endif
-diff --git a/src/mainloop.cpp b/src/mainloop.cpp
-index ca6ba5e..402737f 100644
---- a/src/mainloop.cpp
-+++ b/src/mainloop.cpp
-@@ -180,11 +180,13 @@ void
- MainLoop::process_events()
- {
-   main_controller->update();
-+  secondary_controller->update();
-   Uint8* keystate = SDL_GetKeyState(NULL);
-   SDL_Event event;
-   while(SDL_PollEvent(&event)) 
-     {
-       main_controller->process_event(event);
-+      secondary_controller->process_event(event);
-       if(Menu::current() != NULL)
-         Menu::current()->event(event);
-diff --git a/src/object/player.cpp b/src/object/player.cpp
-index 709aebd..5c4b96d 100644
---- a/src/object/player.cpp
-+++ b/src/object/player.cpp
-@@ -117,6 +117,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name)
- {
-   this->name = name;
-   controller = main_controller;
-+  if (name == "Penny") controller = secondary_controller;
-   scripting_controller = new CodeController();
-   sprite = sprite_manager->create("images/creatures/tux/tux.sprite");
-   airarrow.reset(new Surface("images/engine/hud/airarrow.png"));
-@@ -958,6 +959,13 @@ Player::draw(DrawingContext& context)
-   else
-     sa_prefix = "small";
+   scripting::exit_squirrel();
+Index: src/supertux/menu/menu_storage.cpp\r
+===================================================================\r
+--- src/supertux/menu/menu_storage.cpp (revision 6139)\r
++++ src/supertux/menu/menu_storage.cpp (working copy)\r
+@@ -26,6 +26,8 @@\r
+ ProfileMenu*  MenuStorage::profile_menu = 0;
+ KeyboardMenu* MenuStorage::key_options_menu = 0;
+ JoystickMenu* MenuStorage::joystick_options_menu = 0;
++KeyboardMenu* MenuStorage::key_options_p2_menu = 0;
++JoystickMenu* MenuStorage::joystick_options_p2_menu = 0;
  
-+  // two-player hack: draw Penny in a different color
-+  if (name == "Penny") {
-+    sprite->set_color(Color(1.0f, 1.0f, 0.5f, 1.0f));
-+  } else {
-+    sprite->set_color(Color(1.0f, 1.0f, 1.0f, 1.0f));
+ OptionsMenu*
+ MenuStorage::get_options_menu()
+@@ -63,4 +65,26 @@\r
+   return joystick_options_menu;
+ }
++KeyboardMenu*
++MenuStorage::get_key_options_p2_menu()
++{
++  if (!key_options_p2_menu)
++  { // FIXME: this in never freed
++    key_options_p2_menu = new KeyboardMenu(g_secondary_controller);
 +  }
 +
-   /* Set Tux sprite action */
-   if(dying) {
-     sprite->set_action("gameover");
-@@ -1116,6 +1124,12 @@ Player::collision(GameObject& other, const CollisionHit& hit)
-     return FORCE_MOVE;
-   }
-+  // Multiple Players pass through one another
-+  Player* player = dynamic_cast<Player*> (&other);
-+  if(player) {
-+    return FORCE_MOVE;
++  return key_options_p2_menu;
++}
++
++JoystickMenu*
++MenuStorage::get_joystick_options_p2_menu()
++{
++  if (!joystick_options_p2_menu)
++  { // FIXME: this in never freed
++    joystick_options_p2_menu = new JoystickMenu(g_secondary_controller);
 +  }
 +
-   if(hit.left || hit.right) {
-     try_grab(); //grab objects right now, in update it will be too late
-   }
-@@ -1217,6 +1231,8 @@ Player::kill(bool completely)
-     dying_timer.start(3.0);
-     set_group(COLGROUP_DISABLED);
-+    if (name == "Penny") return;
++  return joystick_options_p2_menu;
++}
 +
-     DisplayEffect* effect = new DisplayEffect();
-     effect->fade_out(3.0);
-     Sector::current()->add_object(effect);
-diff --git a/src/options_menu.cpp b/src/options_menu.cpp
-index ad1eff7..dbd7a49 100644
---- a/src/options_menu.cpp
-+++ b/src/options_menu.cpp
-@@ -223,6 +223,13 @@ OptionsMenu::OptionsMenu()
-   add_submenu(_("Setup Joystick"),main_controller->get_joystick_options_menu())
+ /* EOF */
+Index: src/supertux/menu/menu_storage.hpp\r
+===================================================================\r
+--- src/supertux/menu/menu_storage.hpp (revision 6139)\r
++++ src/supertux/menu/menu_storage.hpp (working copy)\r
+@@ -32,12 +32,16 @@\r
+   static ProfileMenu*  get_profile_menu();
+   static KeyboardMenu* get_key_options_menu();
+   static JoystickMenu* get_joystick_options_menu();
++  static KeyboardMenu* get_key_options_p2_menu();
++  static JoystickMenu* get_joystick_options_p2_menu();
+ private:
+   static OptionsMenu*  options_menu;
+   static ProfileMenu*  profile_menu;
+   static KeyboardMenu* key_options_menu;
+   static JoystickMenu* joystick_options_menu;
++  static KeyboardMenu* key_options_p2_menu;
++  static JoystickMenu* joystick_options_p2_menu;
+ private:
+   MenuStorage(const MenuStorage&);
+Index: src/supertux/menu/options_menu.cpp\r
+===================================================================\r
+--- src/supertux/menu/options_menu.cpp (revision 6139)\r
++++ src/supertux/menu/options_menu.cpp (working copy)\r
+@@ -161,6 +161,13 @@\r
+   add_submenu(_("Setup Joystick"), MenuStorage::get_joystick_options_menu())
      ->set_help(_("Configure joystick control-action mappings"));
 +
-+  add_submenu(_("Setup Keyboard (P2)"), secondary_controller->get_key_options_menu())
++  add_submenu(_("Setup P2 Keyboard"), MenuStorage::get_key_options_p2_menu())
 +    ->set_help(_("Configure key-action mappings"));
 +
-+  add_submenu(_("Setup Joystick (P2)"),secondary_controller->get_joystick_options_menu())
++  add_submenu(_("Setup P2 Joystick"), MenuStorage::get_joystick_options_p2_menu())
 +    ->set_help(_("Configure joystick control-action mappings"));
 +
    add_hl();
    add_back(_("Back"));
  }
-diff --git a/src/sector.cpp b/src/sector.cpp
-index 1ff1692..c62f632 100644
---- a/src/sector.cpp
-+++ b/src/sector.cpp
-@@ -77,11 +77,21 @@ Sector* Sector::_current = 0;
- bool Sector::show_collrects = false;
- bool Sector::draw_solids_only = false;
-+namespace {
-+  // two-player hack: second player's player_status 
-+  PlayerStatus* second_player_status = 0;
-+}
+Index: src/supertux/player_status.cpp\r
+===================================================================\r
+--- src/supertux/player_status.cpp     (revision 6139)\r
++++ src/supertux/player_status.cpp     (working copy)\r
+@@ -30,6 +30,7 @@\r
+ static const int MAX_COINS = 9999;
+ PlayerStatus* player_status = 0;
++PlayerStatus* second_player_status = 0;
+ PlayerStatus::PlayerStatus() :
+   coins(START_COINS),
+Index: src/supertux/resources.cpp\r
+===================================================================\r
+--- src/supertux/resources.cpp (revision 6139)\r
++++ src/supertux/resources.cpp (working copy)\r
+@@ -48,6 +48,7 @@\r
+   sprite_manager = new SpriteManager();
+   player_status = new PlayerStatus();
++  second_player_status = new PlayerStatus();
+ }
+ /* Free shared data: */
+@@ -67,6 +68,9 @@\r
+   delete player_status;
+   player_status = NULL;
 +
- Sector::Sector(Level* parent)
-   : level(parent), currentmusic(LEVEL_MUSIC),
-   ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), gravity(10.0), player(0), camera(0)
++  delete second_player_status;
++  second_player_status = NULL;
+ }
+ /* EOF */
+Index: src/supertux/screen_manager.cpp\r
+===================================================================\r
+--- src/supertux/screen_manager.cpp    (revision 6139)\r
++++ src/supertux/screen_manager.cpp    (working copy)\r
+@@ -190,11 +190,13 @@\r
+ ScreenManager::process_events()
+ {
+   g_main_controller->update();
++  g_secondary_controller->update();
+   Uint8* keystate = SDL_GetKeyState(NULL);
+   SDL_Event event;
+   while(SDL_PollEvent(&event)) 
+   {
+     g_main_controller->process_event(event);
++    g_secondary_controller->process_event(event);
+     if(MenuManager::current() != NULL)
+       MenuManager::current()->event(event);
+Index: src/supertux/sector.cpp\r
+===================================================================\r
+--- src/supertux/sector.cpp    (revision 6139)\r
++++ src/supertux/sector.cpp    (working copy)\r
+@@ -84,6 +84,7 @@\r
+   effect(0)
  {
    add_object(new Player(player_status, "Tux"));
-+
-+  // two-player hack: second player has dummy player_status
-+  if (!second_player_status) second_player_status = new PlayerStatus();
 +  add_object(new Player(second_player_status, "Penny"));
-+
    add_object(new DisplayEffect("Effect"));
    add_object(new TextObject("Text"));
  
-@@ -610,6 +620,16 @@ Sector::activate(const Vector& player_pos)
-     player->move(npos);
+@@ -572,19 +573,27 @@\r
    }
+   try_expose_me();
+-  // spawn smalltux below spawnpoint
+-  if (!player->is_big()) {
+-    player->move(player_pos + Vector(0,32));
+-  } else {
+-    player->move(player_pos);
+-  }
  
+-  // spawning tux in the ground would kill him
+-  if(!is_free_of_tiles(player->get_bbox())) {
+-    log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
+-    Vector npos = player->get_bbox().p1;
+-    npos.y-=32;
+-    player->move(npos);
 +  // two-player hack: move other players to main player's position
 +  for(GameObjects::iterator i = gameobjects.begin();
 +      i != gameobjects.end(); ++i) {
 +    Player* p = dynamic_cast<Player*>(*i);
 +    if (!p) continue;
-+    if (p == player) continue;
-+    p->move(player->get_pos());
-+  }
 +
++    // spawn smalltux below spawnpoint
++    if (!p->is_big()) {
++      p->move(player_pos + Vector(0,32));
++    } else {
++      p->move(player_pos);
++    }
 +
-   camera->reset(player->get_pos());
-   update_game_objects();
++    // spawning tux in the ground would kill him
++    if(!is_free_of_tiles(p->get_bbox())) {
++      log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
++      Vector npos = p->get_bbox().p1;
++      npos.y-=32;
++      p->move(npos);
++    }
+   }
  
-@@ -670,6 +690,15 @@ Sector::update(float elapsed_time)
+   camera->reset(player->get_pos());
+@@ -645,7 +654,13 @@\r
+ void
+ Sector::update(float elapsed_time)
  {
-   player->check_bounds(camera);
-+  // two-player hack: keep other players in bound, too
+-  player->check_bounds(camera);
++  // keep players in bounds
 +  for(GameObjects::iterator i = gameobjects.begin();
 +      i != gameobjects.end(); ++i) {
 +    Player* p = dynamic_cast<Player*>(*i);
 +    if (!p) continue;
-+    if (p == player) continue;
 +    p->check_bounds(camera);
 +  }
-+
    /* update objects */
    for(GameObjects::iterator i = gameobjects.begin();
-           i != gameobjects.end(); ++i) {
-@@ -764,7 +793,7 @@ Sector::before_object_add(GameObject* object)
+@@ -741,10 +756,11 @@\r
    Player* player = dynamic_cast<Player*> (object);
    if(player != NULL) {
      if(this->player != 0) {
 -      log_warning << "Multiple players added. Ignoring" << std::endl;
-+      //log_warning << "Multiple players added. Ignoring" << std::endl;
-       return false;
+-      return false;
++//      log_warning << "Multiple players added. Ignoring" << std::endl;
++//      return false;
++    } else {
++      this->player = player;
      }
-     this->player = player;
+-    this->player = player;
+   }
+   DisplayEffect* effect = dynamic_cast<DisplayEffect*> (object);