diff options
author | Robert Špalek | 2009-10-04 22:55:54 +0000 |
---|---|---|
committer | Robert Špalek | 2009-10-04 22:55:54 +0000 |
commit | cc39c5022a1cfcca0f2f0caff6b38e44c40a65c9 (patch) | |
tree | 66632ef39b22cb569c88f8dfb22e338d8cb6e70a /engines/draci | |
parent | db8c6e3f6cc6f9ca889adfd58f78be8571e407e7 (diff) | |
download | scummvm-rg350-cc39c5022a1cfcca0f2f0caff6b38e44c40a65c9.tar.gz scummvm-rg350-cc39c5022a1cfcca0f2f0caff6b38e44c40a65c9.tar.bz2 scummvm-rg350-cc39c5022a1cfcca0f2f0caff6b38e44c40a65c9.zip |
Work-around a bug in the original game files.
svn-id: r44645
Diffstat (limited to 'engines/draci')
-rw-r--r-- | engines/draci/script.cpp | 69 | ||||
-rw-r--r-- | engines/draci/script.h | 6 |
2 files changed, 57 insertions, 18 deletions
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp index d05c1852a4..722af9e21e 100644 --- a/engines/draci/script.cpp +++ b/engines/draci/script.cpp @@ -357,6 +357,27 @@ void Script::play(Common::Queue<int> ¶ms) { _vm->_game->setLoopSubstatus(kSubstatusOrdinary); } +Animation *Script::loadObjectAnimation(GameObject *obj, int animID) { + // Load the animation into memory + + _vm->_game->loadAnimation(animID, obj->_z); + + // We insert the ID of the loaded animation into the object's internal array + // of owned animation IDs. + // Care must be taken to store them sorted (increasing order) as some things + // depend on this. + + uint i; + for (i = 0; i < obj->_anims.size(); ++i) { + if (obj->_anims[i] > animID) { + break; + } + } + + obj->_anims.insert_at(i, animID); + return _vm->_anims->getAnimation(animID); +} + void Script::load(Common::Queue<int> ¶ms) { if (_vm->_game->getLoopStatus() == kStatusInventory) { return; @@ -375,22 +396,7 @@ void Script::load(Common::Queue<int> ¶ms) { } } - // Load the animation into memory - - _vm->_game->loadAnimation(animID, obj->_z); - - // We insert the ID of the loaded animation into the object's internal array - // of owned animation IDs. - // Care must be taken to store them sorted (increasing order) as some things - // depend on this. - - for (i = 0; i < obj->_anims.size(); ++i) { - if (obj->_anims[i] > animID) { - break; - } - } - - obj->_anims.insert_at(i, animID); + loadObjectAnimation(obj, animID); } void Script::start(Common::Queue<int> ¶ms) { @@ -401,7 +407,7 @@ void Script::start(Common::Queue<int> ¶ms) { int objID = params.pop() - 1; int animID = params.pop() - 1; - const GameObject *obj = _vm->_game->getObject(objID); + GameObject *obj = _vm->_game->getObject(objID); // Stop all animation that the object owns @@ -410,6 +416,28 @@ void Script::start(Common::Queue<int> ¶ms) { } Animation *anim = _vm->_anims->getAnimation(animID); + if (!anim) { + // The original game files seem to contain errors, which I have + // verified by inspecting their source code. They try to load + // each animation before starting it, but fail to anticipate + // all possible code paths when game loading comes into play. + // + // In particular, if I load the game at the stump location, + // apply a hedgehog on them, and then talk to them, one of the + // animations is not loaded. This animation would have been + // loaded had I talked to them before applying the hedgehog + // (because a different dialog init code is run before the + // application). Talking to the stumps is necessary to be able + // to apply the hedgehog, so normal game-play is safe. + // However, if I save the game after talking to them and load + // it later, then the game variables are set so as to allow me + // to apply the hedgehog, but there is no way that the game + // player would load the requested animation by itself. + // See objekty:5077 and parezy.txt:27. + anim = loadObjectAnimation(obj, animID); + debugC(1, kDraciBytecodeDebugLevel, "start(%d=%s) cannot find animation %d. Loading.", + objID, obj->_title.c_str(), animID); + } if (objID == kDragonObject) _vm->_game->positionAnimAsHero(anim); @@ -431,7 +459,7 @@ void Script::startPlay(Common::Queue<int> ¶ms) { int objID = params.pop() - 1; int animID = params.pop() - 1; - const GameObject *obj = _vm->_game->getObject(objID); + GameObject *obj = _vm->_game->getObject(objID); // Stop all animation that the object owns @@ -440,6 +468,11 @@ void Script::startPlay(Common::Queue<int> ¶ms) { } Animation *anim = _vm->_anims->getAnimation(animID); + if (!anim) { + anim = loadObjectAnimation(obj, animID); + debugC(1, kDraciBytecodeDebugLevel, "startPlay(%d=%s) cannot find animation %d. Loading.", + objID, obj->_title.c_str(), animID); + } if (objID == kDragonObject) _vm->_game->positionAnimAsHero(anim); diff --git a/engines/draci/script.h b/engines/draci/script.h index 8e2a3af50c..6165d32121 100644 --- a/engines/draci/script.h +++ b/engines/draci/script.h @@ -83,6 +83,9 @@ struct GPL2Program { uint16 _length; }; +class Animation; +class GameObject; + class Script { public: @@ -168,6 +171,9 @@ private: int handleMathExpression(Common::MemoryReadStream *reader) const; DraciEngine *_vm; + + // Auxilliary functions + Animation *loadObjectAnimation(GameObject *obj, int animID); }; } // End of namespace Draci |