X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=lib%2Fspecial%2Fsprite.cpp;h=48aa325658ad938e115128be9db629527af54cc0;hb=495f8b77cb935fe8eff81bec755efca8e34e8a99;hp=f6cbdebfc36f6e0e3ccb5667bb5adfd106a9ed31;hpb=e68610f027ad6f35025d9aca87202ceb4501e97e;p=supertux.git diff --git a/lib/special/sprite.cpp b/lib/special/sprite.cpp index f6cbdebfc..48aa32565 100644 --- a/lib/special/sprite.cpp +++ b/lib/special/sprite.cpp @@ -16,248 +16,85 @@ // 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" +#include "app/globals.h" +#include "app/setup.h" +#include "sprite.h" +#include "video/drawing_context.h" -using namespace SuperTux; - -Sprite::Sprite(lisp_object_t* cur) +namespace SuperTux { - 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()) - Termination::abort("Error: Sprite wihtout name.", ""); - if(actions.empty()) - Termination::abort("Error: Sprite wihtout actions.", ""); -} -Sprite::~Sprite() +Sprite::Sprite(SpriteData& newdata) + : data(newdata), frame(0), animation_loops(-1) { - for(Actions::iterator i_act = actions.begin(); i_act != actions.end(); ++i_act) - { - for(std::vector::iterator i_sur = i_act->second->surfaces.begin(); - i_sur != i_act->second->surfaces.end(); ++i_sur) - { - delete *i_sur; - } - delete i_act->second; - } + action = data.get_action("normal"); + if(!action) + action = data.actions.begin()->second; + last_ticks = SDL_GetTicks(); } -void -Sprite::parse_action(LispReader& lispreader) +Sprite::Sprite(const Sprite& other) + : data(other.data), frame(other.frame), + animation_loops(other.animation_loops), + action(other.action) { - action = new Action; - - init_defaults(action); - - if(!lispreader.read_string("name", action->name)) - if(!actions.empty()) - Termination::abort("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) - std::cerr << "Warning: Could not mirror action. Action not found\n" - "Mirror actions must be defined after the real one!\n"; - 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)) - Termination::abort("Sprite contains no images: ", action->name); - - 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; + last_ticks = SDL_GetTicks(); } -/*void Sprite::parse_filter(LispReader& lispreader) -{ - -}*/ - -void -Sprite::init_defaults(Action* act) +Sprite::~Sprite() { - act->x_offset = 0; - act->y_offset = 0; - act->z_order = 0; - act->fps = 10; - - start_animation(-1); } void -Sprite::set_action(std::string act) +Sprite::set_action(std::string name, int loops) { -if(!next_action.empty() && animation_loops > 0) - { - next_action = act; - return; - } -Actions::iterator i = actions.find(act); -if(i == actions.end()) - { - std::cerr << "Warning: Action '" << act << "' not found on Sprite '" << name << "'\n"; - return; - } -action = i->second; -} + if(action && action->name == name) + return; -Sprite::Action* -Sprite::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 NULL; + SpriteData::Action* newaction = data.get_action(name); + if(!newaction) { +#ifdef DEBUG + std::cerr << "Action '" << name << "' not found.\n"; +#endif + return; } -return i->second; -} - -void -Sprite::start_animation(int loops) -{ -reset(); -animation_loops = loops; -} -void -Sprite::reset() -{ -frame = 0; -last_tick = SDL_GetTicks(); -animation_reversed = false; -next_action.clear(); + action = newaction; + animation_loops = loops; + frame = 0; } bool Sprite::check_animation() { -return animation_loops; -} - -void -Sprite::reverse_animation(bool reverse) -{ -animation_reversed = reverse; - -if(animation_reversed) - frame = get_frames()-1; -else - frame = 0; + return animation_loops == 0; } void Sprite::update() { -if(animation_loops == 0) - { - if(frame >= get_frames() || frame < 0) - frame = 0; - return; - } + if(animation_loops == 0) + return; -float frame_inc = (action->fps/1000.0) * (SDL_GetTicks() - last_tick); -last_tick = SDL_GetTicks(); + Uint32 ticks = SDL_GetTicks(); + float frame_inc = action->fps * float(ticks - last_ticks)/1000.0; + last_ticks = ticks; -if(animation_reversed) - frame -= frame_inc; -else frame += frame_inc; -if(animation_reversed) - { - if(frame < 0 || frame >= (float)get_frames()) - { // last case can happen when not used reverse_animation() - float excedent = frame - 0; - frame = get_frames() - 1; - if(animation_loops > 0) - { - animation_loops--; - if(animation_loops == 0 && !next_action.empty()) - { - set_action(next_action); - start_animation(-1); - } - } - - if(fabsf(excedent) < get_frames()) - frame += excedent; - } - } -else - { - if(frame >= (float)get_frames()) - { - float excedent = frame - get_frames(); - frame = 0; - if(animation_loops > 0) - { - animation_loops--; - if(animation_loops == 0 && !next_action.empty()) - { - set_action(next_action); - start_animation(-1); - } - } - - if(excedent < get_frames()) - frame += excedent; - } + if(frame >= get_frames()) { + frame = fmodf(frame+get_frames(), get_frames()); + + animation_loops--; + if(animation_loops == 0) + frame = 0; } } @@ -265,6 +102,7 @@ void Sprite::draw(DrawingContext& context, const Vector& pos, int layer, Uint32 drawing_effect) { + assert(action != 0); update(); if((int)frame >= get_frames() || (int)frame < 0) @@ -273,13 +111,15 @@ Sprite::draw(DrawingContext& context, const Vector& pos, int layer, << "/" << get_action_name() << std::endl; else context.draw_surface(action->surfaces[(int)frame], - pos - Vector(action->x_offset, action->y_offset), layer + action->z_order, drawing_effect); + pos - Vector(action->x_offset, action->y_offset), + layer + action->z_order, drawing_effect); } void -Sprite::draw_part(DrawingContext& context, const Vector& source, const Vector& size, - const Vector& pos, int layer, Uint32 drawing_effect) +Sprite::draw_part(DrawingContext& context, const Vector& source, + const Vector& size, const Vector& pos, int layer, Uint32 drawing_effect) { + assert(action != 0); update(); if((int)frame >= get_frames() || (int)frame < 0) @@ -288,19 +128,21 @@ Sprite::draw_part(DrawingContext& context, const Vector& source, const Vector& s << "/" << get_action_name() << std::endl; else context.draw_surface_part(action->surfaces[(int)frame], source, size, - pos - Vector(action->x_offset, action->y_offset), layer + action->z_order, drawing_effect); + pos - Vector(action->x_offset, action->y_offset), + layer + action->z_order, drawing_effect); } int -Sprite::get_width() +Sprite::get_width() const { return action->surfaces[get_frame()]->w; } int -Sprite::get_height() +Sprite::get_height() const { return action->surfaces[get_frame()]->h; } -/* EOF */ +} +