mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
680 lines
20 KiB
C++
680 lines
20 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This code is based on Broken Sword 2.5 engine
|
|
*
|
|
* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
|
|
*
|
|
* Licensed under GNU GPL v2
|
|
*
|
|
*/
|
|
|
|
#include "sword25/gfx/animation.h"
|
|
|
|
#include "sword25/kernel/kernel.h"
|
|
#include "sword25/kernel/resmanager.h"
|
|
#include "sword25/kernel/inputpersistenceblock.h"
|
|
#include "sword25/kernel/outputpersistenceblock.h"
|
|
#include "sword25/package/packagemanager.h"
|
|
#include "sword25/gfx/image/image.h"
|
|
#include "sword25/gfx/animationtemplate.h"
|
|
#include "sword25/gfx/animationtemplateregistry.h"
|
|
#include "sword25/gfx/animationresource.h"
|
|
#include "sword25/gfx/bitmapresource.h"
|
|
#include "sword25/gfx/graphicengine.h"
|
|
|
|
namespace Sword25 {
|
|
|
|
Animation::Animation(RenderObjectPtr<RenderObject> parentPtr, const Common::String &fileName) :
|
|
TimedRenderObject(parentPtr, RenderObject::TYPE_ANIMATION) {
|
|
// Das BS_RenderObject konnte nicht erzeugt werden, daher muss an dieser Stelle abgebrochen werden.
|
|
if (!_initSuccess)
|
|
return;
|
|
|
|
initMembers();
|
|
|
|
// Vom negativen Fall ausgehen.
|
|
_initSuccess = false;
|
|
|
|
initializeAnimationResource(fileName);
|
|
|
|
// Erfolg signalisieren.
|
|
_initSuccess = true;
|
|
}
|
|
|
|
Animation::Animation(RenderObjectPtr<RenderObject> parentPtr, const AnimationTemplate &templ) :
|
|
TimedRenderObject(parentPtr, RenderObject::TYPE_ANIMATION) {
|
|
// Das BS_RenderObject konnte nicht erzeugt werden, daher muss an dieser Stelle abgebrochen werden.
|
|
if (!_initSuccess)
|
|
return;
|
|
|
|
initMembers();
|
|
|
|
// Vom negativen Fall ausgehen.
|
|
_initSuccess = false;
|
|
|
|
_animationTemplateHandle = AnimationTemplate::create(templ);
|
|
|
|
// Erfolg signalisieren.
|
|
_initSuccess = true;
|
|
}
|
|
|
|
Animation::Animation(InputPersistenceBlock &reader, RenderObjectPtr<RenderObject> parentPtr, uint handle) :
|
|
TimedRenderObject(parentPtr, RenderObject::TYPE_ANIMATION, handle) {
|
|
// Das BS_RenderObject konnte nicht erzeugt werden, daher muss an dieser Stelle abgebrochen werden.
|
|
if (!_initSuccess)
|
|
return;
|
|
|
|
initMembers();
|
|
|
|
// Objekt vom Stream laden.
|
|
_initSuccess = unpersist(reader);
|
|
}
|
|
|
|
void Animation::initializeAnimationResource(const Common::String &fileName) {
|
|
// Die Resource wird für die gesamte Lebensdauer des Animations-Objektes gelockt.
|
|
Resource *resourcePtr = Kernel::getInstance()->getResourceManager()->requestResource(fileName);
|
|
if (resourcePtr && resourcePtr->getType() == Resource::TYPE_ANIMATION)
|
|
_animationResourcePtr = static_cast<AnimationResource *>(resourcePtr);
|
|
else {
|
|
error("The resource \"%s\" could not be requested. The Animation can't be created.", fileName.c_str());
|
|
return;
|
|
}
|
|
|
|
// Größe und Position der Animation anhand des aktuellen Frames bestimmen.
|
|
computeCurrentCharacteristics();
|
|
}
|
|
|
|
void Animation::initMembers() {
|
|
_currentFrame = 0;
|
|
_currentFrameTime = 0;
|
|
_direction = FORWARD;
|
|
_running = false;
|
|
_finished = false;
|
|
_relX = 0;
|
|
_relY = 0;
|
|
_scaleFactorX = 1.0f;
|
|
_scaleFactorY = 1.0f;
|
|
_modulationColor = BS_ARGBMASK;
|
|
_animationResourcePtr = 0;
|
|
_animationTemplateHandle = 0;
|
|
_framesLocked = false;
|
|
|
|
_loopPointCallback = 0;
|
|
_actionCallback = 0;
|
|
_deleteCallback = 0;
|
|
}
|
|
|
|
Animation::~Animation() {
|
|
if (getAnimationDescription()) {
|
|
stop();
|
|
getAnimationDescription()->unlock();
|
|
}
|
|
|
|
// Invoke the "delete" callback
|
|
if (_deleteCallback)
|
|
(_deleteCallback)(getHandle());
|
|
|
|
}
|
|
|
|
void Animation::play() {
|
|
// If the animation was completed, then play it again from the start.
|
|
if (_finished)
|
|
stop();
|
|
|
|
_running = true;
|
|
lockAllFrames();
|
|
}
|
|
|
|
void Animation::pause() {
|
|
_running = false;
|
|
unlockAllFrames();
|
|
}
|
|
|
|
void Animation::stop() {
|
|
_currentFrame = 0;
|
|
_currentFrameTime = 0;
|
|
_direction = FORWARD;
|
|
pause();
|
|
}
|
|
|
|
void Animation::setFrame(uint nr) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
|
|
if (nr >= animationDescriptionPtr->getFrameCount()) {
|
|
error("Tried to set animation to illegal frame (%d). Value must be between 0 and %d.",
|
|
nr, animationDescriptionPtr->getFrameCount());
|
|
return;
|
|
}
|
|
|
|
_currentFrame = nr;
|
|
_currentFrameTime = 0;
|
|
computeCurrentCharacteristics();
|
|
forceRefresh();
|
|
}
|
|
|
|
bool Animation::doRender(RectangleList *updateRects) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
assert(_currentFrame < animationDescriptionPtr->getFrameCount());
|
|
|
|
// Bitmap des aktuellen Frames holen
|
|
Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(animationDescriptionPtr->getFrame(_currentFrame).fileName);
|
|
assert(pResource);
|
|
assert(pResource->getType() == Resource::TYPE_BITMAP);
|
|
BitmapResource *pBitmapResource = static_cast<BitmapResource *>(pResource);
|
|
|
|
// Framebufferobjekt holen
|
|
GraphicEngine *pGfx = Kernel::getInstance()->getGfx();
|
|
assert(pGfx);
|
|
|
|
// Bitmap zeichnen
|
|
bool result;
|
|
if (isScalingAllowed() && (_width != pBitmapResource->getWidth() || _height != pBitmapResource->getHeight())) {
|
|
result = pBitmapResource->blit(_absoluteX, _absoluteY,
|
|
(animationDescriptionPtr->getFrame(_currentFrame).flipV ? Graphics::FLIP_V : 0) |
|
|
(animationDescriptionPtr->getFrame(_currentFrame).flipH ? Graphics::FLIP_H : 0),
|
|
0, _modulationColor, _width, _height,
|
|
updateRects);
|
|
} else {
|
|
result = pBitmapResource->blit(_absoluteX, _absoluteY,
|
|
(animationDescriptionPtr->getFrame(_currentFrame).flipV ? Graphics::FLIP_V : 0) |
|
|
(animationDescriptionPtr->getFrame(_currentFrame).flipH ? Graphics::FLIP_H : 0),
|
|
0, _modulationColor, -1, -1,
|
|
updateRects);
|
|
}
|
|
|
|
// Resource freigeben
|
|
pBitmapResource->release();
|
|
|
|
return result;
|
|
}
|
|
|
|
void Animation::frameNotification(int timeElapsed) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
assert(timeElapsed >= 0);
|
|
|
|
// Nur wenn die Animation läuft wird sie auch weiterbewegt
|
|
if (_running) {
|
|
// Gesamte vergangene Zeit bestimmen (inkl. Restzeit des aktuellen Frames)
|
|
_currentFrameTime += timeElapsed;
|
|
|
|
// Anzahl an zu überpringenden Frames bestimmen
|
|
int skipFrames = animationDescriptionPtr->getMillisPerFrame() == 0 ? 0 : _currentFrameTime / animationDescriptionPtr->getMillisPerFrame();
|
|
|
|
// Neue Frame-Restzeit bestimmen
|
|
_currentFrameTime -= animationDescriptionPtr->getMillisPerFrame() * skipFrames;
|
|
|
|
// Neuen Frame bestimmen (je nach aktuellener Abspielrichtung wird addiert oder subtrahiert)
|
|
int tmpCurFrame = _currentFrame;
|
|
switch (_direction) {
|
|
case FORWARD:
|
|
tmpCurFrame += skipFrames;
|
|
break;
|
|
|
|
case BACKWARD:
|
|
tmpCurFrame -= skipFrames;
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
}
|
|
|
|
// Deal with overflows
|
|
if (tmpCurFrame < 0) {
|
|
// Loop-Point callback
|
|
if (_loopPointCallback && !(_loopPointCallback)(getHandle()))
|
|
_loopPointCallback = 0;
|
|
|
|
// An underflow may only occur if the animation type is JOJO.
|
|
assert(animationDescriptionPtr->getAnimationType() == AT_JOJO);
|
|
tmpCurFrame = - tmpCurFrame;
|
|
_direction = FORWARD;
|
|
} else if (static_cast<uint>(tmpCurFrame) >= animationDescriptionPtr->getFrameCount()) {
|
|
// Loop-Point callback
|
|
if (_loopPointCallback && !(_loopPointCallback)(getHandle()))
|
|
_loopPointCallback = 0;
|
|
|
|
switch (animationDescriptionPtr->getAnimationType()) {
|
|
case AT_ONESHOT:
|
|
tmpCurFrame = animationDescriptionPtr->getFrameCount() - 1;
|
|
_finished = true;
|
|
pause();
|
|
break;
|
|
|
|
case AT_LOOP:
|
|
tmpCurFrame = tmpCurFrame % animationDescriptionPtr->getFrameCount();
|
|
break;
|
|
|
|
case AT_JOJO:
|
|
tmpCurFrame = animationDescriptionPtr->getFrameCount() - (tmpCurFrame % animationDescriptionPtr->getFrameCount()) - 1;
|
|
_direction = BACKWARD;
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
if ((int)_currentFrame != tmpCurFrame) {
|
|
forceRefresh();
|
|
|
|
if (animationDescriptionPtr->getFrame(_currentFrame).action != "") {
|
|
// action callback
|
|
if (_actionCallback && !(_actionCallback)(getHandle()))
|
|
_actionCallback = 0;
|
|
}
|
|
}
|
|
|
|
_currentFrame = static_cast<uint>(tmpCurFrame);
|
|
}
|
|
|
|
// Größe und Position der Animation anhand des aktuellen Frames bestimmen
|
|
computeCurrentCharacteristics();
|
|
|
|
assert(_currentFrame < animationDescriptionPtr->getFrameCount());
|
|
assert(_currentFrameTime >= 0);
|
|
}
|
|
|
|
void Animation::computeCurrentCharacteristics() {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
const AnimationResource::Frame &curFrame = animationDescriptionPtr->getFrame(_currentFrame);
|
|
|
|
Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(curFrame.fileName);
|
|
assert(pResource);
|
|
assert(pResource->getType() == Resource::TYPE_BITMAP);
|
|
BitmapResource *pBitmap = static_cast<BitmapResource *>(pResource);
|
|
|
|
// Größe des Bitmaps auf die Animation übertragen
|
|
_width = static_cast<int>(pBitmap->getWidth() * _scaleFactorX);
|
|
_height = static_cast<int>(pBitmap->getHeight() * _scaleFactorY);
|
|
|
|
// Position anhand des Hotspots berechnen und setzen
|
|
int posX = _relX + computeXModifier();
|
|
int posY = _relY + computeYModifier();
|
|
|
|
RenderObject::setPos(posX, posY);
|
|
|
|
pBitmap->release();
|
|
}
|
|
|
|
bool Animation::lockAllFrames() {
|
|
if (!_framesLocked) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
for (uint i = 0; i < animationDescriptionPtr->getFrameCount(); ++i) {
|
|
if (!Kernel::getInstance()->getResourceManager()->requestResource(animationDescriptionPtr->getFrame(i).fileName)) {
|
|
error("Could not lock all animation frames.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
_framesLocked = true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Animation::unlockAllFrames() {
|
|
if (_framesLocked) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
for (uint i = 0; i < animationDescriptionPtr->getFrameCount(); ++i) {
|
|
Resource *pResource;
|
|
if (!(pResource = Kernel::getInstance()->getResourceManager()->requestResource(animationDescriptionPtr->getFrame(i).fileName))) {
|
|
error("Could not unlock all animation frames.");
|
|
return false;
|
|
}
|
|
|
|
// Zwei mal freigeben um den Request von LockAllFrames() und den jetzigen Request aufzuheben
|
|
pResource->release();
|
|
if (pResource->getLockCount())
|
|
pResource->release();
|
|
}
|
|
|
|
_framesLocked = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Animation::ANIMATION_TYPES Animation::getAnimationType() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
return animationDescriptionPtr->getAnimationType();
|
|
}
|
|
|
|
int Animation::getFPS() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
return animationDescriptionPtr->getFPS();
|
|
}
|
|
|
|
int Animation::getFrameCount() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
return animationDescriptionPtr->getFrameCount();
|
|
}
|
|
|
|
bool Animation::isScalingAllowed() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
return animationDescriptionPtr->isScalingAllowed();
|
|
}
|
|
|
|
bool Animation::isAlphaAllowed() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
return animationDescriptionPtr->isAlphaAllowed();
|
|
}
|
|
|
|
bool Animation::isColorModulationAllowed() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
return animationDescriptionPtr->isColorModulationAllowed();
|
|
}
|
|
|
|
void Animation::setPos(int relX, int relY) {
|
|
_relX = relX;
|
|
_relY = relY;
|
|
|
|
computeCurrentCharacteristics();
|
|
}
|
|
|
|
void Animation::setX(int relX) {
|
|
_relX = relX;
|
|
|
|
computeCurrentCharacteristics();
|
|
}
|
|
|
|
void Animation::setY(int relY) {
|
|
_relY = relY;
|
|
|
|
computeCurrentCharacteristics();
|
|
}
|
|
|
|
void Animation::setAlpha(int alpha) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
if (!animationDescriptionPtr->isAlphaAllowed()) {
|
|
warning("Tried to set alpha value on an animation that does not support alpha. Call was ignored.");
|
|
return;
|
|
}
|
|
|
|
uint newModulationColor = (_modulationColor & BS_RGBMASK) | alpha << BS_ASHIFT;
|
|
if (newModulationColor != _modulationColor) {
|
|
_modulationColor = newModulationColor;
|
|
forceRefresh();
|
|
}
|
|
}
|
|
|
|
void Animation::setModulationColor(uint modulationColor) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
if (!animationDescriptionPtr->isColorModulationAllowed()) {
|
|
warning("Tried to set modulation color on an animation that does not support color modulation. Call was ignored");
|
|
return;
|
|
}
|
|
|
|
uint newModulationColor = (modulationColor & BS_RGBMASK) | (_modulationColor & BS_AMASK);
|
|
if (newModulationColor != _modulationColor) {
|
|
_modulationColor = newModulationColor;
|
|
forceRefresh();
|
|
}
|
|
}
|
|
|
|
void Animation::setScaleFactor(float scaleFactor) {
|
|
setScaleFactorX(scaleFactor);
|
|
setScaleFactorY(scaleFactor);
|
|
}
|
|
|
|
void Animation::setScaleFactorX(float scaleFactorX) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
if (!animationDescriptionPtr->isScalingAllowed()) {
|
|
warning("Tried to set x scale factor on an animation that does not support scaling. Call was ignored");
|
|
return;
|
|
}
|
|
|
|
if (scaleFactorX != _scaleFactorX) {
|
|
_scaleFactorX = scaleFactorX;
|
|
if (_scaleFactorX <= 0.0f)
|
|
_scaleFactorX = 0.001f;
|
|
forceRefresh();
|
|
computeCurrentCharacteristics();
|
|
}
|
|
}
|
|
|
|
void Animation::setScaleFactorY(float scaleFactorY) {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
if (!animationDescriptionPtr->isScalingAllowed()) {
|
|
warning("Tried to set y scale factor on an animation that does not support scaling. Call was ignored");
|
|
return;
|
|
}
|
|
|
|
if (scaleFactorY != _scaleFactorY) {
|
|
_scaleFactorY = scaleFactorY;
|
|
if (_scaleFactorY <= 0.0f)
|
|
_scaleFactorY = 0.001f;
|
|
forceRefresh();
|
|
computeCurrentCharacteristics();
|
|
}
|
|
}
|
|
|
|
const Common::String &Animation::getCurrentAction() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
return animationDescriptionPtr->getFrame(_currentFrame).action;
|
|
}
|
|
|
|
int Animation::getX() const {
|
|
return _relX;
|
|
}
|
|
|
|
int Animation::getY() const {
|
|
return _relY;
|
|
}
|
|
|
|
int Animation::getAbsoluteX() const {
|
|
return _absoluteX + (_relX - _x);
|
|
}
|
|
|
|
int Animation::getAbsoluteY() const {
|
|
return _absoluteY + (_relY - _y);
|
|
}
|
|
|
|
int Animation::computeXModifier() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
const AnimationResource::Frame &curFrame = animationDescriptionPtr->getFrame(_currentFrame);
|
|
|
|
Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(curFrame.fileName);
|
|
assert(pResource);
|
|
assert(pResource->getType() == Resource::TYPE_BITMAP);
|
|
BitmapResource *pBitmap = static_cast<BitmapResource *>(pResource);
|
|
|
|
int result = curFrame.flipV ? - static_cast<int>((pBitmap->getWidth() - 1 - curFrame.hotspotX) * _scaleFactorX) :
|
|
- static_cast<int>(curFrame.hotspotX * _scaleFactorX);
|
|
|
|
pBitmap->release();
|
|
|
|
return result;
|
|
}
|
|
|
|
int Animation::computeYModifier() const {
|
|
AnimationDescription *animationDescriptionPtr = getAnimationDescription();
|
|
assert(animationDescriptionPtr);
|
|
const AnimationResource::Frame &curFrame = animationDescriptionPtr->getFrame(_currentFrame);
|
|
|
|
Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource(curFrame.fileName);
|
|
assert(pResource);
|
|
assert(pResource->getType() == Resource::TYPE_BITMAP);
|
|
BitmapResource *pBitmap = static_cast<BitmapResource *>(pResource);
|
|
|
|
int result = curFrame.flipH ? - static_cast<int>((pBitmap->getHeight() - 1 - curFrame.hotspotY) * _scaleFactorY) :
|
|
- static_cast<int>(curFrame.hotspotY * _scaleFactorY);
|
|
|
|
pBitmap->release();
|
|
|
|
return result;
|
|
}
|
|
|
|
bool Animation::persist(OutputPersistenceBlock &writer) {
|
|
bool result = true;
|
|
|
|
result &= RenderObject::persist(writer);
|
|
|
|
writer.write(_relX);
|
|
writer.write(_relY);
|
|
writer.write(_scaleFactorX);
|
|
writer.write(_scaleFactorY);
|
|
writer.write(_modulationColor);
|
|
writer.write(_currentFrame);
|
|
writer.write(_currentFrameTime);
|
|
writer.write(_running);
|
|
writer.write(_finished);
|
|
writer.write(static_cast<uint32>(_direction));
|
|
|
|
// Je nach Animationstyp entweder das Template oder die Ressource speichern.
|
|
if (_animationResourcePtr) {
|
|
uint32 marker = 0;
|
|
writer.write(marker);
|
|
writer.writeString(_animationResourcePtr->getFileName());
|
|
} else if (_animationTemplateHandle) {
|
|
uint32 marker = 1;
|
|
writer.write(marker);
|
|
writer.write(_animationTemplateHandle);
|
|
} else {
|
|
assert(false);
|
|
}
|
|
|
|
//writer.write(_AnimationDescriptionPtr);
|
|
|
|
writer.write(_framesLocked);
|
|
|
|
// The following is only there to for compatibility with older saves
|
|
// resp. the original engine.
|
|
writer.write((uint32)1);
|
|
writer.writeString("LuaLoopPointCB");
|
|
writer.write(getHandle());
|
|
writer.write((uint32)1);
|
|
writer.writeString("LuaActionCB");
|
|
writer.write(getHandle());
|
|
writer.write((uint32)1);
|
|
writer.writeString("LuaDeleteCB");
|
|
writer.write(getHandle());
|
|
|
|
result &= RenderObject::persistChildren(writer);
|
|
|
|
return result;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
bool Animation::unpersist(InputPersistenceBlock &reader) {
|
|
bool result = true;
|
|
|
|
result &= RenderObject::unpersist(reader);
|
|
|
|
reader.read(_relX);
|
|
reader.read(_relY);
|
|
reader.read(_scaleFactorX);
|
|
reader.read(_scaleFactorY);
|
|
reader.read(_modulationColor);
|
|
reader.read(_currentFrame);
|
|
reader.read(_currentFrameTime);
|
|
reader.read(_running);
|
|
reader.read(_finished);
|
|
uint32 direction;
|
|
reader.read(direction);
|
|
_direction = static_cast<Direction>(direction);
|
|
|
|
// Animationstyp einlesen.
|
|
uint32 marker;
|
|
reader.read(marker);
|
|
if (marker == 0) {
|
|
Common::String resourceFilename;
|
|
reader.readString(resourceFilename);
|
|
initializeAnimationResource(resourceFilename);
|
|
} else if (marker == 1) {
|
|
reader.read(_animationTemplateHandle);
|
|
} else {
|
|
assert(false);
|
|
}
|
|
|
|
reader.read(_framesLocked);
|
|
if (_framesLocked)
|
|
lockAllFrames();
|
|
|
|
|
|
// The following is only there to for compatibility with older saves
|
|
// resp. the original engine.
|
|
uint32 callbackCount;
|
|
Common::String callbackFunctionName;
|
|
uint32 callbackData;
|
|
|
|
// loop point callback
|
|
reader.read(callbackCount);
|
|
assert(callbackCount == 1);
|
|
reader.readString(callbackFunctionName);
|
|
assert(callbackFunctionName == "LuaLoopPointCB");
|
|
reader.read(callbackData);
|
|
assert(callbackData == getHandle());
|
|
|
|
// loop point callback
|
|
reader.read(callbackCount);
|
|
assert(callbackCount == 1);
|
|
reader.readString(callbackFunctionName);
|
|
assert(callbackFunctionName == "LuaActionCB");
|
|
reader.read(callbackData);
|
|
assert(callbackData == getHandle());
|
|
|
|
// loop point callback
|
|
reader.read(callbackCount);
|
|
assert(callbackCount == 1);
|
|
reader.readString(callbackFunctionName);
|
|
assert(callbackFunctionName == "LuaDeleteCB");
|
|
reader.read(callbackData);
|
|
assert(callbackData == getHandle());
|
|
|
|
// Set the callbacks
|
|
setCallbacks();
|
|
|
|
result &= RenderObject::unpersistChildren(reader);
|
|
|
|
return reader.isGood() && result;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
AnimationDescription *Animation::getAnimationDescription() const {
|
|
if (_animationResourcePtr)
|
|
return _animationResourcePtr;
|
|
else
|
|
return AnimationTemplateRegistry::instance().resolveHandle(_animationTemplateHandle);
|
|
}
|
|
|
|
} // End of namespace Sword25
|