aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/glk/advsys/advsys.cpp3
-rw-r--r--engines/glk/advsys/advsys.h3
-rw-r--r--engines/glk/advsys/detection.cpp2
-rw-r--r--engines/glk/advsys/game.cpp44
-rw-r--r--engines/glk/advsys/game.h41
5 files changed, 70 insertions, 23 deletions
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index d5709d0619..5664bc8bc0 100644
--- a/engines/glk/advsys/advsys.cpp
+++ b/engines/glk/advsys/advsys.cpp
@@ -45,8 +45,7 @@ bool AdvSys::initialize() {
return false;
// Load the game's header
- _header.load(&_gameFile);
- if (!_header._valid)
+ if (!load(_gameFile))
return false;
return true;
diff --git a/engines/glk/advsys/advsys.h b/engines/glk/advsys/advsys.h
index 3fdf39f482..ea2558fa58 100644
--- a/engines/glk/advsys/advsys.h
+++ b/engines/glk/advsys/advsys.h
@@ -33,10 +33,9 @@ namespace AdvSys {
/**
* AdvSys game interpreter
*/
-class AdvSys : public GlkAPI {
+class AdvSys : public GlkAPI, public Game {
private:
winid_t _window;
- Header _header;
private:
/**
* Engine initialization
diff --git a/engines/glk/advsys/detection.cpp b/engines/glk/advsys/detection.cpp
index d3b376f0b6..921be4eef8 100644
--- a/engines/glk/advsys/detection.cpp
+++ b/engines/glk/advsys/detection.cpp
@@ -65,7 +65,7 @@ bool AdvSysMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
if (!gameFile.open(*file))
continue;
- Header hdr(&gameFile);
+ Header hdr(gameFile);
if (!hdr._valid)
continue;
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index ce1da29456..0b9db7e8aa 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -26,27 +26,34 @@
namespace Glk {
namespace AdvSys {
+void Decrypter::decrypt(byte *data, size_t size) {
+ for (; --size; ++data)
+ *data = ~(*data + 30);
+}
+
+/*--------------------------------------------------------------------------*/
+
#define HEADER_SIZE 62
-void Header::load(Common::ReadStream *s) {
+bool Header::load(Common::ReadStream &s) {
_valid = false;
byte data[HEADER_SIZE];
// Read in the data
- if (s->read(data, HEADER_SIZE) != HEADER_SIZE)
- return;
- Compression::decompress(data, HEADER_SIZE);
+ if (s.read(data, HEADER_SIZE) != HEADER_SIZE)
+ return false;
+ decrypt(data, HEADER_SIZE);
Common::MemoryReadStream ms(data, HEADER_SIZE, DisposeAfterUse::NO);
// Validate the header
_valid = !strncmp((const char*)data + 2, "ADVSYS", 6);
if (!_valid)
- return;
+ return false;
_size = ms.readUint16LE();
ms.skip(6);
_headerVersion = ms.readUint16LE();
- _name = Common::String((const char*)data + 10, (const char*)data + 28);
+ _name = Common::String((const char *)data + 10, (const char *)data + 28);
ms.skip(18);
_version = ms.readUint16LE();
_wordTable = ms.readUint16LE();
@@ -65,11 +72,30 @@ void Header::load(Common::ReadStream *s) {
_errorHandler = ms.readUint16LE();
_saveArea = ms.readUint16LE();
_saveSize = ms.readUint16LE();
+
+ return true;
}
-void Compression::decompress(byte *data, size_t size) {
- for (; --size; ++data)
- *data = ~(*data + 30);
+/*--------------------------------------------------------------------------*/
+
+#define MAX_VERSION 102
+
+bool Game::load(Common::SeekableReadStream &s) {
+ // Load the header
+ s.seek(0);
+ if (!Header::load(s))
+ return false;
+
+ if (_headerVersion < 101 || _headerVersion > MAX_VERSION)
+ error("Wrong version number");
+
+ // Load the needed game data and decrypt it
+ _data.resize(_size);
+ if (!s.read(&_data[0], _size))
+ return false;
+ decrypt(&_data[0], _size);
+
+ return true;
}
} // End of namespace AdvSys
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index 9e2a6f759f..044d2642e7 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -23,27 +23,30 @@
#ifndef GLK_ADVSYS_GAME
#define GLK_ADVSYS_GAME
+#include "common/array.h"
#include "common/stream.h"
namespace Glk {
namespace AdvSys {
/**
- * Decompressor
+ * Data decryption
*/
-struct Compression {
+class Decrypter {
+public:
/**
- * Decompress a data block
+ * Decrypt a data block
*/
- static void decompress(byte* data, size_t size);
+ static void decrypt(byte* data, size_t size);
};
/**
* AdvSys game header
*/
-struct Header {
+class Header : public Decrypter {
+public:
bool _valid; ///< Signals whether header is valid
- size_t _size; ///< Header size in bytes
+ size_t _size; ///< Size in bytes
uint _headerVersion; ///< Header structure version
Common::String _name; ///< Adventure name
uint _version; ///< Adventure version
@@ -63,7 +66,7 @@ struct Header {
uint _errorHandler; ///< Error handler code offset
uint _saveArea; ///< Save area offset
uint _saveSize; ///< Save area size
-
+public:
/**
* Constructor
*/
@@ -76,14 +79,34 @@ struct Header {
/**
* Constructor
*/
- Header(Common::ReadStream* s) {
+ Header(Common::ReadStream &s) {
load(s);
}
/**
* Load the header
*/
- void load(Common::ReadStream *s);
+ bool load(Common::ReadStream &s);
+};
+
+/**
+ * Game abstraction class
+ */
+class Game : public Header {
+private:
+ uint _saveOffset;
+public:
+ Common::Array<byte> _data;
+public:
+ /**
+ * Constructor
+ */
+ Game() : Header(), _saveOffset(0) {}
+
+ /**
+ * Load data for the game
+ */
+ bool load(Common::SeekableReadStream &s);
};
} // End of namespace AdvSys