4 // Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.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.
26 #include "sprite_data.h"
27 #include "app/globals.h"
28 #include "app/setup.h"
29 #include "video/drawing_context.h"
34 SpriteData::Action::Action()
42 SpriteData::Action::~Action()
44 for(std::vector<Surface*>::iterator i = surfaces.begin();
45 i != surfaces.end(); ++i)
49 SpriteData::SpriteData(lisp_object_t* cur)
51 for(; !lisp_nil_p(cur); cur = lisp_cdr(cur)) {
52 std::string token = lisp_symbol(lisp_car(lisp_car(cur)));
53 lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur)));
54 LispReader reader(lisp_cdr(lisp_car(cur)));
57 name = lisp_string(data);
58 else if(token == "action")
61 std::cerr << "Warning: Unknown sprite field: " << token << std::endl;
65 throw std::runtime_error("Error: Sprite wihtout name.");
67 throw std::runtime_error("Error: Sprite wihtout actions.");
70 SpriteData::~SpriteData()
72 for(Actions::iterator i=actions.begin(); i != actions.end(); ++i)
77 SpriteData::parse_action(LispReader& lispreader)
79 Action* action = new Action;
81 if(!lispreader.read_string("name", action->name)) {
83 throw std::runtime_error(
84 "If there are more than one action, they need names!");
86 lispreader.read_int("x-offset", action->x_offset);
87 lispreader.read_int("y-offset", action->y_offset);
88 lispreader.read_int("z-order", action->z_order);
89 lispreader.read_float("fps", action->fps);
91 /* TODO: add a top filter entry */
92 std::vector <int> mask_color;
93 lispreader.read_int_vector("apply-mask", mask_color);
94 if(mask_color.size() == 4) {
95 for(std::vector<Surface*>::iterator i = action->surfaces.begin();
96 i < action->surfaces.end(); i++) {
97 (*i)->apply_filter(MASK_FILTER, Color(mask_color));
101 std::string mirror_action;
102 lispreader.read_string("mirror-action", mirror_action);
103 if(!mirror_action.empty()) {
104 Action* act_tmp = get_action(mirror_action);
105 if(act_tmp == NULL) {
106 throw std::runtime_error("Could not mirror action. Action not found\n"
107 "Mirror actions must be defined after the real one!");
109 for(int i = 0; static_cast<unsigned int>(i) < act_tmp->surfaces.size();
111 Surface* surface = new Surface(sdl_surface_from_sdl_surface(
112 act_tmp->surfaces[i]->impl->get_sdl_surface(), true), true);
113 surface->apply_filter(HORIZONTAL_FLIP_FILTER);
114 action->surfaces.push_back(surface);
117 } else { // Load images
118 std::vector<std::string> images;
119 if(!lispreader.read_string_vector("images", images)) {
120 std::stringstream msg;
121 msg << "Sprite '" << name << "' contains no images in action '"
122 << action->name << "'.";
123 throw std::runtime_error(msg.str());
126 for(std::vector<std::string>::size_type i = 0; i < images.size(); i++) {
127 action->surfaces.push_back(
128 new Surface(datadir + "/images/" + images[i], true));
131 actions[action->name] = action;
135 SpriteData::get_action(std::string act)
137 Actions::iterator i = actions.find(act);
138 if(i == actions.end()) {
139 std::cerr << "Warning: Action '" << act <<
140 "' not found on Sprite '" << name << "'\n";