4 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include "sprite_data.hpp"
28 #include "resources.hpp"
29 #include "video/drawing_context.hpp"
30 #include "lisp/list_iterator.hpp"
33 SpriteData::Action::Action()
43 SpriteData::Action::~Action()
45 for(std::vector<Surface*>::iterator i = surfaces.begin();
46 i != surfaces.end(); ++i)
50 SpriteData::SpriteData(const lisp::Lisp* lisp, const std::string& basedir)
52 lisp::ListIterator iter(lisp);
54 if(iter.item() == "name") {
55 iter.value()->get(name);
56 } else if(iter.item() == "action") {
57 parse_action(iter.lisp(), basedir);
59 log_warning << "Unknown sprite field: " << iter.item() << std::endl;
63 throw std::runtime_error("Error: Sprite wihtout actions.");
66 SpriteData::~SpriteData()
68 for(Actions::iterator i=actions.begin(); i != actions.end(); ++i)
73 SpriteData::parse_action(const lisp::Lisp* lisp, const std::string& basedir)
75 Action* action = new Action;
77 if(!lisp->get("name", action->name)) {
79 throw std::runtime_error(
80 "If there are more than one action, they need names!");
82 std::vector<float> hitbox;
83 if (lisp->get_vector("hitbox", hitbox)) {
84 if (hitbox.size() != 4) throw std::runtime_error("hitbox must specify exactly 4 coordinates");
85 action->x_offset = hitbox[0];
86 action->y_offset = hitbox[1];
87 action->hitbox_w = hitbox[2];
88 action->hitbox_h = hitbox[3];
90 lisp->get("z-order", action->z_order);
91 lisp->get("fps", action->fps);
93 std::string mirror_action;
94 lisp->get("mirror-action", mirror_action);
95 if(!mirror_action.empty()) {
96 Action* act_tmp = get_action(mirror_action);
98 throw std::runtime_error("Could not mirror action. Action not found\n"
99 "Mirror actions must be defined after the real one!");
103 for(int i = 0; static_cast<unsigned int>(i) < act_tmp->surfaces.size();
105 Surface* surface = new Surface(*(act_tmp->surfaces[i]));
107 max_w = std::max(max_w, surface->get_width());
108 max_h = std::max(max_h, surface->get_height());
109 action->surfaces.push_back(surface);
111 if (action->hitbox_w < 1) action->hitbox_w = max_w;
112 if (action->hitbox_h < 1) action->hitbox_h = max_h;
114 } else { // Load images
115 std::vector<std::string> images;
116 if(!lisp->get_vector("images", images)) {
117 std::stringstream msg;
118 msg << "Sprite '" << name << "' contains no images in action '"
119 << action->name << "'.";
120 throw std::runtime_error(msg.str());
125 for(std::vector<std::string>::size_type i = 0; i < images.size(); i++) {
126 Surface* surface = new Surface(basedir + images[i]);
127 max_w = std::max(max_w, surface->get_width());
128 max_h = std::max(max_h, surface->get_height());
129 action->surfaces.push_back(surface);
131 if (action->hitbox_w < 1) action->hitbox_w = max_w;
132 if (action->hitbox_h < 1) action->hitbox_h = max_h;
134 actions[action->name] = action;
138 SpriteData::get_action(std::string act)
140 Actions::iterator i = actions.find(act);
141 if(i == actions.end()) {