From 5934ccd184a302720103f7e803bdf4c9157db54b Mon Sep 17 00:00:00 2001 From: Sylvain Dupont Date: Sun, 30 Jan 2011 02:18:53 +0000 Subject: TOON: Fix the last known z-order issues Rewrote the Z-order management, it's now very close to the original code svn-id: r55650 --- engines/toon/anim.cpp | 57 ++++++++++++++++++++++++++++++-------------- engines/toon/anim.h | 2 ++ engines/toon/script_func.cpp | 16 +++++++++---- engines/toon/toon.cpp | 27 ++++++++++----------- 4 files changed, 65 insertions(+), 37 deletions(-) (limited to 'engines/toon') diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp index 00cfdad9cc..bb5a1e7dbc 100644 --- a/engines/toon/anim.cpp +++ b/engines/toon/anim.cpp @@ -604,6 +604,8 @@ void AnimationInstance::setZ(int32 z, bool relative) { void AnimationInstance::setLayerZ(int32 z) { _layerZ = z; + if (_vm->getAnimationManager()->hasInstance(this)) + _vm->getAnimationManager()->updateInstance(this); } int32 AnimationInstance::getLayerZ() const { @@ -678,8 +680,44 @@ void AnimationInstance::reset() { AnimationManager::AnimationManager(ToonEngine *vm) : _vm(vm) { } +bool AnimationManager::hasInstance(AnimationInstance* instance) { + for (uint32 i = 0; i < _instances.size(); i++) { + if(_instances[i] == instance) + return true; + } + return false; +} + +void AnimationManager::updateInstance(AnimationInstance* instance) { + // simply remove and readd the instance in the ordered list + removeInstance(instance); + addInstance(instance); +} + void AnimationManager::addInstance(AnimationInstance *instance) { - _instances.push_back(instance); + + // if the instance already exists, we skip the add + for (uint32 i = 0; i < _instances.size(); i++) { + if(_instances[i] == instance) + return; + } + + int found = -1; + + // here we now do an ordered insert (closer to the original game) + for (uint32 i = 0; i < _instances.size(); i++) { + if (_instances[i]->getLayerZ() >= instance->getLayerZ()) { + found = i; + break; + } + } + + if ( found == -1 ) { + _instances.push_back(instance); + } else { + _instances.insert_at(found, instance); + } + } void AnimationManager::removeInstance(AnimationInstance *instance) { @@ -712,23 +750,6 @@ void AnimationManager::update(int32 timeIncrement) { void AnimationManager::render() { debugC(5, kDebugAnim, "render()"); - // sort the instance by layer z - // bubble sort (replace by faster afterwards) - bool changed = true; - while (changed) { - changed = false; - for (uint32 i = 0; i < _instances.size() - 1; i++) { - if ((_instances[i]->getLayerZ() > _instances[i + 1]->getLayerZ()) || - ((_instances[i]->getLayerZ() == _instances[i + 1]->getLayerZ()) && - (_instances[i]->getId() < _instances[i+1]->getId()))) { - AnimationInstance *instance = _instances[i]; - _instances[i] = _instances[i + 1]; - _instances[i + 1] = instance; - changed = true; - } - } - } - for (uint32 i = 0; i < _instances.size(); i++) { if (_instances[i]->getVisible()) _instances[i]->render(); diff --git a/engines/toon/anim.h b/engines/toon/anim.h index 8c5d63dd41..d7f64ab687 100644 --- a/engines/toon/anim.h +++ b/engines/toon/anim.h @@ -161,9 +161,11 @@ public: AnimationInstance *createNewInstance(AnimationInstanceType type); void addInstance(AnimationInstance *instance); void removeInstance(AnimationInstance *instance); + void updateInstance(AnimationInstance* instance); void removeAllInstances(AnimationInstanceType type); void render(); void update(int32 timeIncrement); + bool hasInstance(AnimationInstance* instance); protected: ToonEngine *_vm; diff --git a/engines/toon/script_func.cpp b/engines/toon/script_func.cpp index 2e727f2ab5..67e20f3354 100644 --- a/engines/toon/script_func.cpp +++ b/engines/toon/script_func.cpp @@ -941,7 +941,7 @@ int32 ScriptFunc::sys_Cmd_Init_Scene_Anim(EMCState *state) { sceneAnim->_animInstance->setAnimationRange(stackPos(11), stackPos(11)); sceneAnim->_animInstance->setFrame(stackPos(11)); - _vm->getAnimationManager()->addInstance(sceneAnim->_animInstance); + debugC(0, 0xfff, "Init Anim %s %d %d %d %d %d %d %d %d %d %d %d %d %d\n", GetText(12, state), stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPos(12)); @@ -977,9 +977,12 @@ int32 ScriptFunc::sys_Cmd_Init_Scene_Anim(EMCState *state) { } sceneAnim->_animInstance->setId(stackPos(0)); - - sceneAnim->_active = true; + + // add the animation to the list only if it's already visible + if (flags & 1) { + _vm->getAnimationManager()->addInstance(sceneAnim->_animInstance); + } return 0; } @@ -989,9 +992,14 @@ int32 ScriptFunc::sys_Cmd_Set_Scene_Animation_Active_Flag(EMCState *state) { SceneAnimation *sceneAnim = _vm->getSceneAnimation(animId); - if (sceneAnim->_active) + if (sceneAnim->_active) { sceneAnim->_animInstance->setVisible(activeFlag > 0); + if(activeFlag) { + _vm->getAnimationManager()->addInstance(sceneAnim->_animInstance); + } + } + return 0; } diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 4c377220d1..61b558ca6c 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -3118,22 +3118,15 @@ bool ToonEngine::loadGame(int32 slot) { _sceneAnimations[i].load(this, loadFile); } - _gameState->_timerTimeout[0] += timerDiff; - _gameState->_timerTimeout[1] += timerDiff; - - /* - int32 diff = _conversationData - _gameState->_conversationData; - - for (int32 i = 0; i < 60; i++) { - if (_gameState->_conversationState[i]._enable) { - // we have to fix up our pointers... - for (int32 a = 0; a < 10; a++) { - if (_gameState->_conversationState[i].state[a]._data4) - _gameState->_conversationState[i].state[a]._data4 = (int16 *)_gameState->_conversationState[i].state[a]._data4 + diff; - } + // scene animations have to be added in reverse order in animation manager to preserve the z order + for (int32 i = 63; i >= 0; i--) { + if (_sceneAnimations[i]._active && _sceneAnimations[i]._animInstance) { + _animationManager->addInstance(_sceneAnimations[i]._animInstance); } } - */ + + _gameState->_timerTimeout[0] += timerDiff; + _gameState->_timerTimeout[1] += timerDiff; _gameState->_conversationData = _conversationData; _firstFrame = true; @@ -4689,8 +4682,12 @@ void SceneAnimation::load(ToonEngine *vm, Common::ReadStream *stream) { if (stream->readByte() == 1) { _animInstance = vm->getAnimationManager()->createNewInstance(kAnimationScene); _animInstance->load(stream); - vm->getAnimationManager()->addInstance(_animInstance); + // we add them at the end of loading in reverse order + //vm->getAnimationManager()->addInstance(_animInstance); _originalAnimInstance = _animInstance; + } else { + _animInstance = NULL; + _originalAnimInstance = NULL; } // load animation if any -- cgit v1.2.3