Bug 474: Flip bonus-block flowers and partial-size tilemaps properly.
[supertux.git] / src / sprite / sprite.cpp
index 782fc52..abf3c93 100644 (file)
 //  You should have received a copy of the GNU General Public License
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include <cmath>
+#include <math.h>
 
 #include "sprite/sprite.hpp"
 #include "supertux/timer.hpp"
 
-Sprite::Sprite(SpriteData& newdata)
-  : data(newdata),
-    frame(0),
-    animation_loops(-1),
-    angle(0.0f),
-    color(1.0f, 1.0f, 1.0f, 1.0f)
+Sprite::Sprite(SpriteData& newdata) :
+  data(newdata),
+  frame(0),
+  animation_loops(-1),
+  last_ticks(),
+  angle(0.0f),
+  color(1.0f, 1.0f, 1.0f, 1.0f),
+  blend(),
+  action()
 {
   action = data.get_action("normal");
   if(!action)
@@ -32,27 +35,35 @@ Sprite::Sprite(SpriteData& newdata)
   last_ticks = game_time;
 }
 
-Sprite::Sprite(const Sprite& other)
-  : data(other.data), frame(other.frame),
-    animation_loops(other.animation_loops),
-    angle(0.0f),
-    color(1.0f, 1.0f, 1.0f, 1.0f),
-    action(other.action)
+Sprite::Sprite(const Sprite& other) :
+  data(other.data), 
+  frame(other.frame),
+  animation_loops(other.animation_loops),
+  last_ticks(game_time),
+  angle(0.0f), // FIXME: this can't be right
+  color(1.0f, 1.0f, 1.0f, 1.0f),
+  blend(),
+  action(other.action)
 {
-  last_ticks = game_time;
 }
 
 Sprite::~Sprite()
 {
 }
 
+SpritePtr
+Sprite::clone() const
+{
+  return SpritePtr(new Sprite(*this));
+}
+
 void
 Sprite::set_action(const std::string& name, int loops)
 {
   if(action && action->name == name)
     return;
 
-  SpriteData::Action* newaction = data.get_action(name);
+  const SpriteData::Action* newaction = data.get_action(name);
   if(!newaction) {
     log_debug << "Action '" << name << "' not found." << std::endl;
     return;
@@ -69,7 +80,7 @@ Sprite::set_action_continued(const std::string& name)
   if(action && action->name == name)
     return;
 
-  SpriteData::Action* newaction = data.get_action(name);
+  const SpriteData::Action* newaction = data.get_action(name);
   if(!newaction) {
     log_debug << "Action '" << name << "' not found." << std::endl;
     return;
@@ -112,20 +123,23 @@ Sprite::update()
 }
 
 void
-Sprite::draw(DrawingContext& context, const Vector& pos, int layer)
+Sprite::draw(DrawingContext& context, const Vector& pos, int layer,
+             DrawingEffect effect)
 {
   assert(action != 0);
   update();
 
   if((int)frame >= get_frames() || (int)frame < 0)
     log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl;
-  else
+  else {
+    context.set_drawing_effect(effect);
     context.draw_surface(action->surfaces[(int)frame],
                          pos - Vector(action->x_offset, action->y_offset),
                          angle,
                          color,
                          blend,
                          layer + action->z_order);
+  }
 }
 
 void
@@ -138,11 +152,8 @@ Sprite::draw_part(DrawingContext& context, const Vector& source,
   int frameidx = (int) frame;
 
   if(frameidx >= get_frames() || frameidx < 0) {
-#ifndef DEBUG
     // in optimized mode we get some small rounding errors in floating point
     // number sometimes...
-    log_warning << "frame out of range: " << frameidx << "/" << get_frames() << " at sprite: " << get_name() << "/" << get_action() << std::endl;
-#endif
     frameidx = get_frames() - 1;
   }
 
@@ -154,13 +165,29 @@ Sprite::draw_part(DrawingContext& context, const Vector& source,
 int
 Sprite::get_width() const
 {
-  return (int) action->surfaces[get_frame()]->get_width();
+  if((int)frame >= get_frames() || (int)frame < 0)
+  {
+    log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl;
+    return 0;
+  }
+  else
+  {
+    return (int) action->surfaces[get_frame()]->get_width();
+  }
 }
 
 int
 Sprite::get_height() const
 {
+  if((int)frame >= get_frames() || (int)frame < 0)
+  {
+    log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl;
+    return 0;
+  }
+  else
+  {
   return (int) action->surfaces[get_frame()]->get_height();
+  }
 }
 
 float
@@ -187,16 +214,10 @@ Sprite::get_current_hitbox_height() const
   return action->hitbox_h;
 }
 
-Rect
+Rectf
 Sprite::get_current_hitbox() const
 {
-  return Rect(action->x_offset, action->y_offset, action->x_offset + action->hitbox_w, action->y_offset + action->hitbox_h);
-}
-
-void
-Sprite::set_fps(float new_fps)
-{
-  action->fps = new_fps;
+  return Rectf(action->x_offset, action->y_offset, action->x_offset + action->hitbox_w, action->y_offset + action->hitbox_h);
 }
 
 void