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/>.
25 #include <SDL/SDL_rotozoom.h>
29 #define PI 3.141592653589793
31 using namespace fragrant
;
33 Sprite
* Sprite::makeSprite(std::vector
<SDL_Surface
*> dframes
,
36 Sprite
* the_sprite
= new Sprite(dframes
, dparams
);
42 std::cerr
<< "Sprite::makeSprite(): Error making sprite" << std::endl
;
52 std::map
<int, std::vector
<SDL_Surface
*> >::iterator biter
;
53 std::vector
<SDL_Surface
*>::iterator niter
;
55 for (biter
= angle_frames
.begin(); biter
!= angle_frames
.end(); biter
++)
56 for (niter
= biter
->second
.begin(); niter
!= biter
->second
.end(); niter
++)
58 SDL_FreeSurface(*niter
);
62 void Sprite::draw(SDL_Surface
* dest
)
66 int cur_ticks
= SDL_GetTicks();
67 ticks_left
-= (cur_ticks
- last_tick
);
69 last_tick
= cur_ticks
;
71 while (ticks_left
<= 0)
74 if (cur_frame
== frames
.size() && sequence
.repeat
)
77 ticks_left
= sequence
.frames
.at(cur_frame
).duration
+ ticks_left
;
81 std::map
<int, std::vector
<SDL_Surface
*> >::iterator iter
;
83 std::vector
<SDL_Surface
*> cocked_frames
;
85 for (iter
= angle_frames
.begin(); iter
!= angle_frames
.end(); iter
++)
87 if ((sequence
.angle
+ ANGLE_SNAP
> iter
->first
) &&
88 (sequence
.angle
- ANGLE_SNAP
< iter
->first
))
89 cocked_frames
= iter
->second
;
92 if (!cocked_frames
.size())
94 makeNewAngleFrame(sequence
.angle
);
95 cocked_frames
= angle_frames
[sequence
.angle
];
100 SDL_Surface
* surface
= cocked_frames
.at(cur_frame
);
102 SDL_Rect pos
= {sequence
.position
.at(0) + angle_offset
.at(0),
103 sequence
.position
.at(1) + angle_offset
.at(1),
104 surface
->w
, surface
->h
};
105 SDL_BlitSurface(surface
, 0, dest
, &pos
);
110 Sprite::Sprite(std::vector
<SDL_Surface
*> dframes
, SpriteParams dparams
)
114 if (!dframes
.size() || !dparams
.frames
.size())
117 std::vector
<Frame
>::iterator iter
;
118 for (iter
= dparams
.frames
.begin(); iter
!= dparams
.frames
.end(); iter
++)
119 if (iter
->frame
>= dframes
.size())
122 if ((dparams
.position
.size() < 2) || (dparams
.focal_point
.size() < 2))
125 if (dparams
.position
.size() > 2)
126 std::cerr
<< "Sprite::makeSprite(): Warning, More position "
127 << "parameters then needed..." << std::endl
;
129 if (dparams
.focal_point
.size() > 2)
130 std::cerr
<< "Sprite::makeSprite(): Warning, More focal point "
131 << "parameters then needed..." << std::endl
;
133 if (dparams
.angle
> 360)
135 std::cerr
<< "Sprite::makeSprite(): Warning, Angle is greater than 360, "
136 << "wrapping around..." << std::endl
;
137 dparams
.angle
%= 360;
154 bool Sprite::makeAngleFrames()
158 for (cur
= 0; cur
< CIRCLE
; cur
+= ANGLE_CACHE
)
159 makeNewAngleFrame(cur
);
164 void Sprite::makeNewAngleFrame(int angle
)
168 std::vector
<SDL_Surface
*> new_frames
;
170 std::vector
<SDL_Surface
*>::iterator iter
;
172 for (iter
= frames
.begin(); iter
!= frames
.end(); iter
++)
174 temp
= rotozoomSurface(*iter
, static_cast<double>(angle
), 1, 1);
175 new_frames
.push_back(temp
);
178 angle_frames
[angle
] = new_frames
;
183 void Sprite::calcAngleOffset()
185 std::vector
<int> new_offset
;
188 SDL_Surface
* temp_surf
= 0;
190 std::map
<int, std::vector
<SDL_Surface
*> >::iterator iter
;
191 for (iter
= angle_frames
.begin(); iter
!= angle_frames
.end(); iter
++)
192 if ((sequence
.angle
+ ANGLE_SNAP
> iter
->first
) &&
193 (sequence
.angle
- ANGLE_SNAP
< iter
->first
))
196 temp_surf
= iter
->second
.at(0);
202 float x_1
, y_1
, x_2
, y_2
, radius
, theta_1
, theta_2
;
203 float w_1
, h_1
, w_2
, h_2
;
205 x_1
= sequence
.focal_point
.at(0);
206 y_1
= sequence
.focal_point
.at(1);
208 w_1
= frames
.at(0)->w
;
209 h_1
= frames
.at(0)->h
;
211 radius
= static_cast<int>(sqrt(
212 pow((static_cast<double>(x_1
), static_cast<double>(w_1
) / 2), 2) +
213 pow((static_cast<double>(y_1
), static_cast<double>(h_1
) / 2), 2) ));
215 theta_1
= (180 / PI
) * acos(static_cast<double>(x_1
) /
216 static_cast<double>(radius
));
217 theta_2
= theta_1
+ rot
;
219 x_2
= radius
* cos(theta_2
* (PI
/ 180)) + (w_1
/ 2);
220 y_2
= radius
* sin(theta_2
* (PI
/ 180)) + (h_1
/ 2);
225 new_offset
.push_back(static_cast<int>(
226 (x_2
- x_1
) + ((w_1
/ 2) - (w_2
/ 2))));
227 new_offset
.push_back(static_cast<int>(
228 (y_2
, - y_1
) + ((h_1
/ 2) - (h_2
/ 2))));
230 angle_offset
= new_offset
;
235 bool Sprite::was_made
= false;