diff options
Diffstat (limited to 'engines/draci')
-rw-r--r-- | engines/draci/game.cpp | 75 | ||||
-rw-r--r-- | engines/draci/game.h | 9 | ||||
-rw-r--r-- | engines/draci/saveload.cpp | 7 | ||||
-rw-r--r-- | engines/draci/saveload.h | 2 | ||||
-rw-r--r-- | engines/draci/script.cpp | 21 | ||||
-rw-r--r-- | engines/draci/walking.cpp | 10 | ||||
-rw-r--r-- | engines/draci/walking.h | 5 |
7 files changed, 102 insertions, 27 deletions
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp index e5ff1f079a..4893b0fe34 100644 --- a/engines/draci/game.cpp +++ b/engines/draci/game.cpp @@ -72,6 +72,7 @@ Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) { _fadePhases = 0; _fadePhase = 0; _fadeTick = 0; + _isFadeOut = 1; _mouseChangeTick = 0; _enableQuickHero = 0; _wantQuickHero = 0; @@ -216,6 +217,7 @@ void Game::start() { // init scripts. This flag was turned on to skip the rest of // those programs. Don't call loop(), because the // location may have changed. + fadePalette(true); continue; } @@ -478,6 +480,7 @@ void Game::handleDialogueLoop() { } void Game::fadePalette(bool fading_out) { + _isFadeOut = fading_out; const byte *startPal = NULL; const byte *endPal = _currentRoom._palette >= 0 ? _vm->_paletteArchive->getFile(_currentRoom._palette)->_data @@ -551,6 +554,19 @@ void Game::advanceAnimationsAndTestLoopExit() { _vm->_anims->drawScene(_vm->_screen->getSurface()); _vm->_screen->copyToScreen(); _vm->_system->delayMillis(kTimeUnit); + if(_isFadeOut) { + fadePalette(false); + // Set cursor state + // Need to do this after we set the palette since the cursors use it + if (_currentRoom._mouseOn) { + debugC(6, kDraciLogicDebugLevel, "Mouse: ON"); + _vm->_mouse->cursorOn(); + _vm->_mouse->setCursorType(kNormalCursor); + } else { + debugC(6, kDraciLogicDebugLevel, "Mouse: OFF"); + _vm->_mouse->cursorOff(); + } + } // If the hero has arrived at his destination, after even the last // phase was correctly animated, run the callback. @@ -598,6 +614,8 @@ void Game::loop(LoopSubstatus substatus, bool shouldExit) { break; } + advanceAnimationsAndTestLoopExit(); + if (_vm->_mouse->isCursorOn()) { // Find animation under cursor and the game object // corresponding to it @@ -629,8 +647,6 @@ void Game::loop(LoopSubstatus substatus, bool shouldExit) { } } - advanceAnimationsAndTestLoopExit(); - } while (!shouldExitLoop()); setLoopSubstatus(kOuterLoop); @@ -875,9 +891,6 @@ void Game::putItem(GameItem *item, int position) { void Game::inventoryInit() { // Pause all "background" animations _vm->_anims->pauseAnimations(); - if (_walkingState.isActive()) { - walkHero(_hero.x, _hero.y, kDirectionLast); - } // Draw the inventory and the current items inventoryDraw(); @@ -888,6 +901,13 @@ void Game::inventoryInit() { // Set the appropriate loop status setLoopStatus(kStatusInventory); + if (_walkingState.isActive()) { + _walkingState.stopWalking(); + walkHero(_hero.x, _hero.y, kDirectionLast); + } else { + _lastTarget = _hero; + } + // Don't return from the inventory mode immediately if the mouse is out. _mouseChangeTick = kMouseDoNotSwitch; } @@ -906,6 +926,10 @@ void Game::inventoryDone() { } } + // Start moving to last target + walkHero(_lastTarget.x, _lastTarget.y, kDirectionLast); + _walkingState.callbackLast(); + // Reset item under cursor _itemUnderCursor = NULL; @@ -926,10 +950,12 @@ void Game::inventoryDraw() { void Game::inventoryReload() { // Make sure all items are loaded into memory (e.g., after loading a // savegame) by re-putting them on the same spot in the inventory. + GameItem *tempItem = _currentItem; for (uint i = 0; i < kInventorySlots; ++i) { putItem(_inventory[i], i); } setPreviousItemPosition(0); + _currentItem = tempItem; } void Game::inventorySwitch(int keycode) { @@ -1190,6 +1216,12 @@ void Game::walkHero(int x, int y, SightDirection dir) { debug(1, "Unreachable point [%d,%d]", target.x, target.y); return; } + + // Save point of player's last target. + if (_loopStatus != kStatusInventory) { + _lastTarget = target; + } + _walkingMap.obliquePath(shortestPath, &obliquePath); debugC(2, kDraciWalkingDebugLevel, "Walking path lengths: shortest=%d oblique=%d", shortestPath.size(), obliquePath.size()); if (_vm->_showWalkingMap) { @@ -1433,7 +1465,6 @@ void Game::enterNewRoom() { _vm->_screen->setPalette(NULL, 0, kNumColors); _vm->_anims->drawScene(_vm->_screen->getSurface()); _vm->_screen->copyToScreen(); - fadePalette(false); // Run the program for the gate the dragon came through debugC(6, kDraciLogicDebugLevel, "Running program for gate %d", _newGate); @@ -1446,17 +1477,6 @@ void Game::enterNewRoom() { // Don't immediately switch to the map or inventory even if the mouse // position tell us to. _mouseChangeTick = kMouseDoNotSwitch; - - // Set cursor state - // Need to do this after we set the palette since the cursors use it - if (_currentRoom._mouseOn) { - debugC(6, kDraciLogicDebugLevel, "Mouse: ON"); - _vm->_mouse->cursorOn(); - _vm->_mouse->setCursorType(kNormalCursor); - } else { - debugC(6, kDraciLogicDebugLevel, "Mouse: OFF"); - _vm->_mouse->cursorOff(); - } } void Game::positionAnimAsHero(Animation *anim) { @@ -1572,7 +1592,7 @@ Game::~Game() { delete[] _items; } -void Game::DoSync(Common::Serializer &s) { +void Game::DoSync(Common::Serializer &s, uint8 saveVersion) { s.syncAsUint16LE(_currentRoom._roomNum); for (uint i = 0; i < _info._numObjects; ++i) { @@ -1603,6 +1623,25 @@ void Game::DoSync(Common::Serializer &s) { s.syncAsSint16LE(_dialogueVars[i]); } + if(saveVersion >= 2) { + setPositionLoaded(true); + if (s.isSaving()) { + s.syncAsSint16LE(_hero.x); + s.syncAsSint16LE(_hero.y); + + int handItemID = _currentItem ? _currentItem->_absNum : -1; + s.syncAsSint16LE(handItemID); + } else { + s.syncAsSint16LE(_heroLoading.x); + s.syncAsSint16LE(_heroLoading.y); + + int handItemID = -1; + s.syncAsSint16LE(handItemID); + _currentItem = getItem(handItemID); + } + } else { + _currentItem = 0; + } } static double real_to_double(byte real[6]) { diff --git a/engines/draci/game.h b/engines/draci/game.h index 4a8f3de269..53a472a552 100644 --- a/engines/draci/game.h +++ b/engines/draci/game.h @@ -215,6 +215,7 @@ public: void walkHero(int x, int y, SightDirection dir); // start walking and leave callback as is void setHeroPosition(const Common::Point &p); const Common::Point &getHeroPosition() const { return _hero; } + const Common::Point &getHeroLoadingPosition() const { return _heroLoading; } void positionAnimAsHero(Animation *anim); void positionHeroAsAnim(Animation *anim); @@ -290,6 +291,8 @@ public: void setExitLoop(bool exit) { _shouldExitLoop = exit; } bool isReloaded() const { return _isReloaded; } void setIsReloaded(bool value) { _isReloaded = value; } + bool isPositionLoaded() { return _isPositionLoaded; } + void setPositionLoaded(bool value) { _isPositionLoaded = value; } void setSpeechTiming(uint tick, uint duration); void shiftSpeechAndFadeTick(int delta); @@ -327,7 +330,7 @@ public: void setEnableSpeedText(bool value) { _enableSpeedText = value; } bool getEnableSpeedText() const { return _enableSpeedText; } - void DoSync(Common::Serializer &s); + void DoSync(Common::Serializer &s, uint8 saveVersion); private: void updateOrdinaryCursor(); @@ -352,6 +355,8 @@ private: GameInfo _info; Common::Point _hero; + Common::Point _heroLoading; + Common::Point _lastTarget; int *_variables; Person *_persons; @@ -395,6 +400,7 @@ private: bool _shouldQuit; bool _shouldExitLoop; bool _isReloaded; + bool _isPositionLoaded; uint _speechTick; uint _speechDuration; @@ -408,6 +414,7 @@ private: int _fadePhases; int _fadePhase; uint _fadeTick; + bool _isFadeOut; int _mouseChangeTick; bool _enableQuickHero; diff --git a/engines/draci/saveload.cpp b/engines/draci/saveload.cpp index 31ac63b791..3e7f8651c1 100644 --- a/engines/draci/saveload.cpp +++ b/engines/draci/saveload.cpp @@ -45,7 +45,8 @@ bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) { return false; header.version = in->readByte(); - if (header.version != DRACI_SAVEGAME_VERSION) + // Version 1 is compatible with Version 2 + if (header.version > DRACI_SAVEGAME_VERSION) return false; // Read in the string @@ -106,7 +107,7 @@ Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName, } else { // Create the remainder of the savegame Common::Serializer s(NULL, f); - vm._game->DoSync(s); + vm._game->DoSync(s, header.version); f->finalize(); delete f; @@ -140,7 +141,7 @@ Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm) { // Synchronise the remaining data of the savegame Common::Serializer s(f, NULL); - vm->_game->DoSync(s); + vm->_game->DoSync(s, header.version); delete f; // Post-processing diff --git a/engines/draci/saveload.h b/engines/draci/saveload.h index 8b38ccb94f..6f951a3409 100644 --- a/engines/draci/saveload.h +++ b/engines/draci/saveload.h @@ -29,7 +29,7 @@ namespace Draci { -#define DRACI_SAVEGAME_VERSION 1 +#define DRACI_SAVEGAME_VERSION 2 struct DraciSavegameHeader { uint8 version; diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp index 97dde39809..09c74f5e0d 100644 --- a/engines/draci/script.cpp +++ b/engines/draci/script.cpp @@ -634,8 +634,16 @@ void Script::stayOn(const Common::Array<int> ¶ms) { return; } - int x = params[0]; - int y = params[1]; + int x, y; + Common::Point afterLoadingPos = _vm->_game->getHeroLoadingPosition(); + if(_vm->_game->isPositionLoaded() == true) { + x = afterLoadingPos.x; + y = afterLoadingPos.y; + } + else { + x = params[0]; + y = params[1]; + } SightDirection dir = static_cast<SightDirection> (params[2]); // Jumps into the given position regardless of the walking map. @@ -670,6 +678,11 @@ void Script::walkOnPlay(const Common::Array<int> ¶ms) { return; } + if(_vm->_game->isPositionLoaded() == true) { + _vm->_game->setPositionLoaded(false); + return; + } + int x = params[0]; int y = params[1]; SightDirection dir = static_cast<SightDirection> (params[2]); @@ -687,6 +700,10 @@ void Script::newRoom(const Common::Array<int> ¶ms) { return; } + if(_vm->_game->isPositionLoaded() == true) { + _vm->_game->setPositionLoaded(false); + } + int room = params[0] - 1; int gate = params[1] - 1; diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp index 1467ecee35..6914898ec1 100644 --- a/engines/draci/walking.cpp +++ b/engines/draci/walking.cpp @@ -439,8 +439,8 @@ void WalkingState::startWalking(const Common::Point &p1, const Common::Point &p2 } void WalkingState::setCallback(const GPL2Program *program, uint16 offset) { - _callback = program; - _callbackOffset = offset; + _callback = _callbackLast = program; + _callbackOffset = _callbackOffsetLast = offset; } void WalkingState::callback() { @@ -452,6 +452,12 @@ void WalkingState::callback() { const GPL2Program &originalCallback = *_callback; _callback = NULL; _vm->_script->runWrapper(originalCallback, _callbackOffset, true, false); + _callbackLast = NULL; + _callbackOffset = NULL; +} + +void WalkingState::callbackLast() { + setCallback(_callbackLast, _callbackOffsetLast); } bool WalkingState::continueWalkingOrClearPath() { diff --git a/engines/draci/walking.h b/engines/draci/walking.h index ee2b48d083..fcdef3830e 100644 --- a/engines/draci/walking.h +++ b/engines/draci/walking.h @@ -110,6 +110,8 @@ public: _lastAnimPhase = 0; _turningFinished = 0; _callbackOffset = 0; + _callbackOffsetLast = 0; + _callbackLast = 0; stopWalking(); } @@ -124,6 +126,7 @@ public: void setCallback(const GPL2Program *program, uint16 offset); void callback(); + void callbackLast(); bool isActive() const { return _path.size() > 0; } @@ -157,7 +160,9 @@ private: bool _turningFinished; const GPL2Program *_callback; + const GPL2Program *_callbackLast; uint16 _callbackOffset; + uint16 _callbackOffsetLast; // Initiates turning of the dragon into the direction for the next // segment / after walking. Returns false when there is nothing left |