#include "object/background.hpp"
#include <iostream>
+#include <math.h>
+#include <stdexcept>
+
#include "math/sizef.hpp"
#include "supertux/globals.hpp"
#include "supertux/object_factory.hpp"
#include "util/log.hpp"
#include "util/reader.hpp"
-#include <stdexcept>
-
Background::Background() :
alignment(NO_ALIGNMENT),
layer(LAYER_BACKGROUND0),
reader.get("scroll-speed-x", scroll_speed.x);
reader.get("scroll-speed-y", scroll_speed.y);
- reader.get("layer", layer);
- if (layer > (LAYER_GUI - 100)) {
- log_warning << "Layer of background (" << layer << ") is too large. "
- << "Clipping to " << (LAYER_GUI - 100) << "." << std::endl;
- layer = LAYER_GUI - 100;
- }
+ layer = reader_get_layer (reader, /* default = */ LAYER_BACKGROUND0);
if(!reader.get("image", imagefile) || !reader.get("speed", speed))
throw std::runtime_error("Must specify image and speed for background");
}
void
-Background::set_image(const std::string& name, float speed)
+Background::set_image(const std::string& name_, float speed_)
{
- this->imagefile = name;
- this->speed = speed;
+ this->imagefile = name_;
+ this->speed = speed_;
- image = Surface::create(name);
+ image = Surface::create(name_);
}
void
-Background::draw_image(DrawingContext& context, const Vector& pos)
+Background::draw_image(DrawingContext& context, const Vector& pos_)
{
Sizef level(Sector::current()->get_width(), Sector::current()->get_height());
Sizef screen(SCREEN_WIDTH, SCREEN_HEIGHT);
Sizef parallax_image_size = (1.0f - speed) * screen + level * speed;
+ Rectf cliprect = context.get_cliprect();
- // FIXME: Implement proper clipping here
- int start_x = -parallax_image_size.width / 2.0f / image->get_width() - 1;
- int end_x = parallax_image_size.width / 2.0f / image->get_width() + 1;
- int start_y = -parallax_image_size.height / 2.0f / image->get_height() - 1;
- int end_y = parallax_image_size.height / 2.0f / image->get_height() + 1;
+ int start_x = static_cast<int>(floorf((cliprect.get_left() - (pos_.x - image->get_width() /2.0f)) / image->get_width()));
+ int end_x = static_cast<int>(ceilf((cliprect.get_right() - (pos_.x + image->get_width() /2.0f)) / image->get_width()))+1;
+ int start_y = static_cast<int>(floorf((cliprect.get_top() - (pos_.y - image->get_height()/2.0f)) / image->get_height()));
+ int end_y = static_cast<int>(ceilf((cliprect.get_bottom() - (pos_.y + image->get_height()/2.0f)) / image->get_height()))+1;
switch(alignment)
{
case LEFT_ALIGNMENT:
- for(int y = start_y; y <= end_y; ++y)
+ for(int y = start_y; y < end_y; ++y)
{
- Vector p(pos.x - parallax_image_size.width / 2.0f,
- pos.y + y * image->get_height() - image->get_height() / 2.0f);
+ Vector p(pos_.x - parallax_image_size.width / 2.0f,
+ pos_.y + y * image->get_height() - image->get_height() / 2.0f);
context.draw_surface(image, p, layer);
}
break;
case RIGHT_ALIGNMENT:
- for(int y = start_y; y <= end_y; ++y)
+ for(int y = start_y; y < end_y; ++y)
{
- Vector p(pos.x + parallax_image_size.width / 2.0f - image->get_width(),
- pos.y + y * image->get_height() - image->get_height() / 2.0f);
+ Vector p(pos_.x + parallax_image_size.width / 2.0f - image->get_width(),
+ pos_.y + y * image->get_height() - image->get_height() / 2.0f);
context.draw_surface(image, p, layer);
}
break;
case TOP_ALIGNMENT:
- for(int x = start_x; x <= end_x; ++x)
+ for(int x = start_x; x < end_x; ++x)
{
- Vector p(pos.x + x * image->get_width() - image->get_width() / 2.0f,
- pos.y - parallax_image_size.height / 2.0f);
+ Vector p(pos_.x + x * image->get_width() - image->get_width() / 2.0f,
+ pos_.y - parallax_image_size.height / 2.0f);
context.draw_surface(image, p, layer);
}
break;
case BOTTOM_ALIGNMENT:
- for(int x = start_x; x <= end_x; ++x)
+ for(int x = start_x; x < end_x; ++x)
{
- Vector p(pos.x + x * image->get_width() - image->get_width() / 2.0f,
- pos.y - image->get_height() + parallax_image_size.height / 2.0f);
+ Vector p(pos_.x + x * image->get_width() - image->get_width() / 2.0f,
+ pos_.y - image->get_height() + parallax_image_size.height / 2.0f);
context.draw_surface(image, p, layer);
}
break;
case NO_ALIGNMENT:
- for(int y = start_y; y <= end_y; ++y)
- for(int x = start_x; x <= end_x; ++x)
+ for(int y = start_y; y < end_y; ++y)
+ for(int x = start_x; x < end_x; ++x)
{
- Vector p(pos.x + x * image->get_width() - image->get_width()/2,
- pos.y + y * image->get_height() - image->get_height()/2);
+ Vector p(pos_.x + x * image->get_width() - image->get_width()/2,
+ pos_.y + y * image->get_height() - image->get_height()/2);
if (image_top.get() != NULL && (y < 0))
{
Sector::current()->get_height());
Sizef screen(SCREEN_WIDTH, SCREEN_HEIGHT);
Sizef translation_range = level_size - screen;
- Vector center_offset(context.get_translation().x - translation_range.width / 2.0f,
+ Vector center_offset(context.get_translation().x - translation_range.width / 2.0f,
context.get_translation().y - translation_range.height / 2.0f);
// FIXME: We are not handling 'pos'