From b5949010a61e3d12f22ea762ed8d09cc1a79b850 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 1 May 2014 22:36:36 -0400 Subject: MADS: Implemented more savegame synchronization --- engines/mads/action.cpp | 40 ++++++++++++++++ engines/mads/action.h | 17 ++++++- engines/mads/game.cpp | 26 +++++----- engines/mads/game.h | 6 +-- engines/mads/game_data.cpp | 18 +------ engines/mads/game_data.h | 3 +- engines/mads/globals.h | 2 +- engines/mads/hotspots.cpp | 18 +++++++ engines/mads/hotspots.h | 13 +++++ engines/mads/nebular/game_nebular.cpp | 3 ++ engines/mads/nebular/game_nebular.h | 5 ++ engines/mads/nebular/globals_nebular.cpp | 10 ++++ engines/mads/nebular/globals_nebular.h | 23 ++++----- engines/mads/player.cpp | 81 ++++++++++++++++---------------- engines/mads/resources.cpp | 41 ++++++++++++++++ engines/mads/resources.h | 14 ++++++ engines/mads/scene.cpp | 8 +++- engines/mads/scene_data.h | 1 + engines/mads/screen.cpp | 5 ++ engines/mads/screen.h | 5 ++ engines/mads/user_interface.cpp | 3 ++ 21 files changed, 247 insertions(+), 95 deletions(-) (limited to 'engines') diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp index f1e27d7482..48393e17f6 100644 --- a/engines/mads/action.cpp +++ b/engines/mads/action.cpp @@ -24,6 +24,7 @@ #include "mads/mads.h" #include "mads/action.h" #include "mads/inventory.h" +#include "mads/resources.h" #include "mads/scene.h" #include "mads/staticres.h" @@ -35,6 +36,18 @@ void ActionDetails::synchronize(Common::Serializer &s) { s.syncAsUint16LE(_indirectObjectId); } +void ActionSavedFields::synchronize(Common::Serializer &s) { + s.syncAsByte(_commandError); + s.syncAsSint16LE(_commandSource); + s.syncAsSint16LE(_command); + s.syncAsSint16LE(_mainObject); + s.syncAsSint16LE(_secondObject); + s.syncAsSint16LE(_mainObjectSource); + s.syncAsSint16LE(_secondObjectSource); + s.syncAsSint16LE(_articleNumber); + s.syncAsSint16LE(_lookFlag); +} + /*------------------------------------------------------------------------*/ MADSAction::MADSAction(MADSEngine *vm) : _vm(vm) { @@ -645,4 +658,31 @@ void MADSAction::leftClick() { } } +void MADSAction::synchronize(Common::Serializer &s) { + _action.synchronize(s); + _activeAction.synchronize(s); + s.syncAsSint16LE(_articleNumber); + s.syncAsByte(_lookFlag); + s.syncAsByte(_textChanged); + s.syncAsSint16LE(_selectedRow); + s.syncAsSint16LE(_selectedAction); + s.syncAsSint16LE(_statusTextIndex); + s.syncAsSint16LE(_hotspotId); + _savedFields.synchronize(s); + synchronizeString(s, _sentence); + + s.syncAsSint16LE(_verbType); + s.syncAsSint16LE(_prepType); + s.syncAsSint16LE(_commandSource); + s.syncAsSint16LE(_mainObjectSource); + s.syncAsSint16LE(_secondObject); + s.syncAsSint16LE(_secondObjectSource); + s.syncAsSint16LE(_recentCommandSource); + s.syncAsSint16LE(_recentCommand); + s.syncAsSint16LE(_interAwaiting); + s.syncAsSint16LE(_pickedWord); + s.syncAsByte(_pointEstablished); + s.syncAsByte(_inProgress); +} + } // End of namespace MADS diff --git a/engines/mads/action.h b/engines/mads/action.h index 6e51e12483..ac6c35c863 100644 --- a/engines/mads/action.h +++ b/engines/mads/action.h @@ -78,6 +78,9 @@ struct ActionDetails { int _objectNameId; int _indirectObjectId; + /** + * Synchronize the action details + */ void synchronize(Common::Serializer &s); }; @@ -91,6 +94,11 @@ struct ActionSavedFields { int _secondObjectSource; int _articleNumber; int _lookFlag; + + /** + * Synchronize the saved action details + */ + void synchronize(Common::Serializer &s); }; class MADSAction { @@ -117,11 +125,11 @@ public: PrepType _prepType; ScrCategory _commandSource; ScrCategory _mainObjectSource; - int16 _secondObject; + int _secondObject; ScrCategory _secondObjectSource; ScrCategory _recentCommandSource; bool _pointEstablished; - int16 _recentCommand; + int _recentCommand; InterAwaiting _interAwaiting; bool _inProgress; int _pickedWord; @@ -154,6 +162,11 @@ public: * Execute a click within the scene */ void leftClick(); + + /** + * Synchronize the saved action details + */ + void synchronize(Common::Serializer &s); }; } // End of namespace MADS diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index 1435681612..4b8805df3e 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -59,8 +59,8 @@ Game *Game::init(MADSEngine *vm) { Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm), _scene(vm), _screenObjects(vm), _player(vm) { _sectionNumber = _priorSectionNumber = 0; - _difficulty = DIFFICULTY_IMPOSSIBLE; _loadGameSlot = -1; + _lastSave = -1; _saveFile = nullptr; _statusFlag = 0; _sectionHandler = nullptr; @@ -452,24 +452,26 @@ void Game::handleKeypress(const Common::Event &event) { void Game::synchronize(Common::Serializer &s, bool phase1) { if (phase1) { - s.syncAsUint16LE(_scene._nextSceneId); - s.syncAsUint16LE(_scene._priorSceneId); + s.syncAsSint16LE(_fx); + s.syncAsSint16LE(_trigger); + s.syncAsUint16LE(_triggerSetupMode); + s.syncAsUint16LE(_triggerMode); + synchronizeString(s, _aaName); + s.syncAsSint16LE(_lastSave); + + _scene.synchronize(s); + _objects.synchronize(s); _visitedScenes.synchronize(s); + _player.synchronize(s); + _screenObjects.synchronize(s); if (s.isLoading()) { _sectionNumber = _scene._nextSceneId / 100; _currentSectionNumber = _sectionNumber; - _scene._frameStartTime = _vm->_events->getFrameCounter(); - - _player._spritesLoaded = false; - _player._spritesChanged = true; } } else { - s.syncAsByte(_difficulty); - - _scene.synchronize(s); - _objects.synchronize(s); - _player.synchronize(s); + // Load scene specific data for the loaded scene + _scene._sceneLogic->synchronize(s); } } diff --git a/engines/mads/game.h b/engines/mads/game.h index 246a7857a6..5ae670df76 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -43,10 +43,6 @@ enum { PLAYER_INVENTORY = 2 }; -enum Difficulty { - DIFFICULTY_HARD = 1, DIFFICULTY_REALLY_HARD = 2, DIFFICULTY_IMPOSSIBLE = 3 -}; - enum KernelMode { KERNEL_GAME_LOAD = 0, KERNEL_SECTION_PRELOAD = 1, KERNEL_SECTION_INIT = 2, KERNEL_ROOM_PRELOAD = 3, KERNEL_ROOM_INIT = 4, KERNEL_ACTIVE_CODE = 5 @@ -92,6 +88,7 @@ protected: bool _vocabEmergency; bool _anyEmergency; int _loadGameSlot; + int _lastSave; Common::String _saveName; Common::InSaveFile *_saveFile; @@ -136,7 +133,6 @@ public: public: Player _player; ScreenObjects _screenObjects; - Difficulty _difficulty; int _sectionNumber; int _priorSectionNumber; int _currentSectionNumber; diff --git a/engines/mads/game_data.cpp b/engines/mads/game_data.cpp index 72137cfa69..4a9d02c75f 100644 --- a/engines/mads/game_data.cpp +++ b/engines/mads/game_data.cpp @@ -47,22 +47,8 @@ bool VisitedScenes::exists(int sceneId) { } void VisitedScenes::synchronize(Common::Serializer &s) { - uint count = size(); - int v = 0; - s.syncAsUint16LE(count); - - if (s.isSaving()) { - for (uint i = 0; i < size(); ++i) { - v = (*this)[i]; - s.syncAsSint16LE(v); - } - } else { - clear(); - for (uint i = 0; i < count; ++i) { - s.syncAsSint16LE(v); - push_back(v); - } - } + SynchronizedList:synchronize(s); + s.syncAsByte(_sceneRevisited); } } // End of namespace MADS diff --git a/engines/mads/game_data.h b/engines/mads/game_data.h index 1a8791e815..6ea59d6d2b 100644 --- a/engines/mads/game_data.h +++ b/engines/mads/game_data.h @@ -25,13 +25,14 @@ #include "common/scummsys.h" #include "common/array.h" +#include "mads/resources.h" namespace MADS { class MADSEngine; class Game; -class VisitedScenes: public Common::Array { +class VisitedScenes: public SynchronizedList { public: /** * Stores true when a previously visited scene is revisited diff --git a/engines/mads/globals.h b/engines/mads/globals.h index fa7a630f7f..e44e97fd3c 100644 --- a/engines/mads/globals.h +++ b/engines/mads/globals.h @@ -48,7 +48,7 @@ public: /** * Synchronize the globals data */ - void synchronize(Common::Serializer &s); + virtual void synchronize(Common::Serializer &s); }; } // End of namespace MADS diff --git a/engines/mads/hotspots.cpp b/engines/mads/hotspots.cpp index 02617e92c7..560726bda6 100644 --- a/engines/mads/hotspots.cpp +++ b/engines/mads/hotspots.cpp @@ -34,6 +34,10 @@ DynamicHotspot::DynamicHotspot() { _cursor = CURSOR_NONE; } +void DynamicHotspot::synchronize(Common::Serializer &s) { + +} + /*------------------------------------------------------------------------*/ DynamicHotspots::DynamicHotspots(MADSEngine *vm) : _vm(vm) { @@ -142,6 +146,20 @@ void DynamicHotspots::refresh() { } } +void DynamicHotspots::synchronize(Common::Serializer &s) { + int count = _entries.size(); + s.syncAsSint16LE(count); + + if (s.isSaving()) { + for (int i = 0; i < count; ++i) + _entries[i].synchronize(s); + } else { + DynamicHotspot rec; + rec.synchronize(s); + _entries.push_back(rec); + } +} + /*------------------------------------------------------------------------*/ Hotspot::Hotspot() { diff --git a/engines/mads/hotspots.h b/engines/mads/hotspots.h index 9e1cb44a4e..5fd910e1aa 100644 --- a/engines/mads/hotspots.h +++ b/engines/mads/hotspots.h @@ -43,7 +43,15 @@ public: int _articleNumber; CursorType _cursor; + /** + * Constructor + */ DynamicHotspot(); + + /** + * Synchronize the data + */ + void synchronize(Common::Serializer &s); }; #define DYNAMIC_HOTSPOTS_SIZE 8 @@ -67,6 +75,11 @@ public: void clear(); void reset(); void refresh(); + + /** + * Synchronize the data + */ + void synchronize(Common::Serializer &s); }; class Hotspot { diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp index 34eb6f140c..ce3f0869cd 100644 --- a/engines/mads/nebular/game_nebular.cpp +++ b/engines/mads/nebular/game_nebular.cpp @@ -38,6 +38,7 @@ namespace Nebular { GameNebular::GameNebular(MADSEngine *vm): Game(vm) { _surface = new MSurface(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT); _storyMode = STORYMODE_NAUGHTY; + _difficulty = DIFFICULTY_IMPOSSIBLE; } ProtectionResult GameNebular::checkCopyProtection() { @@ -749,6 +750,8 @@ void GameNebular::synchronize(Common::Serializer &s, bool phase1) { if (!phase1) { _globals.synchronize(s); + s.syncAsByte(_storyMode); + s.syncAsByte(_difficulty); } } diff --git a/engines/mads/nebular/game_nebular.h b/engines/mads/nebular/game_nebular.h index 0e2d564236..ab82cf68d7 100644 --- a/engines/mads/nebular/game_nebular.h +++ b/engines/mads/nebular/game_nebular.h @@ -34,6 +34,10 @@ namespace Nebular { enum StoryMode { STORYMODE_NAUGHTY = 1, STORYMODE_NICE = 2 }; +enum Difficulty { + DIFFICULTY_HARD = 1, DIFFICULTY_REALLY_HARD = 2, DIFFICULTY_IMPOSSIBLE = 3 +}; + enum InventoryObject { OBJ_NONE = -1, OBJ_BINOCULARS = 0, OBJ_BURGER = 1, OBJ_DEAD_FISH = 2, OBJ_STUFFED_FISH = 3, OBJ_REBREATHER = 4, OBJ_TIMER_MODULE = 5, OBJ_BIG_LEAVES = 6, OBJ_POISON_DARTS = 7, OBJ_PLANT_STALK = 8, @@ -65,6 +69,7 @@ protected: public: NebularGlobals _globals; StoryMode _storyMode; + Difficulty _difficulty; virtual Globals &globals() { return _globals; } diff --git a/engines/mads/nebular/globals_nebular.cpp b/engines/mads/nebular/globals_nebular.cpp index 4144797abc..d839d29d9a 100644 --- a/engines/mads/nebular/globals_nebular.cpp +++ b/engines/mads/nebular/globals_nebular.cpp @@ -39,6 +39,16 @@ NebularGlobals::NebularGlobals(): Globals() { _timebombTimer = 0; } +void NebularGlobals::synchronize(Common::Serializer &s) { + Globals::synchronize(s); + + s.syncAsUint32BE(_timebombClock); + s.syncAsUint32LE(_timebombTimer); + _spriteIndexes.synchronize(s); + _sequenceIndexes.synchronize(s); +} + + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/globals_nebular.h b/engines/mads/nebular/globals_nebular.h index 56fbc1b4ca..9a7873f5b5 100644 --- a/engines/mads/nebular/globals_nebular.h +++ b/engines/mads/nebular/globals_nebular.h @@ -26,6 +26,7 @@ #include "common/scummsys.h" #include "common/array.h" #include "mads/game.h" +#include "mads/resources.h" namespace MADS { @@ -281,28 +282,20 @@ enum { class NebularGlobals: public Globals { public: - Common::Array _spriteIndexes; - Common::Array _sequenceIndexes; + SynchronizedList _spriteIndexes; + SynchronizedList _sequenceIndexes; int _timebombClock, _timebombTimer; - /* - int _v0; - uint32 _frameTime; - int _v2; - int _v3; - int _v4; - int _v5; - int _v6; - uint32 _v7; - int _v8; - int _abortVal; - int _v84262, _v84264, _v84266, _v84268; - */ public: /** * Constructor */ NebularGlobals(); + + /** + * Synchronize the globals data + */ + virtual void synchronize(Common::Serializer &s); }; } // End of namespace Nebular diff --git a/engines/mads/player.cpp b/engines/mads/player.cpp index 2049042e07..0c9a496144 100644 --- a/engines/mads/player.cpp +++ b/engines/mads/player.cpp @@ -695,71 +695,70 @@ void Player::releasePlayerSprites() { } 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.syncAsSint16LE(_posDiff.x); + s.syncAsSint16LE(_posDiff.y); + s.syncAsSint16LE(_posChange.x); + s.syncAsSint16LE(_posChange.y); s.syncAsUint16LE(_targetFacing); - s.syncAsByte(_spritesChanged); - s.syncAsByte(_walkAnywhere); - s.syncAsByte(_walkOffScreen); + s.syncAsSint16LE(_special); + s.syncAsByte(_forceRefresh); s.syncAsSint16LE(_ticksAmount); - s.syncAsSint16LE(_centerOfGravity); + s.syncAsByte(_walkAnywhere); s.syncAsUint16LE(_walkOffScreenSceneId); + s.syncAsByte(_walkOffScreen); s.syncAsByte(_needToWalk); s.syncAsByte(_readyToWalk); s.syncAsUint16LE(_prepareWalkFacing); s.syncAsSint16LE(_prepareWalkPos.x); s.syncAsSint16LE(_prepareWalkPos.y); + s.syncAsByte(_stepEnabled); + s.syncAsByte(_visible); + s.syncAsByte(_priorVisible); - s.syncAsByte(_mirror); - s.syncAsUint16LE(_frameCount); + s.syncAsSint16LE(_spritesStart); + for (int i = 0; i < 8; ++i) + s.syncAsByte(_spriteSetsPresent[i]); + + s.syncAsByte(_facing); + s.syncAsByte(_turnToFacing); + s.syncAsSint16LE(_spritesIdx); + s.syncAsSint16LE(_frameNumber); + s.syncAsSint16LE(_currentDepth); + s.syncAsSint16LE(_currentScale); 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; - } - } + s.syncAsSint16LE(_scalingVelocity); + s.syncAsSint16LE(_pixelAccum); + s.syncAsSint16LE(_distAccum); + s.syncAsSint16LE(_deltaDistance); + s.syncAsSint16LE(_totalDistance); + s.syncAsSint16LE(_velocity); + s.syncAsUint16LE(_frameCount); + synchronizeString(s, _spritesPrefix); + s.syncAsUint32LE(_priorTimer); + s.syncAsSint16LE(_numSprites); + s.syncAsByte(_loadsFirst); + s.syncAsByte(_loadedFirst); + s.syncAsByte(_spritesLoaded); + s.syncAsByte(_spritesChanged); + s.syncAsByte(_beenVisible); + s.syncAsSint16LE(_centerOfGravity); + s.syncAsByte(_mirror); } } // End of namespace MADS diff --git a/engines/mads/resources.cpp b/engines/mads/resources.cpp index b6caed7b0c..f0609448bb 100644 --- a/engines/mads/resources.cpp +++ b/engines/mads/resources.cpp @@ -384,4 +384,45 @@ void File::openFile(const Common::String &filename) { error("Could not open file - %s", filename.c_str()); } +/*------------------------------------------------------------------------*/ + +void SynchronizedList::synchronize(Common::Serializer &s) { + int v; + int count = size(); + s.syncAsUint16LE(count); + + if (s.isSaving()) { + for (int idx = 0; idx < count; ++idx) { + v = (*this)[idx]; + s.syncAsSint32LE(v); + } + } else { + clear(); + reserve(count); + for (int idx = 0; idx < count; ++idx) { + s.syncAsSint32LE(v); + push_back(v); + } + } +} + +/*------------------------------------------------------------------------*/ + +void synchronizeString(Common::Serializer &s, Common::String &str) { + int len = str.size(); + char c; + s.syncAsUint16LE(len); + + if (s.isSaving()) { + s.syncBytes((byte *)str.c_str(), len); + } else { + str.clear(); + for (int i = 0; i < len; ++i) { + s.syncAsByte(c); + str += c; + } + } +} + + } // End of namespace MADS diff --git a/engines/mads/resources.h b/engines/mads/resources.h index 3d5d582707..7d56138da5 100644 --- a/engines/mads/resources.h +++ b/engines/mads/resources.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/file.h" +#include "common/serializer.h" #include "common/str.h" namespace MADS { @@ -75,6 +76,19 @@ public: void openFile(const Common::String &filename); }; +class SynchronizedList : public Common::Array { +public: + /** + * Synchronize the list + */ + void synchronize(Common::Serializer &s); +}; + +/** +* Synchronize string support method +*/ +void synchronizeString(Common::Serializer &s, Common::String &str); + } // End of namespace MADS #endif /* MADS_RESOURCES_H */ diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index 5c86e4590e..e53061c750 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -705,10 +705,14 @@ void Scene::freeAnimation() { } void Scene::synchronize(Common::Serializer &s) { - _action._activeAction.synchronize(s); + _action.synchronize(s); _rails.synchronize(s); _userInterface.synchronize(s); - _sceneLogic->synchronize(s); + s.syncAsByte(_reloadSceneFlag); + s.syncAsByte(_roomChanged); + s.syncAsUint16LE(_nextSceneId); + s.syncAsUint16LE(_priorSceneId); + _dynamicHotspots.synchronize(s); } } // End of namespace MADS diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h index 9b1825f4b7..c295ae0de8 100644 --- a/engines/mads/scene_data.h +++ b/engines/mads/scene_data.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/serializer.h" #include "common/str.h" #include "common/str-array.h" #include "common/rect.h" diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index ea73d41222..640617e127 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -529,6 +529,11 @@ void ScreenObjects::setActive(ScrCategory category, int descId, bool active) { } } +void ScreenObjects::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_selectedObject); + s.syncAsSint16LE(_category); +} + /*------------------------------------------------------------------------*/ ScreenSurface::ScreenSurface() { diff --git a/engines/mads/screen.h b/engines/mads/screen.h index ba01cbc468..4ad5820d14 100644 --- a/engines/mads/screen.h +++ b/engines/mads/screen.h @@ -189,6 +189,11 @@ public: * @param active Whether to set item as active or not */ void setActive(ScrCategory category, int descId, bool active); + + /** + * Synchronize the data + */ + void synchronize(Common::Serializer &s); }; class ScreenSurface : public MSurface { diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp index 194fda0164..8208c14f4d 100644 --- a/engines/mads/user_interface.cpp +++ b/engines/mads/user_interface.cpp @@ -1092,6 +1092,9 @@ void UserInterface::synchronize(Common::Serializer &s) { if (s.isLoading()) { _selectedInvIndex = invObjects._inventoryList.empty() ? -1 : 0; } + + for (int i = 0; i < 8; ++i) + s.syncAsSint16LE(_categoryIndexes[i]); } } // End of namespace MADS -- cgit v1.2.3