aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mads/action.cpp8
-rw-r--r--engines/mads/action.h3
-rw-r--r--engines/mads/game.cpp34
-rw-r--r--engines/mads/game.h10
-rw-r--r--engines/mads/inventory.cpp63
-rw-r--r--engines/mads/inventory.h10
-rw-r--r--engines/mads/messages.cpp2
-rw-r--r--engines/mads/nebular/nebular_scenes2.cpp2
-rw-r--r--engines/mads/player.cpp72
-rw-r--r--engines/mads/player.h9
-rw-r--r--engines/mads/rails.cpp17
-rw-r--r--engines/mads/rails.h7
-rw-r--r--engines/mads/scene.cpp5
-rw-r--r--engines/mads/scene.h5
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