Animation plugin works beautifully.
[potpourri.git] / src / SDLAnimation / SDLAnimation.cpp
blob09af615bb449abd1d4df69ed12e7195636dbbd1a
1 // Copyright 2008 Brian Caine
3 // This file is part of Potpourri.
5 // Potpourri is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // Potpourri is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTIBILITY of FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Potpourri. If not, see <http://www.gnu.org/licenses/>.
19 // NOTES:
20 // uhh, sauce?
22 #include "SDLAnimation.h"
23 #include "../SDLPlugin/SDLSurface.h"
25 #include "../../include/core/common.h"
26 #include "../../include/core/Actor.h"
28 #include <SDL/SDL_rotozoom.h>
30 using namespace fragrant;
32 SDLAnimation::SDLAnimation(SDLAnimationData ndata)
34 data = ndata;
35 cur_frame = -1;
36 time = -1;
39 SDLAnimation::~SDLAnimation()
41 this->destroy();
44 GraphicsPair makePair(int x, int y)
46 GraphicsPair results;
47 results.x = x;
48 results.y = y;
50 return results;
53 GraphicsPair rotate_point(GraphicsPair src, float angle)
55 src.y = -src.y;
57 float radius = sqrt(pow(src.x, 2) + pow(src.y, 2));
58 float nangle = (radius > 0) ? fromRadians(acos(src.x / radius)) : 0;
60 if (src.x == 0 && src.y == 0)
61 return src;
63 if (angle == 0)
64 return makePair(src.x, -src.y);
66 while (angle < 0)
67 angle += 360;
68 angle = static_cast<int>(angle) % 360;
70 angle += nangle;
72 GraphicsPair results = makePair(
73 static_cast<int>(radius * cos(toRadians(angle))),
74 -static_cast<int>(radius * sin(toRadians(angle))));
76 return results;
79 void SDLAnimation::draw(Target* target, GraphicsRect* destrect,
80 GraphicsPair* srcrect, float angle)
82 if (cur_frame == -1 && time == -1)
84 cur_frame = 0;
85 time = SDL_GetTicks();
86 ticks_left = 0;
89 else
91 int ntime = SDL_GetTicks();
92 ticks_left -= (ntime - time);
93 time = ntime;
95 while (ticks_left <= 0)
97 cur_frame++;
98 cur_frame %= data.frames.size();
100 ticks_left = data.frames.at(cur_frame).y + ticks_left;
104 SDLSurface* target_surf = dynamic_cast<SDLSurface*>(target);
106 // sometime later make this more efficient
108 SDLAnimationFrame current_frame_data = data.images.at(cur_frame);
109 SDL_Surface* rotated_image = (angle == 0.0) ?
110 (current_frame_data.image) :
111 (rotozoomSurface(current_frame_data.image, angle, 1, SMOOTH));
112 SDL_Surface* dest_surf = target_surf->surf;
113 bool free_me = rotated_image != current_frame_data.image;
115 SDL_Rect destrect_sdl = {0, 0, 0, 0};
116 SDL_Rect srcrect_sdl = {0, 0, rotated_image->w, rotated_image->h};
118 Pair<float> offset = getOffset(
119 makePair(current_frame_data.image->w,current_frame_data.image->h), angle);
120 GraphicsPair sub_offset = rotate_point(
121 ::makePair(static_cast<int>(current_frame_data.offset.x),
122 static_cast<int>(current_frame_data.offset.y)), angle);
124 if (destrect)
126 destrect_sdl.x = destrect->xy.x + offset.x + sub_offset.x;
127 destrect_sdl.y = destrect->xy.y + offset.y + sub_offset.y;
130 SDL_BlitSurface(rotated_image, &srcrect_sdl, dest_surf, &destrect_sdl);
132 if (srcrect)
134 srcrect->x = srcrect_sdl.x;
135 srcrect->y = srcrect_sdl.y;
138 if (free_me)
139 SDL_FreeSurface(rotated_image);
141 return;
144 void SDLAnimation::destroy()
146 int cur;
147 for (cur = 0; cur < data.images.size(); cur++)
148 SDL_FreeSurface(data.images.at(cur).image);
150 for (cur = 0; cur < data.root_surfaces.size(); cur++)
151 SDL_FreeSurface(data.root_surfaces.at(cur));
153 return;