Initial commit
This commit is contained in:
677
engines/stark/resources/anim.cpp
Normal file
677
engines/stark/resources/anim.cpp
Normal file
@@ -0,0 +1,677 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include "engines/stark/debug.h"
|
||||
#include "engines/stark/formats/biffmesh.h"
|
||||
#include "engines/stark/formats/tm.h"
|
||||
#include "engines/stark/formats/xrc.h"
|
||||
|
||||
#include "engines/stark/gfx/driver.h"
|
||||
#include "engines/stark/resources/anim.h"
|
||||
#include "engines/stark/resources/animscript.h"
|
||||
#include "engines/stark/resources/bonesmesh.h"
|
||||
#include "engines/stark/resources/direction.h"
|
||||
#include "engines/stark/resources/image.h"
|
||||
#include "engines/stark/resources/item.h"
|
||||
#include "engines/stark/resources/location.h"
|
||||
#include "engines/stark/resources/textureset.h"
|
||||
|
||||
#include "engines/stark/services/archiveloader.h"
|
||||
#include "engines/stark/services/global.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/settings.h"
|
||||
#include "engines/stark/services/stateprovider.h"
|
||||
|
||||
#include "engines/stark/model/animhandler.h"
|
||||
#include "engines/stark/model/skeleton_anim.h"
|
||||
#include "engines/stark/visual/actor.h"
|
||||
#include "engines/stark/visual/prop.h"
|
||||
#include "engines/stark/visual/smacker.h"
|
||||
|
||||
namespace Stark {
|
||||
namespace Resources {
|
||||
|
||||
Object *Anim::construct(Object *parent, byte subType, uint16 index, const Common::String &name) {
|
||||
switch (subType) {
|
||||
case kAnimImages:
|
||||
return new AnimImages(parent, subType, index, name);
|
||||
case kAnimProp:
|
||||
return new AnimProp(parent, subType, index, name);
|
||||
case kAnimVideo:
|
||||
return new AnimVideo(parent, subType, index, name);
|
||||
case kAnimSkeleton:
|
||||
return new AnimSkeleton(parent, subType, index, name);
|
||||
default:
|
||||
error("Unknown anim subtype %d", subType);
|
||||
}
|
||||
}
|
||||
|
||||
Anim::~Anim() {
|
||||
}
|
||||
|
||||
Anim::Anim(Object *parent, byte subType, uint16 index, const Common::String &name) :
|
||||
Object(parent, subType, index, name),
|
||||
_activity(0),
|
||||
_currentFrame(0),
|
||||
_numFrames(0),
|
||||
_refCount(0) {
|
||||
_type = TYPE;
|
||||
}
|
||||
|
||||
void Anim::readData(Formats::XRCReadStream *stream) {
|
||||
_activity = stream->readUint32LE();
|
||||
_numFrames = stream->readUint32LE();
|
||||
}
|
||||
|
||||
void Anim::selectFrame(uint32 frameIndex) {
|
||||
}
|
||||
|
||||
uint32 Anim::getActivity() const {
|
||||
return _activity;
|
||||
}
|
||||
|
||||
void Anim::applyToItem(Item *item) {
|
||||
_refCount++;
|
||||
}
|
||||
void Anim::removeFromItem(Item *item) {
|
||||
_refCount--;
|
||||
}
|
||||
|
||||
bool Anim::isInUse() const {
|
||||
return _refCount > 0;
|
||||
}
|
||||
|
||||
int Anim::getPointHotspotIndex(const Common::Point &point) const {
|
||||
// Most anim types only have one hotspot
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Anim::playAsAction(ItemVisual *item) {
|
||||
AnimScript *animScript = findChild<AnimScript>();
|
||||
animScript->goToScriptItem(0);
|
||||
}
|
||||
|
||||
bool Anim::isAtTime(uint32 time) const {
|
||||
warning("Anim::isAtTime is not implemented");
|
||||
return true;
|
||||
}
|
||||
|
||||
void Anim::shouldResetItem(bool resetItem) {
|
||||
// Script animations don't keep track of the item
|
||||
}
|
||||
|
||||
void Anim::resetItem() {
|
||||
// Script animations don't keep track of the item
|
||||
}
|
||||
|
||||
bool Anim::isDone() const {
|
||||
AnimScript *animScript = findChild<AnimScript>();
|
||||
return animScript->isDone();
|
||||
}
|
||||
|
||||
uint32 Anim::getMovementSpeed() const {
|
||||
return 100;
|
||||
}
|
||||
|
||||
uint32 Anim::getIdleActionFrequency() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Anim::printData() {
|
||||
debug("activity: %d", _activity);
|
||||
debug("numFrames: %d", _numFrames);
|
||||
}
|
||||
|
||||
AnimImages::~AnimImages() {
|
||||
}
|
||||
|
||||
AnimImages::AnimImages(Object *parent, byte subType, uint16 index, const Common::String &name) :
|
||||
Anim(parent, subType, index, name),
|
||||
_field_3C(0),
|
||||
_currentDirection(0),
|
||||
_currentFrameImage(nullptr) {
|
||||
}
|
||||
|
||||
void AnimImages::readData(Formats::XRCReadStream *stream) {
|
||||
Anim::readData(stream);
|
||||
|
||||
_field_3C = stream->readFloatLE();
|
||||
}
|
||||
|
||||
void AnimImages::onAllLoaded() {
|
||||
Anim::onAllLoaded();
|
||||
|
||||
_directions = listChildren<Direction>();
|
||||
}
|
||||
|
||||
void AnimImages::selectFrame(uint32 frameIndex) {
|
||||
if (frameIndex > _numFrames) {
|
||||
// The original silently ignores this as well
|
||||
warning("Request for frame %d for anim '%s' has been ignored, it is above max frame %d", frameIndex, getName().c_str(), _numFrames);
|
||||
_currentFrame = 0;
|
||||
}
|
||||
|
||||
_currentFrame = frameIndex;
|
||||
}
|
||||
|
||||
Visual *AnimImages::getVisual() {
|
||||
Direction *direction = _directions[_currentDirection];
|
||||
_currentFrameImage = direction->findChildWithIndex<Image>(_currentFrame);
|
||||
return _currentFrameImage->getVisual();
|
||||
}
|
||||
|
||||
void AnimImages::printData() {
|
||||
Anim::printData();
|
||||
|
||||
debug("field_3C: %f", _field_3C);
|
||||
}
|
||||
|
||||
int AnimImages::getPointHotspotIndex(const Common::Point &point) const {
|
||||
if (_currentFrameImage) {
|
||||
return _currentFrameImage->indexForPoint(point);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Common::Point AnimImages::getHotspotPosition(uint index) const {
|
||||
if (_currentFrameImage) {
|
||||
return _currentFrameImage->getHotspotPosition(index);
|
||||
}
|
||||
return Common::Point(-1, -1);
|
||||
}
|
||||
|
||||
void AnimImages::saveLoad(ResourceSerializer *serializer) {
|
||||
Anim::saveLoad(serializer);
|
||||
|
||||
serializer->syncAsUint32LE(_currentFrame);
|
||||
|
||||
if (serializer->isLoading()) {
|
||||
selectFrame(_currentFrame);
|
||||
}
|
||||
}
|
||||
|
||||
AnimProp::~AnimProp() {
|
||||
delete _visual;
|
||||
}
|
||||
|
||||
AnimProp::AnimProp(Object *parent, byte subType, uint16 index, const Common::String &name) :
|
||||
Anim(parent, subType, index, name),
|
||||
_movementSpeed(100) {
|
||||
_visual = StarkGfx->createPropRenderer();
|
||||
}
|
||||
|
||||
Visual *AnimProp::getVisual() {
|
||||
return _visual;
|
||||
}
|
||||
|
||||
uint32 AnimProp::getMovementSpeed() const {
|
||||
return _movementSpeed;
|
||||
}
|
||||
|
||||
void AnimProp::readData(Formats::XRCReadStream *stream) {
|
||||
Anim::readData(stream);
|
||||
|
||||
_field_3C = stream->readString();
|
||||
|
||||
uint32 meshCount = stream->readUint32LE();
|
||||
for (uint i = 0; i < meshCount; i++) {
|
||||
_meshFilenames.push_back(Common::Path(stream->readString()));
|
||||
}
|
||||
|
||||
_textureFilename = stream->readString();
|
||||
_movementSpeed = stream->readUint32LE();
|
||||
_archiveName = stream->getArchiveName();
|
||||
}
|
||||
|
||||
void AnimProp::onPostRead() {
|
||||
if (_meshFilenames.size() != 1) {
|
||||
error("Unexpected mesh count in prop anim: '%d'", _meshFilenames.size());
|
||||
}
|
||||
|
||||
ArchiveReadStream *stream = StarkArchiveLoader->getFile(_meshFilenames[0], _archiveName);
|
||||
_visual->setModel(Formats::BiffMeshReader::read(stream));
|
||||
delete stream;
|
||||
|
||||
stream = StarkArchiveLoader->getFile(_textureFilename, _archiveName);
|
||||
_visual->setTexture(Formats::TextureSetReader::read(stream));
|
||||
delete stream;
|
||||
}
|
||||
|
||||
void AnimProp::printData() {
|
||||
Anim::printData();
|
||||
|
||||
debug("field_3C: %s", _field_3C.c_str());
|
||||
|
||||
Common::String description;
|
||||
for (uint32 i = 0; i < _meshFilenames.size(); i++) {
|
||||
debug("meshFilename[%d]: %s", i, _meshFilenames[i].toString().c_str());
|
||||
}
|
||||
debug("textureFilename: %s", _textureFilename.toString().c_str());
|
||||
debug("movementSpeed: %d", _movementSpeed);
|
||||
}
|
||||
|
||||
AnimVideo::~AnimVideo() {
|
||||
delete _smacker;
|
||||
}
|
||||
|
||||
AnimVideo::AnimVideo(Object *parent, byte subType, uint16 index, const Common::String &name) :
|
||||
Anim(parent, subType, index, name),
|
||||
_width(0),
|
||||
_height(0),
|
||||
_smacker(nullptr),
|
||||
_frameRateOverride(-1),
|
||||
_preload(false),
|
||||
_loop(false),
|
||||
_actionItem(nullptr),
|
||||
_shouldResetItem(true),
|
||||
_done(false) {
|
||||
}
|
||||
|
||||
void AnimVideo::readData(Formats::XRCReadStream *stream) {
|
||||
Anim::readData(stream);
|
||||
_smackerFile = stream->readString();
|
||||
_width = stream->readUint32LE();
|
||||
_height = stream->readUint32LE();
|
||||
|
||||
_positions.clear();
|
||||
_sizes.clear();
|
||||
|
||||
uint32 size = stream->readUint32LE();
|
||||
for (uint i = 0; i < size; i++) {
|
||||
_positions.push_back(stream->readPoint());
|
||||
_sizes.push_back(stream->readRect());
|
||||
}
|
||||
|
||||
_loop = stream->readBool();
|
||||
_frameRateOverride = stream->readUint32LE();
|
||||
|
||||
if (stream->isDataLeft()) {
|
||||
_preload = stream->readBool();
|
||||
}
|
||||
|
||||
_archiveName = stream->getArchiveName();
|
||||
|
||||
// WORKAROUND: Fix the position of various items being incorrect in the game datafiles
|
||||
Location *location = findParent<Location>();
|
||||
if (_name == "Mountain comes down" && location && location->getName() == "Below Floating Mountain") {
|
||||
for (uint i = 0; i < _sizes.size(); i++) {
|
||||
_positions[i].x = 352;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimVideo::onAllLoaded() {
|
||||
if (!_smacker) {
|
||||
|
||||
_smacker = new VisualSmacker(StarkGfx);
|
||||
|
||||
Common::SeekableReadStream *overrideStreamBink = nullptr;
|
||||
Common::SeekableReadStream *overrideStreamSmacker = nullptr;
|
||||
if (StarkSettings->isAssetsModEnabled() && StarkGfx->supportsModdedAssets()) {
|
||||
overrideStreamBink = openOverrideFile(".bik");
|
||||
if (!overrideStreamBink) {
|
||||
overrideStreamSmacker = openOverrideFile(".smk");
|
||||
}
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *stream = StarkArchiveLoader->getExternalFile(_smackerFile, _archiveName);
|
||||
if (overrideStreamBink) {
|
||||
_smacker->loadBink(overrideStreamBink);
|
||||
_smacker->readOriginalSize(stream);
|
||||
} else if (overrideStreamSmacker) {
|
||||
_smacker->loadSmacker(overrideStreamSmacker);
|
||||
_smacker->readOriginalSize(stream);
|
||||
} else {
|
||||
_smacker->loadSmacker(stream);
|
||||
}
|
||||
|
||||
_smacker->overrideFrameRate(_frameRateOverride);
|
||||
|
||||
updateSmackerPosition();
|
||||
}
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *AnimVideo::openOverrideFile(const Common::String &extension) const {
|
||||
Common::String baseName(_smackerFile.baseName());
|
||||
if (!baseName.hasSuffixIgnoreCase(".sss")) {
|
||||
return nullptr;
|
||||
}
|
||||
baseName = Common::String(baseName.c_str(), baseName.size() - 4) + extension;
|
||||
|
||||
Common::Path filePath(_smackerFile.getParent().appendComponent(baseName));
|
||||
filePath = StarkArchiveLoader->getExternalFilePath(filePath, _archiveName);
|
||||
|
||||
debugC(kDebugModding, "Attempting to load %s", filePath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
|
||||
Common::SeekableReadStream *smkStream = SearchMan.createReadStreamForMember(filePath);
|
||||
if (!smkStream) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
debugC(kDebugModding, "Loaded %s", filePath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
|
||||
return smkStream;
|
||||
}
|
||||
|
||||
void AnimVideo::onGameLoop() {
|
||||
if (!_smacker || !isInUse()) {
|
||||
return; // Animation not in use, no need to update the movie
|
||||
}
|
||||
|
||||
if (_smacker->isDone()) {
|
||||
// The last frame has been reached
|
||||
_done = true;
|
||||
|
||||
if (_shouldResetItem) {
|
||||
resetItem();
|
||||
}
|
||||
|
||||
if (_loop) {
|
||||
_smacker->rewind();
|
||||
}
|
||||
}
|
||||
|
||||
if (!_smacker->isDone()) {
|
||||
_smacker->update();
|
||||
updateSmackerPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimVideo::resetItem() {
|
||||
if (!_loop && _actionItem) {
|
||||
// Reset our item if needed
|
||||
if (_actionItem->getActionAnim() == this) {
|
||||
_actionItem->resetActionAnim();
|
||||
}
|
||||
_actionItem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimVideo::onEnginePause(bool pause) {
|
||||
Object::onEnginePause(pause);
|
||||
|
||||
if (_smacker && isInUse()) {
|
||||
_smacker->pause(pause);
|
||||
}
|
||||
}
|
||||
|
||||
Visual *AnimVideo::getVisual() {
|
||||
return _smacker;
|
||||
}
|
||||
|
||||
void AnimVideo::updateSmackerPosition() {
|
||||
int frame = _smacker->getFrameNumber();
|
||||
if (frame == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame < (int) _positions.size()) {
|
||||
_smacker->setPosition(_positions[frame]);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimVideo::shouldResetItem(bool resetItem) {
|
||||
_shouldResetItem = resetItem;
|
||||
}
|
||||
|
||||
void AnimVideo::playAsAction(ItemVisual *item) {
|
||||
_actionItem = item;
|
||||
_shouldResetItem = true;
|
||||
_done = false;
|
||||
|
||||
if (!_loop) {
|
||||
_smacker->rewind();
|
||||
}
|
||||
|
||||
// Update here so we have something up to date to show when rendering this frame
|
||||
_smacker->update();
|
||||
}
|
||||
|
||||
bool AnimVideo::isAtTime(uint32 time) const {
|
||||
uint32 currentTime = _smacker->getCurrentTime();
|
||||
return currentTime >= time;
|
||||
}
|
||||
|
||||
void AnimVideo::saveLoadCurrent(ResourceSerializer *serializer) {
|
||||
Anim::saveLoadCurrent(serializer);
|
||||
|
||||
int32 frameNumber = _smacker->getFrameNumber();
|
||||
serializer->syncAsSint32LE(frameNumber);
|
||||
serializer->syncAsSint32LE(_refCount);
|
||||
|
||||
// TODO: Seek to the saved frame number when loading
|
||||
}
|
||||
|
||||
void AnimVideo::printData() {
|
||||
Anim::printData();
|
||||
|
||||
debug("smackerFile: %s", _smackerFile.toString().c_str());
|
||||
debug("size: x %d, y %d", _width, _height);
|
||||
|
||||
Common::String description;
|
||||
for (uint32 i = 0; i < _positions.size(); i++) {
|
||||
description += Common::String::format("(x %d, y %d) ", _positions[i].x, _positions[i].y);
|
||||
}
|
||||
debug("positions: %s", description.c_str());
|
||||
|
||||
description.clear();
|
||||
for (uint32 i = 0; i < _sizes.size(); i++) {
|
||||
description += Common::String::format("(l %d, t %d, r %d, b %d) ",
|
||||
_sizes[i].left, _sizes[i].top, _sizes[i].right, _sizes[i].bottom);
|
||||
}
|
||||
debug("sizes: %s", description.c_str());
|
||||
|
||||
debug("frameRateOverride: %d", _frameRateOverride);
|
||||
debug("preload: %d", _preload);
|
||||
debug("loop: %d", _loop);
|
||||
}
|
||||
|
||||
AnimSkeleton::~AnimSkeleton() {
|
||||
delete _visual;
|
||||
delete _skeletonAnim;
|
||||
}
|
||||
|
||||
AnimSkeleton::AnimSkeleton(Object *parent, byte subType, uint16 index, const Common::String &name) :
|
||||
Anim(parent, subType, index, name),
|
||||
_castsShadow(true),
|
||||
_loop(false),
|
||||
_movementSpeed(100),
|
||||
_idleActionFrequency(1),
|
||||
_skeletonAnim(nullptr),
|
||||
_currentTime(0),
|
||||
_totalTime(0),
|
||||
_done(false),
|
||||
_actionItem(nullptr),
|
||||
_shouldResetItem(true) {
|
||||
_visual = StarkGfx->createActorRenderer();
|
||||
}
|
||||
|
||||
void AnimSkeleton::applyToItem(Item *item) {
|
||||
Anim::applyToItem(item);
|
||||
|
||||
if (!_loop) {
|
||||
_currentTime = 0;
|
||||
}
|
||||
|
||||
if (_currentTime > _totalTime) {
|
||||
_currentTime = 0;
|
||||
}
|
||||
|
||||
debugC(kDebugAnimation, "%s: add %s", item->getName().c_str(), getName().c_str());
|
||||
|
||||
ModelItem *modelItem = Object::cast<ModelItem>(item);
|
||||
|
||||
BonesMesh *mesh = modelItem->findBonesMesh();
|
||||
TextureSet *texture = modelItem->findTextureSet(TextureSet::kTextureNormal);
|
||||
|
||||
AnimHandler *animHandler = modelItem->getAnimHandler();
|
||||
animHandler->setModel(mesh->getModel());
|
||||
animHandler->setAnim(_skeletonAnim);
|
||||
|
||||
_visual->setModel(mesh->getModel());
|
||||
_visual->setAnimHandler(animHandler);
|
||||
_visual->setTexture(texture->getTexture());
|
||||
_visual->setTextureFacial(nullptr);
|
||||
_visual->setTime(_currentTime);
|
||||
_visual->setCastShadow(_castsShadow);
|
||||
}
|
||||
|
||||
void AnimSkeleton::removeFromItem(Item *item) {
|
||||
Anim::removeFromItem(item);
|
||||
|
||||
debugC(kDebugAnimation, "%s: remove %s", item->getName().c_str(), getName().c_str());
|
||||
|
||||
_actionItem = nullptr;
|
||||
}
|
||||
|
||||
Visual *AnimSkeleton::getVisual() {
|
||||
return _visual;
|
||||
}
|
||||
|
||||
void AnimSkeleton::readData(Formats::XRCReadStream *stream) {
|
||||
Anim::readData(stream);
|
||||
|
||||
_animFilename = stream->readString();
|
||||
stream->readString(); // Skipped in the original
|
||||
stream->readString(); // Skipped in the original
|
||||
stream->readString(); // Skipped in the original
|
||||
|
||||
_loop = stream->readBool();
|
||||
_movementSpeed = stream->readUint32LE();
|
||||
|
||||
if (_movementSpeed < 1) {
|
||||
_movementSpeed = 100;
|
||||
}
|
||||
|
||||
if (stream->isDataLeft()) {
|
||||
_castsShadow = stream->readBool();
|
||||
} else {
|
||||
_castsShadow = true;
|
||||
}
|
||||
|
||||
if (stream->isDataLeft()) {
|
||||
_idleActionFrequency = stream->readUint32LE();
|
||||
} else {
|
||||
_idleActionFrequency = 1;
|
||||
}
|
||||
|
||||
_archiveName = stream->getArchiveName();
|
||||
}
|
||||
|
||||
void AnimSkeleton::onPostRead() {
|
||||
ArchiveReadStream *stream = StarkArchiveLoader->getFile(_animFilename, _archiveName);
|
||||
|
||||
_skeletonAnim = new SkeletonAnim();
|
||||
_skeletonAnim->createFromStream(stream);
|
||||
|
||||
delete stream;
|
||||
}
|
||||
|
||||
void AnimSkeleton::onAllLoaded() {
|
||||
Anim::onAllLoaded();
|
||||
|
||||
_totalTime = _skeletonAnim->getLength();
|
||||
_currentTime = 0;
|
||||
}
|
||||
|
||||
void AnimSkeleton::onGameLoop() {
|
||||
Anim::onGameLoop();
|
||||
|
||||
if (isInUse() && _totalTime) {
|
||||
uint32 newTime = _currentTime + StarkGlobal->getMillisecondsPerGameloop();
|
||||
|
||||
if (!_loop && newTime >= _totalTime) {
|
||||
_done = true;
|
||||
|
||||
if (_shouldResetItem) {
|
||||
resetItem();
|
||||
}
|
||||
} else {
|
||||
_currentTime = newTime % _totalTime;
|
||||
_visual->setTime(_currentTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimSkeleton::resetItem() {
|
||||
if (_actionItem) {
|
||||
if (_actionItem->getActionAnim() == this) {
|
||||
_actionItem->resetActionAnim();
|
||||
}
|
||||
_actionItem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimSkeleton::onPreDestroy() {
|
||||
resetItem();
|
||||
|
||||
Anim::onPreDestroy();
|
||||
}
|
||||
|
||||
uint32 AnimSkeleton::getMovementSpeed() const {
|
||||
return _movementSpeed;
|
||||
}
|
||||
|
||||
uint32 AnimSkeleton::getCurrentTime() const {
|
||||
return _currentTime;
|
||||
}
|
||||
|
||||
uint32 AnimSkeleton::getRemainingTime() const {
|
||||
int32 remainingTime = _totalTime - _currentTime;
|
||||
return CLIP<int32>(remainingTime, 0, _totalTime);
|
||||
}
|
||||
|
||||
void AnimSkeleton::shouldResetItem(bool resetItem) {
|
||||
_shouldResetItem = resetItem;
|
||||
}
|
||||
|
||||
void AnimSkeleton::playAsAction(ItemVisual *item) {
|
||||
_actionItem = item;
|
||||
_done = false;
|
||||
_shouldResetItem = true;
|
||||
|
||||
if (!_loop) {
|
||||
_currentTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool AnimSkeleton::isAtTime(uint32 time) const {
|
||||
return _currentTime >= time;
|
||||
}
|
||||
|
||||
uint32 AnimSkeleton::getIdleActionFrequency() const {
|
||||
return _idleActionFrequency;
|
||||
}
|
||||
|
||||
void AnimSkeleton::printData() {
|
||||
Anim::printData();
|
||||
|
||||
debug("filename: %s", _animFilename.toString().c_str());
|
||||
debug("castsShadow: %d", _castsShadow);
|
||||
debug("loop: %d", _loop);
|
||||
debug("movementSpeed: %d", _movementSpeed);
|
||||
debug("idleActionFrequency: %d", _idleActionFrequency);
|
||||
}
|
||||
|
||||
} // End of namespace Resources
|
||||
} // End of namespace Stark
|
||||
Reference in New Issue
Block a user