~ubuntu-branches/ubuntu/raring/scummvm/raring

« back to all changes in this revision

Viewing changes to engines/sword25/gfx/animation.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: (21.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20110525190223-fiqm0oaec714xk31
Tags: upstream-1.3.0
ImportĀ upstreamĀ versionĀ 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ScummVM - Graphic Adventure Engine
 
2
 *
 
3
 * ScummVM is the legal property of its developers, whose names
 
4
 * are too numerous to list here. Please refer to the COPYRIGHT
 
5
 * file distributed with this source distribution.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * as published by the Free Software Foundation; either version 2
 
10
 * of the License, or (at your option) any later version.
 
11
 
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
20
 *
 
21
 * $URL$
 
22
 * $Id$
 
23
 *
 
24
 */
 
25
 
 
26
/*
 
27
 * This code is based on Broken Sword 2.5 engine
 
28
 *
 
29
 * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
 
30
 *
 
31
 * Licensed under GNU GPL v2
 
32
 *
 
33
 */
 
34
 
 
35
#include "sword25/gfx/animation.h"
 
36
 
 
37
#include "sword25/kernel/kernel.h"
 
38
#include "sword25/kernel/resmanager.h"
 
39
#include "sword25/kernel/inputpersistenceblock.h"
 
40
#include "sword25/kernel/outputpersistenceblock.h"
 
41
#include "sword25/package/packagemanager.h"
 
42
#include "sword25/gfx/image/image.h"
 
43
#include "sword25/gfx/animationtemplate.h"
 
44
#include "sword25/gfx/animationtemplateregistry.h"
 
45
#include "sword25/gfx/animationresource.h"
 
46
#include "sword25/gfx/bitmapresource.h"
 
47
#include "sword25/gfx/graphicengine.h"
 
48
 
 
49
namespace Sword25 {
 
50
 
 
51
Animation::Animation(RenderObjectPtr<RenderObject> parentPtr, const Common::String &fileName) :
 
52
        TimedRenderObject(parentPtr, RenderObject::TYPE_ANIMATION) {
 
53
        // Das BS_RenderObject konnte nicht erzeugt werden, daher muss an dieser Stelle abgebrochen werden.
 
54
        if (!_initSuccess)
 
55
                return;
 
56
 
 
57
        initMembers();
 
58
 
 
59
        // Vom negativen Fall ausgehen.
 
60
        _initSuccess = false;
 
61
 
 
62
        initializeAnimationResource(fileName);
 
63
 
 
64
        // Erfolg signalisieren.
 
65
        _initSuccess = true;
 
66
}
 
67
 
 
68
Animation::Animation(RenderObjectPtr<RenderObject> parentPtr, const AnimationTemplate &templ) :
 
69
        TimedRenderObject(parentPtr, RenderObject::TYPE_ANIMATION) {
 
70
        // Das BS_RenderObject konnte nicht erzeugt werden, daher muss an dieser Stelle abgebrochen werden.
 
71
        if (!_initSuccess)
 
72
                return;
 
73
 
 
74
        initMembers();
 
75
 
 
76
        // Vom negativen Fall ausgehen.
 
77
        _initSuccess = false;
 
78
 
 
79
        _animationTemplateHandle = AnimationTemplate::create(templ);
 
80
 
 
81
        // Erfolg signalisieren.
 
82
        _initSuccess = true;
 
83
}
 
84
 
 
85
Animation::Animation(InputPersistenceBlock &reader, RenderObjectPtr<RenderObject> parentPtr, uint handle) :
 
86
        TimedRenderObject(parentPtr, RenderObject::TYPE_ANIMATION, handle) {
 
87
        // Das BS_RenderObject konnte nicht erzeugt werden, daher muss an dieser Stelle abgebrochen werden.
 
88
        if (!_initSuccess)
 
89
                return;
 
90
 
 
91
        initMembers();
 
92
 
 
93
        // Objekt vom Stream laden.
 
94
        _initSuccess = unpersist(reader);
 
95
}
 
96
 
 
97
void Animation::initializeAnimationResource(const Common::String &fileName) {
 
98
        // Die Resource wird fļæ½r die gesamte Lebensdauer des Animations-Objektes gelockt.
 
99
        Resource *resourcePtr = Kernel::getInstance()->getResourceManager()->requestResource(fileName);
 
100
        if (resourcePtr && resourcePtr->getType() == Resource::TYPE_ANIMATION)
 
101
                _animationResourcePtr = static_cast<AnimationResource *>(resourcePtr);
 
102
        else {
 
103
                error("The resource \"%s\" could not be requested. The Animation can't be created.", fileName.c_str());
 
104
                return;
 
105
        }
 
106
 
 
107
        // Grļæ½ļæ½e und Position der Animation anhand des aktuellen Frames bestimmen.
 
108
        computeCurrentCharacteristics();
 
109
}
 
110
 
 
111
void Animation::initMembers() {
 
112
        _currentFrame = 0;
 
113
        _currentFrameTime = 0;
 
114
        _direction = FORWARD;
 
115
        _running = false;
 
116
        _finished = false;
 
117
        _relX = 0;
 
118
        _relY = 0;
 
119
        _scaleFactorX = 1.0f;
 
120
        _scaleFactorY = 1.0f;
 
121
        _modulationColor = 0xffffffff;
 
122
        _animationResourcePtr = 0;
 
123
        _animationTemplateHandle = 0;
 
124
        _framesLocked = false;
 
125
}
 
126
 
 
127
Animation::~Animation() {
 
128
        if (getAnimationDescription()) {
 
129
                stop();
 
130
                getAnimationDescription()->unlock();
 
131
        }
 
132
 
 
133
        // Invoke the "delete" callback
 
134
        if (_deleteCallback)
 
135
                (_deleteCallback)(getHandle());
 
136
 
 
137
}
 
138
 
 
139
void Animation::play() {
 
140
        // If the animation was completed, then play it again from the start.
 
141
        if (_finished)
 
142
                stop();
 
143
 
 
144
        _running = true;
 
145
        lockAllFrames();
 
146
}
 
147
 
 
148
void Animation::pause() {
 
149
        _running = false;
 
150
        unlockAllFrames();
 
151
}
 
152
 
 
153
void Animation::stop() {
 
154
        _currentFrame = 0;
 
155
        _currentFrameTime = 0;
 
156
        _direction = FORWARD;
 
157
        pause();
 
158
}
 
159
 
 
160
void Animation::setFrame(uint nr) {
 
161
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
162
        assert(animationDescriptionPtr);
 
163
 
 
164
        if (nr >= animationDescriptionPtr->getFrameCount()) {
 
165
                error("Tried to set animation to illegal frame (%d). Value must be between 0 and %d.",
 
166
                               nr, animationDescriptionPtr->getFrameCount());
 
167
                return;
 
168
        }
 
169
 
 
170
        _currentFrame = nr;
 
171
        _currentFrameTime = 0;
 
172
        computeCurrentCharacteristics();
 
173
        forceRefresh();
 
174
}
 
175
 
 
176
bool Animation::doRender() {
 
177
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
178
        assert(animationDescriptionPtr);
 
179
        assert(_currentFrame < animationDescriptionPtr->getFrameCount());
 
180
 
 
181
        // Bitmap des aktuellen Frames holen
 
182
        Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(animationDescriptionPtr->getFrame(_currentFrame).fileName);
 
183
        assert(pResource);
 
184
        assert(pResource->getType() == Resource::TYPE_BITMAP);
 
185
        BitmapResource *pBitmapResource = static_cast<BitmapResource *>(pResource);
 
186
 
 
187
        // Framebufferobjekt holen
 
188
        GraphicEngine *pGfx = Kernel::getInstance()->getGfx();
 
189
        assert(pGfx);
 
190
 
 
191
        // Bitmap zeichnen
 
192
        bool result;
 
193
        if (isScalingAllowed() && (_width != pBitmapResource->getWidth() || _height != pBitmapResource->getHeight())) {
 
194
                result = pBitmapResource->blit(_absoluteX, _absoluteY,
 
195
                                               (animationDescriptionPtr->getFrame(_currentFrame).flipV ? BitmapResource::FLIP_V : 0) |
 
196
                                               (animationDescriptionPtr->getFrame(_currentFrame).flipH ? BitmapResource::FLIP_H : 0),
 
197
                                               0, _modulationColor, _width, _height);
 
198
        } else {
 
199
                result = pBitmapResource->blit(_absoluteX, _absoluteY,
 
200
                                               (animationDescriptionPtr->getFrame(_currentFrame).flipV ? BitmapResource::FLIP_V : 0) |
 
201
                                               (animationDescriptionPtr->getFrame(_currentFrame).flipH ? BitmapResource::FLIP_H : 0),
 
202
                                               0, _modulationColor, -1, -1);
 
203
        }
 
204
 
 
205
        // Resource freigeben
 
206
        pBitmapResource->release();
 
207
 
 
208
        return result;
 
209
}
 
210
 
 
211
void Animation::frameNotification(int timeElapsed) {
 
212
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
213
        assert(animationDescriptionPtr);
 
214
        assert(timeElapsed >= 0);
 
215
 
 
216
        // Nur wenn die Animation lļæ½uft wird sie auch weiterbewegt
 
217
        if (_running) {
 
218
                // Gesamte vergangene Zeit bestimmen (inkl. Restzeit des aktuellen Frames)
 
219
                _currentFrameTime += timeElapsed;
 
220
 
 
221
                // Anzahl an zu ļæ½berpringenden Frames bestimmen
 
222
                int skipFrames = animationDescriptionPtr->getMillisPerFrame() == 0 ? 0 : _currentFrameTime / animationDescriptionPtr->getMillisPerFrame();
 
223
 
 
224
                // Neue Frame-Restzeit bestimmen
 
225
                _currentFrameTime -= animationDescriptionPtr->getMillisPerFrame() * skipFrames;
 
226
 
 
227
                // Neuen Frame bestimmen (je nach aktuellener Abspielrichtung wird addiert oder subtrahiert)
 
228
                int tmpCurFrame = _currentFrame;
 
229
                switch (_direction) {
 
230
                case FORWARD:
 
231
                        tmpCurFrame += skipFrames;
 
232
                        break;
 
233
 
 
234
                case BACKWARD:
 
235
                        tmpCurFrame -= skipFrames;
 
236
                        break;
 
237
 
 
238
                default:
 
239
                        assert(0);
 
240
                }
 
241
 
 
242
                // Deal with overflows
 
243
                if (tmpCurFrame < 0) {
 
244
                        // Loop-Point callback
 
245
                        if (_loopPointCallback && !(_loopPointCallback)(getHandle()))
 
246
                                _loopPointCallback = 0;
 
247
 
 
248
                        // An underflow may only occur if the animation type is JOJO.
 
249
                        assert(animationDescriptionPtr->getAnimationType() == AT_JOJO);
 
250
                        tmpCurFrame = - tmpCurFrame;
 
251
                        _direction = FORWARD;
 
252
                } else if (static_cast<uint>(tmpCurFrame) >= animationDescriptionPtr->getFrameCount()) {
 
253
                        // Loop-Point callback
 
254
                        if (_loopPointCallback && !(_loopPointCallback)(getHandle()))
 
255
                                _loopPointCallback = 0;
 
256
 
 
257
                        switch (animationDescriptionPtr->getAnimationType()) {
 
258
                        case AT_ONESHOT:
 
259
                                tmpCurFrame = animationDescriptionPtr->getFrameCount() - 1;
 
260
                                _finished = true;
 
261
                                pause();
 
262
                                break;
 
263
 
 
264
                        case AT_LOOP:
 
265
                                tmpCurFrame = tmpCurFrame % animationDescriptionPtr->getFrameCount();
 
266
                                break;
 
267
 
 
268
                        case AT_JOJO:
 
269
                                tmpCurFrame = animationDescriptionPtr->getFrameCount() - (tmpCurFrame % animationDescriptionPtr->getFrameCount()) - 1;
 
270
                                _direction = BACKWARD;
 
271
                                break;
 
272
 
 
273
                        default:
 
274
                                assert(0);
 
275
                        }
 
276
                }
 
277
 
 
278
                if ((int)_currentFrame != tmpCurFrame) {
 
279
                        forceRefresh();
 
280
 
 
281
                        if (animationDescriptionPtr->getFrame(_currentFrame).action != "") {
 
282
                                // action callback
 
283
                                if (_actionCallback && !(_actionCallback)(getHandle()))
 
284
                                        _actionCallback = 0;
 
285
                        }
 
286
                }
 
287
 
 
288
                _currentFrame = static_cast<uint>(tmpCurFrame);
 
289
        }
 
290
 
 
291
        // Grļæ½ļæ½e und Position der Animation anhand des aktuellen Frames bestimmen
 
292
        computeCurrentCharacteristics();
 
293
 
 
294
        assert(_currentFrame < animationDescriptionPtr->getFrameCount());
 
295
        assert(_currentFrameTime >= 0);
 
296
}
 
297
 
 
298
void Animation::computeCurrentCharacteristics() {
 
299
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
300
        assert(animationDescriptionPtr);
 
301
        const AnimationResource::Frame &curFrame = animationDescriptionPtr->getFrame(_currentFrame);
 
302
 
 
303
        Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(curFrame.fileName);
 
304
        assert(pResource);
 
305
        assert(pResource->getType() == Resource::TYPE_BITMAP);
 
306
        BitmapResource *pBitmap = static_cast<BitmapResource *>(pResource);
 
307
 
 
308
        // Grļæ½ļæ½e des Bitmaps auf die Animation ļæ½bertragen
 
309
        _width = static_cast<int>(pBitmap->getWidth() * _scaleFactorX);
 
310
        _height = static_cast<int>(pBitmap->getHeight() * _scaleFactorY);
 
311
 
 
312
        // Position anhand des Hotspots berechnen und setzen
 
313
        int posX = _relX + computeXModifier();
 
314
        int posY = _relY + computeYModifier();
 
315
 
 
316
        RenderObject::setPos(posX, posY);
 
317
 
 
318
        pBitmap->release();
 
319
}
 
320
 
 
321
bool Animation::lockAllFrames() {
 
322
        if (!_framesLocked) {
 
323
                AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
324
                assert(animationDescriptionPtr);
 
325
                for (uint i = 0; i < animationDescriptionPtr->getFrameCount(); ++i) {
 
326
                        if (!Kernel::getInstance()->getResourceManager()->requestResource(animationDescriptionPtr->getFrame(i).fileName)) {
 
327
                                error("Could not lock all animation frames.");
 
328
                                return false;
 
329
                        }
 
330
                }
 
331
 
 
332
                _framesLocked = true;
 
333
        }
 
334
 
 
335
        return true;
 
336
}
 
337
 
 
338
bool Animation::unlockAllFrames() {
 
339
        if (_framesLocked) {
 
340
                AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
341
                assert(animationDescriptionPtr);
 
342
                for (uint i = 0; i < animationDescriptionPtr->getFrameCount(); ++i) {
 
343
                        Resource *pResource;
 
344
                        if (!(pResource = Kernel::getInstance()->getResourceManager()->requestResource(animationDescriptionPtr->getFrame(i).fileName))) {
 
345
                                error("Could not unlock all animation frames.");
 
346
                                return false;
 
347
                        }
 
348
 
 
349
                        // Zwei mal freigeben um den Request von LockAllFrames() und den jetzigen Request aufzuheben
 
350
                        pResource->release();
 
351
                        if (pResource->getLockCount())
 
352
                                pResource->release();
 
353
                }
 
354
 
 
355
                _framesLocked = false;
 
356
        }
 
357
 
 
358
        return true;
 
359
}
 
360
 
 
361
Animation::ANIMATION_TYPES Animation::getAnimationType() const {
 
362
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
363
        assert(animationDescriptionPtr);
 
364
        return animationDescriptionPtr->getAnimationType();
 
365
}
 
366
 
 
367
int Animation::getFPS() const {
 
368
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
369
        assert(animationDescriptionPtr);
 
370
        return animationDescriptionPtr->getFPS();
 
371
}
 
372
 
 
373
int Animation::getFrameCount() const {
 
374
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
375
        assert(animationDescriptionPtr);
 
376
        return animationDescriptionPtr->getFrameCount();
 
377
}
 
378
 
 
379
bool Animation::isScalingAllowed() const {
 
380
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
381
        assert(animationDescriptionPtr);
 
382
        return animationDescriptionPtr->isScalingAllowed();
 
383
}
 
384
 
 
385
bool Animation::isAlphaAllowed() const {
 
386
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
387
        assert(animationDescriptionPtr);
 
388
        return animationDescriptionPtr->isAlphaAllowed();
 
389
}
 
390
 
 
391
bool Animation::isColorModulationAllowed() const {
 
392
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
393
        assert(animationDescriptionPtr);
 
394
        return animationDescriptionPtr->isColorModulationAllowed();
 
395
}
 
396
 
 
397
void Animation::setPos(int relX, int relY) {
 
398
        _relX = relX;
 
399
        _relY = relY;
 
400
 
 
401
        computeCurrentCharacteristics();
 
402
}
 
403
 
 
404
void Animation::setX(int relX) {
 
405
        _relX = relX;
 
406
 
 
407
        computeCurrentCharacteristics();
 
408
}
 
409
 
 
410
void Animation::setY(int relY) {
 
411
        _relY = relY;
 
412
 
 
413
        computeCurrentCharacteristics();
 
414
}
 
415
 
 
416
void Animation::setAlpha(int alpha) {
 
417
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
418
        assert(animationDescriptionPtr);
 
419
        if (!animationDescriptionPtr->isAlphaAllowed()) {
 
420
                warning("Tried to set alpha value on an animation that does not support alpha. Call was ignored.");
 
421
                return;
 
422
        }
 
423
 
 
424
        uint newModulationColor = (_modulationColor & 0x00ffffff) | alpha << 24;
 
425
        if (newModulationColor != _modulationColor) {
 
426
                _modulationColor = newModulationColor;
 
427
                forceRefresh();
 
428
        }
 
429
}
 
430
 
 
431
void Animation::setModulationColor(uint modulationColor) {
 
432
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
433
        assert(animationDescriptionPtr);
 
434
        if (!animationDescriptionPtr->isColorModulationAllowed()) {
 
435
                warning("Tried to set modulation color on an animation that does not support color modulation. Call was ignored");
 
436
                return;
 
437
        }
 
438
 
 
439
        uint newModulationColor = (modulationColor & 0x00ffffff) | (_modulationColor & 0xff000000);
 
440
        if (newModulationColor != _modulationColor) {
 
441
                _modulationColor = newModulationColor;
 
442
                forceRefresh();
 
443
        }
 
444
}
 
445
 
 
446
void Animation::setScaleFactor(float scaleFactor) {
 
447
        setScaleFactorX(scaleFactor);
 
448
        setScaleFactorY(scaleFactor);
 
449
}
 
450
 
 
451
void Animation::setScaleFactorX(float scaleFactorX) {
 
452
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
453
        assert(animationDescriptionPtr);
 
454
        if (!animationDescriptionPtr->isScalingAllowed()) {
 
455
                warning("Tried to set x scale factor on an animation that does not support scaling. Call was ignored");
 
456
                return;
 
457
        }
 
458
 
 
459
        if (scaleFactorX != _scaleFactorX) {
 
460
                _scaleFactorX = scaleFactorX;
 
461
                if (_scaleFactorX <= 0.0f)
 
462
                        _scaleFactorX = 0.001f;
 
463
                forceRefresh();
 
464
                computeCurrentCharacteristics();
 
465
        }
 
466
}
 
467
 
 
468
void Animation::setScaleFactorY(float scaleFactorY) {
 
469
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
470
        assert(animationDescriptionPtr);
 
471
        if (!animationDescriptionPtr->isScalingAllowed()) {
 
472
                warning("Tried to set y scale factor on an animation that does not support scaling. Call was ignored");
 
473
                return;
 
474
        }
 
475
 
 
476
        if (scaleFactorY != _scaleFactorY) {
 
477
                _scaleFactorY = scaleFactorY;
 
478
                if (_scaleFactorY <= 0.0f)
 
479
                        _scaleFactorY = 0.001f;
 
480
                forceRefresh();
 
481
                computeCurrentCharacteristics();
 
482
        }
 
483
}
 
484
 
 
485
const Common::String &Animation::getCurrentAction() const {
 
486
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
487
        assert(animationDescriptionPtr);
 
488
        return animationDescriptionPtr->getFrame(_currentFrame).action;
 
489
}
 
490
 
 
491
int Animation::getX() const {
 
492
        return _relX;
 
493
}
 
494
 
 
495
int Animation::getY() const {
 
496
        return _relY;
 
497
}
 
498
 
 
499
int Animation::getAbsoluteX() const {
 
500
        return _absoluteX + (_relX - _x);
 
501
}
 
502
 
 
503
int Animation::getAbsoluteY() const {
 
504
        return _absoluteY + (_relY - _y);
 
505
}
 
506
 
 
507
int Animation::computeXModifier() const {
 
508
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
509
        assert(animationDescriptionPtr);
 
510
        const AnimationResource::Frame &curFrame = animationDescriptionPtr->getFrame(_currentFrame);
 
511
 
 
512
        Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(curFrame.fileName);
 
513
        assert(pResource);
 
514
        assert(pResource->getType() == Resource::TYPE_BITMAP);
 
515
        BitmapResource *pBitmap = static_cast<BitmapResource *>(pResource);
 
516
 
 
517
        int result = curFrame.flipV ? - static_cast<int>((pBitmap->getWidth() - 1 - curFrame.hotspotX) * _scaleFactorX) :
 
518
                     - static_cast<int>(curFrame.hotspotX * _scaleFactorX);
 
519
 
 
520
        pBitmap->release();
 
521
 
 
522
        return result;
 
523
}
 
524
 
 
525
int Animation::computeYModifier() const {
 
526
        AnimationDescription *animationDescriptionPtr = getAnimationDescription();
 
527
        assert(animationDescriptionPtr);
 
528
        const AnimationResource::Frame &curFrame = animationDescriptionPtr->getFrame(_currentFrame);
 
529
 
 
530
        Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(curFrame.fileName);
 
531
        assert(pResource);
 
532
        assert(pResource->getType() == Resource::TYPE_BITMAP);
 
533
        BitmapResource *pBitmap = static_cast<BitmapResource *>(pResource);
 
534
 
 
535
        int result = curFrame.flipH ? - static_cast<int>((pBitmap->getHeight() - 1 - curFrame.hotspotY) * _scaleFactorY) :
 
536
                     - static_cast<int>(curFrame.hotspotY * _scaleFactorY);
 
537
 
 
538
        pBitmap->release();
 
539
 
 
540
        return result;
 
541
}
 
542
 
 
543
bool Animation::persist(OutputPersistenceBlock &writer) {
 
544
        bool result = true;
 
545
 
 
546
        result &= RenderObject::persist(writer);
 
547
 
 
548
        writer.write(_relX);
 
549
        writer.write(_relY);
 
550
        writer.write(_scaleFactorX);
 
551
        writer.write(_scaleFactorY);
 
552
        writer.write(_modulationColor);
 
553
        writer.write(_currentFrame);
 
554
        writer.write(_currentFrameTime);
 
555
        writer.write(_running);
 
556
        writer.write(_finished);
 
557
        writer.write(static_cast<uint>(_direction));
 
558
 
 
559
        // Je nach Animationstyp entweder das Template oder die Ressource speichern.
 
560
        if (_animationResourcePtr) {
 
561
                uint marker = 0;
 
562
                writer.write(marker);
 
563
                writer.writeString(_animationResourcePtr->getFileName());
 
564
        } else if (_animationTemplateHandle) {
 
565
                uint marker = 1;
 
566
                writer.write(marker);
 
567
                writer.write(_animationTemplateHandle);
 
568
        } else {
 
569
                assert(false);
 
570
        }
 
571
 
 
572
        //writer.write(_AnimationDescriptionPtr);
 
573
 
 
574
        writer.write(_framesLocked);
 
575
 
 
576
        // The following is only there to for compatibility with older saves
 
577
        // resp. the original engine.
 
578
        writer.write((uint)1);
 
579
        writer.writeString("LuaLoopPointCB");
 
580
        writer.write(getHandle());
 
581
        writer.write((uint)1);
 
582
        writer.writeString("LuaActionCB");
 
583
        writer.write(getHandle());
 
584
        writer.write((uint)1);
 
585
        writer.writeString("LuaDeleteCB");
 
586
        writer.write(getHandle());
 
587
 
 
588
        result &= RenderObject::persistChildren(writer);
 
589
 
 
590
        return result;
 
591
}
 
592
 
 
593
// -----------------------------------------------------------------------------
 
594
 
 
595
bool Animation::unpersist(InputPersistenceBlock &reader) {
 
596
        bool result = true;
 
597
 
 
598
        result &= RenderObject::unpersist(reader);
 
599
 
 
600
        reader.read(_relX);
 
601
        reader.read(_relY);
 
602
        reader.read(_scaleFactorX);
 
603
        reader.read(_scaleFactorY);
 
604
        reader.read(_modulationColor);
 
605
        reader.read(_currentFrame);
 
606
        reader.read(_currentFrameTime);
 
607
        reader.read(_running);
 
608
        reader.read(_finished);
 
609
        uint direction;
 
610
        reader.read(direction);
 
611
        _direction = static_cast<Direction>(direction);
 
612
 
 
613
        // Animationstyp einlesen.
 
614
        uint marker;
 
615
        reader.read(marker);
 
616
        if (marker == 0) {
 
617
                Common::String resourceFilename;
 
618
                reader.readString(resourceFilename);
 
619
                initializeAnimationResource(resourceFilename);
 
620
        } else if (marker == 1) {
 
621
                reader.read(_animationTemplateHandle);
 
622
        } else {
 
623
                assert(false);
 
624
        }
 
625
 
 
626
        reader.read(_framesLocked);
 
627
        if (_framesLocked)
 
628
                lockAllFrames();
 
629
 
 
630
 
 
631
        // The following is only there to for compatibility with older saves
 
632
        // resp. the original engine.
 
633
        uint callbackCount;
 
634
        Common::String callbackFunctionName;
 
635
        uint callbackData;
 
636
 
 
637
        // loop point callback
 
638
        reader.read(callbackCount);
 
639
        assert(callbackCount == 1);
 
640
        reader.readString(callbackFunctionName);
 
641
        assert(callbackFunctionName == "LuaLoopPointCB");
 
642
        reader.read(callbackData);
 
643
        assert(callbackData == getHandle());
 
644
 
 
645
        // loop point callback
 
646
        reader.read(callbackCount);
 
647
        assert(callbackCount == 1);
 
648
        reader.readString(callbackFunctionName);
 
649
        assert(callbackFunctionName == "LuaActionCB");
 
650
        reader.read(callbackData);
 
651
        assert(callbackData == getHandle());
 
652
 
 
653
        // loop point callback
 
654
        reader.read(callbackCount);
 
655
        assert(callbackCount == 1);
 
656
        reader.readString(callbackFunctionName);
 
657
        assert(callbackFunctionName == "LuaDeleteCB");
 
658
        reader.read(callbackData);
 
659
        assert(callbackData == getHandle());
 
660
 
 
661
        // Set the callbacks
 
662
        setCallbacks();
 
663
 
 
664
        result &= RenderObject::unpersistChildren(reader);
 
665
 
 
666
        return reader.isGood() && result;
 
667
}
 
668
 
 
669
// -----------------------------------------------------------------------------
 
670
 
 
671
AnimationDescription *Animation::getAnimationDescription() const {
 
672
        if (_animationResourcePtr)
 
673
                return _animationResourcePtr;
 
674
        else
 
675
                return AnimationTemplateRegistry::instance().resolveHandle(_animationTemplateHandle);
 
676
}
 
677
 
 
678
} // End of namespace Sword25