Skip to content

Commit

Permalink
SHERLOCK: Implement savegame synchronization
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Apr 22, 2015
1 parent 3186016 commit 0984405
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 32 deletions.
20 changes: 20 additions & 0 deletions engines/sherlock/inventory.cpp
Expand Up @@ -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
3 changes: 3 additions & 0 deletions engines/sherlock/inventory.h
Expand Up @@ -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"
Expand Down Expand Up @@ -99,6 +100,8 @@ class Inventory : public Common::Array<InventoryItem> {
int putItemInInventory(Object &obj);

int deleteItemFromInventory(const Common::String &name);

void synchronize(Common::Serializer &s);
};

} // End of namespace Sherlock
Expand Down
31 changes: 31 additions & 0 deletions engines/sherlock/journal.cpp
Expand Up @@ -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
5 changes: 5 additions & 0 deletions engines/sherlock/journal.h
Expand Up @@ -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"

Expand Down Expand Up @@ -77,6 +78,10 @@ class Journal {
void drawInterface();

bool handleEvents(int key);

void resetPosition();

void synchronize(Common::Serializer &s);
};

} // End of namespace Sherlock
Expand Down
13 changes: 12 additions & 1 deletion engines/sherlock/people.cpp
Expand Up @@ -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];
}
Expand Down Expand Up @@ -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
5 changes: 4 additions & 1 deletion engines/sherlock/people.h
Expand Up @@ -24,6 +24,7 @@
#define SHERLOCK_PEOPLE_H

#include "common/scummsys.h"
#include "common/serializer.h"
#include "common/stack.h"
#include "sherlock/objects.h"

Expand Down Expand Up @@ -84,7 +85,7 @@ class People {
int _portraitSide;
bool _speakerFlip;
bool _holmesFlip;
int _homesQuotient;
int _holmesQuotient;
public:
People(SherlockEngine *vm);
~People();
Expand Down Expand Up @@ -118,6 +119,8 @@ class People {

void clearTalking();
void setTalking(int speaker);

void synchronize(Common::Serializer &s);
};

} // End of namespace Sherlock
Expand Down
71 changes: 69 additions & 2 deletions engines/sherlock/saveload.cpp
Expand Up @@ -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() {
Expand Down Expand Up @@ -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;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions engines/sherlock/saveload.h
Expand Up @@ -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"
Expand Down Expand Up @@ -56,10 +57,15 @@ class SaveManager {
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();
Expand Down
61 changes: 38 additions & 23 deletions engines/sherlock/scene.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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

0 comments on commit 0984405

Please sign in to comment.