aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2014-04-26 11:01:21 -0400
committerPaul Gilbert2014-04-26 11:01:21 -0400
commitbb5edf5426c3d8717d3a3f843a3dbf6193bbe9e9 (patch)
treeabd149381ed333a565cadb1cee3bce7eec8a5f1c
parentbae0a6590a4ba843ef51f4cc67875c578863f5b2 (diff)
downloadscummvm-rg350-bb5edf5426c3d8717d3a3f843a3dbf6193bbe9e9.tar.gz
scummvm-rg350-bb5edf5426c3d8717d3a3f843a3dbf6193bbe9e9.tar.bz2
scummvm-rg350-bb5edf5426c3d8717d3a3f843a3dbf6193bbe9e9.zip
MADS: Implemented more save/load logic
-rw-r--r--engines/mads/game.cpp47
-rw-r--r--engines/mads/game.h2
-rw-r--r--engines/mads/game_data.cpp19
-rw-r--r--engines/mads/game_data.h5
-rw-r--r--engines/mads/mads.cpp10
-rw-r--r--engines/mads/mads.h10
6 files changed, 88 insertions, 5 deletions
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
index 50c3ccd916..9a5ec1264b 100644
--- a/engines/mads/game.cpp
+++ b/engines/mads/game.cpp
@@ -51,7 +51,7 @@ Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm),
_sectionNumber = _priorSectionNumber = 0;
_difficulty = DIFFICULTY_HARD;
_loadGameSlot = -1;
- _serializer = nullptr;
+ _saveFile = nullptr;
_statusFlag = 0;
_sectionHandler = nullptr;
_sectionNumber = 1;
@@ -79,6 +79,7 @@ Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm),
}
Game::~Game() {
+ delete _saveFile;
delete _surface;
delete _sectionHandler;
}
@@ -118,7 +119,7 @@ void Game::run() {
// Get the initial starting time for the first scene
_scene._frameStartTime = _vm->_events->getFrameCounter();
- if (_serializer == nullptr && protectionResult != -1 && protectionResult != -2) {
+ if (_saveFile == nullptr && protectionResult != -1 && protectionResult != -2) {
initSection(_sectionNumber);
_statusFlag = true;
@@ -142,8 +143,10 @@ void Game::run() {
void Game::gameLoop() {
while (!_vm->shouldQuit() && _statusFlag) {
- if (_serializer)
- synchronize(*_serializer, true);
+ if (_loadGameSlot != -1) {
+ loadGame(_loadGameSlot);
+ _loadGameSlot = -1;
+ }
setSectionHandler();
_sectionHandler->preLoadSection();
@@ -255,6 +258,13 @@ void Game::sectionLoop() {
_triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_scene._sceneLogic->enter();
+ // If in the middle of restoring a game, handle the rest of the loading
+ if (_saveFile != nullptr) {
+ Common::Serializer s(_saveFile, nullptr);
+ synchronize(s, false);
+ delete _saveFile;
+ }
+
// Set player data
_player._targetPos = _player._playerPos;
_player._turnToFacing = _player._facing;
@@ -420,6 +430,7 @@ void Game::synchronize(Common::Serializer &s, bool phase1) {
if (phase1) {
s.syncAsUint16LE(_scene._nextSceneId);
s.syncAsUint16LE(_scene._priorSceneId);
+ _visitedScenes.synchronize(s);
if (s.isLoading()) {
_sectionNumber = _scene._nextSceneId / 100;
@@ -439,11 +450,39 @@ void Game::synchronize(Common::Serializer &s, bool phase1) {
}
void Game::loadGame(int slotNumber) {
+ _saveFile = g_system->getSavefileManager()->openForLoading(
+ _vm->generateSaveName(slotNumber));
+
+ Common::Serializer s(_saveFile, nullptr);
+
+ // Load the savaegame header
+ MADSSavegameHeader header;
+ if (!readSavegameHeader(_saveFile, header))
+ error("Invalid savegame");
+
+ if (header._thumbnail) {
+ header._thumbnail->free();
+ delete header._thumbnail;
+ }
+ // Load the initial data such as what scene needs to be loaded up
+ synchronize(s, true);
}
void Game::saveGame(int slotNumber, const Common::String &saveName) {
+ Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(
+ _vm->generateSaveName(slotNumber));
+
+ MADSSavegameHeader header;
+ header._saveName = saveName;
+ writeSavegameHeader(out, header);
+
+ Common::Serializer s(nullptr, out);
+ synchronize(s, true);
+ synchronize(s, false);
+ out->finalize();
+ delete out;
}
const char *const SAVEGAME_STR = "MADS";
diff --git a/engines/mads/game.h b/engines/mads/game.h
index 8334d94256..982f880dca 100644
--- a/engines/mads/game.h
+++ b/engines/mads/game.h
@@ -92,7 +92,7 @@ protected:
bool _anyEmergency;
int _loadGameSlot;
Common::String _saveName;
- Common::Serializer *_serializer;
+ Common::InSaveFile *_saveFile;
/**
* Constructor
diff --git a/engines/mads/game_data.cpp b/engines/mads/game_data.cpp
index 0f41692e2c..9211bbfa5a 100644
--- a/engines/mads/game_data.cpp
+++ b/engines/mads/game_data.cpp
@@ -46,4 +46,23 @@ bool VisitedScenes::exists(int sceneId) {
return false;
}
+void VisitedScenes::synchronize(Common::Serializer &s) {
+ int 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);
+ }
+ }
+}
+
} // End of namespace MADS
diff --git a/engines/mads/game_data.h b/engines/mads/game_data.h
index 8b31e5260c..1a8791e815 100644
--- a/engines/mads/game_data.h
+++ b/engines/mads/game_data.h
@@ -47,6 +47,11 @@ public:
* Adds a scene Id to the list of previously visited scenes, if it doesn't already exist
*/
void add(int sceneId);
+
+ /**
+ * Synchronizes the list
+ */
+ void synchronize(Common::Serializer &s);
};
class SectionHandler {
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index 1df41ad3fd..cb84f4da88 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -138,4 +138,14 @@ Common::String MADSEngine::generateSaveName(int slot) {
return Common::String::format("%s.%03d", _targetName.c_str(), slot);
}
+Common::Error MADSEngine::loadGameState(int slot) {
+ _game->loadGame(slot);
+ return Common::kNoError;
+}
+
+Common::Error MADSEngine::saveGameState(int slot, const Common::String &desc) {
+ _game->saveGame(slot, desc);
+ return Common::kNoError;
+}
+
} // End of namespace MADS
diff --git a/engines/mads/mads.h b/engines/mads/mads.h
index 8a4b7f64d1..9acd469d27 100644
--- a/engines/mads/mads.h
+++ b/engines/mads/mads.h
@@ -135,6 +135,16 @@ public:
* @param slot Slot number
*/
Common::String generateSaveName(int slot);
+
+ /**
+ * Handles loading a game via the GMM
+ */
+ virtual Common::Error loadGameState(int slot);
+
+ /**
+ * Handles saving the game via the GMM
+ */
+ virtual Common::Error saveGameState(int slot, const Common::String &desc);
};
} // End of namespace MADS