1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "Animation.h"
26 #include "Interface.h"
30 Animation::Animation(int count
)
32 frames
= (Sprite2D
**) calloc(count
, sizeof(Sprite2D
*));
48 gameAnimation
= false;
51 Animation::~Animation(void)
53 Video
*video
= core
->GetVideoDriver();
55 for (unsigned int i
= 0; i
< indicesCount
; i
++) {
56 video
->FreeSprite( frames
[i
] );
61 void Animation::SetPos(unsigned int index
)
63 if (index
<indicesCount
) {
70 /* when adding NULL, it means we already added a frame of index */
71 void Animation::AddFrame(Sprite2D
* frame
, unsigned int index
)
73 if (index
>=indicesCount
) {
74 printf("You tried to write past a buffer in animation, BAD!\n");
77 core
->GetVideoDriver()->FreeSprite(frames
[index
]);
83 int h
= frame
->Height
;
85 animArea
.w
+= (animArea
.x
- x
);
89 animArea
.h
+= (animArea
.y
- y
);
92 if (x
+w
> animArea
.x
+animArea
.w
) {
93 animArea
.w
= x
+w
-animArea
.x
;
95 if (y
+h
> animArea
.y
+animArea
.h
) {
96 animArea
.h
= y
+h
-animArea
.y
;
100 unsigned int Animation::GetCurrentFrame() const
103 return indicesCount
-pos
-1;
107 Sprite2D
* Animation::LastFrame(void)
109 if (!Flags
&A_ANI_ACTIVE
) {
110 printf("Frame fetched while animation is inactive!\n");
114 starttime
= core
->GetGame()->Ticks
;
116 GetTime( starttime
);
120 ret
= frames
[indicesCount
-pos
-1];
126 Sprite2D
* Animation::NextFrame(void)
128 if (!Flags
&A_ANI_ACTIVE
) {
129 printf("Frame fetched while animation is inactive!\n");
132 if (starttime
== 0) {
134 starttime
= core
->GetGame()->Ticks
;
136 GetTime( starttime
);
141 ret
= frames
[indicesCount
-pos
-1];
145 if (endReached
&& (Flags
&A_ANI_PLAYONCE
) )
150 time
= core
->GetGame()->Ticks
;
155 //it could be that we skip more than one frame in case of slow rendering
156 //large, composite animations (dragons, multi-part area anims) require synchronisation
157 if (( time
- starttime
) >= ( unsigned long ) ( 1000 / fps
)) {
158 int inc
= (time
-starttime
)*fps
/1000;
160 starttime
+= inc
*1000/fps
;
162 if (pos
>= indicesCount
) {
164 if (Flags
&A_ANI_PLAYONCE
) {
165 pos
= indicesCount
-1;
168 pos
= pos
%indicesCount
;
169 endReached
= false; //looping, there is no end
180 Sprite2D
* Animation::GetSyncedNextFrame(Animation
* master
)
182 if (!Flags
&A_ANI_ACTIVE
) {
183 printf("Frame fetched while animation is inactive!\n");
188 ret
= frames
[indicesCount
-pos
-1];
192 starttime
= master
->starttime
;
194 endReached
= master
->endReached
;
200 void Animation::release(void)
204 /** Gets the i-th frame */
205 Sprite2D
* Animation::GetFrame(unsigned int i
)
207 if (i
>= indicesCount
) {
213 void Animation::MirrorAnimation()
215 Video
*video
= core
->GetVideoDriver();
217 for (size_t i
= 0; i
< indicesCount
; i
++) {
218 Sprite2D
* tmp
= frames
[i
];
219 frames
[i
] = video
->MirrorSpriteHorizontal( tmp
, true );
220 video
->FreeSprite(tmp
);
223 // flip animArea horizontally as well
224 animArea
.x
= -animArea
.w
- animArea
.x
;
227 void Animation::MirrorAnimationVert()
229 Video
*video
= core
->GetVideoDriver();
231 for (size_t i
= 0; i
< indicesCount
; i
++) {
232 Sprite2D
* tmp
= frames
[i
];
233 frames
[i
] = video
->MirrorSpriteVertical( tmp
, true );
234 video
->FreeSprite(tmp
);
237 // flip animArea vertically as well
238 // animArea.y = -animArea.h - animArea.y;
241 void Animation::AddAnimArea(Animation
* slave
)
243 int x
= slave
->animArea
.x
;
244 int y
= slave
->animArea
.y
;
245 int w
= slave
->animArea
.w
;
246 int h
= slave
->animArea
.h
;
247 if (x
< animArea
.x
) {
248 animArea
.w
+= (animArea
.x
- x
);
251 if (y
< animArea
.y
) {
252 animArea
.h
+= (animArea
.y
- y
);
255 if (x
+w
> animArea
.x
+animArea
.w
) {
256 animArea
.w
= x
+w
-animArea
.x
;
258 if (y
+h
> animArea
.y
+animArea
.h
) {
259 animArea
.h
= y
+h
-animArea
.y
;