aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2018-11-03 20:41:59 -0700
committerPaul Gilbert2018-12-08 19:05:59 -0800
commit8333aed5c2952ff7aa46870cac93acb595a67f14 (patch)
treea20f77b0071edb4dfc8160cd747463162370d077
parent30cd230d883091397c7e6ca73442d560824efd0d (diff)
downloadscummvm-rg350-8333aed5c2952ff7aa46870cac93acb595a67f14.tar.gz
scummvm-rg350-8333aed5c2952ff7aa46870cac93acb595a67f14.tar.bz2
scummvm-rg350-8333aed5c2952ff7aa46870cac93acb595a67f14.zip
GLK: Adding extra fields to the savegame format for validation
-rw-r--r--engines/gargoyle/detection.cpp46
-rw-r--r--engines/gargoyle/gargoyle.h21
-rw-r--r--engines/gargoyle/glk.cpp2
-rw-r--r--engines/gargoyle/streams.cpp30
-rw-r--r--engines/gargoyle/streams.h7
5 files changed, 79 insertions, 27 deletions
diff --git a/engines/gargoyle/detection.cpp b/engines/gargoyle/detection.cpp
index 63ada3e5dd..ffd7fa9cd5 100644
--- a/engines/gargoyle/detection.cpp
+++ b/engines/gargoyle/detection.cpp
@@ -23,11 +23,12 @@
#include "gargoyle/gargoyle.h"
#include "base/plugins.h"
+#include "common/md5.h"
+#include "common/memstream.h"
#include "common/savefile.h"
#include "common/str-array.h"
-#include "common/memstream.h"
-#include "engines/advancedDetector.h"
#include "common/system.h"
+#include "engines/advancedDetector.h"
#include "graphics/colormasks.h"
#include "graphics/surface.h"
@@ -36,28 +37,33 @@
namespace Gargoyle {
struct GargoyleGameDescription {
- ADGameDescription desc;
- Common::String filename;
- InterpreterType interpType;
+ ADGameDescription _desc;
+ Common::String _filename;
+ InterpreterType _interpType;
+ Common::String _md5;
};
const Common::String &GargoyleEngine::getFilename() const {
- return _gameDescription->filename;
+ return _gameDescription->_filename;
}
uint32 GargoyleEngine::getFeatures() const {
- return _gameDescription->desc.flags;
+ return _gameDescription->_desc.flags;
}
bool GargoyleEngine::isDemo() const {
- return (bool)(_gameDescription->desc.flags & ADGF_DEMO);
+ return (bool)(_gameDescription->_desc.flags & ADGF_DEMO);
}
Common::Language GargoyleEngine::getLanguage() const {
- return _gameDescription->desc.language;
+ return _gameDescription->_desc.language;
}
InterpreterType GargoyleEngine::getInterpreterType() const {
- return _gameDescription->interpType;
+ return _gameDescription->_interpType;
+}
+
+const Common::String &GargoyleEngine::getGameMD5() const {
+ return _gameDescription->_md5;
}
} // End of namespace Gargoyle
@@ -117,9 +123,9 @@ bool Gargoyle::GargoyleEngine::hasFeature(EngineFeature f) const {
bool GargoyleMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
Gargoyle::GargoyleGameDescription *gd = (Gargoyle::GargoyleGameDescription *)desc;
- gd->filename = ConfMan.get("filename");
+ gd->_filename = ConfMan.get("filename");
- switch (gd->interpType) {
+ switch (gd->_interpType) {
case Gargoyle::INTERPRETER_SCOTT:
*engine = new Gargoyle::Scott::Scott(syst, gd);
break;
@@ -160,13 +166,15 @@ ADDetectedGames GargoyleMetaEngine::detectGame(const Common::FSNode &parent, con
static char gameId[100];
strcpy(gameId, ConfMan.get("gameid").c_str());
Common::String filename = ConfMan.get("filename");
-
- if (parent.getChild(filename).exists()) {
- gameDescription.desc.gameId = gameId;
- gameDescription.desc.language = language;
- gameDescription.desc.platform = platform;
- gameDescription.desc.extra = extra.c_str();
- gameDescription.filename = filename;
+ Common::File f;
+
+ if (f.open(parent.getChild(filename))) {
+ gameDescription._desc.gameId = gameId;
+ gameDescription._desc.language = language;
+ gameDescription._desc.platform = platform;
+ gameDescription._desc.extra = extra.c_str();
+ gameDescription._filename = filename;
+ gameDescription._md5 = Common::computeStreamMD5AsString(f, 5000);
ADDetectedGame dg((ADGameDescription *)&gameDescription);
detectedGames.push_back(dg);
diff --git a/engines/gargoyle/gargoyle.h b/engines/gargoyle/gargoyle.h
index 88859b4d68..5ec804e7db 100644
--- a/engines/gargoyle/gargoyle.h
+++ b/engines/gargoyle/gargoyle.h
@@ -43,7 +43,21 @@ class Windows;
class WindowMask;
enum InterpreterType {
- INTERPRETER_SCOTT
+ INTERPRETER_ADVSYS = 0,
+ INTERPRETER_AGILITY = 1,
+ INTERPRETER_ALAN2 = 2,
+ INTERPRETER_ALAN3 = 3,
+ INTERPRETER_BOCFEL = 4,
+ INTERPRETER_FROTZ = 5,
+ INTERPRETER_GEAS = 6,
+ INTERPRETER_HUGO = 7,
+ INTERPRETER_JACL = 8,
+ INTERPRETER_LEVEL9 = 9,
+ INTERPRETER_MAGNETIC = 10,
+ INTERPRETER_NITFOL = 11,
+ INTERPRETER_SCARE = 12,
+ INTERPRETER_SCOTT = 13,
+ INTERPRETER_TADS = 14
};
enum GargoyleDebugChannels {
@@ -133,6 +147,11 @@ public:
InterpreterType getInterpreterType() const;
/**
+ * Returns the game's md5
+ */
+ const Common::String &getGameMD5() const;
+
+ /**
* Returns the primary filename for the game
*/
const Common::String &GargoyleEngine::getFilename() const;
diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp
index fb140a3390..2f0f0b4a46 100644
--- a/engines/gargoyle/glk.cpp
+++ b/engines/gargoyle/glk.cpp
@@ -59,7 +59,7 @@ Glk::Glk(OSystem *syst, const GargoyleGameDescription *gameDesc) :
}
void Glk::glk_exit(void) {
- glk_put_string("[ press any key to exit ]");
+ glk_put_string("[ press any key to exit ]");
_events->waitForPress();
quitGame();
diff --git a/engines/gargoyle/streams.cpp b/engines/gargoyle/streams.cpp
index 7995f4d04e..a8c85a177f 100644
--- a/engines/gargoyle/streams.cpp
+++ b/engines/gargoyle/streams.cpp
@@ -963,6 +963,15 @@ glui32 FileStream::getLineUni(glui32 *ubuf, glui32 len) {
}
}
+static Common::String readString(Common::ReadStream *src) {
+ char c;
+ Common::String result;
+ while ((c = src->readByte()) != 0)
+ result += c;
+
+ return result;
+}
+
bool FileStream::readSavegameHeader(Common::SeekableReadStream *stream, SavegameHeader &header) {
header._totalFrames = 0;
@@ -975,10 +984,17 @@ bool FileStream::readSavegameHeader(Common::SeekableReadStream *stream, Savegame
if (header._version > SAVEGAME_VERSION)
error("Savegame is too recent");
+ // Read the interpreter, language, and game Id
+ header._interpType = stream->readByte();
+ header._language = stream->readByte();
+ header._md5 = readString(stream);
+
+ if (header._interpType != g_vm->getInterpreterType() || header._language != g_vm->getLanguage()
+ || header._md5 != g_vm->getGameMD5())
+ return false;
+
// Read in name
- char c;
- while ((c = stream->readByte()) != '\0')
- header._saveName += c;
+ header._saveName = readString(stream);
// Read in save date/time
header._year = stream->readUint16LE();
@@ -994,9 +1010,15 @@ bool FileStream::readSavegameHeader(Common::SeekableReadStream *stream, Savegame
void FileStream::writeSavegameHeader(Common::WriteStream *stream, const Common::String &saveName) {
// Write out a savegame header
stream->writeUint32BE(MKTAG('G', 'A', 'R', 'G'));
-
stream->writeByte(SAVEGAME_VERSION);
+ // Write out intrepreter type, language, and game Id
+ stream->writeByte(g_vm->getInterpreterType());
+ stream->writeByte(g_vm->getLanguage());
+ Common::String md5 = g_vm->getGameMD5();
+ stream->write(md5.c_str(), md5.size());
+ stream->writeByte('\0');
+
// Write savegame name
stream->write(saveName.c_str(), saveName.size());
stream->writeByte('\0');
diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h
index 517192af3f..dad67816e3 100644
--- a/engines/gargoyle/streams.h
+++ b/engines/gargoyle/streams.h
@@ -68,6 +68,9 @@ typedef StreamResult stream_result_t;
struct SavegameHeader {
uint8 _version;
+ byte _interpType;
+ byte _language;
+ Common::String _md5;
Common::String _saveName;
int _year, _month, _day;
int _hour, _minute;
@@ -76,8 +79,8 @@ struct SavegameHeader {
/**
* Constructor
*/
- SavegameHeader() : _version(0), _year(0), _month(0), _day(0), _hour(0),
- _minute(0), _totalFrames(0) {}
+ SavegameHeader() : _version(0), _interpType(0), _language(0), _year(0), _month(0), _day(0),
+ _hour(0), _minute(0), _totalFrames(0) {}
};
/**