aboutsummaryrefslogtreecommitdiff
path: root/engines/toon
diff options
context:
space:
mode:
authorSylvain Dupont2011-01-30 02:18:53 +0000
committerSylvain Dupont2011-01-30 02:18:53 +0000
commit5934ccd184a302720103f7e803bdf4c9157db54b (patch)
treeb1ecdfac5e2c92258abda96bc9d4930317874bce /engines/toon
parent01c32f7287481e6784619167d5de344fe8209c12 (diff)
downloadscummvm-rg350-5934ccd184a302720103f7e803bdf4c9157db54b.tar.gz
scummvm-rg350-5934ccd184a302720103f7e803bdf4c9157db54b.tar.bz2
scummvm-rg350-5934ccd184a302720103f7e803bdf4c9157db54b.zip
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
Diffstat (limited to 'engines/toon')
-rw-r--r--engines/toon/anim.cpp57
-rw-r--r--engines/toon/anim.h2
-rw-r--r--engines/toon/script_func.cpp16
-rw-r--r--engines/toon/toon.cpp27
4 files changed, 65 insertions, 37 deletions
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