aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-04-21 22:51:03 -0500
committerPaul Gilbert2015-04-21 22:51:03 -0500
commit0984405a0dbe718522117507d7c75dc619c586a8 (patch)
tree4755b06e6838a93847d09d48bd1d425ba1010674
parent31860163709b12a38856fc017a217eb5e32610a7 (diff)
downloadscummvm-rg350-0984405a0dbe718522117507d7c75dc619c586a8.tar.gz
scummvm-rg350-0984405a0dbe718522117507d7c75dc619c586a8.tar.bz2
scummvm-rg350-0984405a0dbe718522117507d7c75dc619c586a8.zip
SHERLOCK: Implement savegame synchronization
-rw-r--r--engines/sherlock/inventory.cpp20
-rw-r--r--engines/sherlock/inventory.h3
-rw-r--r--engines/sherlock/journal.cpp31
-rw-r--r--engines/sherlock/journal.h5
-rw-r--r--engines/sherlock/people.cpp13
-rw-r--r--engines/sherlock/people.h5
-rw-r--r--engines/sherlock/saveload.cpp71
-rw-r--r--engines/sherlock/saveload.h6
-rw-r--r--engines/sherlock/scene.cpp61
-rw-r--r--engines/sherlock/scene.h5
-rw-r--r--engines/sherlock/screen.cpp10
-rw-r--r--engines/sherlock/screen.h3
-rw-r--r--engines/sherlock/sherlock.cpp10
-rw-r--r--engines/sherlock/sherlock.h3
-rw-r--r--engines/sherlock/talk.cpp12
-rw-r--r--engines/sherlock/talk.h6
-rw-r--r--engines/sherlock/user_interface.cpp2
17 files changed, 234 insertions, 32 deletions
diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp
index 9eedac7c6a..3ba6f9d2bd 100644
--- a/engines/sherlock/inventory.cpp
+++ b/engines/sherlock/inventory.cpp
@@ -486,4 +486,24 @@ int Inventory::deleteItemFromInventory(const Common::String &name) {
return 1;
}
+/**
+ * Synchronize the data for a savegame
+ */
+void Inventory::synchronize(Common::Serializer &s) {
+ s.syncAsSint16LE(_holdings);
+
+ uint count = size();
+ s.syncAsUint16LE(count);
+ if (s.isLoading()) {
+ resize(count);
+
+ // Reset inventory back to start
+ _invIndex = 0;
+ }
+
+ for (uint idx = 0; idx < size(); ++idx) {
+ // TODO
+ }
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h
index 4e426beaf4..bccdc9336e 100644
--- a/engines/sherlock/inventory.h
+++ b/engines/sherlock/inventory.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/serializer.h"
#include "common/str-array.h"
#include "sherlock/objects.h"
#include "sherlock/resources.h"
@@ -99,6 +100,8 @@ public:
int putItemInInventory(Object &obj);
int deleteItemFromInventory(const Common::String &name);
+
+ void synchronize(Common::Serializer &s);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp
index f9c2c54289..15d3a07c75 100644
--- a/engines/sherlock/journal.cpp
+++ b/engines/sherlock/journal.cpp
@@ -1175,4 +1175,35 @@ int Journal::getFindName(bool printError) {
return done;
}
+/**
+ * Reset viewing position to the start of the journal
+ */
+void Journal::resetPosition() {
+ _index = _sub = _up = _down = 0;
+ _page = 1;
+}
+
+/**
+ * Synchronize the data for a savegame
+ */
+void Journal::synchronize(Common::Serializer &s) {
+ s.syncAsSint16LE(_count);
+ s.syncAsSint16LE(_index);
+ s.syncAsSint16LE(_sub);
+ s.syncAsSint16LE(_page);
+ s.syncAsSint16LE(_maxPage);
+
+ int journalCount = _journal.size();
+ if (s.isLoading())
+ _journal.resize(journalCount);
+
+ for (uint idx = 0; idx < _journal.size(); ++idx) {
+ JournalEntry &je = _journal[idx];
+
+ s.syncAsSint16LE(je._converseNum);
+ s.syncAsByte(je._replyOnly);
+ s.syncAsSint16LE(je._statementNum);
+ }
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h
index 894065759b..9db4b28665 100644
--- a/engines/sherlock/journal.h
+++ b/engines/sherlock/journal.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/serializer.h"
#include "common/str-array.h"
#include "common/stream.h"
@@ -77,6 +78,10 @@ public:
void drawInterface();
bool handleEvents(int key);
+
+ void resetPosition();
+
+ void synchronize(Common::Serializer &s);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index d22c08f625..86c560a1d9 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -203,7 +203,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) {
_portraitSide = 0;
_speakerFlip = false;
_holmesFlip = false;
- _homesQuotient = 0;
+ _holmesQuotient = 0;
_portrait._sequences = new byte[32];
}
@@ -700,4 +700,15 @@ void People::setTalking(int speaker) {
}
}
+/**
+ * Synchronize the data for a savegame
+ */
+void People::synchronize(Common::Serializer &s) {
+ s.syncAsByte(_holmesOn);
+ s.syncAsSint16LE(_data[AL]._position.x);
+ s.syncAsSint16LE(_data[AL]._position.y);
+ s.syncAsSint16LE(_data[AL]._sequenceNumber);
+ s.syncAsSint16LE(_holmesQuotient);
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index 593b516ee6..94f1d05c0d 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -24,6 +24,7 @@
#define SHERLOCK_PEOPLE_H
#include "common/scummsys.h"
+#include "common/serializer.h"
#include "common/stack.h"
#include "sherlock/objects.h"
@@ -84,7 +85,7 @@ public:
int _portraitSide;
bool _speakerFlip;
bool _holmesFlip;
- int _homesQuotient;
+ int _holmesQuotient;
public:
People(SherlockEngine *vm);
~People();
@@ -118,6 +119,8 @@ public:
void clearTalking();
void setTalking(int speaker);
+
+ void synchronize(Common::Serializer &s);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp
index 78c86c836e..0cdf1d228f 100644
--- a/engines/sherlock/saveload.cpp
+++ b/engines/sherlock/saveload.cpp
@@ -44,6 +44,7 @@ SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) :
_vm(vm), _target(target) {
_saveThumb = nullptr;
_envMode = SAVEMODE_NONE;
+ _justLoaded = false;
}
SaveManager::~SaveManager() {
@@ -308,14 +309,80 @@ void SaveManager::highlightButtons(int btnIndex) {
* Load the game in the specified slot
*/
void SaveManager::loadGame(int slot) {
- // TODO
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
+ generateSaveName(slot));
+ Common::Serializer s(saveFile, nullptr);
+
+ // Load the savaegame header
+ SherlockSavegameHeader header;
+ if (!readSavegameHeader(saveFile, header))
+ error("Invalid savegame");
+
+ if (header._thumbnail) {
+ header._thumbnail->free();
+ delete header._thumbnail;
+ }
+
+ // Synchronize the savegame data
+ synchronize(s);
+
+ delete saveFile;
}
/**
* Save the game in the specified slot with the given name
*/
void SaveManager::saveGame(int slot, const Common::String &name) {
- // TODO
+ Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(
+ generateSaveName(slot));
+
+ SherlockSavegameHeader header;
+ header._saveName = name;
+ writeSavegameHeader(out, header);
+
+ Common::Serializer s(nullptr, out);
+ synchronize(s);
+
+ out->finalize();
+ delete out;
+}
+
+/**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+Common::String SaveManager::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _target.c_str(), slot);
+}
+
+/**
+ * Synchronize the data for a savegame
+ */
+void SaveManager::synchronize(Common::Serializer &s) {
+ Journal &journal = *_vm->_journal;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+
+ int oldFont = screen.fontNumber();
+
+ journal.synchronize(s);
+ people.synchronize(s);
+ scene.synchronize(s);
+ screen.synchronize(s);
+ talk.synchronize(s);
+ _vm->synchronize(s);
+
+ if (screen.fontNumber() != oldFont)
+ journal.resetPosition();
+ /*
+ char room_flags[MAX_ROOMS * 9];
+
+ */
+
+ _vm->_loadingSavedGame = true;
+ _justLoaded = true;
}
/**
diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h
index 20ce4e6067..0dad6256ca 100644
--- a/engines/sherlock/saveload.h
+++ b/engines/sherlock/saveload.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/savefile.h"
+#include "common/serializer.h"
#include "common/str-array.h"
#include "engines/savestate.h"
#include "graphics/surface.h"
@@ -56,10 +57,15 @@ private:
Graphics::Surface *_saveThumb;
void createSavegameList();
+
+ Common::String generateSaveName(int slot);
+
+ void synchronize(Common::Serializer &s);
public:
Common::StringArray _savegames;
int _savegameIndex;
SaveMode _envMode;
+ bool _justLoaded;
public:
SaveManager(SherlockEngine *vm, const Common::String &target);
~SaveManager();
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index 575523bc45..4671dbdade 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -85,7 +85,7 @@ void SceneSound::synchronize(Common::SeekableReadStream &s) {
Scene::Scene(SherlockEngine *vm): _vm(vm) {
for (int idx = 0; idx < SCENES_COUNT; ++idx)
- Common::fill(&_stats[idx][0], &_stats[idx][9], false);
+ Common::fill(&_sceneStats[idx][0], &_sceneStats[idx][65], false);
_currentScene = -1;
_goToScene = -1;
_changes = false;
@@ -195,6 +195,7 @@ bool Scene::loadScene(const Common::String &filename) {
Events &events = *_vm->_events;
Map &map = *_vm->_map;
People &people = *_vm->_people;
+ SaveManager &saves = *_vm->_saves;
Screen &screen = *_vm->_screen;
Sound &sound = *_vm->_sound;
UserInterface &ui = *_vm->_ui;
@@ -398,7 +399,7 @@ bool Scene::loadScene(const Common::String &filename) {
_changes = false;
checkSceneStatus();
- if (!_vm->_justLoaded) {
+ if (!saves._justLoaded) {
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
if (_bgShapes[idx]._type == HIDDEN && _bgShapes[idx]._aType == TALK_EVERY)
_bgShapes[idx].toggleHidden();
@@ -450,30 +451,25 @@ bool Scene::loadScene(const Common::String &filename) {
* opening or moving them
*/
void Scene::checkSceneStatus() {
- if (_stats[_currentScene][8]) {
- for (int idx = 0; idx < 8; ++idx) {
- int val = _stats[_currentScene][idx];
+ if (_sceneStats[_currentScene][65]) {
+ for (uint idx = 0; idx < 64; ++idx) {
+ int val = _sceneStats[_currentScene][idx];
- for (int bit = 0; bit < 8; ++bit) {
- uint objNumber = idx * 8 + bit;
- if (objNumber < _bgShapes.size()) {
- Object &obj = _bgShapes[objNumber];
+ if (idx < _bgShapes.size()) {
+ Object &obj = _bgShapes[idx];
- if (val & 1) {
- // No shape to erase, so flag as hidden
- obj._type = HIDDEN;
- } else if (obj._images == nullptr || obj._images->size() == 0) {
- // No shape
- obj._type = NO_SHAPE;
- } else {
- obj._type = ACTIVE_BG_SHAPE;
- }
+ if (val & 1) {
+ // No shape to erase, so flag as hidden
+ obj._type = HIDDEN;
+ } else if (obj._images == nullptr || obj._images->size() == 0) {
+ // No shape
+ obj._type = NO_SHAPE;
} else {
- // Finished checks
- return;
+ obj._type = ACTIVE_BG_SHAPE;
}
-
- val >>= 1;
+ } else {
+ // Finished checks
+ return;
}
}
}
@@ -560,6 +556,7 @@ void Scene::checkInventory() {
*/
void Scene::transitionToScene() {
People &people = *_vm->_people;
+ SaveManager &saves = *_vm->_saves;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
@@ -583,7 +580,7 @@ void Scene::transitionToScene() {
// Exit information exists, translate it to real sequence info
// Note: If a savegame was just loaded, then the data is already correct.
// Otherwise, this is a linked scene or entrance info, and must be translated
- if (_hsavedFs < 8 && !_vm->_justLoaded) {
+ if (_hsavedFs < 8 && !saves._justLoaded) {
_hsavedFs = FS_TRANS[_hsavedFs];
_hsavedPos.x *= 100;
_hsavedPos.y *= 100;
@@ -1457,4 +1454,22 @@ int Scene::closestZone(const Common::Point &pt) {
return zone;
}
+/**
+ * Synchronize the data for a savegame
+ */
+void Scene::synchronize(Common::Serializer &s) {
+ s.syncAsSint16LE(_bigPos.x);
+ s.syncAsSint16LE(_bigPos.y);
+ s.syncAsSint16LE(_overPos.x);
+ s.syncAsSint16LE(_overPos.y);
+ s.syncAsSint16LE(_oldCharPoint);
+ s.syncAsSint16LE(_goToScene);
+
+ for (int sceneNum = 0; sceneNum < SCENES_COUNT; ++sceneNum) {
+ for (int flag = 0; flag < 65; ++flag) {
+ s.syncAsByte(_sceneStats[sceneNum][flag]);
+ }
+ }
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index 3549325e8e..cc01fa92ab 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/rect.h"
+#include "common/serializer.h"
#include "sherlock/objects.h"
#include "sherlock/resources.h"
@@ -104,7 +105,7 @@ public:
int _currentScene;
int _goToScene;
bool _changes;
- bool _stats[SCENES_COUNT][9];
+ bool _sceneStats[SCENES_COUNT][65];
bool _savedStats[SCENES_COUNT][9];
Common::Point _bigPos;
Common::Point _overPos;
@@ -167,6 +168,8 @@ public:
int closestZone(const Common::Point &pt);
void updateBackground();
+
+ void synchronize(Common::Serializer &s);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp
index a30108118c..3c9a10e4a1 100644
--- a/engines/sherlock/screen.cpp
+++ b/engines/sherlock/screen.cpp
@@ -480,4 +480,14 @@ Common::Rect Screen::getDisplayBounds() {
return Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
}
+/**
+ * Synchronize the data for a savegame
+ */
+void Screen::synchronize(Common::Serializer &s) {
+ int fontNumber = _fontNumber;
+ s.syncAsByte(fontNumber);
+ if (s.isLoading())
+ setFont(fontNumber);
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h
index 2cfd7c8a88..a8bdc53b5a 100644
--- a/engines/sherlock/screen.h
+++ b/engines/sherlock/screen.h
@@ -25,6 +25,7 @@
#include "common/list.h"
#include "common/rect.h"
+#include "common/serializer.h"
#include "graphics/surface.h"
#include "sherlock/graphics.h"
#include "sherlock/resources.h"
@@ -128,6 +129,8 @@ public:
Common::Rect getDisplayBounds();
int fontNumber() const { return _fontNumber; }
+
+ void synchronize(Common::Serializer &s);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index d0744c4775..bc7b545719 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -45,7 +45,6 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
_talk = nullptr;
_ui = nullptr;
_useEpilogue2 = false;
- _justLoaded = false;
_loadingSavedGame = false;
_onChessboard = false;
_slowChess = false;
@@ -185,4 +184,13 @@ void SherlockEngine::saveConfig() {
// TODO
}
+
+/**
+ * Synchronize the data for a savegame
+ */
+void SherlockEngine::synchronize(Common::Serializer &s) {
+ for (uint idx = 0; idx < _flags.size(); ++idx)
+ s.syncAsByte(_flags[idx]);
+}
+
} // End of namespace Comet
diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h
index 20afb6f0e3..48850fff06 100644
--- a/engines/sherlock/sherlock.h
+++ b/engines/sherlock/sherlock.h
@@ -101,7 +101,6 @@ public:
Common::String _soundOverride;
Common::String _titleOverride;
bool _useEpilogue2;
- bool _justLoaded;
bool _loadingSavedGame;
int _oldCharPoint; // Old scene
Common::Point _over; // Old map position
@@ -131,6 +130,8 @@ public:
void freeSaveGameList();
void saveConfig();
+
+ void synchronize(Common::Serializer &s);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index 158cae38a9..6740e89efc 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -1745,4 +1745,16 @@ void Talk::popStack() {
}
}
+/**
+ * Synchronize the data for a savegame
+ */
+void Talk::synchronize(Common::Serializer &s) {
+ for (int idx = 0; idx < MAX_TALK_FILES; ++idx) {
+ TalkHistoryEntry &he = _talkHistory[idx];
+
+ for (int flag = 0; flag < 16; ++flag)
+ s.syncAsByte(he._data[flag]);
+ }
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h
index 4a33f2f557..620a986454 100644
--- a/engines/sherlock/talk.h
+++ b/engines/sherlock/talk.h
@@ -26,12 +26,14 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/rect.h"
+#include "common/serializer.h"
#include "common/stream.h"
#include "common/stack.h"
namespace Sherlock {
#define MAX_TALK_SEQUENCES 11
+#define MAX_TALK_FILES 500
struct SequenceEntry {
int _objNum;
@@ -93,7 +95,7 @@ private:
Common::Stack<SequenceEntry> _sequenceStack;
Common::Stack<ScriptStackEntry> _scriptStack;
Common::Array<Statement> _statements;
- TalkHistoryEntry _talkHistory[500];
+ TalkHistoryEntry _talkHistory[MAX_TALK_FILES];
int _speaker;
int _talkIndex;
int _scriptSelect;
@@ -145,6 +147,8 @@ public:
bool isSequencesEmpty() const { return _scriptStack.empty(); }
void popStack();
+
+ void synchronize(Common::Serializer &s);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp
index c8cd300b5e..f7f387e9ad 100644
--- a/engines/sherlock/user_interface.cpp
+++ b/engines/sherlock/user_interface.cpp
@@ -1820,7 +1820,7 @@ void UserInterface::doTalkControl() {
// Add any Holmes point to Holmes' total, if any
if (talk._statements[_selector]._quotient)
- people._homesQuotient += talk._statements[_selector]._quotient;
+ people._holmesQuotient += talk._statements[_selector]._quotient;
}
// Flag the response as having been used