From 263c19c4a6f20f04262d12a59cd8bd98a525e49c Mon Sep 17 00:00:00 2001 From: mathnerd314 Date: Fri, 27 Nov 2009 20:11:55 +0000 Subject: [PATCH] update supertux-coop.diff git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@6140 837edb03-e0f3-0310-88ca-d4d4e8b29345 --- contrib/supertux-coop.diff | 516 ++++++++++++++++++++++++++------------------- 1 file changed, 303 insertions(+), 213 deletions(-) diff --git a/contrib/supertux-coop.diff b/contrib/supertux-coop.diff index 7313aeb64..f2c08b3ac 100644 --- a/contrib/supertux-coop.diff +++ b/contrib/supertux-coop.diff @@ -1,76 +1,91 @@ -# -# SuperTux -coop patch -# Copyright (C) 2007,2008 Christoph Sommer -# -# 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 +=================================================================== +--- src/control/joystickkeyboardcontroller.cpp (revision 6139) ++++ src/control/joystickkeyboardcontroller.cpp (working copy) +@@ -479,11 +479,12 @@ 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 +=================================================================== +--- src/object/player.cpp (revision 6139) ++++ src/object/player.cpp (working copy) +@@ -152,7 +152,7 @@ + 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 @@ + 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 @@ + return FORCE_MOVE; + } + ++ Player* player = dynamic_cast (&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 @@ + 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 +=================================================================== +--- src/supertux/game_session.cpp (revision 6139) ++++ src/supertux/game_session.cpp (working copy) +@@ -93,6 +93,7 @@ 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 @@ 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 +=================================================================== +--- src/supertux/gameconfig.cpp (revision 6139) ++++ src/supertux/gameconfig.cpp (working copy) +@@ -94,6 +94,11 @@ + 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 @@ 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 +=================================================================== +--- src/supertux/globals.cpp (revision 6139) ++++ src/supertux/globals.cpp (working copy) +@@ -19,6 +19,7 @@ + + 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 +=================================================================== +--- src/supertux/globals.hpp (revision 6139) ++++ src/supertux/globals.hpp (working copy) +@@ -41,6 +41,7 @@ + + // global variables + extern JoystickKeyboardController* g_main_controller; ++extern JoystickKeyboardController* g_secondary_controller; + + extern SDL_Surface* g_screen; + +@@ -64,6 +65,7 @@ + + // global player state + extern PlayerStatus* player_status; ++extern PlayerStatus* second_player_status; + + extern SpriteManager* sprite_manager; + +Index: src/supertux/main.cpp +=================================================================== +--- src/supertux/main.cpp (revision 6139) ++++ src/supertux/main.cpp (working copy) +@@ -541,6 +541,7 @@ 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 @@ + 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 +=================================================================== +--- src/supertux/menu/menu_storage.cpp (revision 6139) ++++ src/supertux/menu/menu_storage.cpp (working copy) +@@ -26,6 +26,8 @@ + 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 @@ + 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 (&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 +=================================================================== +--- src/supertux/menu/menu_storage.hpp (revision 6139) ++++ src/supertux/menu/menu_storage.hpp (working copy) +@@ -32,12 +32,16 @@ + 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 +=================================================================== +--- src/supertux/menu/options_menu.cpp (revision 6139) ++++ src/supertux/menu/options_menu.cpp (working copy) +@@ -161,6 +161,13 @@ + + 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 +=================================================================== +--- src/supertux/player_status.cpp (revision 6139) ++++ src/supertux/player_status.cpp (working copy) +@@ -30,6 +30,7 @@ + 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 +=================================================================== +--- src/supertux/resources.cpp (revision 6139) ++++ src/supertux/resources.cpp (working copy) +@@ -48,6 +48,7 @@ + sprite_manager = new SpriteManager(); + + player_status = new PlayerStatus(); ++ second_player_status = new PlayerStatus(); + } + + /* Free shared data: */ +@@ -67,6 +68,9 @@ + + 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 +=================================================================== +--- src/supertux/screen_manager.cpp (revision 6139) ++++ src/supertux/screen_manager.cpp (working copy) +@@ -190,11 +190,13 @@ + 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 +=================================================================== +--- src/supertux/sector.cpp (revision 6139) ++++ src/supertux/sector.cpp (working copy) +@@ -84,6 +84,7 @@ + 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 @@ } + 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(*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 @@ + 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(*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 @@ Player* player = dynamic_cast (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 (object); -- 2.11.0