+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";
+
++ // 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));
++ }
++
+ /* 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;
++ }
++
+ 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;
++
+ 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())
+ ->set_help(_("Configure joystick control-action mappings"));
++
++ add_submenu(_("Setup Keyboard (P2)"), secondary_controller->get_key_options_menu())
++ ->set_help(_("Configure key-action mappings"));
++
++ add_submenu(_("Setup Joystick (P2)"),secondary_controller->get_joystick_options_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;