Fixed trailing whitespaces in all(?) source files of supertux, also fixed some svn...
[supertux.git] / src / object / camera.cpp
index b9d0097..b6f2a01 100644 (file)
 #include "path.hpp"
 #include "path_walker.hpp"
 
+namespace {
+  enum CameraStyle { CameraStyleYI, CameraStyleKD };
+  const CameraStyle cameraStyle = CameraStyleKD;
+}
+
 Camera::Camera(Sector* newsector, std::string name)
   : mode(NORMAL), sector(newsector), do_backscrolling(true),
     scrollchange(NONE)
@@ -120,8 +125,25 @@ Camera::write(lisp::Writer& writer)
 }
 
 void
+Camera::reset_kd(const Vector& tuxpos)
+{
+  translation.x = tuxpos.x - (SCREEN_WIDTH * 0.5);
+  translation.y = tuxpos.y - (SCREEN_HEIGHT * 0.5);
+
+  shakespeed = 0;
+  shaketimer.stop();
+  keep_in_bounds(translation);
+}
+
+
+void
 Camera::reset(const Vector& tuxpos)
 {
+  if (cameraStyle == CameraStyleKD) {
+    reset_kd(tuxpos);
+    return;
+  }
+
   translation.x = tuxpos.x - SCREEN_WIDTH/3 * 2;
   translation.y = tuxpos.y - SCREEN_HEIGHT/2;
   shakespeed = 0;
@@ -150,7 +172,7 @@ Camera::scroll_to(const Vector& goal, float scrolltime)
   mode = SCROLLTO;
 }
 
-static const float EPSILON = .00001;
+static const float EPSILON = .00001f;
 static const float max_speed_y = 140;
 
 void
@@ -182,10 +204,14 @@ Camera::keep_in_bounds(Vector& translation)
     translation.y = height - SCREEN_HEIGHT;
   if(translation.y < 0)
     translation.y = 0;
+  if (height < SCREEN_HEIGHT)
+    translation.y = height/2.0 - SCREEN_HEIGHT/2.0;
   if(translation.x > width - SCREEN_WIDTH)
     translation.x = width - SCREEN_WIDTH;
   if(translation.x < 0)
     translation.x = 0;
+  if (width < SCREEN_WIDTH)
+    translation.x = width/2.0 - SCREEN_WIDTH/2.0;
 }
 
 void
@@ -198,8 +224,51 @@ Camera::shake()
 }
 
 void
+Camera::update_scroll_normal_kd(float elapsed_time)
+{
+  // make sure some time has actually passed
+  if(elapsed_time < EPSILON) return;
+
+  // make sure we have an active player
+  assert(sector != 0);
+  Player* player = sector->player;
+  Vector playerCenter = player->get_bbox().get_middle();
+
+  // If player is peeking, scroll in that direction
+  if (player->peeking_direction() == ::LEFT) {
+        translation.x -= elapsed_time * 128.0f;
+  }
+  else if (player->peeking_direction() == ::RIGHT) {
+        translation.x += elapsed_time * 128.0f;
+  }
+
+  // keep player within a small box, centered on the screen (vertical part)
+  bool do_y_scrolling = true;
+  if (player->is_dying() || sector->get_height() == 19*32) do_y_scrolling = false;
+  if (do_y_scrolling) {
+    translation.y = std::min(player->get_bbox().p1.y - SCREEN_HEIGHT * (0.5f - 0.17f), translation.y);
+    translation.y = std::max(player->get_bbox().p2.y - SCREEN_HEIGHT * (0.5f + 0.17f), translation.y);
+  }
+
+  // keep player within a small box, centered on the screen (horizontal part)
+  translation.x = std::min(player->get_bbox().p1.x - SCREEN_WIDTH * (0.5f - 0.1f), translation.x);
+  translation.x = std::max(player->get_bbox().p2.x - SCREEN_WIDTH * (0.5f + 0.1f), translation.x);
+
+  // make sure camera doesn't point outside level borders
+  keep_in_bounds(translation);
+
+  // handle shaking of camera (if applicable)
+  shake();
+}
+
+void
 Camera::update_scroll_normal(float elapsed_time)
 {
+  if (cameraStyle == CameraStyleKD) {
+    update_scroll_normal_kd(elapsed_time);
+    return;
+  }
+
   assert(sector != 0);
   Player* player = sector->player;
 
@@ -253,8 +322,19 @@ Camera::update_scroll_normal(float elapsed_time)
   // when suddenly changing directions while scrolling into the other direction.
   // abort scrolling, since tux might be going left/right at a relatively small
   // part of the map (like when jumping upwards)
-  if((player->dir == ::LEFT && scrollchange == RIGHT)
-      || (player->dir == ::RIGHT && scrollchange == LEFT))
+
+
+  // Find out direction in which the player walks: We want to try and show a
+  // bit more of what's in front of the player and less of what's behind
+  LeftRightScrollChange walkDirection;
+  if (player->physic.get_velocity_x() < -EPSILON) walkDirection = LEFT;
+  else if (player->physic.get_velocity_x() > EPSILON) walkDirection = RIGHT;
+  else if (player->dir == ::LEFT) walkDirection = LEFT;
+  else walkDirection = RIGHT;
+
+
+  if((walkDirection == LEFT && scrollchange == RIGHT)
+      || (walkDirection == RIGHT && scrollchange == LEFT))
     scrollchange = NONE;
   // when in left 1/3rd of screen scroll left
   if(player->get_bbox().get_middle().x < translation.x + SCREEN_WIDTH/3 - 16