mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-22 10:17:22 +00:00
682 lines
20 KiB
C++
682 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 2
|
||
* 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, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
*
|
||
*/
|
||
|
||
/*
|
||
* 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<47><72>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 = 0xffffffff;
|
||
_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 <20>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<47><72>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<47><72>e des Bitmaps auf die Animation <20>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 & 0x00ffffff) | alpha << 24;
|
||
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 & 0x00ffffff) | (_modulationColor & 0xff000000);
|
||
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
|