aboutsummaryrefslogtreecommitdiff
path: root/engines/adl
diff options
context:
space:
mode:
authorWalter van Niftrik2016-02-29 00:32:47 +0100
committerWalter van Niftrik2016-03-09 10:03:13 +0100
commite3d13d06ee32fa1cb3663c0e9c46f356f08b5c9b (patch)
tree59e48469221f5a583dea2e66fc0c471d4c1316a7 /engines/adl
parent727469d4a7ad9ba516538009efdac3834a6daccd (diff)
downloadscummvm-rg350-e3d13d06ee32fa1cb3663c0e9c46f356f08b5c9b.tar.gz
scummvm-rg350-e3d13d06ee32fa1cb3663c0e9c46f356f08b5c9b.tar.bz2
scummvm-rg350-e3d13d06ee32fa1cb3663c0e9c46f356f08b5c9b.zip
ADL: Add save game support
Diffstat (limited to 'engines/adl')
-rw-r--r--engines/adl/adl.cpp118
-rw-r--r--engines/adl/adl.h6
-rw-r--r--engines/adl/hires1.h1
3 files changed, 123 insertions, 2 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 24a18d62ac..9c86b3a022 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -28,6 +28,7 @@
#include "common/system.h"
#include "common/events.h"
#include "common/stream.h"
+#include "common/savefile.h"
#include "engines/util.h"
@@ -261,18 +262,21 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
++offset;
break;
case IDO_ACT_SAVE:
- warning("Save game not implemented");
+ saveState(0);
++offset;
break;
case IDO_ACT_LOAD:
- warning("Load game not implemented");
+ loadState(0);
++offset;
+ // Original engine continues processing here (?)
break;
case IDO_ACT_RESTART: {
_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
Common::String input = _display->inputString();
if (input.size() == 0 || input[0] != APPLECHAR('N')) {
_isRestarting = true;
+ _display->clear(0x00);
+ _display->decodeFrameBuffer();
restartGame();
return;
}
@@ -451,6 +455,116 @@ void AdlEngine::showRoom() {
printMessage(_state.rooms[_state.room].description, false);
}
+bool AdlEngine::saveState(uint slot) {
+ Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
+ Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
+
+ if (!outFile) {
+ warning("Failed to open file '%s'", fileName.c_str());
+ return false;
+ }
+
+ outFile->writeUint32BE(getTag());
+ outFile->writeByte(SAVEGAME_VERSION);
+
+ outFile->writeByte(_state.room);
+ outFile->writeByte(_state.moves);
+ outFile->writeByte(_state.isDark);
+
+ outFile->writeUint32BE(_state.rooms.size());
+ for (uint i = 0; i < _state.rooms.size(); ++i) {
+ outFile->writeByte(_state.rooms[i].picture);
+ outFile->writeByte(_state.rooms[i].curPicture);
+ }
+
+ outFile->writeUint32BE(_state.items.size());
+ for (uint i = 0; i < _state.items.size(); ++i) {
+ outFile->writeByte(_state.items[i].room);
+ outFile->writeByte(_state.items[i].picture);
+ outFile->writeByte(_state.items[i].position.x);
+ outFile->writeByte(_state.items[i].position.y);
+ outFile->writeByte(_state.items[i].state);
+ }
+
+ outFile->writeUint32BE(_state.vars.size());
+ for (uint i = 0; i < _state.vars.size(); ++i)
+ outFile->writeByte(_state.vars[i]);
+
+ outFile->finalize();
+
+ if (outFile->err()) {
+ delete outFile;
+ warning("Failed to save game '%s'", fileName.c_str());
+ return false;
+ }
+
+ delete outFile;
+ return true;
+}
+
+bool AdlEngine::loadState(uint slot) {
+ Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
+ Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
+
+ if (!inFile) {
+ warning("Failed to open file '%s'", fileName.c_str());
+ return false;
+ }
+
+ if (inFile->readUint32BE() != getTag()) {
+ warning("No header found in '%s'", fileName.c_str());
+ delete inFile;
+ return false;
+ }
+
+ byte saveVersion = inFile->readByte();
+ if (saveVersion != SAVEGAME_VERSION) {
+ warning("Save game version %i not supported", saveVersion);
+ delete inFile;
+ return false;
+ }
+
+ initState();
+
+ _state.room = inFile->readByte();
+ _state.moves = inFile->readByte();
+ _state.isDark = inFile->readByte();
+
+ uint32 size = inFile->readUint32BE();
+ if (size != _state.rooms.size())
+ error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size);
+
+ for (uint i = 0; i < size; ++i) {
+ _state.rooms[i].picture = inFile->readByte();
+ _state.rooms[i].curPicture = inFile->readByte();
+ }
+
+ size = inFile->readUint32BE();
+ if (size != _state.items.size())
+ error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
+
+ for (uint i = 0; i < size; ++i) {
+ _state.items[i].room = inFile->readByte();
+ _state.items[i].picture = inFile->readByte();
+ _state.items[i].position.x = inFile->readByte();
+ _state.items[i].position.y = inFile->readByte();
+ _state.items[i].state = inFile->readByte();
+ }
+
+ size = inFile->readUint32BE();
+ if (size != _state.vars.size())
+ error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size);
+
+ for (uint i = 0; i < size; ++i)
+ _state.vars[i] = inFile->readByte();
+
+ if (inFile->err() || inFile->eos())
+ error("Failed to load game '%s'", fileName.c_str());
+
+ delete inFile;
+ return true;
+}
+
AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
switch(type) {
case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 8b0aa45937..abb62ee8b2 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -37,6 +37,8 @@ class SeekableReadStream;
namespace Adl {
+#define SAVEGAME_VERSION 0
+
class Display;
class Parser;
class Console;
@@ -178,6 +180,7 @@ protected:
virtual void initState() = 0;
virtual void restartGame() = 0;
virtual uint getEngineMessage(EngineMessage msg) = 0;
+ virtual uint32 getTag() = 0;
Common::String readString(Common::ReadStream &stream, byte until = 0);
void printStrings(Common::SeekableReadStream &stream, int count = 1);
virtual void printMessage(uint idx, bool wait = true);
@@ -211,6 +214,9 @@ protected:
private:
void printEngineMessage(EngineMessage);
+ bool saveState(uint slot);
+ bool loadState(uint slot);
+ Common::String getTargetName() { return _targetName; }
};
AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index a378dc9423..ab26b2c87d 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -52,6 +52,7 @@ private:
void restartGame();
void printMessage(uint idx, bool wait = true);
uint getEngineMessage(EngineMessage msg);
+ uint32 getTag() { return MKTAG('H', 'R', 'A', '1'); }
void initState();
void runIntro();