forgot to add some files
authorMatthias Braun <matze@braunis.de>
Sat, 20 Nov 2004 22:18:32 +0000 (22:18 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 20 Nov 2004 22:18:32 +0000 (22:18 +0000)
SVN-Revision: 2117

lib/math/aatriangle.h [new file with mode: 0644]
lib/math/rectangle.h [new file with mode: 0644]
lib/special/sprite_data.cpp [new file with mode: 0644]

diff --git a/lib/math/aatriangle.h b/lib/math/aatriangle.h
new file mode 100644 (file)
index 0000000..8760938
--- /dev/null
@@ -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 (file)
index 0000000..e0254bc
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef __RECTANGLE_H__
+#define __RECTANGLE_H__
+
+#include <assert.h>
+#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 (file)
index 0000000..6289076
--- /dev/null
@@ -0,0 +1,146 @@
+//  $Id$
+//
+//  SuperTux
+//  Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+//  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 <config.h>
+
+#include <iostream>
+#include <cmath>
+#include <sstream>
+#include <stdexcept>
+
+#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<Surface*>::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 <int> mask_color;
+  lispreader.read_int_vector("apply-mask", mask_color);
+  if(mask_color.size() == 4) {
+    for(std::vector<Surface*>::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<unsigned int>(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<std::string> 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<std::string>::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;
+}
+
+}