aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/access/access.cpp61
-rw-r--r--engines/access/access.h33
-rw-r--r--engines/access/detection.cpp18
-rw-r--r--engines/access/room.cpp9
4 files changed, 119 insertions, 2 deletions
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index f6382262fd..a039139f0a 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -72,6 +72,7 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_scaleMaxY = 0;
_scaleI = 0;
_scaleFlag = false;
+ _canSaveLoad = false;
_eseg = nullptr;
_conversation = 0;
@@ -387,6 +388,66 @@ void AccessEngine::freeChar() {
_animation->freeAnimationData();
}
+Common::Error AccessEngine::saveGameState(int slot, const Common::String &desc) {
+ Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(
+ generateSaveName(slot));
+ if (!out)
+ return Common::kCreatingFileFailed;
+
+ AccessSavegameHeader header;
+ header._saveName = desc;
+ writeSavegameHeader(out, header);
+
+ Common::Serializer s(nullptr, out);
+ synchronize(s);
+
+ out->finalize();
+ delete out;
+
+ return Common::kNoError;
+}
+
+Common::Error AccessEngine::loadGameState(int slot) {
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
+ generateSaveName(slot));
+ if (!saveFile)
+ return Common::kReadingFailed;
+
+ Common::Serializer s(saveFile, nullptr);
+
+ // Load the savaegame header
+ AccessSavegameHeader header;
+ if (!readSavegameHeader(saveFile, header))
+ error("Invalid savegame");
+
+ if (header._thumbnail) {
+ header._thumbnail->free();
+ delete header._thumbnail;
+ }
+
+ // Load most of the savegame data
+ synchronize(s);
+ delete saveFile;
+
+ // Set extra post-load state
+ _room->_function = 1;
+ _timers._timersSavedFlag = false;
+
+ return Common::kNoError;
+}
+
+Common::String AccessEngine::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+bool AccessEngine::canLoadGameStateCurrently() {
+ return _canSaveLoad;
+}
+
+bool AccessEngine::canSaveGameStateCurrently() {
+ return _canSaveLoad;
+}
+
void AccessEngine::synchronize(Common::Serializer &s) {
s.syncAsUint16LE(_conversation);
s.syncAsUint16LE(_currentMan);
diff --git a/engines/access/access.h b/engines/access/access.h
index a192da3904..8e7c42f959 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -114,6 +114,12 @@ protected:
void speakText(ASurface *s, Common::Array<Common::String>msgArr);
+ /**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+ Common::String AccessEngine::generateSaveName(int slot);
+
// Engine APIs
virtual Common::Error run();
virtual bool hasFeature(EngineFeature f) const;
@@ -180,6 +186,7 @@ public:
int _scaleMaxY;
int _scaleI;
bool _scaleFlag;
+ bool _canSaveLoad;
Resource *_eseg;
int _et;
@@ -261,8 +268,34 @@ public:
void freeChar();
+ /**
+ * Load a savegame
+ */
+ virtual Common::Error loadGameState(int slot);
+
+ /**
+ * Save the game
+ */
+ virtual Common::Error saveGameState(int slot, const Common::String &desc);
+
+ /**
+ * Returns true if a savegame can currently be loaded
+ */
+ bool canLoadGameStateCurrently();
+
+ /**
+ * Returns true if the game can currently be saved
+ */
+ bool canSaveGameStateCurrently();
+
+ /**
+ * Read in a savegame header
+ */
static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header);
+ /**
+ * Write out a savegame header
+ */
void writeSavegameHeader(Common::OutSaveFile *out, AccessSavegameHeader &header);
};
diff --git a/engines/access/detection.cpp b/engines/access/detection.cpp
index 293cd3dccb..59c4bc4738 100644
--- a/engines/access/detection.cpp
+++ b/engines/access/detection.cpp
@@ -177,6 +177,24 @@ void AccessMetaEngine::removeSaveState(const char *target, int slot) const {
}
SaveStateDescriptor AccessMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Common::String::format("%s.%03d", target, slot);
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);
+
+ if (f) {
+ Access::AccessSavegameHeader header;
+ Access::AccessEngine::readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header._saveName);
+ desc.setThumbnail(header._thumbnail);
+ desc.setSaveDate(header._year, header._month, header._day);
+ desc.setSaveTime(header._hour, header._minute);
+ desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME);
+
+ return desc;
+ }
+
return SaveStateDescriptor();
}
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index c9e150f8ea..d4e8886cac 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -80,7 +80,10 @@ void Room::doRoom() {
}
// Handle any events
+ _vm->_canSaveLoad = true;
_vm->_events->pollEvents();
+ _vm->_canSaveLoad = false;
+ g_system->delayMillis(5);
_vm->_player->walk();
_vm->_sound->midiRepeat();
@@ -432,9 +435,11 @@ void Room::handleCommand(int commandId) {
if (commandId == 1)
--commandId;
- if (commandId == 9)
+ if (commandId == 9) {
+ _vm->_canSaveLoad = true;
_vm->openMainMenuDialog();
- else if (commandId == _selectCommand) {
+ _vm->_canSaveLoad = false;
+ } else if (commandId == _selectCommand) {
_vm->_events->debounceLeft();
commandOff();
} else {