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.
22 #include "Animation.h"
23 #include "Interface.h"
34 Animation::Animation(int count
)
36 frames
= (Sprite2D
**) calloc(count
, sizeof(Sprite2D
*));
52 gameAnimation
= false;
55 Animation::~Animation(void)
57 Video
*video
= core
->GetVideoDriver();
59 for (unsigned int i
= 0; i
< indicesCount
; i
++) {
60 video
->FreeSprite( frames
[i
] );
65 void Animation::SetPos(unsigned int index
)
67 if (index
<indicesCount
) {
74 /* when adding NULL, it means we already added a frame of index */
75 void Animation::AddFrame(Sprite2D
* frame
, unsigned int index
)
77 if (index
>=indicesCount
) {
78 printf("You tried to write past a buffer in animation, BAD!\n");
81 core
->GetVideoDriver()->FreeSprite(frames
[index
]);
87 int h
= frame
->Height
;
89 animArea
.w
+= (animArea
.x
- x
);
93 animArea
.h
+= (animArea
.y
- y
);
96 if (x
+w
> animArea
.x
+animArea
.w
) {
97 animArea
.w
= x
+w
-animArea
.x
;
99 if (y
+h
> animArea
.y
+animArea
.h
) {
100 animArea
.h
= y
+h
-animArea
.y
;
104 unsigned int Animation::GetCurrentFrame() const
107 return indicesCount
-pos
-1;
111 Sprite2D
* Animation::LastFrame(void)
113 if (!Flags
&A_ANI_ACTIVE
) {
114 printf("Frame fetched while animation is inactive!\n");
118 starttime
= core
->GetGame()->Ticks
;
120 GetTime( starttime
);
124 ret
= frames
[indicesCount
-pos
-1];
130 Sprite2D
* Animation::NextFrame(void)
132 if (!Flags
&A_ANI_ACTIVE
) {
133 printf("Frame fetched while animation is inactive!\n");
136 if (starttime
== 0) {
138 starttime
= core
->GetGame()->Ticks
;
140 GetTime( starttime
);
145 ret
= frames
[indicesCount
-pos
-1];
149 if (endReached
&& (Flags
&A_ANI_PLAYONCE
) )
154 time
= core
->GetGame()->Ticks
;
159 //it could be that we skip more than one frame in case of slow rendering
160 //large, composite animations (dragons, multi-part area anims) require synchronisation
161 if (( time
- starttime
) >= ( unsigned long ) ( 1000 / fps
)) {
162 int inc
= (time
-starttime
)*fps
/1000;
164 starttime
+= inc
*1000/fps
;
166 if (pos
>= indicesCount
) {
168 if (Flags
&A_ANI_PLAYONCE
) {
169 pos
= indicesCount
-1;
172 pos
= pos
%indicesCount
;
173 endReached
= false; //looping, there is no end
184 Sprite2D
* Animation::GetSyncedNextFrame(Animation
* master
)
186 if (!Flags
&A_ANI_ACTIVE
) {
187 printf("Frame fetched while animation is inactive!\n");
192 ret
= frames
[indicesCount
-pos
-1];
196 starttime
= master
->starttime
;
198 endReached
= master
->endReached
;
204 void Animation::release(void)
208 /** Gets the i-th frame */
209 Sprite2D
* Animation::GetFrame(unsigned int i
)
211 if (i
>= indicesCount
) {
217 void Animation::MirrorAnimation()
219 Video
*video
= core
->GetVideoDriver();
221 for (size_t i
= 0; i
< indicesCount
; i
++) {
222 Sprite2D
* tmp
= frames
[i
];
223 frames
[i
] = video
->MirrorSpriteHorizontal( tmp
, true );
224 video
->FreeSprite(tmp
);
227 // flip animArea horizontally as well
228 animArea
.x
= -animArea
.w
- animArea
.x
;
231 void Animation::MirrorAnimationVert()
233 Video
*video
= core
->GetVideoDriver();
235 for (size_t i
= 0; i
< indicesCount
; i
++) {
236 Sprite2D
* tmp
= frames
[i
];
237 frames
[i
] = video
->MirrorSpriteVertical( tmp
, true );
238 video
->FreeSprite(tmp
);
241 // flip animArea vertically as well
242 // animArea.y = -animArea.h - animArea.y;
245 void Animation::AddAnimArea(Animation
* slave
)
247 int x
= slave
->animArea
.x
;
248 int y
= slave
->animArea
.y
;
249 int w
= slave
->animArea
.w
;
250 int h
= slave
->animArea
.h
;
251 if (x
< animArea
.x
) {
252 animArea
.w
+= (animArea
.x
- x
);
255 if (y
< animArea
.y
) {
256 animArea
.h
+= (animArea
.y
- y
);
259 if (x
+w
> animArea
.x
+animArea
.w
) {
260 animArea
.w
= x
+w
-animArea
.x
;
262 if (y
+h
> animArea
.y
+animArea
.h
) {
263 animArea
.h
= y
+h
-animArea
.y
;