[Scummvm-git-logs] scummvm master -> 0074810cb4d9761ef2b3fd4f9350a73faf4da331
dreammaster
paulfgilbert at gmail.com
Mon Jun 10 00:01:38 CEST 2019
This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d5bb06ed17 GLK: ADVSYS: Engine skeleton
0e17d1c1db GLK: ADVSYS: Added game heder reading and detections
f35176d726 GLK: ADVSYS: Basic initialization and header loading in-game
9c05f1771e GLK: ADVSYS: Loading of game data
47b5980323 GLK: ADVSYS: Setting up resident data and pointers
b84e9a3dff GLK: ADVSYS: Save area and variable code
da434f2952 GLK: ADVSYS: Adding game data access methods
a9324c3c9e GLK: ADVSYS: Main game loop
39764f46d2 GLK: ADVSYS: Add overall script execution method
b01e711d65 GLK: ADVSYS: Implementing VM opcodes
0074810cb4 GLK: ADVSYS: Formatting fixes
Commit: d5bb06ed17bd19658a2ff16ccfd297cb63fccc24
https://github.com/scummvm/scummvm/commit/d5bb06ed17bd19658a2ff16ccfd297cb63fccc24
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:45-07:00
Commit Message:
GLK: ADVSYS: Engine skeleton
Changed paths:
A engines/glk/advsys/advsys.cpp
A engines/glk/advsys/advsys.h
A engines/glk/advsys/definitions.h
A engines/glk/advsys/detection.cpp
A engines/glk/advsys/detection.h
A engines/glk/advsys/detection_tables.h
engines/glk/detection.cpp
engines/glk/module.mk
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
new file mode 100644
index 0000000..47c3da1
--- /dev/null
+++ b/engines/glk/advsys/advsys.cpp
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/advsys/advsys.h"
+
+namespace Glk {
+namespace AdvSys {
+
+void AdvSys::runGame() {
+ // TODO
+}
+
+Common::Error AdvSys::loadGameData(strid_t save) {
+ return Common::kNoError;
+}
+
+Common::Error AdvSys::saveGameData(strid_t save, const Common::String& desc) {
+ return Common::kNoError;
+}
+
+} // End of namespace AdvSys
+} // End of namespace Glk
diff --git a/engines/glk/advsys/advsys.h b/engines/glk/advsys/advsys.h
new file mode 100644
index 0000000..ceb2df3
--- /dev/null
+++ b/engines/glk/advsys/advsys.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ADVSYS_ADVSYS
+#define GLK_ADVSYS_ADVSYS
+
+#include "common/scummsys.h"
+#include "glk/glk_api.h"
+
+namespace Glk {
+namespace AdvSys {
+
+/**
+ * AdvSys game interpreter
+ */
+class AdvSys : public GlkAPI {
+private:
+
+public:
+ /**
+ * Constructor
+ */
+ AdvSys(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc) {}
+
+ /**
+ * Run the game
+ */
+ virtual void runGame() override;
+
+ /**
+ * Returns the running interpreter type
+ */
+ virtual InterpreterType getInterpreterType() const override { return INTERPRETER_ADVSYS; }
+
+ /**
+ * Load a savegame from the passed stream
+ */
+ virtual Common::Error loadGameData(strid_t save) override;
+
+ /**
+ * Save the game to the passed stream
+ */
+ virtual Common::Error saveGameData(strid_t save, const Common::String &desc) override;
+};
+
+} // End of namespace AdvSys
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/advsys/definitions.h b/engines/glk/advsys/definitions.h
new file mode 100644
index 0000000..6a02a66
--- /dev/null
+++ b/engines/glk/advsys/definitions.h
@@ -0,0 +1,34 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ADVSYS_DEFINITIONS
+#define GLK_ADVSYS_DEFINITIONS
+
+namespace Glk {
+namespace AdvSys {
+
+
+
+} // End of namespace AdvSys
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/advsys/detection.cpp b/engines/glk/advsys/detection.cpp
new file mode 100644
index 0000000..4cedecf
--- /dev/null
+++ b/engines/glk/advsys/detection.cpp
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/advsys/detection.h"
+#include "glk/advsys/detection_tables.h"
+#include "common/file.h"
+#include "common/md5.h"
+#include "engines/game.h"
+
+namespace Glk {
+namespace AdvSys {
+
+void AdvSysMetaEngine::getSupportedGames(PlainGameList &games) {
+ for (const PlainGameDescriptor *pd = ADVSYS_GAME_LIST; pd->gameId; ++pd)
+ games.push_back(*pd);
+}
+
+GameDescriptor AdvSysMetaEngine::findGame(const char *gameId) {
+ for (const PlainGameDescriptor *pd = ADVSYS_GAME_LIST; pd->gameId; ++pd) {
+ if (!strcmp(gameId, pd->gameId))
+ return *pd;
+ }
+
+ return GameDescriptor::empty();
+}
+
+bool AdvSysMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
+ const char *const EXTENSIONS[] = { ".dat", nullptr };
+
+ // Loop through the files of the folder
+ for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+ // Check for a recognised filename
+ if (file->isDirectory())
+ continue;
+
+ Common::String filename = file->getName();
+ bool hasExt = false;
+ for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
+ hasExt = filename.hasSuffixIgnoreCase(*ext);
+ if (!hasExt)
+ continue;
+
+ Common::File gameFile;
+ if (!gameFile.open(*file))
+ continue;
+ Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
+ int32 filesize = gameFile.size();
+
+ // Scan through the AdvSys game list for a match
+ const AdvSysGame *p = ADVSYS_GAMES;
+ while (p->_md5 && p->_filesize != filesize && md5 != p->_md5)
+ ++p;
+
+ if (p->_filesize) {
+ // Found a match
+ PlainGameDescriptor gameDesc = findGame(p->_gameId);
+ DetectedGame gd(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
+ gd.addExtraEntry("filename", file->getName());
+
+ gameList.push_back(gd);
+ }
+ }
+
+ return !gameList.empty();
+}
+
+void AdvSysMetaEngine::detectClashes(Common::StringMap &map) {
+ for (const PlainGameDescriptor *pd = ADVSYS_GAME_LIST; pd->gameId; ++pd) {
+ if (map.contains(pd->gameId))
+ error("Duplicate game Id found - %s", pd->gameId);
+ map[pd->gameId] = "";
+ }
+}
+
+} // End of namespace AdvSys
+} // End of namespace Glk
diff --git a/engines/glk/advsys/detection.h b/engines/glk/advsys/detection.h
new file mode 100644
index 0000000..3285757
--- /dev/null
+++ b/engines/glk/advsys/detection.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ADVSYS_DETECTION
+#define GLK_ADVSYS_DETECTION
+
+#include "common/fs.h"
+#include "common/hash-str.h"
+#include "engines/game.h"
+#include "glk/detection.h"
+
+namespace Glk {
+namespace AdvSys {
+
+class AdvSysMetaEngine {
+public:
+ /**
+ * Get a list of supported games
+ */
+ static void getSupportedGames(PlainGameList &games);
+
+ /**
+ * Returns a game description for the given game Id, if it's supported
+ */
+ static GameDescriptor findGame(const char *gameId);
+
+ /**
+ * Detect supported games
+ */
+ static bool detectGames(const Common::FSList &fslist, DetectedGames &gameList);
+
+ /**
+ * Check for game Id clashes with other sub-engines
+ */
+ static void detectClashes(Common::StringMap &map);
+};
+
+} // End of namespace AdvSys
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/advsys/detection_tables.h b/engines/glk/advsys/detection_tables.h
new file mode 100644
index 0000000..de36a34
--- /dev/null
+++ b/engines/glk/advsys/detection_tables.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "engines/game.h"
+#include "common/gui_options.h"
+#include "common/language.h"
+
+namespace Glk {
+namespace AdvSys {
+
+/**
+ * Game descriptor for Scott Adams games
+ */
+struct AdvSysGame {
+ const char *_md5;
+ const char *_gameId;
+ int32 _filesize;
+};
+
+const PlainGameDescriptor ADVSYS_GAME_LIST[] = {
+ { nullptr, nullptr }
+};
+
+const AdvSysGame ADVSYS_GAMES[] = {
+
+ { nullptr, nullptr, 0 }
+};
+
+} // End of namespace AdvSys
+} // End of namespace Glk
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index a13bed3..22b2d10 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -22,6 +22,8 @@
#include "glk/glk.h"
#include "glk/detection.h"
+#include "glk/advsys/detection.h"
+#include "glk/advsys/advsys.h"
#include "glk/alan2/detection.h"
#include "glk/alan2/alan2.h"
#include "glk/frotz/detection.h"
@@ -116,6 +118,7 @@ Common::Error GlkMetaEngine::createInstance(OSystem *syst, Engine **engine) cons
else if ((*engine = create<Glk::Hugo::HugoMetaEngine, Glk::Hugo::Hugo>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Scott::ScottMetaEngine, Glk::Scott::Scott>(syst, gameDesc)) != nullptr) {}
#ifndef RELEASE_BUILD
+ else if ((*engine = create<Glk::AdvSys::AdvSysMetaEngine, Glk::AdvSys::AdvSys>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Alan2::Alan2MetaEngine, Glk::Alan2::Alan2>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Magnetic::MagneticMetaEngine, Glk::Magnetic::Magnetic>(syst, gameDesc)) != nullptr) {}
else if ((td = Glk::TADS::TADSMetaEngine::findGame(gameDesc._gameId.c_str()))._description) {
@@ -161,6 +164,7 @@ PlainGameList GlkMetaEngine::getSupportedGames() const {
Glk::Hugo::HugoMetaEngine::getSupportedGames(list);
Glk::Scott::ScottMetaEngine::getSupportedGames(list);
#ifndef RELEASE_BUILD
+ Glk::AdvSys::AdvSysMetaEngine::getSupportedGames(list);
Glk::Alan2::Alan2MetaEngine::getSupportedGames(list);
Glk::Magnetic::MagneticMetaEngine::getSupportedGames(list);
Glk::TADS::TADSMetaEngine::getSupportedGames(list);
@@ -183,6 +187,9 @@ PlainGameDescriptor GlkMetaEngine::findGame(const char *gameId) const {
if (gd._description) return gd;
#ifndef RELEASE_BUILD
+ gd = Glk::AdvSys::AdvSysMetaEngine::findGame(gameId);
+ if (gd._description) return gd;
+
gd = Glk::Alan2::Alan2MetaEngine::findGame(gameId);
if (gd._description) return gd;
@@ -206,6 +213,7 @@ DetectedGames GlkMetaEngine::detectGames(const Common::FSList &fslist) const {
Glk::Scott::ScottMetaEngine::detectGames(fslist, detectedGames);
#ifndef RELEASE_BUILD
+ Glk::AdvSys::AdvSysMetaEngine::detectGames(fslist, detectedGames);
Glk::Alan2::Alan2MetaEngine::detectGames(fslist, detectedGames);
Glk::Magnetic::MagneticMetaEngine::detectGames(fslist, detectedGames);
Glk::TADS::TADSMetaEngine::detectGames(fslist, detectedGames);
@@ -222,6 +230,7 @@ void GlkMetaEngine::detectClashes() const {
Glk::Scott::ScottMetaEngine::detectClashes(map);
#ifndef RELEASE_BUILD
+ Glk::AdvSys::AdvSysMetaEngine::detectClashes(map);
Glk::Alan2::Alan2MetaEngine::detectClashes(map);
Glk::Magnetic::MagneticMetaEngine::detectClashes(map);
Glk::TADS::TADSMetaEngine::detectClashes(map);
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index db930f2..3894969 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -25,6 +25,8 @@ MODULE_OBJS := \
window_pair.o \
window_text_buffer.o \
window_text_grid.o \
+ advsys/advsys.o \
+ advsys/detection.o \
alan2/alan2.o \
alan2/decode.o \
alan2/detection.o \
Commit: 0e17d1c1dbf718cb25fdc4b70638c93f427036a5
https://github.com/scummvm/scummvm/commit/0e17d1c1dbf718cb25fdc4b70638c93f427036a5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Added game heder reading and detections
Changed paths:
A engines/glk/advsys/game.cpp
A engines/glk/advsys/game.h
engines/glk/advsys/advsys.cpp
engines/glk/advsys/advsys.h
engines/glk/advsys/detection.cpp
engines/glk/advsys/detection_tables.h
engines/glk/module.mk
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index 47c3da1..0c62524 100644
--- a/engines/glk/advsys/advsys.cpp
+++ b/engines/glk/advsys/advsys.cpp
@@ -21,12 +21,37 @@
*/
#include "glk/advsys/advsys.h"
+#include "common/translation.h"
namespace Glk {
namespace AdvSys {
void AdvSys::runGame() {
- // TODO
+ if (!initialize()) {
+ GUIErrorMessage(_("Could not start AdvSys game"));
+ return;
+ }
+
+ // TODO: play game
+ print("ADVINT v1.2 - Copyright (c) 1986, by David Betz\n");
+
+
+ deinitialize();
+}
+
+bool AdvSys::initialize() {
+ _window = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
+ if (_window)
+ return false;
+
+ return true;
+}
+
+void AdvSys::deinitialize() {
+}
+
+void AdvSys::print(const char *msg) {
+ glk_put_string_stream(glk_window_get_stream(_window), msg);
}
Common::Error AdvSys::loadGameData(strid_t save) {
diff --git a/engines/glk/advsys/advsys.h b/engines/glk/advsys/advsys.h
index ceb2df3..0aeb14e 100644
--- a/engines/glk/advsys/advsys.h
+++ b/engines/glk/advsys/advsys.h
@@ -34,7 +34,22 @@ namespace AdvSys {
*/
class AdvSys : public GlkAPI {
private:
+ winid_t _window;
+private:
+ /**
+ * Engine initialization
+ */
+ bool initialize();
+
+ /**
+ * Engine cleanup
+ */
+ void deinitialize();
+ /**
+ * Print a string to the window
+ */
+ void print(const char *msg);
public:
/**
* Constructor
diff --git a/engines/glk/advsys/detection.cpp b/engines/glk/advsys/detection.cpp
index 4cedecf..d3b376f 100644
--- a/engines/glk/advsys/detection.cpp
+++ b/engines/glk/advsys/detection.cpp
@@ -22,6 +22,8 @@
#include "glk/advsys/detection.h"
#include "glk/advsys/detection_tables.h"
+#include "glk/advsys/game.h"
+#include "common/debug.h"
#include "common/file.h"
#include "common/md5.h"
#include "engines/game.h"
@@ -62,6 +64,12 @@ bool AdvSysMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
Common::File gameFile;
if (!gameFile.open(*file))
continue;
+
+ Header hdr(&gameFile);
+ if (!hdr._valid)
+ continue;
+
+ gameFile.seek(0);
Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
int32 filesize = gameFile.size();
@@ -77,6 +85,15 @@ bool AdvSysMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
gd.addExtraEntry("filename", file->getName());
gameList.push_back(gd);
+ } else {
+ if (gDebugLevel > 0) {
+ // Print an entry suitable for putting into the detection_tables.h
+ debug("ENTRY0(\"%s\", \"%s\", %u),", filename.c_str(), md5.c_str(), (uint)filesize);
+ }
+
+ const PlainGameDescriptor &desc = ADVSYS_GAME_LIST[0];
+ DetectedGame gd(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
+ gameList.push_back(gd);
}
}
diff --git a/engines/glk/advsys/detection_tables.h b/engines/glk/advsys/detection_tables.h
index de36a34..e109f53 100644
--- a/engines/glk/advsys/detection_tables.h
+++ b/engines/glk/advsys/detection_tables.h
@@ -37,10 +37,25 @@ struct AdvSysGame {
};
const PlainGameDescriptor ADVSYS_GAME_LIST[] = {
+ { "advsys", "AdvSys Game" },
+
+ { "bustedadvsys", "Busted!" },
+ { "starshipcolumbus", "Starship Columbus" },
+ { "elves87", "Elves '87" },
+ { "keytotime", "The Key to Time" },
+ { "onehand", "The Sound of One Hand Clapping" },
+ { "pirating", "Pirating" },
+
{ nullptr, nullptr }
};
const AdvSysGame ADVSYS_GAMES[] = {
+ { "2246a2686a07c714868680eaf980ece9", "bustedadvsys", 79091 },
+ { "120d7041dfa000c9a313a8b0ae9cef33", "starshipcolumbus", 76032 },
+ { "746963e82552f95b5e743fe24ecd1ec3", "elves87", 77947 },
+ { "892217ab8d902a732e82c55efd22931d", "keytotime", 24941 },
+ { "3a2a3cc24709ff3272f3a15d09b5e63e", "onehand", 95762 },
+ { "e55fff2ac51a8a16b979541e8d3210d8", "pirating", 29529 },
{ nullptr, nullptr, 0 }
};
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
new file mode 100644
index 0000000..ce1da29
--- /dev/null
+++ b/engines/glk/advsys/game.cpp
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/advsys/game.h"
+#include "common/memstream.h"
+
+namespace Glk {
+namespace AdvSys {
+
+#define HEADER_SIZE 62
+
+void 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);
+ Common::MemoryReadStream ms(data, HEADER_SIZE, DisposeAfterUse::NO);
+
+ // Validate the header
+ _valid = !strncmp((const char*)data + 2, "ADVSYS", 6);
+ if (!_valid)
+ return;
+
+ _size = ms.readUint16LE();
+ ms.skip(6);
+ _headerVersion = ms.readUint16LE();
+ _name = Common::String((const char*)data + 10, (const char*)data + 28);
+ ms.skip(18);
+ _version = ms.readUint16LE();
+ _wordTable = ms.readUint16LE();
+ _wordTypeTable = ms.readUint16LE();
+ _objectTable = ms.readUint16LE();
+ _actionTable = ms.readUint16LE();
+ _variableTable = ms.readUint16LE();
+ _dataSpace = ms.readUint16LE();
+ _codeSpace = ms.readUint16LE();
+ _dataBlock = ms.readUint16LE();
+ _messageBlock = ms.readUint16LE();
+ _initCode = ms.readUint16LE();
+ _updateCode = ms.readUint16LE();
+ _before = ms.readUint16LE();
+ _after = ms.readUint16LE();
+ _errorHandler = ms.readUint16LE();
+ _saveArea = ms.readUint16LE();
+ _saveSize = ms.readUint16LE();
+}
+
+void Compression::decompress(byte *data, size_t size) {
+ for (; --size; ++data)
+ *data = ~(*data + 30);
+}
+
+} // End of namespace AdvSys
+} // End of namespace Glk
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
new file mode 100644
index 0000000..9e2a6f7
--- /dev/null
+++ b/engines/glk/advsys/game.h
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ADVSYS_GAME
+#define GLK_ADVSYS_GAME
+
+#include "common/stream.h"
+
+namespace Glk {
+namespace AdvSys {
+
+/**
+ * Decompressor
+ */
+struct Compression {
+ /**
+ * Decompress a data block
+ */
+ static void decompress(byte* data, size_t size);
+};
+
+/**
+ * AdvSys game header
+ */
+struct Header {
+ bool _valid; ///< Signals whether header is valid
+ size_t _size; ///< Header size in bytes
+ uint _headerVersion; ///< Header structure version
+ Common::String _name; ///< Adventure name
+ uint _version; ///< Adventure version
+ uint _wordTable; ///< Word table offset
+ uint _wordTypeTable; ///< Word type table offset
+ uint _objectTable; ///< Object table offset
+ uint _actionTable; ///< Action table offset
+ uint _variableTable; ///< Variable table offset
+ uint _dataSpace; ///< Data space offset
+ uint _codeSpace; ///< Code space offset
+ uint _dataBlock; ///< First data block offset
+ uint _messageBlock; ///< First message block offset
+ uint _initCode; ///< Initialization code offset
+ uint _updateCode; ///< Update code offset
+ uint _before; ///< Code offset before verb handler
+ uint _after; ///< Code offset after verb handler
+ uint _errorHandler; ///< Error handler code offset
+ uint _saveArea; ///< Save area offset
+ uint _saveSize; ///< Save area size
+
+ /**
+ * Constructor
+ */
+ Header() : _valid(false), _size(0), _headerVersion(0), _version(0), _wordTable(0),
+ _wordTypeTable(0), _objectTable(0), _actionTable(0), _variableTable(0),
+ _dataSpace(0), _codeSpace(0), _dataBlock(0), _messageBlock(0), _initCode(0),
+ _updateCode(0), _before(0), _after(0), _errorHandler(0), _saveArea(0), _saveSize(0) {
+ }
+
+ /**
+ * Constructor
+ */
+ Header(Common::ReadStream* s) {
+ load(s);
+ }
+
+ /**
+ * Load the header
+ */
+ void load(Common::ReadStream *s);
+};
+
+} // End of namespace AdvSys
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 3894969..827b5e4 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -27,6 +27,7 @@ MODULE_OBJS := \
window_text_grid.o \
advsys/advsys.o \
advsys/detection.o \
+ advsys/game.o \
alan2/alan2.o \
alan2/decode.o \
alan2/detection.o \
Commit: f35176d7262eb0ccd739e231ca24232d640f9f84
https://github.com/scummvm/scummvm/commit/f35176d7262eb0ccd739e231ca24232d640f9f84
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Basic initialization and header loading in-game
Changed paths:
engines/glk/advsys/advsys.cpp
engines/glk/advsys/advsys.h
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index 0c62524..d5709d0 100644
--- a/engines/glk/advsys/advsys.cpp
+++ b/engines/glk/advsys/advsys.cpp
@@ -35,13 +35,18 @@ void AdvSys::runGame() {
// TODO: play game
print("ADVINT v1.2 - Copyright (c) 1986, by David Betz\n");
-
deinitialize();
}
bool AdvSys::initialize() {
+ // Create a Glk window for the game
_window = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
- if (_window)
+ if (!_window)
+ return false;
+
+ // Load the game's header
+ _header.load(&_gameFile);
+ if (!_header._valid)
return false;
return true;
diff --git a/engines/glk/advsys/advsys.h b/engines/glk/advsys/advsys.h
index 0aeb14e..3fdf39f 100644
--- a/engines/glk/advsys/advsys.h
+++ b/engines/glk/advsys/advsys.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "glk/glk_api.h"
+#include "glk/advsys/game.h"
namespace Glk {
namespace AdvSys {
@@ -35,6 +36,7 @@ namespace AdvSys {
class AdvSys : public GlkAPI {
private:
winid_t _window;
+ Header _header;
private:
/**
* Engine initialization
Commit: 9c05f1771ecd656af25cff734e720fcac8be90ce
https://github.com/scummvm/scummvm/commit/9c05f1771ecd656af25cff734e720fcac8be90ce
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Loading of game data
Changed paths:
engines/glk/advsys/advsys.cpp
engines/glk/advsys/advsys.h
engines/glk/advsys/detection.cpp
engines/glk/advsys/game.cpp
engines/glk/advsys/game.h
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index d5709d0..5664bc8 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 3fdf39f..ea2558f 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 d3b376f..921be4e 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 ce1da29..0b9db7e 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 9e2a6f7..044d264 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
Commit: 47b5980323057f5b7e69f50986ed84c23c506a50
https://github.com/scummvm/scummvm/commit/47b5980323057f5b7e69f50986ed84c23c506a50
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Setting up resident data and pointers
Changed paths:
engines/glk/advsys/game.cpp
engines/glk/advsys/game.h
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index 0b9db7e..d1862b7 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -56,21 +56,21 @@ bool Header::load(Common::ReadStream &s) {
_name = Common::String((const char *)data + 10, (const char *)data + 28);
ms.skip(18);
_version = ms.readUint16LE();
- _wordTable = ms.readUint16LE();
- _wordTypeTable = ms.readUint16LE();
- _objectTable = ms.readUint16LE();
- _actionTable = ms.readUint16LE();
- _variableTable = ms.readUint16LE();
- _dataSpace = ms.readUint16LE();
- _codeSpace = ms.readUint16LE();
- _dataBlock = ms.readUint16LE();
- _messageBlock = ms.readUint16LE();
- _initCode = ms.readUint16LE();
- _updateCode = ms.readUint16LE();
- _before = ms.readUint16LE();
- _after = ms.readUint16LE();
- _errorHandler = ms.readUint16LE();
- _saveArea = ms.readUint16LE();
+ _wordTableOffset = ms.readUint16LE();
+ _wordTypeTableOffset = ms.readUint16LE();
+ _objectTableOffset = ms.readUint16LE();
+ _actionTableOffset = ms.readUint16LE();
+ _variableTableOffset = ms.readUint16LE();
+ _dataSpaceOffset = ms.readUint16LE();
+ _codeSpaceOffset = ms.readUint16LE();
+ _dataBlockOffset = ms.readUint16LE();
+ _messageBlockOffset = ms.readUint16LE();
+ _initCodeOffset = ms.readUint16LE();
+ _updateCodeOffset = ms.readUint16LE();
+ _beforeOffset = ms.readUint16LE();
+ _afterOffset = ms.readUint16LE();
+ _errorHandlerOffset = ms.readUint16LE();
+ _saveAreaOffset = ms.readUint16LE();
_saveSize = ms.readUint16LE();
return true;
@@ -89,12 +89,26 @@ bool Game::load(Common::SeekableReadStream &s) {
if (_headerVersion < 101 || _headerVersion > MAX_VERSION)
error("Wrong version number");
- // Load the needed game data and decrypt it
+ // Load the needed resident game data and decrypt it
+ _residentOffset = _dataBlockOffset * 512;
+ s.seek(_residentOffset);
+
_data.resize(_size);
if (!s.read(&_data[0], _size))
return false;
decrypt(&_data[0], _size);
+ _residentBase = &_data[0];
+ _wordTable = &_data[_wordTableOffset];
+ _wordTypeTable = &_data[_wordTypeTableOffset];
+ _objectTable = &_data[_objectTableOffset];
+ _actionTable = &_data[_actionTableOffset];
+ _variableTable = &_data[_variableTableOffset];
+ _saveArea = &_data[_saveAreaOffset];
+ _dataSpace = &_data[_dataSpaceOffset];
+ _codeSpace = &_data[_codeSpaceOffset];
+
+
return true;
}
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index 044d264..9011dac 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -45,35 +45,36 @@ public:
*/
class Header : public Decrypter {
public:
- bool _valid; ///< Signals whether header is valid
- size_t _size; ///< Size in bytes
- uint _headerVersion; ///< Header structure version
- Common::String _name; ///< Adventure name
- uint _version; ///< Adventure version
- uint _wordTable; ///< Word table offset
- uint _wordTypeTable; ///< Word type table offset
- uint _objectTable; ///< Object table offset
- uint _actionTable; ///< Action table offset
- uint _variableTable; ///< Variable table offset
- uint _dataSpace; ///< Data space offset
- uint _codeSpace; ///< Code space offset
- uint _dataBlock; ///< First data block offset
- uint _messageBlock; ///< First message block offset
- uint _initCode; ///< Initialization code offset
- uint _updateCode; ///< Update code offset
- uint _before; ///< Code offset before verb handler
- uint _after; ///< Code offset after verb handler
- uint _errorHandler; ///< Error handler code offset
- uint _saveArea; ///< Save area offset
- uint _saveSize; ///< Save area size
+ bool _valid; ///< Signals whether header is valid
+ size_t _size; ///< Resident size in bytes
+ uint _headerVersion; ///< Header structure version
+ Common::String _name; ///< Adventure name
+ uint _version; ///< Adventure version
+ uint _wordTableOffset; ///< Word table offset
+ uint _wordTypeTableOffset; ///< Word type table offset
+ uint _objectTableOffset; ///< Object table offset
+ uint _actionTableOffset; ///< Action table offset
+ uint _variableTableOffset; ///< Variable table offset
+ uint _dataSpaceOffset; ///< Data space offset
+ uint _codeSpaceOffset; ///< Code space offset
+ uint _dataBlockOffset; ///< First data block offset
+ uint _messageBlockOffset; ///< First message block offset
+ uint _initCodeOffset; ///< Initialization code offset
+ uint _updateCodeOffset; ///< Update code offset
+ uint _beforeOffset; ///< Code offset before verb handler
+ uint _afterOffset; ///< Code offset after verb handler
+ uint _errorHandlerOffset; ///< Error handler code offset
+ uint _saveAreaOffset; ///< Save area offset
+ uint _saveSize; ///< Save area size
public:
/**
* Constructor
*/
- Header() : _valid(false), _size(0), _headerVersion(0), _version(0), _wordTable(0),
- _wordTypeTable(0), _objectTable(0), _actionTable(0), _variableTable(0),
- _dataSpace(0), _codeSpace(0), _dataBlock(0), _messageBlock(0), _initCode(0),
- _updateCode(0), _before(0), _after(0), _errorHandler(0), _saveArea(0), _saveSize(0) {
+ Header() : _valid(false), _size(0), _headerVersion(0), _version(0), _wordTableOffset(0),
+ _wordTypeTableOffset(0), _objectTableOffset(0), _actionTableOffset(0), _variableTableOffset(0),
+ _dataSpaceOffset(0), _codeSpaceOffset(0), _dataBlockOffset(0), _messageBlockOffset(0),
+ _initCodeOffset(0), _updateCodeOffset(0), _beforeOffset(0), _afterOffset(0),
+ _errorHandlerOffset(0), _saveAreaOffset(0), _saveSize(0) {
}
/**
@@ -94,14 +95,25 @@ public:
*/
class Game : public Header {
private:
- uint _saveOffset;
+ uint _residentOffset;
public:
Common::Array<byte> _data;
+ byte* _residentBase;
+ byte* _wordTable;
+ byte* _wordTypeTable;
+ byte* _objectTable;
+ byte* _actionTable;
+ byte* _variableTable;
+ byte* _saveArea;
+ byte* _dataSpace;
+ byte* _codeSpace;
public:
/**
* Constructor
*/
- Game() : Header(), _saveOffset(0) {}
+ Game() : Header(), _residentOffset(0), _residentBase(nullptr), _wordTable(nullptr),
+ _wordTypeTable(nullptr), _objectTable(nullptr), _actionTable(nullptr),
+ _variableTable(nullptr), _saveArea(nullptr) {}
/**
* Load data for the game
Commit: b84e9a3dff91480f5d0356dc289c6bae5690c656
https://github.com/scummvm/scummvm/commit/b84e9a3dff91480f5d0356dc289c6bae5690c656
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Save area and variable code
Changed paths:
engines/glk/advsys/advsys.cpp
engines/glk/advsys/game.cpp
engines/glk/advsys/game.h
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index 5664bc8..5d0f20b 100644
--- a/engines/glk/advsys/advsys.cpp
+++ b/engines/glk/advsys/advsys.cpp
@@ -45,7 +45,7 @@ bool AdvSys::initialize() {
return false;
// Load the game's header
- if (!load(_gameFile))
+ if (!Game::init(_gameFile))
return false;
return true;
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index d1862b7..69dc6e4 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -35,7 +35,7 @@ void Decrypter::decrypt(byte *data, size_t size) {
#define HEADER_SIZE 62
-bool Header::load(Common::ReadStream &s) {
+bool Header::init(Common::ReadStream &s) {
_valid = false;
byte data[HEADER_SIZE];
@@ -80,10 +80,10 @@ bool Header::load(Common::ReadStream &s) {
#define MAX_VERSION 102
-bool Game::load(Common::SeekableReadStream &s) {
+bool Game::init(Common::SeekableReadStream &s) {
// Load the header
s.seek(0);
- if (!Header::load(s))
+ if (!Header::init(s))
return false;
if (_headerVersion < 101 || _headerVersion > MAX_VERSION)
@@ -108,9 +108,38 @@ bool Game::load(Common::SeekableReadStream &s) {
_dataSpace = &_data[_dataSpaceOffset];
_codeSpace = &_data[_codeSpaceOffset];
+ _wordCount = READ_LE_UINT16(_wordTable);
+ _objectCount = READ_LE_UINT16(_objectTable);
+ _actionCount = READ_LE_UINT16(_actionTable);
+ _variableCount = READ_LE_UINT16(_variableTable);
+
+ setVariable(V_OCOUNT, _objectCount);
return true;
}
+void Game::restart(Common::SeekableReadStream& s) {
+ s.seek(_residentOffset + _saveAreaOffset);
+ s.read(_saveArea, _saveSize);
+}
+
+void Game::saveGameData(Common::WriteStream& ws) {
+ ws.write(_saveArea, _saveSize);
+}
+
+void Game::loadGameData(Common::ReadStream& rs) {
+ rs.read(_saveArea, _saveSize);
+}
+
+void Game::setVariable(uint variableNum, int value) {
+ assert(variableNum < _variableCount);
+ WRITE_LE_UINT16(_variableTable + variableNum * 2, value);
+}
+
+int Game::getVariable(uint variableNum) {
+ assert(variableNum < _variableCount);
+ return READ_LE_UINT16(_variableTable + variableNum * 2);
+}
+
} // End of namespace AdvSys
} // End of namespace Glk
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index 9011dac..1c7222d 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -30,6 +30,18 @@ namespace Glk {
namespace AdvSys {
/**
+ * Built-in variables
+ */
+enum Variable {
+ V_ACTOR = 1, ///< Actor noun phrase number
+ V_ACTION = 2, ///< Action from phrase
+ V_DOBJECT = 3, ///< First direct object noun phrase number
+ V_NDOBJECTS = 4, ///< Number of direct object noun phrases
+ V_IOBJECT = 5, ///< Indirect object noun phrase number
+ V_OCOUNT = 6 ///< Total object count
+};
+
+/**
* Data decryption
*/
class Decrypter {
@@ -81,23 +93,27 @@ public:
* Constructor
*/
Header(Common::ReadStream &s) {
- load(s);
+ init(s);
}
/**
- * Load the header
+ * init the header
*/
- bool load(Common::ReadStream &s);
+ bool init(Common::ReadStream &s);
};
/**
* Game abstraction class
*/
class Game : public Header {
-private:
- uint _residentOffset;
public:
Common::Array<byte> _data;
+ uint _residentOffset;
+ uint _wordCount;
+ uint _objectCount;
+ uint _actionCount;
+ uint _variableCount;
+
byte* _residentBase;
byte* _wordTable;
byte* _wordTypeTable;
@@ -111,14 +127,40 @@ public:
/**
* Constructor
*/
- Game() : Header(), _residentOffset(0), _residentBase(nullptr), _wordTable(nullptr),
+ Game() : Header(), _residentOffset(0), _wordCount(0), _objectCount(0), _actionCount(0),
+ _variableCount(0), _residentBase(nullptr), _wordTable(nullptr),
_wordTypeTable(nullptr), _objectTable(nullptr), _actionTable(nullptr),
_variableTable(nullptr), _saveArea(nullptr) {}
/**
- * Load data for the game
+ * init data for the game
+ */
+ bool init(Common::SeekableReadStream &s);
+
+ /**
+ * Restore savegame data from the game to it's initial state
+ */
+ void restart(Common::SeekableReadStream& s);
+
+ /**
+ * Save the game data to a savegame
+ */
+ void saveGameData(Common::WriteStream& ws);
+
+ /**
+ * Restore the game data from a savegame
+ */
+ void loadGameData(Common::ReadStream& rs);
+
+ /**
+ * Set a variable value
+ */
+ void setVariable(uint variableNum, int value);
+
+ /**
+ * Get a variable value
*/
- bool load(Common::SeekableReadStream &s);
+ int getVariable(uint variableNum);
};
} // End of namespace AdvSys
Commit: da434f29522d7ee36f33c1b0bd95d9cc03cc5093
https://github.com/scummvm/scummvm/commit/da434f29522d7ee36f33c1b0bd95d9cc03cc5093
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Adding game data access methods
Changed paths:
engines/glk/advsys/definitions.h
engines/glk/advsys/game.cpp
engines/glk/advsys/game.h
diff --git a/engines/glk/advsys/definitions.h b/engines/glk/advsys/definitions.h
index 6a02a66..8c96a9e 100644
--- a/engines/glk/advsys/definitions.h
+++ b/engines/glk/advsys/definitions.h
@@ -26,7 +26,7 @@
namespace Glk {
namespace AdvSys {
-
+#define NIL 0
} // End of namespace AdvSys
} // End of namespace Glk
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index 69dc6e4..938c85f 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -21,6 +21,7 @@
*/
#include "glk/advsys/game.h"
+#include "glk/advsys/definitions.h"
#include "common/memstream.h"
namespace Glk {
@@ -79,6 +80,23 @@ bool Header::init(Common::ReadStream &s) {
/*--------------------------------------------------------------------------*/
#define MAX_VERSION 102
+#define WORD_SIZE 6
+
+/**
+ * Property flags
+ */
+enum PropertyFlag {
+ P_CLASS = 0x8000
+};
+
+/**
+ * Link fields
+ */
+enum LinkField {
+ L_DATA = 0,
+ L_NEXT = 2,
+ L_SIZE = 4
+};
bool Game::init(Common::SeekableReadStream &s) {
// Load the header
@@ -121,6 +139,9 @@ bool Game::init(Common::SeekableReadStream &s) {
void Game::restart(Common::SeekableReadStream& s) {
s.seek(_residentOffset + _saveAreaOffset);
s.read(_saveArea, _saveSize);
+ decrypt(_saveArea, _saveSize);
+
+ setVariable(V_OCOUNT, _objectCount);
}
void Game::saveGameData(Common::WriteStream& ws) {
@@ -131,15 +152,160 @@ void Game::loadGameData(Common::ReadStream& rs) {
rs.read(_saveArea, _saveSize);
}
-void Game::setVariable(uint variableNum, int value) {
- assert(variableNum < _variableCount);
- WRITE_LE_UINT16(_variableTable + variableNum * 2, value);
+int Game::findWord(const Common::String &word) const {
+ // Limit the word to the maximum allowable size
+ Common::String w(word.c_str(), word.c_str() + WORD_SIZE);
+
+ // Iterate over the dictionary for the word
+ for (int idx = 1; idx <= _wordCount; ++idx) {
+ int wordOffset = READ_LE_UINT16(_wordTable + idx * 2);
+ if (w == (const char*)_residentBase + wordOffset + 2)
+ return READ_LE_UINT16(_residentBase + wordOffset);
+ }
+
+ return NIL;
+}
+
+bool Game::match(int obj, int noun, int* adjectives) {
+ if (!hasNoun(obj, noun))
+ return false;
+
+ for (int* adjPtr = adjectives; *adjPtr; ++adjPtr) {
+ if (!hasAdjective(obj, *adjPtr))
+ return false;
+ }
+
+ return true;
}
-int Game::getVariable(uint variableNum) {
+int Game::checkVerb(int* verbs) {
+ // Iterate through the actions
+ for (int idx = 1; idx <= _actionCount; ++idx) {
+ if (hasVerb(idx, verbs))
+ return idx;
+ }
+
+ return NIL;
+}
+
+int Game::findAction(int* verbs, int preposition, int flag) {
+ // Iterate through the actions
+ for (int idx = 1; idx <= _actionCount; ++idx) {
+ if ((preposition && !hasPreposition(idx, preposition)) || !hasVerb(idx, verbs))
+ continue;
+
+ int mask = ~getActionByte(idx, A_MASK);
+ if ((flag & mask) == (getActionByte(idx, A_FLAG) & mask))
+ return idx;
+ }
+
+ return NIL;
+}
+
+int Game::getObjectProperty(int obj, int prop) {
+ int field;
+
+ for (; obj; obj = getObjectField(obj, O_CLASS)) {
+ if ((field = findProperty(obj, prop)) != 0)
+ return getObjectField(obj, field);
+ }
+
+ return NIL;
+}
+
+void Game::setObjectProperty(int obj, int prop, int val) {
+ int field;
+
+ for (; obj; obj = getObjectField(obj, O_CLASS)) {
+ if ((field = findProperty(obj, prop)) != 0)
+ return setObjectField(obj, field, val);
+ }
+}
+
+int Game::getObjectLocation(int obj) const {
+ if (obj < 1 || obj > _objectCount)
+ error("Invalid object number %d", obj);
+
+ return READ_LE_UINT16(_objectTable + obj * 2);
+}
+
+int Game::getActionLocation(int action) const {
+ if (action < 1 || action >= _actionCount)
+ error("Invalid action number %d", action);
+
+ return READ_LE_UINT16(_actionTable + action * 2);
+}
+
+int Game::getVariable(int variableNum) {
assert(variableNum < _variableCount);
return READ_LE_UINT16(_variableTable + variableNum * 2);
}
+void Game::setVariable(int variableNum, int value) {
+ assert(variableNum < _variableCount);
+ WRITE_LE_UINT16(_variableTable + variableNum * 2, value);
+}
+
+int Game::findProperty(int obj, int prop) const {
+ int nProp = getObjectField(obj, O_NPROPERTIES);
+
+ for (int idx = 0, p = 0; idx < nProp; ++idx, p += 4) {
+ if ((getObjectField(obj, O_PROPERTIES + p) & ~P_CLASS) == prop)
+ return O_PROPERTIES + p + 2;
+ }
+
+ return NIL;
+}
+
+bool Game::hasNoun(int obj, int noun) const {
+ for (; obj; obj = getObjectField(obj, O_CLASS)) {
+ if (inList(getObjectField(obj, O_NOUNS), noun))
+ return true;
+ }
+
+ return false;
+}
+
+bool Game::hasAdjective(int obj, int adjective) const {
+ for (; obj; obj = getObjectField(obj, O_CLASS)) {
+ if (inList(getObjectField(obj, O_ADJECTIVES), adjective))
+ return true;
+ }
+
+ return false;
+}
+
+bool Game::hasVerb(int act, int* verbs) const {
+ // Get the list of verbs
+ int link = getActionField(act, A_VERBS);
+
+ // Look for the verb
+ for (; link; link = readWord(link + L_NEXT)) {
+ int* verb = verbs;
+ int word = readWord(link + L_DATA);
+
+ for (; *verb && word; link = readWord(link + L_NEXT)) {
+ if (*verb != readWord(word + L_DATA))
+ break;
+
+ ++verb;
+ }
+
+ if (!*verb && !word)
+ return true;
+ }
+
+ return true;
+}
+
+bool Game::inList(int link, int word) const {
+ for (; link; link = readWord(link + L_NEXT)) {
+ if (word == readWord(link + L_DATA))
+ return true;
+ }
+
+ return false;
+}
+
} // End of namespace AdvSys
} // End of namespace Glk
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index 1c7222d..bd125f2 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -30,6 +30,30 @@ namespace Glk {
namespace AdvSys {
/**
+ * Actions
+ */
+enum Action {
+ A_VERBS = 0,
+ A_PREPOSITIONS = 2,
+ A_FLAG = 4,
+ A_MASK = 5,
+ A_CODE = 6,
+ A_SIZE = 8
+};
+
+/**
+ * Object fields
+ */
+enum ObjectField {
+ O_CLASS = 0,
+ O_NOUNS = 2,
+ O_ADJECTIVES = 4,
+ O_NPROPERTIES = 6,
+ O_PROPERTIES = 8,
+ O_SIZE = 8
+};
+
+/**
* Built-in variables
*/
enum Variable {
@@ -106,13 +130,45 @@ public:
* Game abstraction class
*/
class Game : public Header {
+private:
+ /**
+ * Find an object property field
+ */
+ int findProperty(int obj, int prop) const;
+
+ /**
+ * Returns true if an object has a given noun
+ */
+ bool hasNoun(int obj, int noun) const;
+
+ /**
+ * Returns true if an object has a given adjective
+ */
+ bool hasAdjective(int obj, int adjective) const;
+
+ /**
+ * Returns true if an action has a given verb
+ */
+ bool hasVerb(int act, int* verbs) const;
+
+ /**
+ * Returns true if an action is in a given list
+ */
+ bool hasPreposition(int act, int preposition) const {
+ return inList(getActionField(act, A_PREPOSITIONS), preposition);
+ }
+
+ /**
+ * Check if a word is in an element of a given list
+ */
+ bool inList(int link, int word) const;
public:
Common::Array<byte> _data;
- uint _residentOffset;
- uint _wordCount;
- uint _objectCount;
- uint _actionCount;
- uint _variableCount;
+ int _residentOffset;
+ int _wordCount;
+ int _objectCount;
+ int _actionCount;
+ int _variableCount;
byte* _residentBase;
byte* _wordTable;
@@ -153,14 +209,108 @@ public:
void loadGameData(Common::ReadStream& rs);
/**
- * Set a variable value
+ * Find a word in the dictionary
+ */
+ int findWord(const Common::String& word) const;
+
+ /**
+ * Return a word's type
+ */
+ int getWordType(int word) const { return _wordTypeTable[word]; }
+
+ /**
+ * Match an object against a name and list of adjectives
+ */
+ bool match(int obj, int noun, int* adjectives);
+
+ /**
+ * Check to see if this is a valid verb
+ */
+ int checkVerb(int* verbs);
+
+ /**
+ * Find an action matching a given description
+ */
+ int findAction(int* verbs, int preposition, int flag);
+
+ /**
+ * Get an object property
*/
- void setVariable(uint variableNum, int value);
+ int getObjectProperty(int obj, int prop);
+
+ /**
+ * Sets an object property
+ */
+ void setObjectProperty(int obj, int prop, int val);
+
+ /**
+ * Gets a field from an object
+ */
+ int getObjectField(int obj, int offset) const {
+ return READ_LE_UINT16(_residentBase + getObjectLocation(obj) + offset);
+ }
+
+ /**
+ * Sets a field in an object
+ */
+ void setObjectField(int obj, int offset, int val) {
+ WRITE_LE_UINT16(_residentBase + getObjectLocation(obj) + offset, val);
+ }
+
+ /**
+ * Gets a field from an action
+ */
+ int getActionField(int action, int offset) const {
+ return READ_LE_UINT16(_residentBase + getActionLocation(action) + offset);
+ }
+
+ /**
+ * Gets a byte field from an action
+ */
+ int getActionByte(int action, int offset) const {
+ return _residentBase[getActionLocation(action) + offset];
+ }
+
+ /**
+ * Gets the offset of an object from the object table
+ */
+ int getObjectLocation(int obj) const;
+
+ /**
+ * Gets the offset of an action from the action table
+ */
+ int getActionLocation(int action) const;
/**
* Get a variable value
*/
- int getVariable(uint variableNum);
+ int getVariable(int variableNum);
+
+ /**
+ * Set a variable value
+ */
+ void setVariable(int variableNum, int value);
+
+ /**
+ * Gets a code byte
+ */
+ int getCodeByte(int offset) const {
+ return _codeSpace[offset];
+ }
+
+ /**
+ * Read a word
+ */
+ int readWord(int offset) const {
+ return READ_LE_UINT16(_residentBase + offset);
+ }
+
+ /**
+ * Write a word
+ */
+ void writeWord(int offset, int val) {
+ WRITE_LE_UINT16(_residentBase + offset, val);
+ }
};
} // End of namespace AdvSys
Commit: a9324c3c9e0eea017f899faf7b2a53039b659ae5
https://github.com/scummvm/scummvm/commit/a9324c3c9e0eea017f899faf7b2a53039b659ae5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Main game loop
Changed paths:
engines/glk/advsys/advsys.cpp
engines/glk/advsys/game.cpp
engines/glk/advsys/game.h
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index 5d0f20b..c1d1f9e 100644
--- a/engines/glk/advsys/advsys.cpp
+++ b/engines/glk/advsys/advsys.cpp
@@ -26,14 +26,49 @@
namespace Glk {
namespace AdvSys {
+void execute(int offset) {
+ // TODO: Stub
+}
+
+bool getInput() {
+ // TODO: Stub
+ return false;
+}
+
+bool singleAction() {
+ // TODO: Stub
+ return false;
+}
+
+bool nextAction() {
+ // TODO: STub
+ return false;
+}
+
void AdvSys::runGame() {
if (!initialize()) {
GUIErrorMessage(_("Could not start AdvSys game"));
return;
}
- // TODO: play game
- print("ADVINT v1.2 - Copyright (c) 1986, by David Betz\n");
+ // Outer play loop - this loop re-iterates if a game is restarted
+ while (!shouldQuit()) {
+ // Run game startup
+ execute(_initCodeOffset);
+
+ // Gameplay loop
+ while (!shouldQuit() && !shouldRestart()) {
+ // Run update code
+ execute(_updateCodeOffset);
+
+ // Get and parse a single line
+ if (getInput()) {
+ if (singleAction()) {
+ while (!shouldQuit() && nextAction() && singleAction()) {}
+ }
+ }
+ }
+ }
deinitialize();
}
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index 938c85f..a20178d 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -142,6 +142,13 @@ void Game::restart(Common::SeekableReadStream& s) {
decrypt(_saveArea, _saveSize);
setVariable(V_OCOUNT, _objectCount);
+ _restartFlag = true;
+}
+
+bool Game::shouldRestart() {
+ bool result = _restartFlag;
+ _restartFlag = false;
+ return result;
}
void Game::saveGameData(Common::WriteStream& ws) {
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index bd125f2..d74245b 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -131,6 +131,8 @@ public:
*/
class Game : public Header {
private:
+ bool _restartFlag;
+private:
/**
* Find an object property field
*/
@@ -183,8 +185,8 @@ public:
/**
* Constructor
*/
- Game() : Header(), _residentOffset(0), _wordCount(0), _objectCount(0), _actionCount(0),
- _variableCount(0), _residentBase(nullptr), _wordTable(nullptr),
+ Game() : Header(), _restartFlag(false), _residentOffset(0), _wordCount(0), _objectCount(0),
+ _actionCount(0), _variableCount(0), _residentBase(nullptr), _wordTable(nullptr),
_wordTypeTable(nullptr), _objectTable(nullptr), _actionTable(nullptr),
_variableTable(nullptr), _saveArea(nullptr) {}
@@ -199,6 +201,11 @@ public:
void restart(Common::SeekableReadStream& s);
/**
+ * Returns true if the game is restarting, and resets the flag
+ */
+ bool shouldRestart();
+
+ /**
* Save the game data to a savegame
*/
void saveGameData(Common::WriteStream& ws);
Commit: 39764f46d2b722e1fbab06eb1489ca7e93e97676
https://github.com/scummvm/scummvm/commit/39764f46d2b722e1fbab06eb1489ca7e93e97676
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Add overall script execution method
Changed paths:
A engines/glk/advsys/glk_interface.cpp
A engines/glk/advsys/glk_interface.h
A engines/glk/advsys/vm.cpp
A engines/glk/advsys/vm.h
engines/glk/advsys/advsys.h
engines/glk/advsys/definitions.h
engines/glk/advsys/game.h
engines/glk/module.mk
diff --git a/engines/glk/advsys/advsys.h b/engines/glk/advsys/advsys.h
index ea2558f..9aa1305 100644
--- a/engines/glk/advsys/advsys.h
+++ b/engines/glk/advsys/advsys.h
@@ -24,8 +24,7 @@
#define GLK_ADVSYS_ADVSYS
#include "common/scummsys.h"
-#include "glk/glk_api.h"
-#include "glk/advsys/game.h"
+#include "glk/advsys/vm.h"
namespace Glk {
namespace AdvSys {
@@ -33,7 +32,7 @@ namespace AdvSys {
/**
* AdvSys game interpreter
*/
-class AdvSys : public GlkAPI, public Game {
+class AdvSys : public VM {
private:
winid_t _window;
private:
@@ -55,7 +54,7 @@ public:
/**
* Constructor
*/
- AdvSys(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc) {}
+ AdvSys(OSystem *syst, const GlkGameDescription &gameDesc) : VM(syst, gameDesc) {}
/**
* Run the game
diff --git a/engines/glk/advsys/definitions.h b/engines/glk/advsys/definitions.h
index 8c96a9e..39e07ca 100644
--- a/engines/glk/advsys/definitions.h
+++ b/engines/glk/advsys/definitions.h
@@ -26,7 +26,6 @@
namespace Glk {
namespace AdvSys {
-#define NIL 0
} // End of namespace AdvSys
} // End of namespace Glk
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index d74245b..40b4fb6 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -29,6 +29,8 @@
namespace Glk {
namespace AdvSys {
+#define NIL 0
+
/**
* Actions
*/
@@ -306,6 +308,13 @@ public:
}
/**
+ * Gets a code byte
+ */
+ int getCodeWord(int offset) const {
+ return READ_LE_UINT16(_codeSpace + offset);
+ }
+
+ /**
* Read a word
*/
int readWord(int offset) const {
diff --git a/engines/glk/advsys/glk_interface.cpp b/engines/glk/advsys/glk_interface.cpp
new file mode 100644
index 0000000..3bc6800
--- /dev/null
+++ b/engines/glk/advsys/glk_interface.cpp
@@ -0,0 +1,30 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/advsys/glk_interface.h"
+
+namespace Glk {
+namespace AdvSys {
+
+
+} // End of namespace AdvSys
+} // End of namespace Glk
diff --git a/engines/glk/advsys/glk_interface.h b/engines/glk/advsys/glk_interface.h
new file mode 100644
index 0000000..58ff831
--- /dev/null
+++ b/engines/glk/advsys/glk_interface.h
@@ -0,0 +1,46 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ADVSYS_GLK_INTERFACE
+#define GLK_ADVSYS_GLK_INTERFACE
+
+#include "glk/glk_api.h"
+
+namespace Glk {
+namespace AdvSys {
+
+/**
+ * Interface class that sits between AdvSys and the GLK base, providing methods for
+ * input and output
+ */
+class GlkInterface : public GlkAPI {
+public:
+ /**
+ * Constructor
+ */
+ GlkInterface(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc) {}
+};
+
+} // End of namespace AdvSys
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp
new file mode 100644
index 0000000..a467a59
--- /dev/null
+++ b/engines/glk/advsys/vm.cpp
@@ -0,0 +1,278 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/advsys/vm.h"
+
+namespace Glk {
+namespace AdvSys {
+
+OpcodeMethod VM::_METHODS[0x34] = {
+ &VM::opBRT,
+ &VM::opBRF,
+ &VM::opBR,
+ &VM::opT,
+ &VM::opNIL,
+ &VM::opPUSH,
+ &VM::opNOT,
+ &VM::opADD,
+ &VM::opSUB,
+ &VM::opMUL,
+ &VM::opDIV,
+ &VM::opREM,
+ &VM::opBAND,
+ &VM::opBOR,
+ &VM::opBNOT,
+ &VM::opLT,
+ &VM::opEQ,
+ &VM::opGT,
+ &VM::opLIT,
+ &VM::opVAR,
+ &VM::opGETP,
+ &VM::opSETP,
+ &VM::opSET,
+ &VM::opPRINT,
+ &VM::opTERPRI,
+ &VM::opPNUMBER,
+ &VM::opFINISH,
+ &VM::opCHAIN,
+ &VM::opABORT,
+ &VM::opEXIT,
+ &VM::opRETURN,
+ &VM::opCALL,
+ &VM::opSVAR,
+ &VM::opSSET,
+ &VM::opSPLIT,
+ &VM::opSNLIT,
+ &VM::opYORN,
+ &VM::opSAVE,
+ &VM::opRESTORE,
+ &VM::opARG,
+ &VM::opASET,
+ &VM::opTMP,
+ &VM::opTSET,
+ &VM::opTSPACE,
+ &VM::opCLASS,
+ &VM::opMATCH,
+ &VM::opPNOUN,
+ &VM::opRESTART,
+ &VM::opRAND,
+ &VM::opRNDMIZE,
+ &VM::opSEND,
+ &VM::opVOWEL
+};
+
+VM::VM(OSystem *syst, const GlkGameDescription &gameDesc) : GlkInterface(syst, gameDesc), Game(),
+ _pc(0), _status(IN_PROGRESS) {
+}
+
+ExecutionResult VM::execute(int offset) {
+ // Set the code pointer
+ _pc = offset;
+
+ // Clear the stack
+ _stack.clear();
+
+ // Iterate through the script
+ for (_status = IN_PROGRESS; !shouldQuit() && _status == IN_PROGRESS; )
+ executeOpcode();
+
+ return _status;
+}
+
+void VM::executeOpcode() {
+ // Get next opcode
+ uint opcode = getCodeByte(_pc);
+ ++_pc;
+
+ if (opcode >= OP_BRT && opcode <= OP_VOWEL) {
+ (this->*_METHODS[(int)opcode - 1])();
+ } else if (opcode >= OP_XVAR && opcode < OP_XSET) {
+ _stack.back() = getVariable((int)opcode - OP_XVAR);
+ } else if (opcode >= OP_XSET && opcode < OP_XPLIT) {
+ setVariable((int)opcode - OP_XSET, _stack.back());
+ } else if (opcode >= OP_XPLIT && opcode < OP_XNLIT) {
+ _stack.back() = (int)opcode - OP_XPLIT;
+ } else if (opcode >= OP_XNLIT && (int)opcode < 256) {
+ _stack.back() = OP_XNLIT - opcode;
+ } else {
+ error("Unknown opcode %x at offset %d", opcode, _pc);
+ }
+}
+
+void VM::opBRT() {
+}
+
+void VM::opBRF() {
+}
+
+void VM::opBR() {
+}
+
+void VM::opT() {
+}
+
+void VM::opNIL() {
+}
+
+void VM::opPUSH() {
+}
+
+void VM::opNOT() {
+}
+
+void VM::opADD() {
+}
+
+void VM::opSUB() {
+}
+
+void VM::opMUL() {
+}
+
+void VM::opDIV() {
+}
+
+void VM::opREM() {
+}
+
+void VM::opBAND() {
+}
+
+void VM::opBOR() {
+}
+
+void VM::opBNOT() {
+}
+
+void VM::opLT() {
+}
+
+void VM::opEQ() {
+}
+
+void VM::opGT() {
+}
+
+void VM::opLIT() {
+}
+
+void VM::opVAR() {
+}
+
+void VM::opGETP() {
+}
+
+void VM::opSETP() {
+}
+
+void VM::opSET() {
+}
+
+void VM::opPRINT() {
+}
+
+void VM::opTERPRI() {
+}
+
+void VM::opPNUMBER() {
+}
+
+void VM::opFINISH() {
+}
+
+void VM::opCHAIN() {
+}
+
+void VM::opABORT() {
+}
+
+void VM::opEXIT() {
+}
+
+void VM::opRETURN() {
+}
+
+void VM::opCALL() {
+}
+
+void VM::opSVAR() {
+}
+
+void VM::opSSET() {
+}
+
+void VM::opSPLIT() {
+}
+
+void VM::opSNLIT() {
+}
+
+void VM::opYORN() {
+}
+
+void VM::opSAVE() {
+}
+
+void VM::opRESTORE() {
+}
+
+void VM::opARG() {
+}
+
+void VM::opASET() {
+}
+
+void VM::opTMP() {
+}
+
+void VM::opTSET() {
+}
+
+void VM::opTSPACE() {
+}
+
+void VM::opCLASS() {
+}
+
+void VM::opMATCH() {
+}
+
+void VM::opPNOUN() {
+}
+
+void VM::opRESTART() {
+}
+
+void VM::opRAND() {
+}
+
+void VM::opRNDMIZE() {
+}
+
+void VM::opSEND() {
+}
+
+void VM::opVOWEL() {
+}
+
+} // End of namespace AdvSys
+} // End of namespace Glk
diff --git a/engines/glk/advsys/vm.h b/engines/glk/advsys/vm.h
new file mode 100644
index 0000000..84cd313
--- /dev/null
+++ b/engines/glk/advsys/vm.h
@@ -0,0 +1,223 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ADVSYS_VM
+#define GLK_ADVSYS_VM
+
+#include "glk/advsys/glk_interface.h"
+#include "glk/advsys/game.h"
+#include "common/array.h"
+
+namespace Glk {
+namespace AdvSys {
+
+/**
+ * Execution result states
+ */
+enum ExecutionResult {
+ IN_PROGRESS = 0, ///< Default state whilst script is in progress
+ FINISH = 1, ///< Script was finished
+ CHAIN = 2, ///< Another script is being chained to
+ ABORT = 3 ///< Script was aborted
+};
+
+/**
+ * Opcode list
+ */
+enum Opcode {
+ OP_BRT = 0x01, ///< Branch on true
+ OP_BRF = 0x02, ///< Branch on false
+ OP_BR = 0x03, ///< Branch unconditionally
+ OP_T = 0x04, ///< Load top of stack with t
+ OP_NIL = 0x05, ///< Load top of stack with nil
+ OP_PUSH = 0x06, ///< Push nil onto stack
+ OP_NOT = 0x07, ///< Logical negate top of stack
+ OP_ADD = 0x08, ///< Add two numeric expressions
+ OP_SUB = 0x09, ///< Subtract two numeric expressions
+ OP_MUL = 0x0A, ///< Multiply two numeric expressions
+ OP_DIV = 0x0B, ///< Divide two numeric expressions
+ OP_REM = 0x0C, ///< Remainder of two numeric expressions
+ OP_BAND = 0x0D, ///< Bitwise and of two numeric expressions
+ OP_BOR = 0x0E, ///< Bitwise or of two numeric expressions
+ OP_BNOT = 0x0F, ///< Bitwise not
+ OP_LT = 0x10, ///< Less than
+ OP_EQ = 0x11, ///< Equal to
+ OP_GT = 0x12, ///< Greater than
+ OP_LIT = 0x13, ///< Load literal
+ OP_VAR = 0x14, ///< Load a variable value
+ OP_GETP = 0x15, ///< Get the value of an object property
+ OP_SETP = 0x16, ///< Set the value of an object property
+ OP_SET = 0x17, ///< Set the value of a variable
+ OP_PRINT = 0x18, ///< Print messages
+ OP_TERPRI = 0x19, ///< Terminate the print line
+ OP_PNUMBER = 0x1A, ///< Print a number
+ OP_FINISH = 0x1B, ///< Finish handling this command
+ OP_CHAIN = 0x1C, ///< Chain to the next handler
+ OP_ABORT = 0x1D, ///< Abort this command
+ OP_EXIT = 0x1E, ///< Exit the game
+ OP_RETURN = 0x1F, ///< Return from function
+ OP_CALL = 0x20, ///< Call subroutine
+ OP_SVAR = 0x21, ///< Short load a variable
+ OP_SSET = 0x22, ///< Short set a variable
+ OP_SPLIT = 0x23, ///< Short load a positive literal
+ OP_SNLIT = 0x24, ///< Short load a negative literal
+ OP_YORN = 0x25, ///< Yes or No predicate
+ OP_SAVE = 0x26, ///< Save data structures
+ OP_RESTORE = 0x27, ///< Restore data structures
+ OP_ARG = 0x28, ///< Load an argument value
+ OP_ASET = 0x29, ///< Set an argument value
+ OP_TMP = 0x2A, ///< Load a temporary variable value
+ OP_TSET = 0x2B, ///< Set a temporary variable
+ OP_TSPACE = 0x2C, ///< Allocate temporary variable space
+ OP_CLASS = 0x2D, ///< Get the class of an object
+ OP_MATCH = 0x2E, ///< Match a noun phrase with an object
+ OP_PNOUN = 0x2F, ///< Print a noun phrase
+ OP_RESTART = 0x30, ///< Restart the current game
+ OP_RAND = 0x31, ///< Generate a random number
+ OP_RNDMIZE = 0x32, ///< Seed the random number generator
+ OP_SEND = 0x33, ///< Send a message to an object
+ OP_VOWEL = 0x34, ///< Check for vowel beginning string
+
+ OP_XVAR = 0x40, ///< Extra short load a variable
+ OP_XSET = 0x60, ///< Extra short set a variable
+ OP_XPLIT = 0x80, ///< Extra short load a positive literal
+ OP_XNLIT = 0xC0 ///< Extra short load a negative literal
+};
+
+class VM;
+typedef void (VM::*OpcodeMethod)();
+
+/**
+ * Main VM for AdvSys
+ */
+class VM : public GlkInterface, public Game {
+ class ArrayStack : public Common::Array<int> {
+ public:
+ /**
+ * Push a value onto the stack
+ */
+ void push(int v) { push_back(v); }
+
+ /**
+ * Pop a value from the stack
+ */
+ int pop() {
+ int v = back();
+ pop_back();
+ return v;
+ }
+ };
+private:
+ static OpcodeMethod _METHODS[0x34];
+ int _pc;
+ ExecutionResult _status;
+ ArrayStack _stack;
+private:
+ /**
+ * Execute a single opcode within the script
+ */
+ void executeOpcode();
+
+ /**
+ * Get the next code byte and increments the PC counter
+ */
+ int readCodeByte() {
+ return getCodeByte(_pc++);
+ }
+
+ /**
+ * Gets the next code word and increases the PC counter to after it
+ */
+ int readCodeWord() {
+ return getCodeWord(_pc += 2);
+ }
+private:
+ void opBRT();
+ void opBRF();
+ void opBR();
+ void opT();
+ void opNIL();
+ void opPUSH();
+ void opNOT();
+ void opADD();
+ void opSUB();
+ void opMUL();
+ void opDIV();
+ void opREM();
+ void opBAND();
+ void opBOR();
+ void opBNOT();
+ void opLT();
+ void opEQ();
+ void opGT();
+ void opLIT();
+ void opVAR();
+ void opGETP();
+ void opSETP();
+ void opSET();
+ void opPRINT();
+ void opTERPRI();
+ void opPNUMBER();
+ void opFINISH();
+ void opCHAIN();
+ void opABORT();
+ void opEXIT();
+ void opRETURN();
+ void opCALL();
+ void opSVAR();
+ void opSSET();
+ void opSPLIT();
+ void opSNLIT();
+ void opYORN();
+ void opSAVE();
+ void opRESTORE();
+ void opARG();
+ void opASET();
+ void opTMP();
+ void opTSET();
+ void opTSPACE();
+ void opCLASS();
+ void opMATCH();
+ void opPNOUN();
+ void opRESTART();
+ void opRAND();
+ void opRNDMIZE();
+ void opSEND();
+ void opVOWEL();
+public:
+ /**
+ * Constructor
+ */
+ VM(OSystem *syst, const GlkGameDescription &gameDesc);
+
+ /**
+ * Exeecute a script
+ * @param offset Script offset
+ * @returns Script result code
+ */
+ ExecutionResult execute(int offset);
+};
+
+} // End of namespace AdvSys
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 827b5e4..b599f02 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -28,6 +28,8 @@ MODULE_OBJS := \
advsys/advsys.o \
advsys/detection.o \
advsys/game.o \
+ advsys/glk_interface.o \
+ advsys/vm.o \
alan2/alan2.o \
alan2/decode.o \
alan2/detection.o \
Commit: b01e711d65e6ef85df90eecde64a857b389a8dbd
https://github.com/scummvm/scummvm/commit/b01e711d65e6ef85df90eecde64a857b389a8dbd
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Implementing VM opcodes
Changed paths:
engines/glk/advsys/game.cpp
engines/glk/advsys/game.h
engines/glk/advsys/vm.cpp
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index a20178d..22b1d11 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -220,13 +220,15 @@ int Game::getObjectProperty(int obj, int prop) {
return NIL;
}
-void Game::setObjectProperty(int obj, int prop, int val) {
+int Game::setObjectProperty(int obj, int prop, int val) {
int field;
for (; obj; obj = getObjectField(obj, O_CLASS)) {
if ((field = findProperty(obj, prop)) != 0)
return setObjectField(obj, field, val);
}
+
+ return NIL;
}
int Game::getObjectLocation(int obj) const {
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index 40b4fb6..5ffb31b 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -250,7 +250,7 @@ public:
/**
* Sets an object property
*/
- void setObjectProperty(int obj, int prop, int val);
+ int setObjectProperty(int obj, int prop, int val);
/**
* Gets a field from an object
@@ -262,8 +262,9 @@ public:
/**
* Sets a field in an object
*/
- void setObjectField(int obj, int offset, int val) {
+ int setObjectField(int obj, int offset, int val) {
WRITE_LE_UINT16(_residentBase + getObjectLocation(obj) + offset, val);
+ return val;
}
/**
diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp
index a467a59..46d2133 100644
--- a/engines/glk/advsys/vm.cpp
+++ b/engines/glk/advsys/vm.cpp
@@ -25,6 +25,8 @@
namespace Glk {
namespace AdvSys {
+#define TRUE -1
+
OpcodeMethod VM::_METHODS[0x34] = {
&VM::opBRT,
&VM::opBRF,
@@ -117,71 +119,105 @@ void VM::executeOpcode() {
error("Unknown opcode %x at offset %d", opcode, _pc);
}
}
-
void VM::opBRT() {
+ _pc = _stack.back() ? readCodeWord() : _pc + 2;
}
void VM::opBRF() {
+ _pc = !_stack.back() ? readCodeWord() : _pc + 2;
}
void VM::opBR() {
+ _pc = readCodeWord();
}
void VM::opT() {
+ _stack.back() = TRUE;
}
void VM::opNIL() {
+ _stack.back() = NIL;
}
void VM::opPUSH() {
+ _stack.push(NIL);
}
void VM::opNOT() {
+ _stack.back() = _stack.back() ? NIL : TRUE;
}
void VM::opADD() {
+ int v = _stack.pop();
+ _stack.back() += v;
}
void VM::opSUB() {
+ int v = _stack.pop();
+ _stack.back() -= v;
}
void VM::opMUL() {
+ int v = _stack.pop();
+ _stack.back() *= v;
}
void VM::opDIV() {
+ int v = _stack.pop();
+ _stack.back() = (v == 0) ? 0 : _stack.back() / v;
}
void VM::opREM() {
+ int v = _stack.pop();
+ _stack.back() = (v == 0) ? 0 : _stack.back() % v;
}
void VM::opBAND() {
+ int v = _stack.pop();
+ _stack.back() &= v;
}
void VM::opBOR() {
+ int v = _stack.pop();
+ _stack.back() |= v;
}
void VM::opBNOT() {
+ _stack.back() = ~_stack.back();
}
void VM::opLT() {
+ int v = _stack.pop();
+ _stack.back() = (_stack.back() < v) ? TRUE : NIL;
}
void VM::opEQ() {
+ int v = _stack.pop();
+ _stack.back() = (_stack.back() == v) ? TRUE : NIL;
}
void VM::opGT() {
+ int v = _stack.pop();
+ _stack.back() = (_stack.back() > v) ? TRUE : NIL;
}
void VM::opLIT() {
+ _stack.back() = readCodeWord();
}
void VM::opVAR() {
+ _stack.back() = getVariable(readCodeWord());
}
void VM::opGETP() {
+ int v = _stack.pop();
+ _stack.back() = getObjectProperty(_stack.back(), v);
}
void VM::opSETP() {
+ int v3 = _stack.pop();
+ int v2 = _stack.pop();
+ _stack.back() = setObjectProperty(_stack.back(), v2, v3);
}
void VM::opSET() {
@@ -215,6 +251,7 @@ void VM::opCALL() {
}
void VM::opSVAR() {
+ _stack.back() = getVariable(readCodeByte());
}
void VM::opSSET() {
Commit: 0074810cb4d9761ef2b3fd4f9350a73faf4da331
https://github.com/scummvm/scummvm/commit/0074810cb4d9761ef2b3fd4f9350a73faf4da331
Author: dreammaster (dreammaster at scummvm.org)
Date: 2019-06-09T15:00:46-07:00
Commit Message:
GLK: ADVSYS: Formatting fixes
Changed paths:
engines/glk/advsys/advsys.cpp
engines/glk/advsys/advsys.h
engines/glk/advsys/game.cpp
engines/glk/advsys/game.h
engines/glk/advsys/vm.cpp
engines/glk/advsys/vm.h
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp
index c1d1f9e..b745222 100644
--- a/engines/glk/advsys/advsys.cpp
+++ b/engines/glk/advsys/advsys.cpp
@@ -97,7 +97,7 @@ Common::Error AdvSys::loadGameData(strid_t save) {
return Common::kNoError;
}
-Common::Error AdvSys::saveGameData(strid_t save, const Common::String& desc) {
+Common::Error AdvSys::saveGameData(strid_t save, const Common::String &desc) {
return Common::kNoError;
}
diff --git a/engines/glk/advsys/advsys.h b/engines/glk/advsys/advsys.h
index 9aa1305..a6e9a5b 100644
--- a/engines/glk/advsys/advsys.h
+++ b/engines/glk/advsys/advsys.h
@@ -64,7 +64,9 @@ public:
/**
* Returns the running interpreter type
*/
- virtual InterpreterType getInterpreterType() const override { return INTERPRETER_ADVSYS; }
+ virtual InterpreterType getInterpreterType() const override {
+ return INTERPRETER_ADVSYS;
+ }
/**
* Load a savegame from the passed stream
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index 22b1d11..17a4104 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -47,10 +47,10 @@ bool Header::init(Common::ReadStream &s) {
Common::MemoryReadStream ms(data, HEADER_SIZE, DisposeAfterUse::NO);
// Validate the header
- _valid = !strncmp((const char*)data + 2, "ADVSYS", 6);
+ _valid = !strncmp((const char *)data + 2, "ADVSYS", 6);
if (!_valid)
return false;
-
+
_size = ms.readUint16LE();
ms.skip(6);
_headerVersion = ms.readUint16LE();
@@ -103,7 +103,7 @@ bool Game::init(Common::SeekableReadStream &s) {
s.seek(0);
if (!Header::init(s))
return false;
-
+
if (_headerVersion < 101 || _headerVersion > MAX_VERSION)
error("Wrong version number");
@@ -136,7 +136,7 @@ bool Game::init(Common::SeekableReadStream &s) {
return true;
}
-void Game::restart(Common::SeekableReadStream& s) {
+void Game::restart(Common::SeekableReadStream &s) {
s.seek(_residentOffset + _saveAreaOffset);
s.read(_saveArea, _saveSize);
decrypt(_saveArea, _saveSize);
@@ -151,11 +151,11 @@ bool Game::shouldRestart() {
return result;
}
-void Game::saveGameData(Common::WriteStream& ws) {
+void Game::saveGameData(Common::WriteStream &ws) {
ws.write(_saveArea, _saveSize);
}
-void Game::loadGameData(Common::ReadStream& rs) {
+void Game::loadGameData(Common::ReadStream &rs) {
rs.read(_saveArea, _saveSize);
}
@@ -166,18 +166,18 @@ int Game::findWord(const Common::String &word) const {
// Iterate over the dictionary for the word
for (int idx = 1; idx <= _wordCount; ++idx) {
int wordOffset = READ_LE_UINT16(_wordTable + idx * 2);
- if (w == (const char*)_residentBase + wordOffset + 2)
+ if (w == (const char *)_residentBase + wordOffset + 2)
return READ_LE_UINT16(_residentBase + wordOffset);
}
return NIL;
}
-bool Game::match(int obj, int noun, int* adjectives) {
+bool Game::match(int obj, int noun, int *adjectives) {
if (!hasNoun(obj, noun))
return false;
- for (int* adjPtr = adjectives; *adjPtr; ++adjPtr) {
+ for (int *adjPtr = adjectives; *adjPtr; ++adjPtr) {
if (!hasAdjective(obj, *adjPtr))
return false;
}
@@ -185,7 +185,7 @@ bool Game::match(int obj, int noun, int* adjectives) {
return true;
}
-int Game::checkVerb(int* verbs) {
+int Game::checkVerb(int *verbs) {
// Iterate through the actions
for (int idx = 1; idx <= _actionCount; ++idx) {
if (hasVerb(idx, verbs))
@@ -195,7 +195,7 @@ int Game::checkVerb(int* verbs) {
return NIL;
}
-int Game::findAction(int* verbs, int preposition, int flag) {
+int Game::findAction(int *verbs, int preposition, int flag) {
// Iterate through the actions
for (int idx = 1; idx <= _actionCount; ++idx) {
if ((preposition && !hasPreposition(idx, preposition)) || !hasVerb(idx, verbs))
@@ -284,13 +284,13 @@ bool Game::hasAdjective(int obj, int adjective) const {
return false;
}
-bool Game::hasVerb(int act, int* verbs) const {
+bool Game::hasVerb(int act, int *verbs) const {
// Get the list of verbs
int link = getActionField(act, A_VERBS);
// Look for the verb
for (; link; link = readWord(link + L_NEXT)) {
- int* verb = verbs;
+ int *verb = verbs;
int word = readWord(link + L_DATA);
for (; *verb && word; link = readWord(link + L_NEXT)) {
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index 5ffb31b..a5c7f41 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -59,12 +59,12 @@ enum ObjectField {
* Built-in variables
*/
enum Variable {
- V_ACTOR = 1, ///< Actor noun phrase number
- V_ACTION = 2, ///< Action from phrase
- V_DOBJECT = 3, ///< First direct object noun phrase number
- V_NDOBJECTS = 4, ///< Number of direct object noun phrases
- V_IOBJECT = 5, ///< Indirect object noun phrase number
- V_OCOUNT = 6 ///< Total object count
+ V_ACTOR = 1, ///< Actor noun phrase number
+ V_ACTION = 2, ///< Action from phrase
+ V_DOBJECT = 3, ///< First direct object noun phrase number
+ V_NDOBJECTS = 4, ///< Number of direct object noun phrases
+ V_IOBJECT = 5, ///< Indirect object noun phrase number
+ V_OCOUNT = 6 ///< Total object count
};
/**
@@ -75,7 +75,7 @@ public:
/**
* Decrypt a data block
*/
- static void decrypt(byte* data, size_t size);
+ static void decrypt(byte *data, size_t size);
};
/**
@@ -83,27 +83,27 @@ public:
*/
class Header : public Decrypter {
public:
- bool _valid; ///< Signals whether header is valid
- size_t _size; ///< Resident size in bytes
- uint _headerVersion; ///< Header structure version
- Common::String _name; ///< Adventure name
- uint _version; ///< Adventure version
- uint _wordTableOffset; ///< Word table offset
- uint _wordTypeTableOffset; ///< Word type table offset
- uint _objectTableOffset; ///< Object table offset
- uint _actionTableOffset; ///< Action table offset
- uint _variableTableOffset; ///< Variable table offset
- uint _dataSpaceOffset; ///< Data space offset
- uint _codeSpaceOffset; ///< Code space offset
- uint _dataBlockOffset; ///< First data block offset
- uint _messageBlockOffset; ///< First message block offset
- uint _initCodeOffset; ///< Initialization code offset
- uint _updateCodeOffset; ///< Update code offset
- uint _beforeOffset; ///< Code offset before verb handler
- uint _afterOffset; ///< Code offset after verb handler
- uint _errorHandlerOffset; ///< Error handler code offset
- uint _saveAreaOffset; ///< Save area offset
- uint _saveSize; ///< Save area size
+ bool _valid; ///< Signals whether header is valid
+ size_t _size; ///< Resident size in bytes
+ uint _headerVersion; ///< Header structure version
+ Common::String _name; ///< Adventure name
+ uint _version; ///< Adventure version
+ uint _wordTableOffset; ///< Word table offset
+ uint _wordTypeTableOffset; ///< Word type table offset
+ uint _objectTableOffset; ///< Object table offset
+ uint _actionTableOffset; ///< Action table offset
+ uint _variableTableOffset; ///< Variable table offset
+ uint _dataSpaceOffset; ///< Data space offset
+ uint _codeSpaceOffset; ///< Code space offset
+ uint _dataBlockOffset; ///< First data block offset
+ uint _messageBlockOffset; ///< First message block offset
+ uint _initCodeOffset; ///< Initialization code offset
+ uint _updateCodeOffset; ///< Update code offset
+ uint _beforeOffset; ///< Code offset before verb handler
+ uint _afterOffset; ///< Code offset after verb handler
+ uint _errorHandlerOffset; ///< Error handler code offset
+ uint _saveAreaOffset; ///< Save area offset
+ uint _saveSize; ///< Save area size
public:
/**
* Constructor
@@ -153,7 +153,7 @@ private:
/**
* Returns true if an action has a given verb
*/
- bool hasVerb(int act, int* verbs) const;
+ bool hasVerb(int act, int *verbs) const;
/**
* Returns true if an action is in a given list
@@ -174,15 +174,15 @@ public:
int _actionCount;
int _variableCount;
- byte* _residentBase;
- byte* _wordTable;
- byte* _wordTypeTable;
- byte* _objectTable;
- byte* _actionTable;
- byte* _variableTable;
- byte* _saveArea;
- byte* _dataSpace;
- byte* _codeSpace;
+ byte *_residentBase;
+ byte *_wordTable;
+ byte *_wordTypeTable;
+ byte *_objectTable;
+ byte *_actionTable;
+ byte *_variableTable;
+ byte *_saveArea;
+ byte *_dataSpace;
+ byte *_codeSpace;
public:
/**
* Constructor
@@ -200,7 +200,7 @@ public:
/**
* Restore savegame data from the game to it's initial state
*/
- void restart(Common::SeekableReadStream& s);
+ void restart(Common::SeekableReadStream &s);
/**
* Returns true if the game is restarting, and resets the flag
@@ -210,37 +210,39 @@ public:
/**
* Save the game data to a savegame
*/
- void saveGameData(Common::WriteStream& ws);
+ void saveGameData(Common::WriteStream &ws);
/**
* Restore the game data from a savegame
*/
- void loadGameData(Common::ReadStream& rs);
+ void loadGameData(Common::ReadStream &rs);
/**
* Find a word in the dictionary
*/
- int findWord(const Common::String& word) const;
+ int findWord(const Common::String &word) const;
/**
* Return a word's type
*/
- int getWordType(int word) const { return _wordTypeTable[word]; }
+ int getWordType(int word) const {
+ return _wordTypeTable[word];
+ }
/**
* Match an object against a name and list of adjectives
*/
- bool match(int obj, int noun, int* adjectives);
+ bool match(int obj, int noun, int *adjectives);
/**
* Check to see if this is a valid verb
*/
- int checkVerb(int* verbs);
+ int checkVerb(int *verbs);
/**
* Find an action matching a given description
*/
- int findAction(int* verbs, int preposition, int flag);
+ int findAction(int *verbs, int preposition, int flag);
/**
* Get an object property
diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp
index 46d2133..754a86a 100644
--- a/engines/glk/advsys/vm.cpp
+++ b/engines/glk/advsys/vm.cpp
@@ -83,7 +83,7 @@ OpcodeMethod VM::_METHODS[0x34] = {
};
VM::VM(OSystem *syst, const GlkGameDescription &gameDesc) : GlkInterface(syst, gameDesc), Game(),
- _pc(0), _status(IN_PROGRESS) {
+ _pc(0), _status(IN_PROGRESS) {
}
ExecutionResult VM::execute(int offset) {
@@ -94,7 +94,7 @@ ExecutionResult VM::execute(int offset) {
_stack.clear();
// Iterate through the script
- for (_status = IN_PROGRESS; !shouldQuit() && _status == IN_PROGRESS; )
+ for (_status = IN_PROGRESS; !shouldQuit() && _status == IN_PROGRESS;)
executeOpcode();
return _status;
diff --git a/engines/glk/advsys/vm.h b/engines/glk/advsys/vm.h
index 84cd313..e1b217f 100644
--- a/engines/glk/advsys/vm.h
+++ b/engines/glk/advsys/vm.h
@@ -24,7 +24,7 @@
#define GLK_ADVSYS_VM
#include "glk/advsys/glk_interface.h"
-#include "glk/advsys/game.h"
+#include "glk/advsys/game.h"
#include "common/array.h"
namespace Glk {
@@ -34,73 +34,73 @@ namespace AdvSys {
* Execution result states
*/
enum ExecutionResult {
- IN_PROGRESS = 0, ///< Default state whilst script is in progress
- FINISH = 1, ///< Script was finished
- CHAIN = 2, ///< Another script is being chained to
- ABORT = 3 ///< Script was aborted
+ IN_PROGRESS = 0, ///< Default state whilst script is in progress
+ FINISH = 1, ///< Script was finished
+ CHAIN = 2, ///< Another script is being chained to
+ ABORT = 3 ///< Script was aborted
};
/**
* Opcode list
*/
enum Opcode {
- OP_BRT = 0x01, ///< Branch on true
- OP_BRF = 0x02, ///< Branch on false
- OP_BR = 0x03, ///< Branch unconditionally
- OP_T = 0x04, ///< Load top of stack with t
- OP_NIL = 0x05, ///< Load top of stack with nil
- OP_PUSH = 0x06, ///< Push nil onto stack
- OP_NOT = 0x07, ///< Logical negate top of stack
- OP_ADD = 0x08, ///< Add two numeric expressions
- OP_SUB = 0x09, ///< Subtract two numeric expressions
- OP_MUL = 0x0A, ///< Multiply two numeric expressions
- OP_DIV = 0x0B, ///< Divide two numeric expressions
- OP_REM = 0x0C, ///< Remainder of two numeric expressions
- OP_BAND = 0x0D, ///< Bitwise and of two numeric expressions
- OP_BOR = 0x0E, ///< Bitwise or of two numeric expressions
- OP_BNOT = 0x0F, ///< Bitwise not
- OP_LT = 0x10, ///< Less than
- OP_EQ = 0x11, ///< Equal to
- OP_GT = 0x12, ///< Greater than
- OP_LIT = 0x13, ///< Load literal
- OP_VAR = 0x14, ///< Load a variable value
- OP_GETP = 0x15, ///< Get the value of an object property
- OP_SETP = 0x16, ///< Set the value of an object property
- OP_SET = 0x17, ///< Set the value of a variable
- OP_PRINT = 0x18, ///< Print messages
- OP_TERPRI = 0x19, ///< Terminate the print line
- OP_PNUMBER = 0x1A, ///< Print a number
- OP_FINISH = 0x1B, ///< Finish handling this command
- OP_CHAIN = 0x1C, ///< Chain to the next handler
- OP_ABORT = 0x1D, ///< Abort this command
- OP_EXIT = 0x1E, ///< Exit the game
- OP_RETURN = 0x1F, ///< Return from function
- OP_CALL = 0x20, ///< Call subroutine
- OP_SVAR = 0x21, ///< Short load a variable
- OP_SSET = 0x22, ///< Short set a variable
- OP_SPLIT = 0x23, ///< Short load a positive literal
- OP_SNLIT = 0x24, ///< Short load a negative literal
- OP_YORN = 0x25, ///< Yes or No predicate
- OP_SAVE = 0x26, ///< Save data structures
- OP_RESTORE = 0x27, ///< Restore data structures
- OP_ARG = 0x28, ///< Load an argument value
- OP_ASET = 0x29, ///< Set an argument value
- OP_TMP = 0x2A, ///< Load a temporary variable value
- OP_TSET = 0x2B, ///< Set a temporary variable
- OP_TSPACE = 0x2C, ///< Allocate temporary variable space
- OP_CLASS = 0x2D, ///< Get the class of an object
- OP_MATCH = 0x2E, ///< Match a noun phrase with an object
- OP_PNOUN = 0x2F, ///< Print a noun phrase
- OP_RESTART = 0x30, ///< Restart the current game
- OP_RAND = 0x31, ///< Generate a random number
- OP_RNDMIZE = 0x32, ///< Seed the random number generator
- OP_SEND = 0x33, ///< Send a message to an object
- OP_VOWEL = 0x34, ///< Check for vowel beginning string
+ OP_BRT = 0x01, ///< Branch on true
+ OP_BRF = 0x02, ///< Branch on false
+ OP_BR = 0x03, ///< Branch unconditionally
+ OP_T = 0x04, ///< Load top of stack with t
+ OP_NIL = 0x05, ///< Load top of stack with nil
+ OP_PUSH = 0x06, ///< Push nil onto stack
+ OP_NOT = 0x07, ///< Logical negate top of stack
+ OP_ADD = 0x08, ///< Add two numeric expressions
+ OP_SUB = 0x09, ///< Subtract two numeric expressions
+ OP_MUL = 0x0A, ///< Multiply two numeric expressions
+ OP_DIV = 0x0B, ///< Divide two numeric expressions
+ OP_REM = 0x0C, ///< Remainder of two numeric expressions
+ OP_BAND = 0x0D, ///< Bitwise and of two numeric expressions
+ OP_BOR = 0x0E, ///< Bitwise or of two numeric expressions
+ OP_BNOT = 0x0F, ///< Bitwise not
+ OP_LT = 0x10, ///< Less than
+ OP_EQ = 0x11, ///< Equal to
+ OP_GT = 0x12, ///< Greater than
+ OP_LIT = 0x13, ///< Load literal
+ OP_VAR = 0x14, ///< Load a variable value
+ OP_GETP = 0x15, ///< Get the value of an object property
+ OP_SETP = 0x16, ///< Set the value of an object property
+ OP_SET = 0x17, ///< Set the value of a variable
+ OP_PRINT = 0x18, ///< Print messages
+ OP_TERPRI = 0x19, ///< Terminate the print line
+ OP_PNUMBER = 0x1A, ///< Print a number
+ OP_FINISH = 0x1B, ///< Finish handling this command
+ OP_CHAIN = 0x1C, ///< Chain to the next handler
+ OP_ABORT = 0x1D, ///< Abort this command
+ OP_EXIT = 0x1E, ///< Exit the game
+ OP_RETURN = 0x1F, ///< Return from function
+ OP_CALL = 0x20, ///< Call subroutine
+ OP_SVAR = 0x21, ///< Short load a variable
+ OP_SSET = 0x22, ///< Short set a variable
+ OP_SPLIT = 0x23, ///< Short load a positive literal
+ OP_SNLIT = 0x24, ///< Short load a negative literal
+ OP_YORN = 0x25, ///< Yes or No predicate
+ OP_SAVE = 0x26, ///< Save data structures
+ OP_RESTORE = 0x27, ///< Restore data structures
+ OP_ARG = 0x28, ///< Load an argument value
+ OP_ASET = 0x29, ///< Set an argument value
+ OP_TMP = 0x2A, ///< Load a temporary variable value
+ OP_TSET = 0x2B, ///< Set a temporary variable
+ OP_TSPACE = 0x2C, ///< Allocate temporary variable space
+ OP_CLASS = 0x2D, ///< Get the class of an object
+ OP_MATCH = 0x2E, ///< Match a noun phrase with an object
+ OP_PNOUN = 0x2F, ///< Print a noun phrase
+ OP_RESTART = 0x30, ///< Restart the current game
+ OP_RAND = 0x31, ///< Generate a random number
+ OP_RNDMIZE = 0x32, ///< Seed the random number generator
+ OP_SEND = 0x33, ///< Send a message to an object
+ OP_VOWEL = 0x34, ///< Check for vowel beginning string
- OP_XVAR = 0x40, ///< Extra short load a variable
- OP_XSET = 0x60, ///< Extra short set a variable
- OP_XPLIT = 0x80, ///< Extra short load a positive literal
- OP_XNLIT = 0xC0 ///< Extra short load a negative literal
+ OP_XVAR = 0x40, ///< Extra short load a variable
+ OP_XSET = 0x60, ///< Extra short set a variable
+ OP_XPLIT = 0x80, ///< Extra short load a positive literal
+ OP_XNLIT = 0xC0 ///< Extra short load a negative literal
};
class VM;
@@ -115,7 +115,9 @@ class VM : public GlkInterface, public Game {
/**
* Push a value onto the stack
*/
- void push(int v) { push_back(v); }
+ void push(int v) {
+ push_back(v);
+ }
/**
* Pop a value from the stack
@@ -211,8 +213,8 @@ public:
/**
* Exeecute a script
- * @param offset Script offset
- * @returns Script result code
+ * @param offset Script offset
+ * @returns Script result code
*/
ExecutionResult execute(int offset);
};
More information about the Scummvm-git-logs
mailing list