From d24699722cde9ae87fc95220c99f230928e72eee Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Sat, 20 Nov 2004 22:18:32 +0000 Subject: [PATCH] forgot to add some files SVN-Revision: 2117 --- lib/math/aatriangle.h | 43 +++++++++++++ lib/math/rectangle.h | 92 ++++++++++++++++++++++++++++ lib/special/sprite_data.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 281 insertions(+) create mode 100644 lib/math/aatriangle.h create mode 100644 lib/math/rectangle.h create mode 100644 lib/special/sprite_data.cpp diff --git a/lib/math/aatriangle.h b/lib/math/aatriangle.h new file mode 100644 index 000000000..876093859 --- /dev/null +++ b/lib/math/aatriangle.h @@ -0,0 +1,43 @@ +#ifndef __AATRIANGLE_H__ +#define __AATRIANGLE_H__ + +#include "rectangle.h" + +namespace SuperTux +{ + +/** + * An axis aligned triangle (ie. a triangle where 2 sides are parallel to the x- + * and y-axis. + */ +class AATriangle : public Rectangle +{ +public: + /** Directions: + * + * SOUTHEWEST NORTHEAST SOUTHEAST NORTHWEST + * * or *---* or * or *---* + * | \ \ | / | | / + * | \ \ | / | | / + * *---* * *---* * + */ + enum Direction { + SOUTHWEST, NORTHEAST, SOUTHEAST, NORTHWEST + }; + + AATriangle() + : dir(SOUTHWEST) + { + } + AATriangle(const Vector& v1, const Vector& v2, Direction newdir) + : Rectangle(v1, v2), dir(newdir) + { + } + + Direction dir; +}; + +} + +#endif + diff --git a/lib/math/rectangle.h b/lib/math/rectangle.h new file mode 100644 index 000000000..e0254bc84 --- /dev/null +++ b/lib/math/rectangle.h @@ -0,0 +1,92 @@ +#ifndef __RECTANGLE_H__ +#define __RECTANGLE_H__ + +#include +#include "vector.h" + +namespace SuperTux +{ + +/** This class represents a rectangle. + * (Implementation Note) We're using upper left and lower right point instead of + * upper left and width/height here, because that makes the collision dectection + * a little bit efficienter. + */ +class Rectangle +{ +public: + Rectangle() + { } + + Rectangle(const Vector& np1, const Vector& np2) + : p1(np1), p2(np2) + { + } + + Rectangle(float x1, float y1, float x2, float y2) + : p1(x1, y1), p2(x2, y2) + { + assert(p1.x <= p2.x && p1.y <= p2.y); + } + + float get_width() const + { return p2.x - p1.x; } + + float get_height() const + { return p2.y - p1.y; } + + Vector get_middle() const + { return Vector((p1.x+p2.x)/2, (p1.y+p2.y)/2); } + + void set_pos(const Vector& v) + { + move(v-p1); + } + + void set_height(float height) + { + p2.y = p1.y + height; + } + void set_width(float width) + { + p2.x = p1.x + width; + } + void set_size(float width, float height) + { + set_width(width); + set_height(height); + } + + void move(const Vector& v) + { + p1 += v; + p2 += v; + } + + bool inside(const Vector& v) const + { + return v.x >= p1.x && v.y >= p1.y && v.x < p2.x && v.y < p2.y; + } + bool inside(const Rectangle& other) const + { + if(p1.x >= other.p2.x || other.p1.x >= p2.x) + return false; + if(p1.y >= other.p2.y || other.p1.y >= p2.y) + return false; + + return true; + } + + // leave these 2 public to safe the headaches of set/get functions for such + // simple things :) + + /// upper left edge + Vector p1; + /// lower right edge + Vector p2; +}; + +} + +#endif + diff --git a/lib/special/sprite_data.cpp b/lib/special/sprite_data.cpp new file mode 100644 index 000000000..6289076fe --- /dev/null +++ b/lib/special/sprite_data.cpp @@ -0,0 +1,146 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2004 Ingo Ruhnke +// +// 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. +#include + +#include +#include +#include +#include + +#include "../app/globals.h" +#include "../app/setup.h" +#include "../special/sprite.h" +#include "../video/drawing_context.h" + +namespace SuperTux +{ + +SpriteData::Action::Action() +{ + x_offset = 0; + y_offset = 0; + z_order = 0; + fps = 10; +} + +SpriteData::Action::~Action() +{ + for(std::vector::iterator i = surfaces.begin(); + i != surfaces.end(); ++i) + delete *i; +} + +SpriteData::SpriteData(lisp_object_t* cur) +{ + for(; !lisp_nil_p(cur); cur = lisp_cdr(cur)) { + std::string token = lisp_symbol(lisp_car(lisp_car(cur))); + lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur))); + LispReader reader(lisp_cdr(lisp_car(cur))); + + if(token == "name") + name = lisp_string(data); + else if(token == "action") + parse_action(reader); + else + std::cerr << "Warning: Unknown sprite field: " << token << std::endl; + } + + if(name.empty()) + throw std::runtime_error("Error: Sprite wihtout name."); + if(actions.empty()) + throw std::runtime_error("Error: Sprite wihtout actions."); +} + +SpriteData::~SpriteData() +{ + for(Actions::iterator i=actions.begin(); i != actions.end(); ++i) + delete i->second; +} + +void +SpriteData::parse_action(LispReader& lispreader) +{ + Action* action = new Action; + + if(!lispreader.read_string("name", action->name)) { + if(!actions.empty()) + throw std::runtime_error( + "If there are more than one action, they need names!"); + } + lispreader.read_int("x-offset", action->x_offset); + lispreader.read_int("y-offset", action->y_offset); + lispreader.read_int("z-order", action->z_order); + lispreader.read_float("fps", action->fps); + + /* TODO: add a top filter entry */ + std::vector mask_color; + lispreader.read_int_vector("apply-mask", mask_color); + if(mask_color.size() == 4) { + for(std::vector::iterator i = action->surfaces.begin(); + i < action->surfaces.end(); i++) { + (*i)->apply_filter(MASK_FILTER, Color(mask_color)); + } + } + + std::string mirror_action; + lispreader.read_string("mirror-action", mirror_action); + if(!mirror_action.empty()) { + Action* act_tmp = get_action(mirror_action); + if(act_tmp == NULL) { + throw std::runtime_error("Could not mirror action. Action not found\n" + "Mirror actions must be defined after the real one!"); + } else { + for(int i = 0; static_cast(i) < act_tmp->surfaces.size(); + i++) { + Surface* surface = new Surface(sdl_surface_from_sdl_surface( + act_tmp->surfaces[i]->impl->get_sdl_surface(), true), true); + surface->apply_filter(HORIZONTAL_FLIP_FILTER); + action->surfaces.push_back(surface); + } + } + } else { // Load images + std::vector images; + if(!lispreader.read_string_vector("images", images)) { + std::stringstream msg; + msg << "Sprite '" << name << "' contains no images in action '" + << action->name << "'."; + throw std::runtime_error(msg.str()); + } + + for(std::vector::size_type i = 0; i < images.size(); i++) { + action->surfaces.push_back( + new Surface(datadir + "/images/" + images[i], true)); + } + } + actions[action->name] = action; +} + +SpriteData::Action* +SpriteData::get_action(std::string act) +{ + Actions::iterator i = actions.find(act); + if(i == actions.end()) { + std::cerr << "Warning: Action '" << act << + "' not found on Sprite '" << name << "'\n"; + return 0; + } + return i->second; +} + +} -- 2.11.0