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
This commit is contained in:
Sylvain Dupont 2011-01-30 02:18:53 +00:00
parent 01c32f7287
commit 5934ccd184
4 changed files with 65 additions and 37 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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