diff options
author | Paul Gilbert | 2014-04-22 23:00:41 -0400 |
---|---|---|
committer | Paul Gilbert | 2014-04-22 23:00:41 -0400 |
commit | 0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9 (patch) | |
tree | d69131833413f6bd75ef84e95c64cc54da568e8e /engines/mads | |
parent | 3f1a49b567aac10fe8a195f7a2b8e07603470a72 (diff) | |
download | scummvm-rg350-0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9.tar.gz scummvm-rg350-0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9.tar.bz2 scummvm-rg350-0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9.zip |
MADS: Beginnings of savegame synchronisation
Diffstat (limited to 'engines/mads')
-rw-r--r-- | engines/mads/action.cpp | 8 | ||||
-rw-r--r-- | engines/mads/action.h | 3 | ||||
-rw-r--r-- | engines/mads/game.cpp | 34 | ||||
-rw-r--r-- | engines/mads/game.h | 10 | ||||
-rw-r--r-- | engines/mads/inventory.cpp | 63 | ||||
-rw-r--r-- | engines/mads/inventory.h | 10 | ||||
-rw-r--r-- | engines/mads/messages.cpp | 2 | ||||
-rw-r--r-- | engines/mads/nebular/nebular_scenes2.cpp | 2 | ||||
-rw-r--r-- | engines/mads/player.cpp | 72 | ||||
-rw-r--r-- | engines/mads/player.h | 9 | ||||
-rw-r--r-- | engines/mads/rails.cpp | 17 | ||||
-rw-r--r-- | engines/mads/rails.h | 7 | ||||
-rw-r--r-- | engines/mads/scene.cpp | 5 | ||||
-rw-r--r-- | engines/mads/scene.h | 5 |
14 files changed, 204 insertions, 43 deletions
diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp index 9d496d5ebf..03c0c1ed8a 100644 --- a/engines/mads/action.cpp +++ b/engines/mads/action.cpp @@ -29,6 +29,14 @@ namespace MADS { +void ActionDetails::synchronize(Common::Serializer &s) { + s.syncAsUint16LE(_verbId); + s.syncAsUint16LE(_objectNameId); + s.syncAsUint16LE(_indirectObjectId); +} + +/*------------------------------------------------------------------------*/ + MADSAction::MADSAction(MADSEngine *vm) : _vm(vm) { clear(); _statusTextIndex = -1; diff --git a/engines/mads/action.h b/engines/mads/action.h index 599fb0e4f9..c588a42324 100644 --- a/engines/mads/action.h +++ b/engines/mads/action.h @@ -24,6 +24,7 @@ #define MADS_ACTION_H #include "common/scummsys.h" +#include "common/serializer.h" #include "common/str.h" namespace MADS { @@ -76,6 +77,8 @@ struct ActionDetails { int _verbId; int _objectNameId; int _indirectObjectId; + + void synchronize(Common::Serializer &s); }; struct ActionSavedFields { diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index d3e3987d4e..3b591d7a9e 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -22,6 +22,7 @@ #include "common/scummsys.h" #include "common/memstream.h" +#include "common/serializer.h" #include "mads/mads.h" #include "mads/compression.h" #include "mads/game.h" @@ -45,7 +46,7 @@ Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm), _scene(vm), _screenObjects(vm), _player(vm) { _sectionNumber = _priorSectionNumber = 0; _difficulty = DIFFICULTY_HARD; - _saveSlot = -1; + _serializer = nullptr; _statusFlag = 0; _sectionHandler = nullptr; _sectionNumber = 1; @@ -86,7 +87,6 @@ void Game::run() { case PROTECTION_FAIL: // Copy protection failed _scene._nextSceneId = 804; - _saveSlot = -1; break; case PROTECTION_ESCAPE: // User escaped out of copy protection dialog @@ -102,7 +102,7 @@ void Game::run() { // Get the initial starting time for the first scene _scene._frameStartTime = _vm->_events->getFrameCounter(); - if (_saveSlot == -1 && protectionResult != -1 && protectionResult != -2) { + if (_serializer == nullptr && protectionResult != -1 && protectionResult != -2) { initSection(_sectionNumber); _statusFlag = true; @@ -118,11 +118,6 @@ void Game::run() { if (protectionResult != 1 && protectionResult != 2) { initialiseGlobals(); - - if (_saveSlot != -1) { - warning("TODO: loadGame(\"REX.SAV\", 210)"); - _statusFlag = false; - } } if (_statusFlag) @@ -131,6 +126,9 @@ void Game::run() { void Game::gameLoop() { while (!_vm->shouldQuit() && _statusFlag) { + if (_serializer) + synchronize(*_serializer, true); + setSectionHandler(); _sectionHandler->preLoadSection(); initSection(_sectionNumber); @@ -248,7 +246,7 @@ void Game::sectionLoop() { _player.selectSeries(); _player.updateFrame(); - _player._visible3 = _player._visible; + _player._beenVisible = _player._visible; _player._special = _scene.getDepthHighBits(_player._playerPos); _player._priorTimer = _scene._frameStartTime - _player._ticksAmount; _player.idle(); @@ -402,4 +400,22 @@ void Game::handleKeypress(const Common::Event &event) { warning("TODO: handleKeypress - %d", (int)event.kbd.keycode); } +void Game::synchronize(Common::Serializer &s, bool phase1) { + if (phase1) { + s.syncAsUint16LE(_scene._nextSceneId); + s.syncAsUint16LE(_scene._priorSceneId); + + if (s.isLoading()) { + _sectionNumber = _scene._nextSceneId / 100; + _currentSectionNumber = _sectionNumber; + } + } else { + s.syncAsByte(_difficulty); + + _scene.synchronize(s); + _objects.synchronize(s); + _player.synchronize(s); + } +} + } // End of namespace MADS diff --git a/engines/mads/game.h b/engines/mads/game.h index 5bb7b31973..ad40fbdcc0 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/str-array.h" +#include "common/serializer.h" #include "mads/scene.h" #include "mads/game_data.h" #include "mads/globals.h" @@ -72,12 +73,12 @@ private: protected: MADSEngine *_vm; MSurface *_surface; - int _saveSlot; int _statusFlag; Common::StringArray _quotes; bool _quoteEmergency; bool _vocabEmergency; bool _anyEmergency; + Common::Serializer *_serializer; /** * Constructor @@ -170,6 +171,13 @@ public: */ virtual void step() = 0; + /** + * Synchronise the game data + * @param s Serializer + * @param phase1 If true, it's synchronising the basic scene information + */ + virtual void synchronize(Common::Serializer &s, bool phase1); + // DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs void clearQuotes() {} void loadQuoteRange(int startNum, int endNum) {} diff --git a/engines/mads/inventory.cpp b/engines/mads/inventory.cpp index bb65430bb1..abd281dcc8 100644 --- a/engines/mads/inventory.cpp +++ b/engines/mads/inventory.cpp @@ -26,42 +26,57 @@ namespace MADS { -void InventoryObject::load(Common::SeekableReadStream &f) { - _descId = f.readUint16LE(); - _roomNumber = f.readUint16LE(); - _article = f.readByte(); - _vocabCount = f.readByte(); +void InventoryObject::synchronize(Common::Serializer &s) { + s.syncAsUint16LE(_descId); + s.syncAsUint16LE(_roomNumber); + s.syncAsByte(_article); + s.syncAsByte(_vocabCount); for (int i = 0; i < 3; ++i) { - _vocabList[i]._verbType = (VerbType)f.readByte(); - _vocabList[i]._prepType = (PrepType)f.readByte(); - _vocabList[i]._vocabId = f.readUint16LE(); + s.syncAsByte(_vocabList[i]._verbType); + s.syncAsByte(_vocabList[i]._prepType); + s.syncAsUint16LE( _vocabList[i]._vocabId); } - f.skip(4); // field12 - f.read(&_mutilateString[0], 10); - f.skip(16); + s.skip(4); // field12 + s.syncBytes((byte *)&_mutilateString[0], 10); + s.skip(16); } /*------------------------------------------------------------------------*/ void InventoryObjects::load() { File f("*OBJECTS.DAT"); + Common::Serializer s(&f, nullptr); - // Get the total numer of inventory objects - int count = f.readUint16LE(); - reserve(count); - - // Read in each object - for (int i = 0; i < count; ++i) { - InventoryObject obj; - obj.load(f); - push_back(obj); + // Load the objects data + synchronize(s); +} - // If it's for the player's inventory, add the index to the inventory list - if (obj._roomNumber == PLAYER_INVENTORY) { - _inventoryList.push_back(i); - assert(_inventoryList.size() <= 32); +void InventoryObjects::synchronize(Common::Serializer &s) { + int count = size(); + s.syncAsUint16LE(count); + + if (s.isSaving()) { + // Store the data for each object in the inventory lsit + for (int idx = 0; idx < count; ++idx) + (*this)[idx].synchronize(s); + } else { + clear(); + _inventoryList.clear(); + reserve(count); + + // Read in each object + for (int i = 0; i < count; ++i) { + InventoryObject obj; + obj.synchronize(s); + push_back(obj); + + // If it's for the player's inventory, add the index to the inventory list + if (obj._roomNumber == PLAYER_INVENTORY) { + _inventoryList.push_back(i); + assert(_inventoryList.size() <= 32); + } } } } diff --git a/engines/mads/inventory.h b/engines/mads/inventory.h index 5c2f925e57..5e3ecd6a69 100644 --- a/engines/mads/inventory.h +++ b/engines/mads/inventory.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/serializer.h" namespace MADS { @@ -49,9 +50,9 @@ public: const byte *_objFolder; // ??? /** - * Loads the data for a given object + * Synchronizes the data for a given object */ - void load(Common::SeekableReadStream &f); + void synchronize(Common::Serializer &s); }; class InventoryObjects: public Common::Array<InventoryObject> { @@ -72,6 +73,11 @@ public: void load(); /** + * Synchronize the objects list in a savegame + */ + void synchronize(Common::Serializer &s); + + /** * Returns the inventory item from the player's inventory */ InventoryObject &getItem(int itemIndex) { diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp index 46b05c1413..2f59a67359 100644 --- a/engines/mads/messages.cpp +++ b/engines/mads/messages.cpp @@ -203,7 +203,7 @@ void KernelMessages::processText(int msgIndex) { Player &player = _vm->_game->_player; if (msg._flags & KMSG_PLAYER_TIMEOUT) { - if (player._visible3) { + if (player._beenVisible) { SpriteAsset &asset = *_vm->_game->_scene._sprites[player._spritesStart + player._spritesIdx]; MSprite *frame = asset.getFrame(player._frameNumber - 1); diff --git a/engines/mads/nebular/nebular_scenes2.cpp b/engines/mads/nebular/nebular_scenes2.cpp index 5054fbef0d..7491ed1479 100644 --- a/engines/mads/nebular/nebular_scenes2.cpp +++ b/engines/mads/nebular/nebular_scenes2.cpp @@ -339,7 +339,7 @@ void Scene202::setup() { } void Scene202::enter() { - _game._player._visible3 = true; + _game._player._beenVisible = true; _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0)); _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 1)); _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('b', 2)); diff --git a/engines/mads/player.cpp b/engines/mads/player.cpp index cc482c0608..3b727b397e 100644 --- a/engines/mads/player.cpp +++ b/engines/mads/player.cpp @@ -48,7 +48,7 @@ Player::Player(MADSEngine *vm): _vm(vm) { _priorVisible = false; _needToWalk = false; _readyToWalk = false; - _visible3 = false; + _beenVisible = false; _loadsFirst = false; _loadedFirst = false; _walkAnywhere = false; @@ -337,7 +337,7 @@ void Player::update() { } } - _visible3 = _visible; + _beenVisible |= _visible; _priorVisible = _visible; _forceRefresh = false; } @@ -691,4 +691,72 @@ void Player::releasePlayerSprites() { _spritesChanged = true; } +void Player::synchronize(Common::Serializer &s) { + s.syncAsByte(_visible); + s.syncAsByte(_priorVisible); + s.syncAsByte(_beenVisible); + s.syncAsByte(_moving); + s.syncAsByte(_stepEnabled); + s.syncAsSint16LE(_playerPos.x); + s.syncAsSint16LE(_playerPos.y); + s.syncAsSint16LE(_targetPos.x); + s.syncAsSint16LE(_targetPos.y); + s.syncAsSint16LE(_posChange.x); + s.syncAsSint16LE(_posChange.y); + s.syncAsSint16LE(_posDiff.x); + s.syncAsSint16LE(_posDiff.y); + s.syncAsSint16LE(_xDirection); + s.syncAsSint16LE(_yDirection); + s.syncAsUint16LE(_facing); + s.syncAsUint16LE(_targetFacing); + s.syncAsByte(_spritesChanged); + s.syncAsByte(_walkAnywhere); + s.syncAsByte(_walkOffScreen); + s.syncAsSint16LE(_ticksAmount); + s.syncAsSint16LE(_centerOfGravity); + s.syncAsUint16LE(_walkOffScreenSceneId); + s.syncAsByte(_needToWalk); + s.syncAsByte(_readyToWalk); + s.syncAsUint16LE(_prepareWalkFacing); + s.syncAsSint16LE(_prepareWalkPos.x); + s.syncAsSint16LE(_prepareWalkPos.y); + + s.syncAsByte(_mirror); + s.syncAsUint16LE(_frameCount); + s.syncAsSint16LE(_frameListIndex); + s.syncAsSint16LE(_distAccum); + s.syncAsSint16LE(_pixelAccum); + s.syncAsSint16LE(_deltaDistance); + + for (int i = 0; i < 12; ++i) { + s.syncAsSint16LE(_stopWalkerList[i]); + s.syncAsSint16LE(_stopWalkerTrigger[i]); + } + s.syncAsSint16LE(_stopWalkerIndex); + s.syncAsSint16LE(_totalDistance); + s.syncAsSint16LE(_frameNumber); + s.syncAsSint16LE(_special); + s.syncAsSint16LE(_velocity); + s.syncAsSint16LE(_scalingVelocity); + s.syncAsSint16LE(_upcomingTrigger); + s.syncAsSint16LE(_trigger); + s.syncAsSint16LE(_currentDepth); + s.syncAsSint16LE(_currentScale); + + int count; + char ch; + if (s.isSaving()) { + count = _spritesPrefix.size(); + s.syncAsUint16LE(count); + s.syncBytes((byte *)_spritesPrefix.c_str(), count); + } else { + s.syncAsSint16LE(count); + _spritesPrefix.clear(); + for (int i = 0; i < count; ++i) { + s.syncAsByte(ch); + _spritesPrefix += ch; + } + } +} + } // End of namespace MADS diff --git a/engines/mads/player.h b/engines/mads/player.h index 6df1159ad4..97fc3e75cd 100644 --- a/engines/mads/player.h +++ b/engines/mads/player.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/str.h" +#include "common/serializer.h" namespace MADS { @@ -110,7 +111,7 @@ public: bool _spritesChanged; bool _visible; bool _priorVisible; - bool _visible3; + bool _beenVisible; bool _walkAnywhere; int _frameNumber; bool _loadsFirst; @@ -122,7 +123,6 @@ public: Common::Point _prepareWalkPos; bool _moving; int _walkOffScreen, _walkOffScreenSceneId; - int _next; int _special; int _ticksAmount; uint32 _priorTimer; @@ -211,6 +211,11 @@ public: */ void releasePlayerSprites(); + /** + * Serialize the data of the player + */ + void synchronize(Common::Serializer &s); + static void preloadSequences(const Common::String &prefix, int level) { // No implementation in ScummVM } diff --git a/engines/mads/rails.cpp b/engines/mads/rails.cpp index 105a85366a..00f7f4cdbc 100644 --- a/engines/mads/rails.cpp +++ b/engines/mads/rails.cpp @@ -263,5 +263,22 @@ int Rails::getRouteFlags(const Common::Point &src, const Common::Point &dest) { return result; } +void Rails::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_routeLength); + s.syncAsSint16LE(_next); + + int count = _routeIndexes.size(); + if (s.isSaving()) { + for (int i = 0; i < count; ++i) + s.syncAsUint16LE(_routeIndexes[i]); + } else { + _routeIndexes.clear(); + for (int i = 0; i < count; ++i) { + int v = 0; + s.syncAsUint16LE(v); + _routeIndexes.push(v); + } + } +} } // End of namespace MADS diff --git a/engines/mads/rails.h b/engines/mads/rails.h index 6338aeab97..4014491e25 100644 --- a/engines/mads/rails.h +++ b/engines/mads/rails.h @@ -26,6 +26,7 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/rect.h" +#include "common/serializer.h" #include "common/stack.h" #include "mads/msurface.h" @@ -60,7 +61,6 @@ private: int _depthStyle; int _routeLength; int _next; - int _routeOffset; int _tempRoute[MAX_ROUTE_NODES]; Common::Stack<int> _routeIndexes; private: @@ -122,6 +122,11 @@ public: void resetNext() { _next = 0; } int getNext() { return _next; } + + /** + * Synchronize the data for the route + */ + void synchronize(Common::Serializer &s); }; } // End of namespace MADS diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index 9d0332e600..239a91c585 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -681,4 +681,9 @@ void Scene::freeAnimation() { _freeAnimationFlag = false; } +void Scene::synchronize(Common::Serializer &s) { + _action._activeAction.synchronize(s); + _rails.synchronize(s); +} + } // End of namespace MADS diff --git a/engines/mads/scene.h b/engines/mads/scene.h index eb84fbd814..48b01b2acb 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -233,6 +233,11 @@ public: * Frees any currently active animation for the scene */ void freeAnimation(); + + /** + * Synchronise the game + */ + void synchronize(Common::Serializer &s); }; } // End of namespace MADS |