[Scummvm-git-logs] scummvm master -> 3aacc800a964583641fa25b764f0052bdd199ca9
dreammaster
paulfgilbert at gmail.com
Wed Jun 3 01:36:50 UTC 2020
This automated email contains information about 59 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5d8838005b GLK: COMPREHEND: Skeleton engine
7423561d21 GLK: COMPREHEND: Adding recomprehend source files
8a9ef1a5a1 GLK: COMPREHEND: Adding startup code, cleanup
2ecbd720ea GLK: COMPREHEND: Work on startup
10aa0e48fe GLK: COMPREHEND: Cleaning up some structure dependencies
20533b4a1a GLK: COMPREHEND: Start of sub-classes for each different game
7e7e6a5fab GLK: COMPREHEND: Changing operation methods to virtual methods
2dd367aa6f GLK: COMPREHEND: Adding initialization defaults for game info
16b1713afd GLK: COMPREHEND: Change comprehend_game to ComprehendGame
14cf02cc1b GLK: COMPREHEND: Field renamings
b0fe096225 GLK: COMPREHEND: Making comprehend game derive from game info
fff77194d7 GLK: COMPREHEND: Converting data loading to be endian safe
5023e261ed GLK: COMPREHEND: Removal of redundant struct prefixes
269b83f31e GLK: COMPREHEND: Removal of redundant struct prefixes
ec99b086fc GLK: COMPREHEND: Capitalizing class names
eca27789b1 GLK: COMPREHEND: Data loading fixes
16c36841aa GLK: COMPREHEND: gcc compilation fixes
fbf8e0a23b GLK: COMPREHEND: Fix opcode map definition
e55aaa91da GLK: COMPREHEND: Adding method to print text to text buffer
51ff674d99 GLK: COMPREHEND: Adding method for reading text
7a88a18d47 GLK: COMPREHEND: Implement action line input
21462c57f6 GLK: COMPREHEND: Creating debugger to hold dumping methods
0f411b62dd GLK: COMPREHEND: Improved graphic vs text area setup
0944b7aa6a GLK: COMPREHEND: Implementing some graphic primitives
687ed8be04 GLK: COMPREHEND: Objectifying image file methods
4fc86e1bc9 GLK: COMPREHEND: Refactoring drawing code
207e8f4ba2 GLK: COMPREHEND: Further refactoring of drawing
645b2132d7 GLK: COMPREHEND: Change debug_printf to use debugC
17454429e4 GLK: COMPREHEND: Move floodfill disable to a debugger command
13b4698c83 GLK: COMPREHEND: Skeleton for savegames within ScummVM
e8c47aa747 GLK: COMPREHEND: Implementing savegames
0a2478984f GLK: COMPREHEND: Change _replaceWords to be an Array
6447f64709 GLK: COMPREHEND: Merged string lookups into Game class
744580a3a0 GLK: COMPREHEND: Change fatal_error to use error
093825f759 GLK: COMPREHEND: Changed StringTable to be a Common StringArray
2671e9a071 GLK: COMPREHEND: Shifting DrawSurface to be a single instance of the engine
3c4bcc9790 GLK: COMPREHEND: Hooking up engine save/load methods
b26044de81 GLK: COMPREHEND: Changing _rooms to be a Common::Array
4d5146341a GLK: COMPREHEND: Change _items to Common::Array
6015d9c914 GLK: COMPREHEND: Change _wordMaps to Common::Array
0ed3473e35 GLK: COMPREHEND: Change _actions to Common::Array
f91628971d GLK: COMPREHEND: Change _functions to Common::Array
08de10a9ec GLK: COMPREHEND: Change _replaceWords to a StringArray
0831f0d93c GLK: COMPREHEND: Remove deprecated utils file
604b8f91ca GLK: COMPREHEND: Fix gcc warnings
9609ef72cc GLK: COMPREHEND: Implement engine readChar method
967c6a277e GLK: COMPREHEND: Remove use of printf macro
d59873704c GLK: COMPREHEND: Converting picture drawing to an Archive abstraction
f7e40621ce GLK: COMPREHEND: Finish implementing PIcs archive
ead0a1bdd4 GLK: COMPREHEND: Proper freeing of Pics on exit
088bb3caf4 GLK: COMPREHEND: Draw images doubled-sized to properly fill screen
9a8d5e51d2 GLK: COMPREHEND: Fix drawing of items on-screen
21eb824978 GLK: COMPREHEND: Fix parsing string table
c6346f2db0 GLK: COMPREHEND: Better placement of location images
a06ed9ef2f GLK: COMPREHEND: Added loading of Transylvania title
508a65a02e GLK: COMPREHEND: Renaming constant arrays to be uppercase
243adfe901 GLK: COMPREHEND: Implemented game font
88c1d4ecf1 GLK: COMPREHEND: Cleanup of Crimson Crown code, remove deprecated data
3aacc800a9 GLK: COMPREHEND: Flesh out and fixes for detection code
Commit: 5d8838005b0311dcf6573d78d0f236b41183ac4b
https://github.com/scummvm/scummvm/commit/5d8838005b0311dcf6573d78d0f236b41183ac4b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:08-07:00
Commit Message:
GLK: COMPREHEND: Skeleton engine
Changed paths:
A engines/glk/comprehend/comprehend.cpp
A engines/glk/comprehend/comprehend.h
A engines/glk/comprehend/detection.cpp
A engines/glk/comprehend/detection.h
A engines/glk/comprehend/detection_tables.h
engines/glk/detection.cpp
engines/glk/detection.h
engines/glk/glk_types.h
engines/glk/module.mk
engines/glk/quetzal.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
new file mode 100644
index 0000000000..36480e02e6
--- /dev/null
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -0,0 +1,51 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/quetzal.h"
+#include "common/config-manager.h"
+#include "common/translation.h"
+
+namespace Glk {
+namespace Comprehend {
+
+Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
+ _saveSlot(-1) {
+}
+
+void Comprehend::runGame() {
+ initialize();
+ #ifdef TODO
+ _bottomWindow = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
+ if (_bottomWindow == nullptr) {
+ glk_exit();
+ return;
+ }
+ glk_set_window(_bottomWindow);
+#endif
+}
+
+void Comprehend::initialize() {
+}
+
+} // End of namespace Comprehend
+} // End of namespace Glk
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
new file mode 100644
index 0000000000..c4a7797a66
--- /dev/null
+++ b/engines/glk/comprehend/comprehend.h
@@ -0,0 +1,78 @@
+/* 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_COMPREHEND_COMPREHEND_H
+#define GLK_COMPREHEND_COMPREHEND_H
+
+#include "common/scummsys.h"
+#include "glk/glk_api.h"
+
+namespace Glk {
+namespace Comprehend {
+
+/**
+ * Scott Adams game interpreter
+ */
+class Comprehend : public GlkAPI {
+private:
+ int _saveSlot; ///< Save slot when loading savegame from launcher
+private:
+ /**
+ * Initialization code
+ */
+ void initialize();
+public:
+ /**
+ * Constructor
+ */
+ Comprehend(OSystem *syst, const GlkGameDescription &gameDesc);
+
+ /**
+ * Returns the running interpreter type
+ */
+ InterpreterType getInterpreterType() const override { return INTERPRETER_SCOTT; }
+
+ /**
+ * Execute the game
+ */
+ void runGame() override;
+
+ /**
+ * Load a savegame from the passed Quetzal file chunk stream
+ */
+ Common::Error readSaveData(Common::SeekableReadStream *rs) override {
+ return Common::kReadingFailed;
+ }
+
+ /**
+ * Save the game. The passed write stream represents access to the UMem chunk
+ * in the Quetzal save file that will be created
+ */
+ Common::Error writeGameData(Common::WriteStream *ws) override {
+ return Common::kWritingFailed;
+ }
+};
+
+} // End of namespace Comprehend
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/detection.cpp b/engines/glk/comprehend/detection.cpp
new file mode 100644
index 0000000000..ca5074a17c
--- /dev/null
+++ b/engines/glk/comprehend/detection.cpp
@@ -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.
+ *
+ */
+
+#include "glk/comprehend/detection.h"
+#include "glk/comprehend/detection_tables.h"
+#include "glk/blorb.h"
+#include "common/file.h"
+#include "common/md5.h"
+#include "engines/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+void ComprehendMetaEngine::getSupportedGames(PlainGameList &games) {
+ for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd)
+ games.push_back(*pd);
+}
+
+GameDescriptor ComprehendMetaEngine::findGame(const char *gameId) {
+ for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd) {
+ if (!strcmp(gameId, pd->gameId))
+ return *pd;
+ }
+
+ return GameDescriptor::empty();
+}
+
+bool ComprehendMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
+ // 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 = filename.hasSuffixIgnoreCase(".gda");
+ if (!hasExt)
+ continue;
+
+ // Get the file's MD5
+ Common::File gameFile;
+ if (!gameFile.open(*file))
+ continue;
+ Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
+ gameFile.close();
+
+ // Iterate through the known games
+ const ComprehendDetectionEntry *p = COMPREHEND_GAMES;
+ for (; p->_gameId; ++p) {
+ if (filename.equalsIgnoreCase(p->_filename)) {
+ // Check for an md5 match
+ if (p->_md5 == md5) {
+ // Found a match
+ PlainGameDescriptor gameDesc = findGame(p->_gameId);
+ gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
+ }
+ }
+ }
+ }
+
+ return !gameList.empty();
+}
+
+void ComprehendMetaEngine::detectClashes(Common::StringMap &map) {
+ for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd) {
+ if (map.contains(pd->gameId))
+ error("Duplicate game Id found - %s", pd->gameId);
+ map[pd->gameId] = "";
+ }
+}
+
+} // End of namespace Comprehend
+} // End of namespace Glk
diff --git a/engines/glk/comprehend/detection.h b/engines/glk/comprehend/detection.h
new file mode 100644
index 0000000000..9317366592
--- /dev/null
+++ b/engines/glk/comprehend/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_COMPREHEND_DETECTION
+#define GLK_COMPREHEND_DETECTION
+
+#include "common/fs.h"
+#include "common/hash-str.h"
+#include "engines/game.h"
+#include "glk/detection.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class ComprehendMetaEngine {
+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 Comprehend
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/detection_tables.h b/engines/glk/comprehend/detection_tables.h
new file mode 100644
index 0000000000..aa8185eeef
--- /dev/null
+++ b/engines/glk/comprehend/detection_tables.h
@@ -0,0 +1,51 @@
+/* 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 "common/gui_options.h"
+#include "common/language.h"
+#include "engines/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+const PlainGameDescriptor COMPREHEND_GAME_LIST[] = {
+ {"crimsoncrown", "Crimson Crown"},
+ {"transylvania", "Transylvania"},
+
+ {nullptr, nullptr}};
+
+struct ComprehendDetectionEntry {
+ const char *const _gameId;
+ const char *const _filename;
+ const char *const _md5;
+};
+
+const ComprehendDetectionEntry COMPREHEND_GAMES[] = {
+ // DOS games
+ {"crimsoncrown", "cc1.gda", "f2abf019675ac5c9bcfd81032bc7787b"},
+ {"transylvania", "tr.gda", "22e08633eea02ceee49b909dfd982d22"},
+
+ {nullptr, nullptr, nullptr}
+};
+
+} // End of namespace Comprehend
+} // End of namespace Glk
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index c36eb6e261..e3271966e9 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -35,6 +35,8 @@
#include "glk/alan3/alan3.h"
#include "glk/archetype/archetype.h"
#include "glk/archetype/detection.h"
+#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/detection.h"
#include "glk/frotz/detection.h"
#include "glk/frotz/frotz.h"
#include "glk/glulxe/detection.h"
@@ -172,6 +174,7 @@ Common::Error GlkMetaEngine::createInstance(OSystem *syst, Engine **engine) cons
else if ((*engine = create<Glk::Alan2::Alan2MetaEngine, Glk::Alan2::Alan2>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Alan3::Alan3MetaEngine, Glk::Alan3::Alan3>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Archetype::ArchetypeMetaEngine, Glk::Archetype::Archetype>(syst, gameDesc)) != nullptr) {}
+ else if ((*engine = create<Glk::Comprehend::ComprehendMetaEngine, Glk::Comprehend::Comprehend>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Frotz::FrotzMetaEngine, Glk::Frotz::Frotz>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Glulxe::GlulxeMetaEngine, Glk::Glulxe::Glulxe>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Hugo::HugoMetaEngine, Glk::Hugo::Hugo>(syst, gameDesc)) != nullptr) {}
@@ -222,6 +225,7 @@ PlainGameList GlkMetaEngine::getSupportedGames() const {
Glk::Alan2::Alan2MetaEngine::getSupportedGames(list);
Glk::Alan3::Alan3MetaEngine::getSupportedGames(list);
Glk::Archetype::ArchetypeMetaEngine::getSupportedGames(list);
+ Glk::Comprehend::ComprehendMetaEngine::getSupportedGames(list);
Glk::Frotz::FrotzMetaEngine::getSupportedGames(list);
Glk::Glulxe::GlulxeMetaEngine::getSupportedGames(list);
Glk::Hugo::HugoMetaEngine::getSupportedGames(list);
@@ -246,6 +250,7 @@ PlainGameDescriptor GlkMetaEngine::findGame(const char *gameId) const {
FIND_GAME(AGT);
FIND_GAME(Alan3);
FIND_GAME(Archetype);
+ FIND_GAME(Comprehend);
FIND_GAME(Frotz);
FIND_GAME(Glulxe);
FIND_GAME(Hugo);
@@ -272,6 +277,7 @@ DetectedGames GlkMetaEngine::detectGames(const Common::FSList &fslist) const {
Glk::Alan2::Alan2MetaEngine::detectGames(fslist, detectedGames);
Glk::Alan3::Alan3MetaEngine::detectGames(fslist, detectedGames);
Glk::Archetype::ArchetypeMetaEngine::detectGames(fslist, detectedGames);
+ Glk::Comprehend::ComprehendMetaEngine::detectGames(fslist, detectedGames);
Glk::Frotz::FrotzMetaEngine::detectGames(fslist, detectedGames);
Glk::Glulxe::GlulxeMetaEngine::detectGames(fslist, detectedGames);
Glk::Hugo::HugoMetaEngine::detectGames(fslist, detectedGames);
@@ -293,6 +299,7 @@ void GlkMetaEngine::detectClashes() const {
Glk::Alan2::Alan2MetaEngine::detectClashes(map);
Glk::Alan3::Alan3MetaEngine::detectClashes(map);
Glk::Archetype::ArchetypeMetaEngine::detectClashes(map);
+ Glk::Comprehend::ComprehendMetaEngine::detectClashes(map);
Glk::Frotz::FrotzMetaEngine::detectClashes(map);
Glk::Glulxe::GlulxeMetaEngine::detectClashes(map);
Glk::Hugo::HugoMetaEngine::detectClashes(map);
diff --git a/engines/glk/detection.h b/engines/glk/detection.h
index 4575b27595..b3328ff264 100644
--- a/engines/glk/detection.h
+++ b/engines/glk/detection.h
@@ -129,6 +129,7 @@ struct GlkDetectionEntry {
const char *const _md5;
size_t _filesize;
Common::Language _language;
+ const char *const _filename;
};
#define DT_ENTRY0(ID, MD5, FILESIZE) { ID, "", MD5, FILESIZE, Common::EN_ANY }
diff --git a/engines/glk/glk_types.h b/engines/glk/glk_types.h
index 7609a90f24..0824661c13 100644
--- a/engines/glk/glk_types.h
+++ b/engines/glk/glk_types.h
@@ -43,6 +43,7 @@ enum InterpreterType {
INTERPRETER_ALAN3,
INTERPRETER_ARCHETYPE,
INTERPRETER_BOCFEL,
+ INTERPRETER_COMPREHEND,
INTERPRETER_FROTZ,
INTERPRETER_GEAS,
INTERPRETER_GLULXE,
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 66028ea394..edffd13a06 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -166,6 +166,8 @@ MODULE_OBJS := \
archetype/sys_object.o \
archetype/timestamp.o \
archetype/token.o \
+ comprehend/comprehend.o \
+ comprehend/detection.o \
frotz/bitmap_font.o \
frotz/config.o \
frotz/detection.o \
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
index 6929a0a8cf..f1cece12c3 100644
--- a/engines/glk/quetzal.cpp
+++ b/engines/glk/quetzal.cpp
@@ -48,6 +48,8 @@ uint32 QuetzalBase::getInterpreterTag(InterpreterType interpType) {
return MKTAG('A', 'L', 'N', '3');
case INTERPRETER_ARCHETYPE:
return MKTAG('A', 'R', 'C', 'H');
+ case INTERPRETER_COMPREHEND:
+ return MKTAG('C', 'O', 'M', 'P');
case INTERPRETER_FROTZ:
return MKTAG('Z', 'C', 'O', 'D');
case INTERPRETER_GEAS:
Commit: 7423561d21c7c73a3ee8418b19c864ed562c2ea1
https://github.com/scummvm/scummvm/commit/7423561d21c7c73a3ee8418b19c864ed562c2ea1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:08-07:00
Commit Message:
GLK: COMPREHEND: Adding recomprehend source files
Changed paths:
A engines/glk/comprehend/dictionary.cpp
A engines/glk/comprehend/dictionary.h
A engines/glk/comprehend/dump_game_data.cpp
A engines/glk/comprehend/dump_game_data.h
A engines/glk/comprehend/file_buf.cpp
A engines/glk/comprehend/file_buf.h
A engines/glk/comprehend/game.cpp
A engines/glk/comprehend/game.h
A engines/glk/comprehend/game_cc.cpp
A engines/glk/comprehend/game_data.cpp
A engines/glk/comprehend/game_data.h
A engines/glk/comprehend/game_oo.cpp
A engines/glk/comprehend/game_tm.cpp
A engines/glk/comprehend/game_tr.cpp
A engines/glk/comprehend/graphics.cpp
A engines/glk/comprehend/graphics.h
A engines/glk/comprehend/image_data.cpp
A engines/glk/comprehend/image_data.h
A engines/glk/comprehend/image_view.cpp
A engines/glk/comprehend/opcode_map.cpp
A engines/glk/comprehend/opcode_map.h
A engines/glk/comprehend/recomprehend.cpp
A engines/glk/comprehend/recomprehend.h
A engines/glk/comprehend/strings.cpp
A engines/glk/comprehend/strings.h
A engines/glk/comprehend/util.cpp
A engines/glk/comprehend/util.h
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/module.mk
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 36480e02e6..a353c2c5cd 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -21,6 +21,7 @@
*/
#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/dump_game_data.h"
#include "glk/quetzal.h"
#include "common/config-manager.h"
#include "common/translation.h"
@@ -28,8 +29,157 @@
namespace Glk {
namespace Comprehend {
+Comprehend *g_comprehend;
+
+extern struct comprehend_game game_transylvania;
+extern struct comprehend_game game_crimson_crown_1;
+extern struct comprehend_game game_crimson_crown_2;
+extern struct comprehend_game game_oo_topos;
+extern struct comprehend_game game_talisman;
+
+static struct comprehend_game *comprehend_games[] = {
+ &game_transylvania,
+ &game_crimson_crown_1,
+ &game_crimson_crown_2,
+ &game_oo_topos,
+ &game_talisman,
+};
+
+struct dump_option {
+ const char *const option;
+ unsigned flag;
+};
+
+static const dump_option dump_options[] = {
+ {"strings", DUMP_STRINGS},
+ {"extra-strings", DUMP_EXTRA_STRINGS},
+ {"rooms", DUMP_ROOMS},
+ {"items", DUMP_ITEMS},
+ {"dictionary", DUMP_DICTIONARY},
+ {"word-pairs", DUMP_WORD_PAIRS},
+ {"actions", DUMP_ACTIONS},
+ {"functions", DUMP_FUNCTIONS},
+ {"replace-words", DUMP_REPLACE_WORDS},
+ {"header", DUMP_HEADER},
+ {"all", DUMP_ALL},
+};
+
+#ifdef TODO
+int main(int argc, char **argv) {
+ struct option long_opts[] = {
+ {"debug", no_argument, 0, 'd'},
+ {"dump", required_argument, 0, 'D'},
+ {"no-play", no_argument, 0, 'p'},
+ {"no-graphics", no_argument, 0, 'g'},
+ {"no-floodfill", no_argument, 0, 'f'},
+ {"graphics-width", required_argument, 0, 'w'},
+ {"graphics-height", required_argument, 0, 'h'},
+ {"help", no_argument, 0, '?'},
+ {NULL, 0, 0, 0},
+ };
+ const char *short_opts = "dD:pgfw:h:?";
+ struct comprehend_game *game;
+ const char *game_name, *game_dir;
+ unsigned dump_flags = 0;
+ int i, c, opt_index;
+ unsigned graphics_width = G_RENDER_WIDTH,
+ graphics_height = G_RENDER_HEIGHT;
+ bool play_game = true, graphics_enabled = true;
+
+ while (1) {
+ c = getopt_long(argc, argv, short_opts, long_opts, &opt_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'd':
+ // FIXME
+ debug_enable(DEBUG_FUNCTIONS);
+ break;
+
+ case 'D':
+ for (i = 0; i < ARRAY_SIZE(dump_options); i++)
+ if (strcmp(optarg, dump_options[i].option) == 0)
+ break;
+ if (i == ARRAY_SIZE(dump_options)) {
+ printf("Invalid dump option '%s'\n", optarg);
+ usage(argv[0]);
+ }
+
+ dump_flags |= dump_options[i].flag;
+ break;
+
+ case 'p':
+ play_game = false;
+ break;
+
+ case 'g':
+ graphics_enabled = false;
+ break;
+
+ case 'f':
+ image_set_draw_flags(IMAGEF_NO_FLOODFILL);
+ break;
+
+ case 'w':
+ graphics_width = strtoul(optarg, NULL, 0);
+ break;
+
+ case 'h':
+ graphics_height = strtoul(optarg, NULL, 0);
+ break;
+
+ case '?':
+ usage(argv[0]);
+ break;
+
+ default:
+ printf("Invalid option\n");
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind >= argc || argc - optind != 2)
+ usage(argv[0]);
+
+ game_name = argv[optind++];
+ game_dir = argv[optind++];
+
+ /* Lookup game */
+ game = NULL;
+ for (i = 0; i < ARRAY_SIZE(comprehend_games); i++) {
+ if (strcmp(game_name, comprehend_games[i]->short_name) == 0) {
+ game = comprehend_games[i];
+ break;
+ }
+ }
+ if (!game) {
+ printf("Unknown game '%s'\n", game_name);
+ usage(argv[0]);
+ }
+
+ if (graphics_enabled)
+ g_init(graphics_width, graphics_height);
+
+ game->info = xmalloc(sizeof(*game->info));
+ comprehend_load_game(game, game_dir);
+
+ if (dump_flags)
+ dump_game_data(game, dump_flags);
+
+ if (play_game)
+ comprehend_play_game(game);
+}
+#endif
+
Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
_saveSlot(-1) {
+ g_comprehend = this;
+}
+
+Comprehend::~Comprehend() {
+ g_comprehend = nullptr;
}
void Comprehend::runGame() {
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index c4a7797a66..f890dd5c80 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -29,8 +29,41 @@
namespace Glk {
namespace Comprehend {
+#undef printf
+#define printf debugN
+#undef getchar
+#define getchar() (0)
+
+#define PATH_MAX 256
+
+struct comprehend_game;
+struct game_info;
+struct game_state;
+
+#define EXTRA_STRING_TABLE(x) (0x8200 | (x))
+
+struct game_strings {
+ uint16 game_restart;
+};
+
+#define ROOM_IS_NORMAL 0
+#define ROOM_IS_DARK 1
+#define ROOM_IS_TOO_BRIGHT 2
+
+struct game_ops {
+ void (*before_game)(struct comprehend_game *game);
+ void (*before_prompt)(struct comprehend_game *game);
+ bool (*before_turn)(struct comprehend_game *game);
+ bool (*after_turn)(struct comprehend_game *game);
+ int (*room_is_special)(struct comprehend_game *game,
+ unsigned room_index,
+ unsigned *room_desc_string);
+ void (*handle_special_opcode)(struct comprehend_game *game,
+ uint8 operand);
+};
+
/**
- * Scott Adams game interpreter
+ * Comprehend engine
*/
class Comprehend : public GlkAPI {
private:
@@ -46,6 +79,8 @@ public:
*/
Comprehend(OSystem *syst, const GlkGameDescription &gameDesc);
+ ~Comprehend() override;
+
/**
* Returns the running interpreter type
*/
@@ -72,6 +107,8 @@ public:
}
};
+extern Comprehend *g_comprehend;
+
} // End of namespace Comprehend
} // End of namespace Glk
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
new file mode 100644
index 0000000000..584d2d4f77
--- /dev/null
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -0,0 +1,97 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/dictionary.h"
+
+namespace Glk {
+namespace Comprehend {
+
+static bool word_match(struct word *word, const char *string)
+{
+ /* Words less than 6 characters must match exactly */
+ if (strlen(word->word) < 6 && strlen(string) != strlen(word->word))
+ return false;
+
+ return strncmp(word->word, string, strlen(word->word)) == 0;
+}
+
+struct word *dict_find_word_by_string(struct comprehend_game *game,
+ const char *string)
+{
+ uint i;
+
+ if (!string)
+ return NULL;
+
+ for (i = 0; i < game->info->nr_words; i++)
+ if (word_match(&game->info->words[i], string))
+ return &game->info->words[i];
+
+ return NULL;
+}
+
+struct word *dict_find_word_by_index_type(struct comprehend_game *game,
+ uint8 index, uint8 type)
+{
+ uint i;
+
+ for (i = 0; i < game->info->nr_words; i++) {
+ if (game->info->words[i].index == index &&
+ game->info->words[i].type == type)
+ return &game->info->words[i];
+ }
+
+ return NULL;
+}
+
+struct word *find_dict_word_by_index(struct comprehend_game *game,
+ uint8 index, uint8 type_mask)
+{
+ uint i;
+
+ for (i = 0; i < game->info->nr_words; i++) {
+ if (game->info->words[i].index == index &&
+ (game->info->words[i].type & type_mask) != 0)
+ return &game->info->words[i];
+ }
+
+ return NULL;
+}
+
+bool dict_match_index_type(struct comprehend_game *game, const char *word,
+ uint8 index, uint8 type_mask)
+{
+ uint i;
+
+ for (i = 0; i < game->info->nr_words; i++)
+ if (game->info->words[i].index == index &&
+ ((game->info->words[i].type & type_mask) != 0) &&
+ word_match(&game->info->words[i], word))
+ return true;
+
+ return false;
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/dictionary.h b/engines/glk/comprehend/dictionary.h
new file mode 100644
index 0000000000..8efa401473
--- /dev/null
+++ b/engines/glk/comprehend/dictionary.h
@@ -0,0 +1,44 @@
+/* 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_COMPREHEND_DICTIONARY_H
+#define GLK_COMPREHEND_DICTIONARY_H
+
+namespace Glk {
+namespace Comprehend {
+
+struct comprehend_game;
+struct word;
+
+struct word *find_dict_word_by_index(struct comprehend_game *game,
+ uint8 index, uint8 type_mask);
+struct word *dict_find_word_by_index_type(struct comprehend_game *game,
+ uint8 index, uint8 type);
+struct word *dict_find_word_by_string(struct comprehend_game *game,
+ const char *string);
+bool dict_match_index_type(struct comprehend_game *game, const char *word,
+ uint8 index, uint8 type_mask);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
new file mode 100644
index 0000000000..99426a36b5
--- /dev/null
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -0,0 +1,453 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/dump_game_data.h"
+#include "glk/comprehend/dictionary.h"
+#include "glk/comprehend/file_buf.h"
+#include "glk/comprehend/strings.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/util.h"
+#include "glk/comprehend/opcode_map.h"
+
+namespace Glk {
+namespace Comprehend {
+
+static const char *opcode_names[] = {
+#ifdef TODO
+ [OPCODE_UNKNOWN] = "unknown",
+
+ [OPCODE_HAVE_OBJECT] = "have_object",
+ [OPCODE_NOT_HAVE_OBJECT] = "not_have_object",
+ [OPCODE_HAVE_CURRENT_OBJECT] = "have_current_object",
+ [OPCODE_NOT_HAVE_CURRENT_OBJECT] = "not_have_current_object",
+
+ [OPCODE_OBJECT_IS_NOT_NOWHERE] = "object_is_not_nowhere",
+
+ [OPCODE_CURRENT_OBJECT_TAKEABLE] = "current_object_takeable",
+ [OPCODE_CURRENT_OBJECT_NOT_TAKEABLE] = "current_object_not_takeable",
+
+ [OPCODE_CURRENT_OBJECT_IS_NOWHERE] = "current_object_is_nowhere",
+
+ [OPCODE_CURRENT_OBJECT_NOT_PRESENT] = "current_object_not_present",
+
+ [OPCODE_TAKE_OBJECT] = "take_object",
+ [OPCODE_TAKE_CURRENT_OBJECT] = "take_current_object",
+ [OPCODE_DROP_OBJECT] = "drop_object",
+ [OPCODE_DROP_CURRENT_OBJECT] = "drop_current_object",
+
+ [OPCODE_OR] = "or",
+ [OPCODE_IN_ROOM] = "in_room",
+ [OPCODE_VAR_EQ] = "var_eq",
+ [OPCODE_OBJECT_NOT_VALID] = "object_not_valid",
+ [OPCODE_INVENTORY_FULL] = "inventory_full",
+ [OPCODE_OBJECT_PRESENT] = "object_present",
+ [OPCODE_ELSE] = "else",
+ [OPCODE_OBJECT_IN_ROOM] = "object_in_room",
+ [OPCODE_TEST_FLAG] = "test_flag",
+ [OPCODE_CURRENT_OBJECT_IN_ROOM] = "current_object_in_room",
+ [OPCODE_CURRENT_OBJECT_PRESENT] = "current_object_present",
+ [OPCODE_TEST_ROOM_FLAG] = "test_room_flag",
+ [OPCODE_NOT_IN_ROOM] = "not_in_room",
+ [OPCODE_OBJECT_NOT_PRESENT] = "object_not_present",
+ [OPCODE_OBJECT_NOT_IN_ROOM] = "object_not_in_room",
+ [OPCODE_TEST_NOT_FLAG] = "test_not_flag",
+ [OPCODE_OBJECT_IS_NOWHERE] = "object_is_nowhere",
+ [OPCODE_TEST_NOT_ROOM_FLAG] = "test_not_room_flag",
+ [OPCODE_INVENTORY] = "inventory",
+ [OPCODE_MOVE_OBJECT_TO_ROOM] = "move_object_to_room",
+ [OPCODE_SAVE_ACTION] = "save_action",
+ [OPCODE_MOVE_TO_ROOM] = "move_to_room",
+ [OPCODE_VAR_ADD] = "var_add",
+ [OPCODE_SET_ROOM_DESCRIPTION] = "set_room_description",
+ [OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM] = "move_object_to_current_room",
+ [OPCODE_VAR_SUB] = "var_sub",
+ [OPCODE_SET_OBJECT_DESCRIPTION] = "set_object_description",
+ [OPCODE_SET_OBJECT_LONG_DESCRIPTION] = "set_object_long_description",
+ [OPCODE_MOVE] = "move",
+ [OPCODE_PRINT] = "print",
+ [OPCODE_REMOVE_OBJECT] = "remove_object",
+ [OPCODE_SET_FLAG] = "set_flag",
+ [OPCODE_CALL_FUNC] = "call_func",
+ [OPCODE_TURN_TICK] = "turn_tick",
+ [OPCODE_CLEAR_FLAG] = "clear_flag",
+ [OPCODE_INVENTORY_ROOM] = "inventory_room",
+ [OPCODE_SPECIAL] = "special",
+ [OPCODE_SET_ROOM_GRAPHIC] = "set_room_graphic",
+ [OPCODE_SET_OBJECT_GRAPHIC] = "set_object_graphic",
+ [OPCODE_REMOVE_CURRENT_OBJECT] = "remove_current_object",
+ [OPCODE_DO_VERB] = "do_verb",
+ [OPCODE_VAR_INC] = "var_inc",
+ [OPCODE_VAR_DEC] = "var_dec",
+ [OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM] = "move_current_object_to_room",
+ [OPCODE_DESCRIBE_CURRENT_OBJECT] = "describe_current_object",
+ [OPCODE_SET_STRING_REPLACEMENT] = "set_string_replacement",
+ [OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT] = "set_current_noun_string_replacement",
+ [OPCODE_CURRENT_NOT_OBJECT] = "current_not_object",
+ [OPCODE_CURRENT_IS_OBJECT] = "current_is_object",
+ [OPCODE_DRAW_ROOM] = "draw_room",
+ [OPCODE_DRAW_OBJECT] = "draw_object",
+ [OPCODE_WAIT_KEY] = "wait_key",
+#else
+ "TODO"
+#endif
+};
+
+void dump_instruction(struct comprehend_game *game,
+ struct function_state *func_state,
+ struct instruction *instr)
+{
+ uint i;
+ int str_index, str_table;
+ uint8 *opcode_map, opcode;
+
+ if (func_state)
+ debugN("[or=%d,and=%d,test=%d,else=%d]",
+ func_state->or_count, func_state->_and,
+ func_state->test_result, func_state->else_result);
+
+ opcode_map = get_opcode_map(game);
+ opcode = opcode_map[instr->opcode];
+
+ debugN(" [%.2x] ", instr->opcode);
+ if (opcode < ARRAY_SIZE(opcode_names) && opcode_names[opcode])
+ debugN("%s", opcode_names[opcode]);
+ else
+ debugN("unknown");
+
+ if (instr->nr_operands) {
+ debugN("(");
+ for (i = 0; i < instr->nr_operands; i++)
+ debugN("%.2x%s", instr->operand[i],
+ i == instr->nr_operands - 1 ? ")" : ", ");
+ }
+
+ switch (opcode) {
+ case OPCODE_PRINT:
+ case OPCODE_SET_ROOM_DESCRIPTION:
+ case OPCODE_SET_OBJECT_DESCRIPTION:
+ case OPCODE_SET_OBJECT_LONG_DESCRIPTION:
+
+ if (opcode == OPCODE_PRINT) {
+ str_index = instr->operand[0];
+ str_table = instr->operand[1];
+ } else {
+ str_index = instr->operand[1];
+ str_table = instr->operand[2];
+ }
+
+ debugN(" %s", instr_lookup_string(game, str_index, str_table));
+ break;
+
+ case OPCODE_SET_STRING_REPLACEMENT:
+ debugN(" %s", game->info->replace_words[instr->operand[0] - 1]);
+ break;
+ }
+
+ debugN("\n");
+}
+
+static void dump_functions(struct comprehend_game *game)
+{
+ struct function *func;
+ uint i, j;
+
+ debugN("Functions (%zd entries)\n", game->info->nr_functions);
+ for (i = 0; i < game->info->nr_functions; i++) {
+ func = &game->info->functions[i];
+
+ debugN("[%.4x] (%zd instructions)\n", i, func->nr_instructions);
+ for (j = 0; j < func->nr_instructions; j++)
+ dump_instruction(game, NULL, &func->instructions[j]);
+ debugN("\n");
+ }
+}
+
+static void dump_action_table(struct comprehend_game *game)
+{
+ struct action *action;
+ struct word *word;
+ uint i, j;
+
+ debugN("Action table (%zd entries)\n", game->info->nr_actions);
+ for (i = 0; i < game->info->nr_actions; i++) {
+ action = &game->info->action[i];
+
+ debugN("(");
+ for (j = 0; j < 4; j++) {
+ if (j < action->nr_words) {
+ switch (action->word_type[j]) {
+ case WORD_TYPE_VERB: debugN("v"); break;
+ case WORD_TYPE_JOIN: debugN("j"); break;
+ case WORD_TYPE_NOUN_MASK: debugN("n"); break;
+ default: debugN("?"); break;
+ }
+ } else {
+ debugN(" ");
+ }
+ }
+
+ debugN(") [%.4x] ", i );
+
+ for (j = 0; j < action->nr_words; j++)
+ debugN("%.2x:%.2x ",
+ action->word[j], action->word_type[j]);
+
+ debugN("| ");
+
+ for (j = 0; j < action->nr_words; j++) {
+ word = find_dict_word_by_index(game, action->word[j],
+ action->word_type[j]);
+ if (word)
+ debugN("%-6s ", word->word);
+ else
+ debugN("%.2x:%.2x ", action->word[j],
+ action->word_type[j]);
+ }
+
+ debugN("-> %.4x\n", action->function);
+ }
+}
+
+static int word_index_compare(const void *a, const void *b)
+{
+ const word *word_a = (const word *)a, *word_b = (const word *)b;
+
+ if (word_a->index > word_b->index)
+ return 1;
+ if (word_a->index < word_b->index)
+ return -1;
+ return 0;
+}
+
+static void dump_dictionary(struct comprehend_game *game)
+{
+ word *dictionary;
+ word *words;
+ uint i;
+
+ /* Sort the dictionary by index */
+ dictionary = (word *)xmalloc(sizeof(*words) * game->info->nr_words);
+ memcpy(dictionary, game->info->words,
+ sizeof(*words) * game->info->nr_words);
+ qsort(dictionary, game->info->nr_words, sizeof(*words),
+ word_index_compare);
+
+ debugN("Dictionary (%zd words)\n", game->info->nr_words);
+ for (i = 0; i < game->info->nr_words; i++) {
+ words = &dictionary[i];
+ debugN(" [%.2x] %.2x %s\n", words->index, words->type,
+ words->word);
+ }
+
+ free(dictionary);
+}
+
+static void dump_word_map(struct comprehend_game *game)
+{
+ struct word *word[3];
+ char str[3][6];
+ struct word_map *map;
+ uint i, j;
+
+ debugN("Word pairs (%zd entries)\n", game->info->nr_word_maps);
+ for (i = 0; i < game->info->nr_word_maps; i++) {
+ map = &game->info->word_map[i];
+
+ for (j = 0; j < 3; j++) {
+ word[j] = dict_find_word_by_index_type(
+ game, map->word[j].index, map->word[j].type);
+ if (word[j])
+ snprintf(str[j], sizeof(str[j]),
+ "%s", word[j]->word);
+ else
+ snprintf(str[j], sizeof(str[j]), "%.2x:%.2x ",
+ map->word[j].index, map->word[j].type);
+ }
+
+ debugN(" [%.2x] %-6s %-6s -> %-6s\n",
+ i, str[0], str[1], str[2]);
+ }
+}
+
+static void dump_rooms(struct comprehend_game *game)
+{
+ struct room *room;
+ uint i;
+
+ /* Room zero acts as the players inventory */
+ debugN("Rooms (%zd entries)\n", game->info->nr_rooms);
+ for (i = 1; i <= game->info->nr_rooms; i++) {
+ room = &game->info->rooms[i];
+
+ debugN(" [%.2x] flags=%.2x, graphic=%.2x\n",
+ i, room->flags, room->graphic);
+ debugN(" %s\n", string_lookup(game, room->string_desc));
+ debugN(" n: %.2x s: %.2x e: %.2x w: %.2x\n",
+ room->direction[DIRECTION_NORTH],
+ room->direction[DIRECTION_SOUTH],
+ room->direction[DIRECTION_EAST],
+ room->direction[DIRECTION_WEST]);
+ debugN(" u: %.2x d: %.2x i: %.2x o: %.2x\n",
+ room->direction[DIRECTION_UP],
+ room->direction[DIRECTION_DOWN],
+ room->direction[DIRECTION_IN],
+ room->direction[DIRECTION_OUT]);
+ debugN("\n");
+ }
+}
+
+static void dump_items(struct comprehend_game *game)
+{
+ struct item *item;
+ uint i, j;
+
+ debugN("Items (%zd entries)\n", game->info->header.nr_items);
+ for (i = 0; i < game->info->header.nr_items; i++) {
+ item = &game->info->item[i];
+
+ debugN(" [%.2x] %s\n", i + 1,
+ item->string_desc ?
+ string_lookup(game, item->string_desc) : "");
+ if (game->info->comprehend_version == 2)
+ debugN(" long desc: %s\n",
+ string_lookup(game, item->long_string));
+
+ debugN(" words: ");
+ for (j = 0; j < game->info->nr_words; j++)
+ if (game->info->words[j].index == item->word &&
+ (game->info->words[j].type & WORD_TYPE_NOUN_MASK))
+ debugN("%s ", game->info->words[j].word);
+ debugN("\n");
+ debugN(" flags=%.2x (takeable=%d, weight=%d)\n",
+ item->flags, !!(item->flags & ITEMF_CAN_TAKE),
+ (item->flags & ITEMF_WEIGHT_MASK));
+ debugN(" room=%.2x, graphic=%.2x\n",
+ item->room, item->graphic);
+ debugN("\n");
+ }
+}
+
+static void dump_string_table(struct string_table *table)
+{
+ uint i;
+
+ for (i = 0; i < table->nr_strings; i++)
+ debugN("[%.4x] %s\n", i, table->strings[i]);
+}
+
+static void dump_game_data_strings(struct comprehend_game *game)
+{
+ debugN("Main string table (%zd entries)\n",
+ game->info->strings.nr_strings);
+ dump_string_table(&game->info->strings);
+}
+
+static void dump_extra_strings(struct comprehend_game *game)
+{
+ debugN("Extra strings (%zd entries)\n",
+ game->info->strings2.nr_strings);
+ dump_string_table(&game->info->strings2);
+}
+
+static void dump_replace_words(struct comprehend_game *game)
+{
+ uint i;
+
+ debugN("Replacement words (%zd entries)\n",
+ game->info->nr_replace_words);
+ for (i = 0; i < game->info->nr_replace_words; i++)
+ debugN(" [%.2x] %s\n", i + 1, game->info->replace_words[i]);
+}
+
+static void dump_header(struct comprehend_game *game)
+{
+ struct game_header *header = &game->info->header;
+ uint16 *dir_table = header->room_direction_table;
+
+ debugN("Game header:\n");
+ debugN(" magic: %.4x\n", header->magic);
+ debugN(" action(vvnn): %.4x\n", header->addr_actions_vvnn);
+ debugN(" actions(?):\n");
+ debugN(" actions(vnjn): %.4x\n", header->addr_actions_vnjn);
+ debugN(" actions(vjn): %.4x\n", header->addr_actions_vjn);
+ debugN(" actions(vdn): %.4x\n", header->addr_actions_vdn);
+ debugN(" actions(vnn): %.4x\n", header->addr_actions_vnn);
+ debugN(" actions(vn): %.4x\n", header->addr_actions_vn);
+ debugN(" actions(v): %.4x\n", header->addr_actions_v);
+ debugN(" functions: %.4x\n", header->addr_vm);
+ debugN(" dictionary: %.4x\n", header->addr_dictionary);
+ debugN(" word map pairs: %.4x\n", header->addr_word_map);
+ debugN(" room desc strings: %.4x\n", header->room_desc_table);
+ debugN(" room north: %.4x\n", dir_table[DIRECTION_NORTH]);
+ debugN(" room south: %.4x\n", dir_table[DIRECTION_SOUTH]);
+ debugN(" room east: %.4x\n", dir_table[DIRECTION_EAST]);
+ debugN(" room west: %.4x\n", dir_table[DIRECTION_WEST]);
+ debugN(" room up: %.4x\n", dir_table[DIRECTION_UP]);
+ debugN(" room down: %.4x\n", dir_table[DIRECTION_DOWN]);
+ debugN(" room in: %.4x\n", dir_table[DIRECTION_IN]);
+ debugN(" room out: %.4x\n", dir_table[DIRECTION_OUT]);
+ debugN(" room flags: %.4x\n", header->room_flags_table);
+ debugN(" room images: %.4x\n", header->room_graphics_table);
+ debugN(" item locations: %.4x\n", header->addr_item_locations);
+ debugN(" item flags: %.4x\n", header->addr_item_flags);
+ debugN(" item words: %.4x\n", header->addr_item_word);
+ debugN(" item desc strings: %.4x\n", header->addr_item_strings);
+ debugN(" item images: %.4x\n", header->addr_item_graphics);
+ debugN(" string table: %.4x\n", header->addr_strings);
+ debugN(" string table end: %.4x\n", header->addr_strings_end);
+}
+
+typedef void (*dump_func_t)(struct comprehend_game *game);
+
+struct dumper {
+ dump_func_t dump_func;
+ unsigned flag;
+};
+
+static struct dumper dumpers[] = {
+ {dump_header, DUMP_HEADER},
+ {dump_game_data_strings, DUMP_STRINGS},
+ {dump_extra_strings, DUMP_EXTRA_STRINGS},
+ {dump_rooms, DUMP_ROOMS},
+ {dump_items, DUMP_ITEMS},
+ {dump_dictionary, DUMP_DICTIONARY},
+ {dump_word_map, DUMP_WORD_PAIRS},
+ {dump_action_table, DUMP_ACTIONS},
+ {dump_functions, DUMP_FUNCTIONS},
+ {dump_replace_words, DUMP_REPLACE_WORDS},
+};
+
+void dump_game_data(struct comprehend_game *game, unsigned flags)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dumpers); i++)
+ if (flags & dumpers[i].flag) {
+ dumpers[i].dump_func(game);
+ debugN("\n\n");
+ }
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/dump_game_data.h b/engines/glk/comprehend/dump_game_data.h
new file mode 100644
index 0000000000..dbcaf52022
--- /dev/null
+++ b/engines/glk/comprehend/dump_game_data.h
@@ -0,0 +1,53 @@
+/* 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_COMPREHEND_DUMP_GAME_DATA_H
+#define GLK_COMPREHEND_DUMP_GAME_DATA_H
+
+namespace Glk {
+namespace Comprehend {
+
+struct comprehend_game;
+struct function_state;
+struct instruction;
+
+#define DUMP_STRINGS (1 << 0)
+#define DUMP_EXTRA_STRINGS (1 << 1)
+#define DUMP_ROOMS (1 << 2)
+#define DUMP_ITEMS (1 << 3)
+#define DUMP_DICTIONARY (1 << 4)
+#define DUMP_WORD_PAIRS (1 << 5)
+#define DUMP_ACTIONS (1 << 6)
+#define DUMP_FUNCTIONS (1 << 7)
+#define DUMP_REPLACE_WORDS (1 << 8)
+#define DUMP_HEADER (1 << 9)
+#define DUMP_ALL (~0)
+
+void dump_instruction(struct comprehend_game *game,
+ struct function_state *func_state,
+ struct instruction *instr);
+void dump_game_data(struct comprehend_game *game, unsigned flags);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/file_buf.cpp b/engines/glk/comprehend/file_buf.cpp
new file mode 100644
index 0000000000..512d88c705
--- /dev/null
+++ b/engines/glk/comprehend/file_buf.cpp
@@ -0,0 +1,166 @@
+/* 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/comprehend/file_buf.h"
+#include "glk/comprehend/util.h"
+#include "common/algorithm.h"
+#include "common/file.h"
+
+namespace Glk {
+namespace Comprehend {
+
+int file_buf_map_may_fail(const char *filename, struct file_buf *fb)
+{
+ Common::File f;
+
+ memset(fb, 0, sizeof(*fb));
+
+ if (!f.open(filename))
+ return -1;
+
+ fb->data = (uint8 *)xmalloc(f.size());
+ fb->size = f.size();
+ f.read(fb->data, fb->size);
+ f.close();
+
+ fb->p = fb->data;
+
+ // FIXME - remove
+ fb->marked = (uint8 *)malloc(fb->size);
+ memset(fb->marked, 0, fb->size);
+
+ return 0;
+}
+
+void file_buf_map(const char *filename, struct file_buf *fb)
+{
+ int err;
+
+ err = file_buf_map_may_fail(filename, fb);
+ if (err)
+ fatal_strerror(errno, "Cannot open file '%s'", filename);
+}
+
+void file_buf_unmap(struct file_buf *fb)
+{
+ free(fb->marked);
+ free(fb->data);
+}
+
+void file_buf_set_pos(struct file_buf *fb, unsigned pos)
+{
+ if (pos > fb->size)
+ error("Bad position set in file (%x > %x)",
+ pos, fb->size);
+
+ fb->p = fb->data + pos;
+}
+
+unsigned file_buf_get_pos(struct file_buf *fb)
+{
+ return fb->p - fb->data;
+}
+
+void *file_buf_data_pointer(struct file_buf *fb)
+{
+ return fb->p;
+}
+
+size_t file_buf_strlen(struct file_buf *fb, bool *eof)
+{
+ uint8 *end;
+
+ if (eof)
+ *eof = false;
+
+ end = (uint8 *)memchr(fb->p, '\0', fb->size - file_buf_get_pos(fb));
+ if (!end) {
+ /* No null terminator - string is remaining length */
+ if (eof)
+ *eof = true;
+ return fb->size - file_buf_get_pos(fb);
+ }
+
+ return end - fb->p;
+}
+
+void file_buf_get_data(struct file_buf *fb, void *data, size_t data_size)
+{
+ if (file_buf_get_pos(fb) + data_size > fb->size)
+ error("Not enough data in file (%x + %x > %x)",
+ file_buf_get_pos(fb), data_size, fb->size);
+
+ if (data)
+ memcpy(data, fb->p, data_size);
+
+ /* Mark this region of the file as read */
+ memset(fb->marked + file_buf_get_pos(fb), '?', data_size);
+
+ fb->p += data_size;
+}
+
+void file_buf_get_u8(struct file_buf *fb, uint8 *val)
+{
+ file_buf_get_data(fb, val, sizeof(*val));
+}
+
+void file_buf_get_le16(struct file_buf *fb, uint16 *val)
+{
+ file_buf_get_data(fb, val, sizeof(*val));
+ *val = READ_LE_UINT16(val);
+}
+
+/*
+ * Debugging function to show regions of a file that have not been read.
+ */
+void file_buf_show_unmarked(struct file_buf *fb)
+{
+ int i, start = -1;
+
+ for (i = 0; i < (int)fb->size; i++) {
+ if (!fb->marked[i] && start == -1)
+ start = i;
+
+ if ((fb->marked[i] || i == (int)fb->size - 1) && start != -1) {
+ warning("%.4x - %.4x unmarked (%d bytes)\n",
+ start, i - 1, i - start);
+ start = -1;
+ }
+ }
+}
+
+void file_buf_put_u8(Common::WriteStream *fd, uint8 val)
+{
+ fd->writeByte(val);
+}
+
+void file_buf_put_le16(Common::WriteStream *fd, uint16 val) {
+ fd->writeUint16LE(val);
+}
+
+void file_buf_put_skip(Common::WriteStream *fd, size_t skip) {
+ for (uint i = 0; i < skip; i++)
+ file_buf_put_u8(fd, 0);
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/file_buf.h b/engines/glk/comprehend/file_buf.h
new file mode 100644
index 0000000000..27d1371034
--- /dev/null
+++ b/engines/glk/comprehend/file_buf.h
@@ -0,0 +1,88 @@
+/* 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_COMPREHEND_FILE_BUF_H
+#define GLK_COMPREHEND_FILE_BUF_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+
+namespace Glk {
+namespace Comprehend {
+
+struct file_buf {
+ uint8 *data;
+ size_t size;
+ uint8 *p;
+
+ uint8 *marked;
+};
+
+void file_buf_map(const char *filename, struct file_buf *fb);
+int file_buf_map_may_fail(const char *filename, struct file_buf *fb);
+void file_buf_unmap(struct file_buf *fb);
+void file_buf_show_unmarked(struct file_buf *fb);
+
+void *file_buf_data_pointer(struct file_buf *fb);
+void file_buf_set_pos(struct file_buf *fb, unsigned pos);
+unsigned file_buf_get_pos(struct file_buf *fb);
+
+size_t file_buf_strlen(struct file_buf *fb, bool *eof);
+
+void file_buf_get_data(struct file_buf *fb, void *data, size_t data_size);
+void file_buf_get_u8(struct file_buf *fb, uint8 *val);
+void file_buf_get_le16(struct file_buf *fb, uint16 *val);
+
+#define file_buf_get_array(fb, type, base, array, member, size) \
+ do { \
+ uint __i; \
+ for (__i = (base); __i < (base) + (size); __i++) \
+ file_buf_get_##type(fb, &((array)[__i]).member); \
+ } while (0)
+
+#define file_buf_get_array_u8(fb, base, array, member, size) \
+ file_buf_get_array(fb, u8, base, array, member, size)
+
+#define file_buf_get_array_le16(fb, base, array, member, size) \
+ file_buf_get_array(fb, le16, base, array, member, size)
+
+void file_buf_put_skip(Common::WriteStream *fd, size_t skip);
+void file_buf_put_u8(Common::WriteStream *fd, uint8 val);
+void file_buf_put_le16(Common::WriteStream *fd, uint16 val);
+
+#define file_buf_put_array(fd, type, base, array, member, size) \
+ do { \
+ int __i; \
+ for (__i = (base); __i < (base) + (size); __i++) \
+ file_buf_put_##type(fd, (array)[__i].member); \
+ } while (0)
+
+#define file_buf_put_array_le16(fd, base, array, member, size) \
+ file_buf_put_array(fd, le16, base, array, member, size)
+
+#define file_buf_put_array_u8(fd, base, array, member, size) \
+ file_buf_put_array(fd, u8, base, array, member, size)
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
new file mode 100644
index 0000000000..8dd1b9d789
--- /dev/null
+++ b/engines/glk/comprehend/game.cpp
@@ -0,0 +1,1231 @@
+/* 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/comprehend/game.h"
+#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/dictionary.h"
+#include "glk/comprehend/dump_game_data.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/opcode_map.h"
+#include "glk/comprehend/strings.h"
+#include "glk/comprehend/util.h"
+
+namespace Glk {
+namespace Comprehend {
+
+struct sentence {
+ struct word words[4];
+ size_t nr_words;
+};
+
+struct winsize {
+ uint ws_col;
+};
+static struct winsize console_winsize;
+
+static void console_init(void) {
+ // ioctl(STDOUT_FILENO, TIOCGWINSZ, &console_winsize);
+}
+
+int console_get_key(void) {
+ int c, dummy;
+
+ dummy = c = getchar();
+
+ /* Clear input buffer */
+ while (dummy != '\n' && dummy != EOF)
+ dummy = getchar();
+
+ return c;
+}
+
+void console_println(comprehend_game *game, const char *text) {
+ const char *replace, *word = nullptr, *p = text;
+ char bad_word[64];
+ size_t line_length = 0;
+ int word_len = 0;
+
+ if (!text) {
+ printf("\n");
+ return;
+ }
+
+ while (*p) {
+ switch (*p) {
+ case '\n':
+ word = NULL;
+ word_len = 0;
+ line_length = 0;
+ printf("\n");
+ p++;
+ break;
+
+ case '@':
+ /* Replace word */
+ if (game->info->current_replace_word >= game->info->nr_replace_words) {
+ snprintf(bad_word, sizeof(bad_word),
+ "[BAD_REPLACE_WORD(%.2x)]",
+ game->info->current_replace_word);
+ word = bad_word;
+ } else {
+ word = game->info->replace_words[game->info->current_replace_word];
+ }
+ word_len = strlen(word);
+ p++;
+ break;
+
+ default:
+ /* Find next space */
+ word_len = strcspn(p, " \n");
+ if (word_len == 0)
+ break;
+
+ /*
+ * If this word contains a replacement symbol, then
+ * print everything before the symbol.
+ */
+ replace = strchr(p, '@');
+ if (replace)
+ word_len = replace - p;
+
+ word = p;
+ p += word_len;
+ break;
+ }
+
+ if (!word || !word_len)
+ continue;
+
+ /* Print this word */
+ if (line_length + word_len > console_winsize.ws_col) {
+ /* Too long - insert a line break */
+ printf("\n");
+ line_length = 0;
+ }
+
+ printf("%.*s", word_len, word);
+ line_length += word_len;
+
+ if (*p == ' ') {
+ if (line_length >= console_winsize.ws_col) {
+ /* Newline, don't print the space */
+ printf("\n");
+ line_length = 0;
+ } else {
+ printf(" ");
+ line_length++;
+ }
+ p++;
+
+ /* Skip any double spaces */
+ while (*p == ' ')
+ p++;
+ }
+ }
+
+ printf("\n");
+}
+
+static struct room *get_room(comprehend_game *game, uint16 index) {
+ /* Room zero is reserved for the players inventory */
+ if (index == 0)
+ fatal_error("Room index 0 (player inventory) is invalid");
+
+ if (index - 1 >= (int)game->info->nr_rooms)
+ fatal_error("Room index %d is invalid", index);
+
+ return &game->info->rooms[index];
+}
+
+struct item *get_item(comprehend_game *game, uint16 index) {
+ if (index >= game->info->header.nr_items)
+ fatal_error("Bad item %d\n", index);
+
+ return &game->info->item[index];
+}
+
+void game_save(comprehend_game *game) {
+ char path[PATH_MAX], filename[32];
+ int c;
+
+ console_println(game, game->info->strings.strings[STRING_SAVE_GAME]);
+
+ c = console_get_key();
+ if (c < '1' || c > '3') {
+ /*
+ * The original Comprehend games just silently ignore any
+ * invalid selection.
+ */
+ console_println(game, "Invalid save game number");
+ return;
+ }
+
+ snprintf(filename, sizeof(filename), game->save_game_file_fmt, c - '0');
+ snprintf(path, sizeof(path), "%s%s", game->game_dir, filename);
+ comprehend_save_game(game, path);
+}
+
+void game_restore(comprehend_game *game) {
+ char path[PATH_MAX], filename[32];
+ int c;
+
+ console_println(game, game->info->strings.strings[STRING_RESTORE_GAME]);
+
+ c = console_get_key();
+ if (c < '1' || c > '3') {
+ /*
+ * The original Comprehend games just silently ignore any
+ * invalid selection.
+ */
+ console_println(game, "Invalid save game number");
+ return;
+ }
+
+ snprintf(filename, sizeof(filename), game->save_game_file_fmt, c - '0');
+ snprintf(path, sizeof(path), "%s%s", game->game_dir, filename);
+ comprehend_restore_game(game, path);
+
+ game->info->update_flags = UPDATE_ALL;
+}
+
+void game_restart(comprehend_game *game) {
+ console_println(game, string_lookup(game, game->strings->game_restart));
+ console_get_key();
+
+ comprehend_load_game(game, game->game_dir);
+ game->info->update_flags = UPDATE_ALL;
+}
+
+static struct word_index *is_word_pair(comprehend_game *game,
+ struct word *word1, struct word *word2) {
+ struct word_map *map;
+ uint i;
+
+ /* Check if this is a word pair */
+ for (i = 0; i < game->info->nr_word_maps; i++) {
+ map = &game->info->word_map[i];
+
+ if (map->word[0].index == word1->index &&
+ map->word[0].type == word1->type &&
+ map->word[1].index == word2->index &&
+ map->word[1].type == word2->type)
+ return &map->word[2];
+ }
+
+ return NULL;
+}
+
+static struct item *get_item_by_noun(comprehend_game *game,
+ struct word *noun) {
+ uint i;
+
+ if (!noun || !(noun->type & WORD_TYPE_NOUN_MASK))
+ return NULL;
+
+ /*
+ * FIXME - in oo-topos the word 'box' matches more than one object
+ * (the box and the snarl-in-a-box). The player is unable
+ * to drop the latter because this will match the former.
+ */
+ for (i = 0; i < game->info->header.nr_items; i++)
+ if (game->info->item[i].word == noun->index)
+ return &game->info->item[i];
+
+ return NULL;
+}
+
+static void update_graphics(comprehend_game *game) {
+ struct item *item;
+ struct room *room;
+ int type;
+ uint i;
+
+ if (!g_enabled())
+ return;
+
+ type = ROOM_IS_NORMAL;
+ if (game->ops->room_is_special)
+ type = game->ops->room_is_special(game, game->info->current_room, NULL);
+
+ switch (type) {
+ case ROOM_IS_DARK:
+ if (game->info->update_flags & UPDATE_GRAPHICS)
+ draw_dark_room();
+ break;
+
+ case ROOM_IS_TOO_BRIGHT:
+ if (game->info->update_flags & UPDATE_GRAPHICS)
+ draw_bright_room();
+ break;
+
+ default:
+ if (game->info->update_flags & UPDATE_GRAPHICS) {
+ room = get_room(game, game->info->current_room);
+ draw_location_image(&game->info->room_images,
+ room->graphic - 1);
+ }
+
+ if ((game->info->update_flags & UPDATE_GRAPHICS) ||
+ (game->info->update_flags & UPDATE_GRAPHICS_ITEMS)) {
+ for (i = 0; i < game->info->header.nr_items; i++) {
+ item = &game->info->item[i];
+
+ if (item->room == game->info->current_room &&
+ item->graphic != 0)
+ draw_image(&game->info->item_images,
+ item->graphic - 1);
+ }
+ }
+ break;
+ }
+}
+
+static void describe_objects_in_current_room(comprehend_game *game) {
+ struct item *item;
+ size_t count = 0;
+ uint i;
+
+ for (i = 0; i < game->info->header.nr_items; i++) {
+ item = &game->info->item[i];
+
+ if (item->room == game->info->current_room &&
+ item->string_desc != 0)
+ count++;
+ }
+
+ if (count > 0) {
+ console_println(game, string_lookup(game, STRING_YOU_SEE));
+
+ for (i = 0; i < game->info->header.nr_items; i++) {
+ item = &game->info->item[i];
+
+ if (item->room == game->info->current_room &&
+ item->string_desc != 0)
+ console_println(game, string_lookup(game, item->string_desc));
+ }
+ }
+}
+
+static void update(comprehend_game *game) {
+ struct room *room = get_room(game, game->info->current_room);
+ unsigned room_type, room_desc_string;
+
+ update_graphics(game);
+
+ /* Check if the room is special (dark, too bright, etc) */
+ room_type = ROOM_IS_NORMAL;
+ room_desc_string = room->string_desc;
+ if (game->ops->room_is_special)
+ room_type = game->ops->room_is_special(game,
+ game->info->current_room,
+ &room_desc_string);
+
+ if (game->info->update_flags & UPDATE_ROOM_DESC)
+ console_println(game, string_lookup(game, room_desc_string));
+
+ if ((game->info->update_flags & UPDATE_ITEM_LIST) &&
+ room_type == ROOM_IS_NORMAL)
+ describe_objects_in_current_room(game);
+
+ game->info->update_flags = 0;
+}
+
+static void move_to(comprehend_game *game, uint8 room) {
+ if (room - 1 >= (int)game->info->nr_rooms)
+ fatal_error("Attempted to move to invalid room %.2x\n", room);
+
+ game->info->current_room = room;
+ game->info->update_flags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
+ UPDATE_ITEM_LIST);
+}
+
+static void func_set_test_result(struct function_state *func_state, bool value) {
+ if (func_state->or_count == 0) {
+ /* And */
+ if (func_state->_and) {
+ if (!value)
+ func_state->test_result = false;
+ } else {
+ func_state->test_result = value;
+ func_state->_and = true;
+ }
+
+ } else {
+ /* Or */
+ if (value)
+ func_state->test_result = value;
+ }
+}
+
+static size_t num_objects_in_room(comprehend_game *game, int room) {
+ size_t count = 0, i;
+
+ for (i = 0; i < game->info->header.nr_items; i++)
+ if (game->info->item[i].room == room)
+ count++;
+
+ return count;
+}
+
+void move_object(comprehend_game *game, struct item *item, int new_room) {
+ unsigned obj_weight = item->flags & ITEMF_WEIGHT_MASK;
+
+ if (item->room == new_room)
+ return;
+
+ if (item->room == ROOM_INVENTORY) {
+ /* Removed from player's inventory */
+ game->info->variable[VAR_INVENTORY_WEIGHT] -= obj_weight;
+ }
+ if (new_room == ROOM_INVENTORY) {
+ /* Moving to the player's inventory */
+ game->info->variable[VAR_INVENTORY_WEIGHT] += obj_weight;
+ }
+
+ if (item->room == game->info->current_room) {
+ /* Item moved away from the current room */
+ game->info->update_flags |= UPDATE_GRAPHICS;
+
+ } else if (new_room == game->info->current_room) {
+ /*
+ * Item moved into the current room. Only the item needs a
+ * redraw, not the whole room.
+ */
+ game->info->update_flags |= (UPDATE_GRAPHICS_ITEMS |
+ UPDATE_ITEM_LIST);
+ }
+
+ item->room = new_room;
+}
+
+static void eval_instruction(comprehend_game *game,
+ struct function_state *func_state,
+ struct instruction *instr,
+ struct word *verb, struct word *noun) {
+ uint8 *opcode_map;
+ struct room *room;
+ struct item *item;
+ uint16 index;
+ bool test;
+ uint i, count;
+
+ room = get_room(game, game->info->current_room);
+
+ if (debugging_enabled()) {
+ if (!instr->is_command) {
+ printf("? ");
+ } else {
+ if (func_state->test_result)
+ printf("+ ");
+ else
+ printf("- ");
+ }
+
+ dump_instruction(game, func_state, instr);
+ }
+
+ if (func_state->or_count)
+ func_state->or_count--;
+
+ if (instr->is_command) {
+ bool do_command;
+
+ func_state->in_command = true;
+ do_command = func_state->test_result;
+
+ if (func_state->or_count != 0)
+ printf("Warning: or_count == %d\n",
+ func_state->or_count);
+ func_state->or_count = 0;
+
+ if (!do_command)
+ return;
+
+ func_state->else_result = false;
+ func_state->executed = true;
+
+ } else {
+ if (func_state->in_command) {
+ /* Finished command sequence - clear test result */
+ func_state->in_command = false;
+ func_state->test_result = false;
+ func_state->_and = false;
+ }
+ }
+
+ opcode_map = get_opcode_map(game);
+ switch (opcode_map[instr->opcode]) {
+ case OPCODE_VAR_ADD:
+ game->info->variable[instr->operand[0]] +=
+ game->info->variable[instr->operand[1]];
+ break;
+
+ case OPCODE_VAR_SUB:
+ game->info->variable[instr->operand[0]] -=
+ game->info->variable[instr->operand[1]];
+ break;
+
+ case OPCODE_VAR_INC:
+ game->info->variable[instr->operand[0]]++;
+ break;
+
+ case OPCODE_VAR_DEC:
+ game->info->variable[instr->operand[0]]--;
+ break;
+
+ case OPCODE_VAR_EQ:
+ func_set_test_result(func_state,
+ game->info->variable[instr->operand[0]] ==
+ game->info->variable[instr->operand[1]]);
+ break;
+
+ case OPCODE_TURN_TICK:
+ game->info->variable[VAR_TURN_COUNT]++;
+ break;
+
+ case OPCODE_PRINT:
+ console_println(game, instr_lookup_string(game,
+ instr->operand[0],
+ instr->operand[1]));
+ break;
+
+ case OPCODE_TEST_NOT_ROOM_FLAG:
+ func_set_test_result(func_state,
+ !(room->flags & instr->operand[0]));
+ break;
+
+ case OPCODE_TEST_ROOM_FLAG:
+ func_set_test_result(func_state,
+ room->flags & instr->operand[0]);
+ break;
+
+ case OPCODE_NOT_IN_ROOM:
+ func_set_test_result(func_state,
+ game->info->current_room != instr->operand[0]);
+ break;
+
+ case OPCODE_IN_ROOM:
+ func_set_test_result(func_state,
+ game->info->current_room == instr->operand[0]);
+ break;
+
+ case OPCODE_MOVE_TO_ROOM:
+ if (instr->operand[0] == 0xff) {
+ /*
+ * FIXME - Not sure what this is for. Transylvania
+ * uses it in the 'go north' case when in room
+ * 0x01 or 0x0c, and Oo-Topos uses it when you shoot
+ * the alien. Ignore it for now.
+ */
+ break;
+ }
+
+ move_to(game, instr->operand[0]);
+ break;
+
+ case OPCODE_MOVE:
+ /* Move in the direction dictated by the current verb */
+ if (verb->index - 1 >= NR_DIRECTIONS)
+ fatal_error("Bad verb %d:%d in move",
+ verb->index, verb->type);
+
+ if (room->direction[verb->index - 1])
+ move_to(game, room->direction[verb->index - 1]);
+ else
+ console_println(game, string_lookup(game, STRING_CANT_GO));
+ break;
+
+ case OPCODE_MOVE_DIRECTION:
+ if (room->direction[instr->operand[0] - 1])
+ move_to(game, room->direction[instr->operand[0] - 1]);
+ else
+ console_println(game, string_lookup(game, STRING_CANT_GO));
+ break;
+
+ case OPCODE_ELSE:
+ func_state->test_result = func_state->else_result;
+ break;
+
+ case OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM:
+ item = get_item(game, instr->operand[0] - 1);
+ move_object(game, item, game->info->current_room);
+ break;
+
+ case OPCODE_OBJECT_IN_ROOM:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room == instr->operand[1]);
+ break;
+
+ case OPCODE_OBJECT_NOT_IN_ROOM:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room != instr->operand[1]);
+ break;
+
+ case OPCODE_MOVE_OBJECT_TO_ROOM:
+ item = get_item(game, instr->operand[0] - 1);
+ move_object(game, item, instr->operand[1]);
+ break;
+
+ case OPCODE_INVENTORY_FULL:
+ item = get_item_by_noun(game, noun);
+ func_set_test_result(func_state,
+ game->info->variable[VAR_INVENTORY_WEIGHT] +
+ (item->flags & ITEMF_WEIGHT_MASK) >
+ game->info->variable[VAR_INVENTORY_LIMIT]);
+ break;
+
+ case OPCODE_DESCRIBE_CURRENT_OBJECT:
+ /*
+ * This opcode is only used in version 2
+ * FIXME - unsure what the single operand is for.
+ */
+ item = get_item_by_noun(game, noun);
+ printf("%s\n", string_lookup(game, item->long_string));
+ break;
+
+ case OPCODE_CURRENT_OBJECT_IN_ROOM:
+ /* FIXME - use common code for these two ops */
+ test = false;
+
+ if (noun) {
+ for (i = 0; i < game->info->header.nr_items; i++) {
+ struct item *itemP = &game->info->item[i];
+
+ if (itemP->word == noun->index &&
+ itemP->room == instr->operand[0]) {
+ test = true;
+ break;
+ }
+ }
+ }
+
+ func_set_test_result(func_state, test);
+ break;
+
+ case OPCODE_CURRENT_OBJECT_NOT_PRESENT:
+ /* FIXME - use common code for these two ops */
+ item = get_item_by_noun(game, noun);
+ if (item)
+ func_set_test_result(func_state,
+ item->room != game->info->current_room);
+ else
+ func_set_test_result(func_state, true);
+ break;
+
+ case OPCODE_CURRENT_OBJECT_PRESENT:
+ item = get_item_by_noun(game, noun);
+ if (item)
+ func_set_test_result(func_state,
+ item->room == game->info->current_room);
+ else
+ func_set_test_result(func_state, false);
+ break;
+
+ case OPCODE_HAVE_OBJECT:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room == ROOM_INVENTORY);
+ break;
+
+ case OPCODE_NOT_HAVE_CURRENT_OBJECT:
+ item = get_item_by_noun(game, noun);
+ func_set_test_result(func_state,
+ !item || item->room != ROOM_INVENTORY);
+ break;
+
+ case OPCODE_HAVE_CURRENT_OBJECT:
+ item = get_item_by_noun(game, noun);
+ func_set_test_result(func_state,
+ item->room == ROOM_INVENTORY);
+ break;
+
+ case OPCODE_NOT_HAVE_OBJECT:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room != ROOM_INVENTORY);
+ break;
+
+ case OPCODE_CURRENT_OBJECT_TAKEABLE:
+ item = get_item_by_noun(game, noun);
+ if (!item)
+ func_set_test_result(func_state, false);
+ else
+ func_set_test_result(func_state,
+ (item->flags & ITEMF_CAN_TAKE));
+ break;
+
+ case OPCODE_CURRENT_OBJECT_NOT_TAKEABLE:
+ item = get_item_by_noun(game, noun);
+ if (!item)
+ func_set_test_result(func_state, true);
+ else
+ func_set_test_result(func_state,
+ !(item->flags & ITEMF_CAN_TAKE));
+ break;
+
+ case OPCODE_CURRENT_OBJECT_IS_NOWHERE:
+ item = get_item_by_noun(game, noun);
+ if (!item)
+ func_set_test_result(func_state, false);
+ else
+ func_set_test_result(func_state,
+ item->room == ROOM_NOWHERE);
+ break;
+
+ case OPCODE_OBJECT_IS_NOWHERE:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room == ROOM_NOWHERE);
+ break;
+
+ case OPCODE_OBJECT_IS_NOT_NOWHERE:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room != ROOM_NOWHERE);
+ break;
+
+ case OPCODE_OBJECT_NOT_PRESENT:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room != game->info->current_room);
+ break;
+
+ case OPCODE_OBJECT_PRESENT:
+ item = get_item(game, instr->operand[0] - 1);
+ func_set_test_result(func_state,
+ item->room == game->info->current_room);
+ break;
+
+ case OPCODE_OBJECT_NOT_VALID:
+ /* FIXME - should be called OPCODE_CURRENT_OBJECT_NOT_VALID */
+ func_set_test_result(func_state, !noun ||
+ (noun->type & WORD_TYPE_NOUN_MASK) == 0);
+ break;
+
+ case OPCODE_CURRENT_IS_OBJECT:
+ func_set_test_result(func_state,
+ get_item_by_noun(game, noun) != NULL);
+ break;
+
+ case OPCODE_CURRENT_NOT_OBJECT:
+ func_set_test_result(func_state,
+ get_item_by_noun(game, noun) == NULL);
+ break;
+
+ case OPCODE_REMOVE_OBJECT:
+ item = get_item(game, instr->operand[0] - 1);
+ move_object(game, item, ROOM_NOWHERE);
+ break;
+
+ case OPCODE_REMOVE_CURRENT_OBJECT:
+ item = get_item_by_noun(game, noun);
+ move_object(game, item, ROOM_NOWHERE);
+ break;
+
+ case OPCODE_INVENTORY:
+ count = num_objects_in_room(game, ROOM_INVENTORY);
+ if (count == 0) {
+ console_println(game, string_lookup(game, STRING_INVENTORY_EMPTY));
+ break;
+ }
+
+ console_println(game, string_lookup(game, STRING_INVENTORY));
+ for (i = 0; i < game->info->header.nr_items; i++) {
+ item = &game->info->item[i];
+ if (item->room == ROOM_INVENTORY)
+ printf("%s\n",
+ string_lookup(game, item->string_desc));
+ }
+ break;
+
+ case OPCODE_INVENTORY_ROOM:
+ count = num_objects_in_room(game, instr->operand[0]);
+ if (count == 0) {
+ console_println(game, string_lookup(game, instr->operand[1] + 1));
+ break;
+ }
+
+ console_println(game, string_lookup(game, instr->operand[1]));
+ for (i = 0; i < game->info->header.nr_items; i++) {
+ item = &game->info->item[i];
+ if (item->room == instr->operand[0])
+ printf("%s\n",
+ string_lookup(game, item->string_desc));
+ }
+ break;
+
+ case OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM:
+ item = get_item_by_noun(game, noun);
+ if (!item)
+ fatal_error("Bad current object\n");
+
+ move_object(game, item, instr->operand[0]);
+ break;
+
+ case OPCODE_DROP_OBJECT:
+ item = get_item(game, instr->operand[0] - 1);
+ move_object(game, item, game->info->current_room);
+ break;
+
+ case OPCODE_DROP_CURRENT_OBJECT:
+ item = get_item_by_noun(game, noun);
+ if (!item)
+ fatal_error("Attempt to take object failed\n");
+
+ move_object(game, item, game->info->current_room);
+ break;
+
+ case OPCODE_TAKE_CURRENT_OBJECT:
+ item = get_item_by_noun(game, noun);
+ if (!item)
+ fatal_error("Attempt to take object failed\n");
+
+ move_object(game, item, ROOM_INVENTORY);
+ break;
+
+ case OPCODE_TAKE_OBJECT:
+ item = get_item(game, instr->operand[0] - 1);
+ move_object(game, item, ROOM_INVENTORY);
+ break;
+
+ case OPCODE_TEST_FLAG:
+ func_set_test_result(func_state,
+ game->info->flags[instr->operand[0]]);
+ break;
+
+ case OPCODE_TEST_NOT_FLAG:
+ func_set_test_result(func_state,
+ !game->info->flags[instr->operand[0]]);
+ break;
+
+ case OPCODE_CLEAR_FLAG:
+ game->info->flags[instr->operand[0]] = false;
+ break;
+
+ case OPCODE_SET_FLAG:
+ game->info->flags[instr->operand[0]] = true;
+ break;
+
+ case OPCODE_OR:
+ if (func_state->or_count) {
+ func_state->or_count += 2;
+ } else {
+ func_state->test_result = false;
+ func_state->or_count += 3;
+ }
+ break;
+
+ case OPCODE_SET_OBJECT_DESCRIPTION:
+ item = get_item(game, instr->operand[0] - 1);
+ item->string_desc = (instr->operand[2] << 8) | instr->operand[1];
+ break;
+
+ case OPCODE_SET_OBJECT_LONG_DESCRIPTION:
+ item = get_item(game, instr->operand[0] - 1);
+ item->long_string = (instr->operand[2] << 8) | instr->operand[1];
+ break;
+
+ case OPCODE_SET_ROOM_DESCRIPTION:
+ room = get_room(game, instr->operand[0]);
+ switch (instr->operand[2]) {
+ case 0x80:
+ room->string_desc = instr->operand[1];
+ break;
+ case 0x81:
+ room->string_desc = instr->operand[1] + 0x100;
+ break;
+ case 0x82:
+ room->string_desc = instr->operand[1] + 0x200;
+ break;
+ default:
+ fatal_error("Bad string desc %.2x:%.2x\n",
+ instr->operand[1], instr->operand[2]);
+ break;
+ }
+ break;
+
+ case OPCODE_SET_OBJECT_GRAPHIC:
+ item = get_item(game, instr->operand[0] - 1);
+ item->graphic = instr->operand[1];
+ if (item->room == game->info->current_room)
+ game->info->update_flags |= UPDATE_GRAPHICS;
+ break;
+
+ case OPCODE_SET_ROOM_GRAPHIC:
+ room = get_room(game, instr->operand[0]);
+ room->graphic = instr->operand[1];
+ if (instr->operand[0] == game->info->current_room)
+ game->info->update_flags |= UPDATE_GRAPHICS;
+ break;
+
+ case OPCODE_CALL_FUNC:
+ index = instr->operand[0];
+ if (instr->operand[1] == 0x81)
+ index += 256;
+ if (index >= game->info->nr_functions)
+ fatal_error("Bad function %.4x >= %.4x\n",
+ index, game->info->nr_functions);
+
+ debug_printf(DEBUG_FUNCTIONS,
+ "Calling subfunction %.4x\n", index);
+ eval_function(game, &game->info->functions[index], verb, noun);
+ break;
+
+ case OPCODE_TEST_FALSE:
+ /*
+ * FIXME - not sure what this is for. In Transylvania
+ * it is opcode 0x50 and is used when attempting to
+ * take the bar in the cellar. If it returns true then
+ * the response is "there's none here".
+ */
+ func_set_test_result(func_state, false);
+ break;
+
+ case OPCODE_SAVE_ACTION:
+ /*
+ * FIXME - This saves the current verb and allows the next
+ * command to use just the noun. This is used to allow
+ * responses to ask the player what they meant, e.g:
+ *
+ * > drop
+ * I don't understand what you want to drop.
+ * > gun
+ * Okay.
+ */
+ break;
+
+ case OPCODE_SET_STRING_REPLACEMENT:
+ game->info->current_replace_word = instr->operand[0] - 1;
+ break;
+
+ case OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT:
+ /*
+ * FIXME - Not sure what the operand is for,
+ * maybe capitalisation?
+ */
+ if (noun && (noun->type & WORD_TYPE_NOUN_PLURAL))
+ game->info->current_replace_word = 3;
+ else if (noun && (noun->type & WORD_TYPE_FEMALE))
+ game->info->current_replace_word = 0;
+ else if (noun && (noun->type & WORD_TYPE_MALE))
+ game->info->current_replace_word = 1;
+ else
+ game->info->current_replace_word = 2;
+ break;
+
+ case OPCODE_DRAW_ROOM:
+ draw_location_image(&game->info->room_images,
+ instr->operand[0] - 1);
+ break;
+
+ case OPCODE_DRAW_OBJECT:
+ draw_image(&game->info->item_images, instr->operand[0] - 1);
+ break;
+
+ case OPCODE_WAIT_KEY:
+ console_get_key();
+ break;
+
+ case OPCODE_SPECIAL:
+ /* Game specific opcode */
+ if (game->ops->handle_special_opcode)
+ game->ops->handle_special_opcode(game,
+ instr->operand[0]);
+ break;
+
+ default:
+ if (instr->opcode & 0x80) {
+ debug_printf(DEBUG_FUNCTIONS,
+ "Unhandled command opcode %.2x\n",
+ instr->opcode);
+ } else {
+ debug_printf(DEBUG_FUNCTIONS,
+ "Unhandled test opcode %.2x - returning false\n",
+ instr->opcode);
+ func_set_test_result(func_state, false);
+ }
+ break;
+ }
+}
+
+/*
+ * Comprehend functions consist of test and command instructions (if the MSB
+ * of the opcode is set then it is a command). Functions are parsed by
+ * evaluating each test until a command instruction is encountered. If the
+ * overall result of the tests was true then the command instructions are
+ * executed until either a test instruction is found or the end of the function
+ * is reached. Otherwise the commands instructions are skipped over and the
+ * next test sequence (if there is one) is tried.
+ */
+void eval_function(comprehend_game *game, struct function *func,
+ struct word *verb, struct word *noun) {
+ struct function_state func_state = {
+ true, false, 0, false, false, false
+ };
+ uint i;
+
+ func_state.else_result = true;
+ func_state.executed = false;
+
+ for (i = 0; i < func->nr_instructions; i++) {
+ if (func_state.executed && !func->instructions[i].is_command) {
+ /*
+ * At least one command has been executed and the
+ * current instruction is a test. Exit the function.
+ */
+ break;
+ }
+
+ eval_instruction(game, &func_state, &func->instructions[i],
+ verb, noun);
+ }
+}
+
+static void skip_whitespace(char **p) {
+ while (**p && Common::isSpace(**p))
+ (*p)++;
+}
+
+static void skip_non_whitespace(char **p) {
+ while (**p && !Common::isSpace(**p) && **p != ',' && **p != '\n')
+ (*p)++;
+}
+
+static void handle_debug_command(comprehend_game *game,
+ const char *line) {
+ int i;
+
+ if (strncmp(line, "quit", 4) == 0) {
+ error("Quit");
+
+ } else if (strncmp(line, "debug", 5) == 0) {
+ if (debugging_enabled())
+ debug_disable(DEBUG_ALL);
+ else
+ debug_enable(DEBUG_FUNCTIONS);
+ printf("Debugging %s\n", debugging_enabled() ? "on" : "off");
+
+ } else if (strncmp(line, "dump objects", 12) == 0) {
+ dump_game_data(game, DUMP_ITEMS);
+
+ } else if (strncmp(line, "dump rooms", 10) == 0) {
+ dump_game_data(game, DUMP_ROOMS);
+
+ } else if (strncmp(line, "dump state", 10) == 0) {
+ printf("Current room: %.2x\n", game->info->current_room);
+ printf("Carry weight %d/%d\n\n",
+ game->info->variable[VAR_INVENTORY_WEIGHT],
+ game->info->variable[VAR_INVENTORY_LIMIT]);
+
+ printf("Flags:\n");
+ for (i = 0; i < ARRAY_SIZE(game->info->flags); i++)
+ printf(" [%.2x]: %d\n", i, game->info->flags[i]);
+ printf("\n");
+
+ printf("Variables:\n");
+ for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
+ printf(" [%.2x]: %5d (0x%.4x)\n",
+ i, game->info->variable[i],
+ game->info->variable[i]);
+ printf("\n");
+ }
+}
+
+static bool handle_sentence(comprehend_game *game,
+ struct sentence *sentence) {
+ struct function *func;
+ struct action *action;
+ uint i, j;
+
+ if (sentence->nr_words == 0)
+ return false;
+
+ /* Find a matching action */
+ for (i = 0; i < game->info->nr_actions; i++) {
+ action = &game->info->action[i];
+
+ if (action->type == ACTION_VERB_OPT_NOUN &&
+ sentence->nr_words > action->nr_words + 1)
+ continue;
+ if (action->type != ACTION_VERB_OPT_NOUN &&
+ sentence->nr_words != action->nr_words)
+ continue;
+
+ /*
+ * If all words in a sentence match those for an action then
+ * run that action's function.
+ */
+ for (j = 0; j < action->nr_words; j++) {
+ if (sentence->words[j].index == action->word[j] &&
+ (sentence->words[j].type & action->word_type[j]))
+ continue;
+
+ /* Word didn't match */
+ break;
+ }
+ if (j == action->nr_words) {
+ /* Match */
+ func = &game->info->functions[action->function];
+ eval_function(game, func,
+ &sentence->words[0], &sentence->words[1]);
+ return true;
+ }
+ }
+
+ /* No matching action */
+ console_println(game, string_lookup(game, STRING_DONT_UNDERSTAND));
+ return false;
+}
+
+static void read_sentence(comprehend_game *game, char **line,
+ struct sentence *sentence) {
+ bool sentence_end = false;
+ char *word_string, *p = *line;
+ struct word_index *pair;
+ struct word *word;
+ int index;
+
+ memset(sentence, 0, sizeof(*sentence));
+ while (1) {
+ skip_whitespace(&p);
+ word_string = p;
+ skip_non_whitespace(&p);
+
+ if (*p == ',' || *p == '\n') {
+ /* Sentence separator */
+ *p++ = '\0';
+ sentence_end = true;
+ } else {
+ if (*p == '\0')
+ sentence_end = true;
+ else
+ *p++ = '\0';
+ }
+
+ /* Find the dictionary word for this */
+ word = dict_find_word_by_string(game, word_string);
+ if (!word)
+ memset(&sentence->words[sentence->nr_words], 0,
+ sizeof(sentence->words[sentence->nr_words]));
+ else
+ memcpy(&sentence->words[sentence->nr_words],
+ word, sizeof(*word));
+
+ sentence->nr_words++;
+
+ if (sentence->nr_words > 1) {
+ index = sentence->nr_words;
+
+ /* See if this word and the previous are a word pair */
+ pair = is_word_pair(game,
+ &sentence->words[index - 2],
+ &sentence->words[index - 1]);
+ if (pair) {
+ sentence->words[index - 2].index = pair->index;
+ sentence->words[index - 2].type = pair->type;
+ strcpy(sentence->words[index - 2].word,
+ "[PAIR]");
+ sentence->nr_words--;
+ }
+ }
+
+ if (sentence->nr_words >= ARRAY_SIZE(sentence->words) ||
+ sentence_end)
+ break;
+ }
+
+ *line = p;
+}
+
+static void before_turn(comprehend_game *game) {
+ /* Run the game specific before turn bits */
+ if (game->ops->before_turn)
+ game->ops->before_turn(game);
+
+ /* Run the each turn functions */
+ eval_function(game, &game->info->functions[0], NULL, NULL);
+
+ update(game);
+}
+
+static void after_turn(comprehend_game *game) {
+ /* Do post turn game specific bits */
+ if (game->ops->after_turn)
+ game->ops->after_turn(game);
+}
+
+static void read_input(comprehend_game *game) {
+#ifdef TODO
+ struct sentence sentence;
+ char *line = NULL, buffer[1024];
+ bool handled;
+
+ if (game->ops->before_prompt)
+ game->ops->before_prompt(game);
+ before_turn(game);
+
+ while (!line) {
+ printf("> ");
+ line = fgets(buffer, sizeof(buffer), stdin);
+ }
+
+ /* Re-comprehend special commands start with '!' */
+ if (*line == '!') {
+ handle_debug_command(game, &line[1]);
+ return;
+ }
+
+ while (1) {
+ read_sentence(game, &line, &sentence);
+ handled = handle_sentence(game, &sentence);
+ if (handled)
+ after_turn(game);
+
+ /* FIXME - handle the 'before you can continue' case */
+ if (*line == '\0')
+ break;
+ line++;
+
+ if (handled)
+ before_turn(game);
+ }
+#else
+ error("TODO: read_input");
+#endif
+}
+
+void comprehend_play_game(comprehend_game *game) {
+ console_init();
+
+ if (game->ops->before_game)
+ game->ops->before_game(game);
+
+ game->info->update_flags = (uint)UPDATE_ALL;
+ while (1)
+ read_input(game);
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
new file mode 100644
index 0000000000..627f7c925b
--- /dev/null
+++ b/engines/glk/comprehend/game.h
@@ -0,0 +1,78 @@
+/* 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_COMPREHEND_GAME_H
+#define GLK_COMPREHEND_GAME_H
+
+#include "common/scummsys.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#define MAX_FILES 10
+
+struct function;
+struct item;
+struct word;
+
+struct string_file {
+ const char *filename;
+ uint32 base_offset;
+ uint32 end_offset;
+};
+
+struct comprehend_game {
+ const char *game_name;
+ const char *short_name;
+
+ const char *game_dir;
+
+ const char *game_data_file;
+ struct string_file string_files[MAX_FILES];
+ const char *location_graphic_files[MAX_FILES];
+ const char *item_graphic_files[MAX_FILES];
+ const char *save_game_file_fmt;
+ unsigned color_table;
+
+ struct game_strings *strings;
+ struct game_ops *ops;
+
+ struct game_info *info;
+};
+
+void console_println(struct comprehend_game *game, const char *text);
+int console_get_key(void);
+
+struct item *get_item(struct comprehend_game *game, uint16 index);
+void move_object(struct comprehend_game *game, struct item *item, int new_room);
+void eval_function(struct comprehend_game *game, struct function *func,
+ struct word *verb, struct word *noun);
+
+void comprehend_play_game(struct comprehend_game *game);
+void game_save(struct comprehend_game *game);
+void game_restore(struct comprehend_game *game);
+void game_restart(struct comprehend_game *game);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
new file mode 100644
index 0000000000..070dbf9c88
--- /dev/null
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -0,0 +1,169 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+static void cc_clear_companion_flags(struct comprehend_game *game)
+{
+ /* Clear the Sabrina/Erik action flags */
+ game->info->flags[0xa] = 0;
+ game->info->flags[0xb] = 0;
+}
+
+static bool cc_common_handle_special_opcode(struct comprehend_game *game,
+ uint8 operand)
+{
+ switch (operand) {
+ case 0x03:
+ /*
+ * Game over - failure.
+ *
+ * FIXME - If playing the second disk this should restart
+ * from the beginning of the first disk.
+ */
+ game_restart(game);
+ break;
+
+ case 0x06:
+ game_save(game);
+ break;
+
+ case 0x07:
+ /*
+ * FIXME - This will only correctly restore games that were
+ * saved for the disk currently being played.
+ */
+ game_restore(game);
+ return true;
+ }
+
+ return false;
+}
+
+static void cc1_handle_special_opcode(struct comprehend_game *game,
+ uint8 operand)
+{
+ if (cc_common_handle_special_opcode(game, operand))
+ return;
+
+ switch (operand) {
+ case 0x05:
+ /*
+ * Completed first part (disk 1) of the game.
+ *
+ * FIXME - This should automatically load disk 2.
+ */
+ error("[Completed disk 1 - to continue run Re-Comprehend with the 'cc2' game]");
+ break;
+ }
+}
+
+static void cc2_handle_special_opcode(struct comprehend_game *game,
+ uint8 operand)
+{
+ if (cc_common_handle_special_opcode(game, operand))
+ return;
+
+ switch (operand) {
+ case 0x01:
+ /* Enter the Vampire's throne room */
+ eval_function(game, &game->info->functions[0xe], NULL, NULL);
+ break;
+
+ case 0x05:
+ /*
+ * Won the game.
+ *
+ * FIXME - The merchant ship should arrives, etc.
+ */
+ game_restart(game);
+ break;
+ }
+}
+
+static void cc2_before_prompt(struct comprehend_game *game)
+{
+ cc_clear_companion_flags(game);
+}
+
+static void cc1_before_prompt(struct comprehend_game *game)
+{
+ cc_clear_companion_flags(game);
+}
+
+static struct game_strings cc1_strings = { 0x9 };
+
+static struct game_ops cc1_ops = {
+ nullptr,
+ cc1_before_prompt,
+ nullptr,
+ nullptr,
+ nullptr,
+ cc1_handle_special_opcode
+};
+
+static struct game_ops cc2_ops = {
+ nullptr,
+ cc2_before_prompt,
+ nullptr,
+ nullptr,
+ nullptr,
+ cc2_handle_special_opcode
+};
+
+struct comprehend_game game_crimson_crown_1 = {
+ "Crimson Crown (Part 1/2)",
+ "cc1",
+ nullptr,
+ "CC1.GDA",
+ { {"MA.MS1", 0x89} },
+ {"RA.MS1", "RB.MS1", "RC.MS1"},
+ {"OA.MS1", "OB.MS1"},
+ "G%d.MS0",
+ 0,
+ &cc1_strings,
+ &cc1_ops,
+ nullptr
+};
+
+struct comprehend_game game_crimson_crown_2 = {
+ "Crimson Crown (Part 2/2)",
+ "cc2",
+ nullptr,
+ "CC2.GDA",
+ { {"MA.MS2", 0x89} },
+ {"RA.MS2", "RB.MS2"},
+ {"OA.MS2", "OB.MS2"},
+ "G%d.MS0",
+ 0,
+ nullptr,
+ &cc2_ops,
+ nullptr
+};
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
new file mode 100644
index 0000000000..70125ff369
--- /dev/null
+++ b/engines/glk/comprehend/game_data.cpp
@@ -0,0 +1,1084 @@
+/* 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/comprehend/game_data.h"
+#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/dictionary.h"
+#include "glk/comprehend/dump_game_data.h"
+#include "glk/comprehend/file_buf.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/strings.h"
+#include "glk/comprehend/util.h"
+
+namespace Glk {
+namespace Comprehend {
+
+static char charset[] = "..abcdefghijklmnopqrstuvwxyz .";
+static char special_charset[] = "[]\n!\"#$%&'(),-/0123456789:;?<>";
+
+static uint16 magic_offset;
+
+static void parse_header_le16(struct file_buf *fb, uint16 *val) {
+ file_buf_get_le16(fb, val);
+ *val += (uint16)magic_offset;
+}
+
+static size_t opcode_nr_operands(uint8 opcode) {
+ /* Number of operands is encoded in the low 2 bits */
+ return opcode & 0x3;
+}
+
+static bool opcode_is_command(uint8 opcode) {
+ /* If the MSB is set the instruction is a command */
+ return opcode & 0x80;
+}
+
+static uint8 parse_vm_instruction(struct file_buf *fb,
+ struct instruction *instr) {
+ uint i;
+
+ /* Get the opcode */
+ file_buf_get_u8(fb, &instr->opcode);
+ instr->nr_operands = opcode_nr_operands(instr->opcode);
+
+ /* Get the operands */
+ for (i = 0; i < instr->nr_operands; i++)
+ file_buf_get_u8(fb, &instr->operand[i]);
+
+ instr->is_command = opcode_is_command(instr->opcode);
+
+ return instr->opcode;
+}
+
+static void parse_function(struct file_buf *fb, struct function *func) {
+ struct instruction *instruction;
+ uint8 *p, opcode;
+
+ p = (uint8 *)memchr(file_buf_data_pointer(fb), 0x00,
+ fb->size - file_buf_get_pos(fb));
+ if (!p)
+ fatal_error("bad function @ %.4x", file_buf_get_pos(fb));
+
+ while (1) {
+ instruction = &func->instructions[func->nr_instructions];
+
+ opcode = parse_vm_instruction(fb, instruction);
+ if (opcode == 0)
+ break;
+
+ func->nr_instructions++;
+ if (func->nr_instructions >= ARRAY_SIZE(func->instructions))
+ fatal_error("Function has too many instructions");
+ }
+}
+
+static void parse_vm(struct comprehend_game *game, struct file_buf *fb) {
+ struct function *func;
+
+ file_buf_set_pos(fb, game->info->header.addr_vm);
+ while (1) {
+ func = &game->info->functions[game->info->nr_functions];
+
+ parse_function(fb, func);
+ if (func->nr_instructions == 0)
+ break;
+
+ game->info->nr_functions++;
+ }
+}
+
+static void parse_action_table_vvnn(struct comprehend_game *game,
+ struct file_buf *fb, size_t *index) {
+ struct action *action;
+ uint8 verb, count;
+ int i, j;
+
+ /*
+ * <verb> <verb> <noun> <noun>
+ *
+ * u8: verb1
+ * u8: count
+ * u8: verb2
+ * u8: noun1
+ * u8: noun2
+ * le16: action
+ */
+ file_buf_set_pos(fb, game->info->header.addr_actions_vvnn);
+ while (1) {
+ file_buf_get_u8(fb, &verb);
+ if (verb == 0)
+ break;
+ file_buf_get_u8(fb, &count);
+
+ for (i = 0; i < count; i++) {
+ action = &game->info->action[*index];
+ action->type = ACTION_VERB_VERB_NOUN_NOUN;
+
+ action->nr_words = 4;
+ action->word_type[0] = WORD_TYPE_VERB;
+ action->word_type[1] = WORD_TYPE_VERB;
+ action->word_type[2] = WORD_TYPE_NOUN_MASK;
+ action->word_type[3] = WORD_TYPE_NOUN_MASK;
+
+ action->word[0] = verb;
+
+ for (j = 0; j < 3; j++)
+ file_buf_get_u8(fb, &action->word[j + 1]);
+ file_buf_get_le16(fb, &action->function);
+
+ (*index)++;
+ }
+ }
+}
+
+static void parse_action_table_vnjn(struct comprehend_game *game,
+ struct file_buf *fb, size_t *index) {
+ struct action *action;
+ uint8 join, count;
+ int i;
+
+ /*
+ * <verb> <noun> <join> <noun>
+ *
+ * u8: join
+ * u8: count
+ * u8: verb
+ * u8: noun1
+ * u8: noun2
+ * le16: action
+ */
+ file_buf_set_pos(fb, game->info->header.addr_actions_vnjn);
+ while (1) {
+ file_buf_get_u8(fb, &join);
+ if (join == 0)
+ break;
+ file_buf_get_u8(fb, &count);
+
+ for (i = 0; i < count; i++) {
+ action = &game->info->action[*index];
+ action->type = ACTION_VERB_NOUN_JOIN_NOUN;
+
+ action->nr_words = 4;
+ action->word_type[0] = WORD_TYPE_VERB;
+ action->word_type[1] = WORD_TYPE_NOUN_MASK;
+ action->word_type[2] = WORD_TYPE_JOIN;
+ action->word_type[3] = WORD_TYPE_NOUN_MASK;
+
+ action->word[2] = join;
+
+ file_buf_get_u8(fb, &action->word[0]);
+ file_buf_get_u8(fb, &action->word[1]);
+ file_buf_get_u8(fb, &action->word[3]);
+ file_buf_get_le16(fb, &action->function);
+
+ (*index)++;
+ }
+ }
+}
+
+static void parse_action_table_vjn(struct comprehend_game *game,
+ struct file_buf *fb, size_t *index) {
+ struct action *action;
+ uint8 join, count;
+ int i;
+
+ /*
+ * <verb> <join> <noun>
+ *
+ * u8: join
+ * u8: count
+ * u8: verb
+ * u8: noun
+ * le16: action
+ */
+ file_buf_set_pos(fb, game->info->header.addr_actions_vjn);
+ while (1) {
+ file_buf_get_u8(fb, &join);
+ if (join == 0)
+ break;
+ file_buf_get_u8(fb, &count);
+
+ for (i = 0; i < count; i++) {
+ action = &game->info->action[*index];
+ action->type = ACTION_VERB_JOIN_NOUN;
+ action->word[1] = join;
+
+ action->nr_words = 3;
+ action->word_type[0] = WORD_TYPE_VERB;
+ action->word_type[1] = WORD_TYPE_JOIN;
+ action->word_type[2] = WORD_TYPE_NOUN_MASK;
+
+ file_buf_get_u8(fb, &action->word[0]);
+ file_buf_get_u8(fb, &action->word[2]);
+ file_buf_get_le16(fb, &action->function);
+
+ (*index)++;
+ }
+ }
+}
+
+static void parse_action_table_vdn(struct comprehend_game *game,
+ struct file_buf *fb, size_t *index) {
+ struct action *action;
+ uint8 verb, count;
+ int i;
+
+ /*
+ * <verb> <dir> <noun>
+ *
+ * u8: verb
+ * u8: count
+ * u8: dir
+ * u8: noun
+ * le16: action
+ */
+ file_buf_set_pos(fb, game->info->header.addr_actions_vdn);
+ while (1) {
+ file_buf_get_u8(fb, &verb);
+ if (verb == 0)
+ break;
+ file_buf_get_u8(fb, &count);
+
+ for (i = 0; i < count; i++) {
+ action = &game->info->action[*index];
+ action->type = ACTION_VERB_JOIN_NOUN;
+ action->word[0] = verb;
+
+ action->nr_words = 3;
+ action->word_type[0] = WORD_TYPE_VERB;
+ action->word_type[1] = WORD_TYPE_VERB;
+ action->word_type[2] = WORD_TYPE_NOUN_MASK;
+
+ file_buf_get_u8(fb, &action->word[1]);
+ file_buf_get_u8(fb, &action->word[2]);
+ file_buf_get_le16(fb, &action->function);
+
+ (*index)++;
+ }
+ }
+}
+
+static void parse_action_table_vnn(struct comprehend_game *game,
+ struct file_buf *fb, size_t *index) {
+ struct action *action;
+ uint8 verb, count;
+ int i;
+
+ /*
+ * <verb> <noun> <noun>
+ *
+ * u8: verb
+ * u8: count
+ * u8: noun1
+ * u8: noun2
+ * le16: action
+ */
+ file_buf_set_pos(fb, game->info->header.addr_actions_vnn);
+ while (1) {
+ /* 2-byte header */
+ file_buf_get_u8(fb, &verb);
+ if (verb == 0)
+ break;
+ file_buf_get_u8(fb, &count);
+
+ for (i = 0; i < count; i++) {
+ action = &game->info->action[*index];
+ action->type = ACTION_VERB_NOUN_NOUN;
+ action->word[0] = verb;
+
+ action->nr_words = 3;
+ action->word_type[0] = WORD_TYPE_VERB;
+ action->word_type[1] = WORD_TYPE_NOUN_MASK;
+ action->word_type[2] = WORD_TYPE_NOUN_MASK;
+
+ file_buf_get_u8(fb, &action->word[1]);
+ file_buf_get_u8(fb, &action->word[2]);
+ file_buf_get_le16(fb, &action->function);
+
+ (*index)++;
+ }
+ }
+}
+
+static void parse_action_table_vn(struct comprehend_game *game,
+ struct file_buf *fb, size_t *index) {
+ struct action *action;
+ uint8 verb, count;
+ int i;
+
+ /*
+ * <verb> <noun>
+ *
+ * u8: verb
+ * u8: count
+ * u8: noun
+ * le16: action
+ */
+ file_buf_set_pos(fb, game->info->header.addr_actions_vn);
+ while (1) {
+ /* 2-byte header */
+ file_buf_get_u8(fb, &verb);
+ if (verb == 0)
+ break;
+ file_buf_get_u8(fb, &count);
+
+ for (i = 0; i < count; i++) {
+ action = &game->info->action[*index];
+ action->type = ACTION_VERB_NOUN;
+ action->word[0] = verb;
+
+ action->nr_words = 2;
+ action->word_type[0] = WORD_TYPE_VERB;
+ action->word_type[1] = WORD_TYPE_NOUN_MASK;
+
+ file_buf_get_u8(fb, &action->word[1]);
+ file_buf_get_le16(fb, &action->function);
+
+ (*index)++;
+ }
+ }
+}
+
+static void parse_action_table_v(struct comprehend_game *game,
+ struct file_buf *fb, size_t *index) {
+ struct action *action;
+ uint8 verb, nr_funcs;
+ uint16 func;
+ int i;
+
+ /*
+ * <verb> [<noun>]
+ *
+ * u8: verb
+ * u8: count (num actions)
+ * le16: action
+ */
+ file_buf_set_pos(fb, game->info->header.addr_actions_v);
+ while (1) {
+ file_buf_get_u8(fb, &verb);
+ if (verb == 0)
+ break;
+
+ action = &game->info->action[*index];
+ action->type = ACTION_VERB_OPT_NOUN;
+ action->word[0] = verb;
+
+ /* Can take an optional noun (nr_words here is maximum) */
+ action->nr_words = 1;
+ action->word_type[0] = WORD_TYPE_VERB;
+
+ /*
+ * Default actions can have more than one function, but only
+ * the first one actually seems to be used?
+ */
+ file_buf_get_u8(fb, &nr_funcs);
+ for (i = 0; i < nr_funcs; i++) {
+ file_buf_get_le16(fb, &func);
+ if (i == 0)
+ action->function = func;
+ }
+
+ (*index)++;
+ }
+}
+
+static void parse_action_table(struct comprehend_game *game,
+ struct file_buf *fb) {
+ game->info->nr_actions = 0;
+
+ if (game->info->comprehend_version == 1) {
+ parse_action_table_vvnn(game, fb, &game->info->nr_actions);
+ parse_action_table_vdn(game, fb, &game->info->nr_actions);
+ }
+ if (game->info->comprehend_version >= 2) {
+ parse_action_table_vnn(game, fb, &game->info->nr_actions);
+ }
+
+ parse_action_table_vnjn(game, fb, &game->info->nr_actions);
+ parse_action_table_vjn(game, fb, &game->info->nr_actions);
+ parse_action_table_vn(game, fb, &game->info->nr_actions);
+ parse_action_table_v(game, fb, &game->info->nr_actions);
+}
+
+static void parse_dictionary(struct comprehend_game *game, struct file_buf *fb) {
+ word *words;
+ uint i, j;
+
+ // FIXME - fixed size 0xff array?
+ game->info->words = (word *)xmalloc(game->info->nr_words * sizeof(words));
+
+ file_buf_set_pos(fb, game->info->header.addr_dictionary);
+ for (i = 0; i < game->info->nr_words; i++) {
+ words = &game->info->words[i];
+
+ file_buf_get_data(fb, words->word, 6);
+
+ /* Decode */
+ for (j = 0; j < 6; j++)
+ words->word[j] ^= 0x8a;
+ words->word[6] = '\0';
+
+ file_buf_get_u8(fb, &words->index);
+ file_buf_get_u8(fb, &words->type);
+ }
+}
+
+static void parse_word_map(struct comprehend_game *game, struct file_buf *fb) {
+ struct word_map *map;
+ uint8 index, type, dummy;
+ uint i;
+
+ game->info->nr_word_maps = 0;
+ file_buf_set_pos(fb, game->info->header.addr_word_map);
+
+ /*
+ * Parse the word pair table. Each entry has a pair of dictionary
+ * index/type values for a first and second word.
+ */
+ while (1) {
+ map = &game->info->word_map[game->info->nr_word_maps];
+
+ file_buf_get_u8(fb, &index);
+ file_buf_get_u8(fb, &type);
+ if (type == 0 && index == 0) {
+ /* End of pairs */
+ break;
+ }
+
+ map->word[0].index = index;
+ map->word[0].type = type;
+ file_buf_get_u8(fb, &map->flags);
+ file_buf_get_u8(fb, &map->word[1].index);
+ file_buf_get_u8(fb, &map->word[1].type);
+
+ game->info->nr_word_maps++;
+ }
+
+ /* Consume two more null bytes (type and index were also null) */
+ file_buf_get_u8(fb, &dummy);
+ file_buf_get_u8(fb, &dummy);
+
+ /*
+ * Parse the target word table. Each entry has a dictionary
+ * index/type. The first and second words from above map to the
+ * target word here. E.g. 'go north' -> 'north'.
+ */
+ for (i = 0; i < game->info->nr_word_maps; i++) {
+ map = &game->info->word_map[i];
+
+ file_buf_get_u8(fb, &map->word[2].index);
+ file_buf_get_u8(fb, &map->word[2].type);
+ }
+}
+
+static void parse_items(struct comprehend_game *game, struct file_buf *fb) {
+ size_t nr_items = game->info->header.nr_items;
+
+ /* Item descriptions */
+ file_buf_set_pos(fb, game->info->header.addr_item_strings);
+ file_buf_get_array_le16(fb, 0, game->info->item, string_desc, nr_items);
+
+ if (game->info->comprehend_version == 2) {
+ /* Comprehend version 2 adds long string descriptions */
+ file_buf_set_pos(fb, game->info->header.addr_item_strings +
+ (game->info->header.nr_items * sizeof(uint16)));
+ file_buf_get_array_le16(fb, 0, game->info->item, long_string, nr_items);
+ }
+
+ /* Item flags */
+ file_buf_set_pos(fb, game->info->header.addr_item_flags);
+ file_buf_get_array_u8(fb, 0, game->info->item, flags, nr_items);
+
+ /* Item word */
+ file_buf_set_pos(fb, game->info->header.addr_item_word);
+ file_buf_get_array_u8(fb, 0, game->info->item, word, nr_items);
+
+ /* Item locations */
+ file_buf_set_pos(fb, game->info->header.addr_item_locations);
+ file_buf_get_array_u8(fb, 0, game->info->item, room, nr_items);
+
+ /* Item graphic */
+ file_buf_set_pos(fb, game->info->header.addr_item_graphics);
+ file_buf_get_array_u8(fb, 0, game->info->item, graphic, nr_items);
+}
+
+static void parse_rooms(struct comprehend_game *game, struct file_buf *fb) {
+ size_t nr_rooms = game->info->nr_rooms;
+ int i;
+
+ /* Room exit directions */
+ for (i = 0; i < NR_DIRECTIONS; i++) {
+ file_buf_set_pos(fb, game->info->header.room_direction_table[i]);
+ file_buf_get_array_u8(fb, 1, game->info->rooms,
+ direction[i], nr_rooms);
+ }
+
+ /* Room string descriptions */
+ file_buf_set_pos(fb, game->info->header.room_desc_table);
+ file_buf_get_array_le16(fb, 1, game->info->rooms, string_desc, nr_rooms);
+
+ /* Room flags */
+ file_buf_set_pos(fb, game->info->header.room_flags_table);
+ file_buf_get_array_u8(fb, 1, game->info->rooms, flags, nr_rooms);
+
+ /* Room graphic */
+ file_buf_set_pos(fb, game->info->header.room_graphics_table);
+ file_buf_get_array_u8(fb, 1, game->info->rooms, graphic, nr_rooms);
+}
+
+static uint64 string_get_chunk(uint8 *string) {
+ uint64 c, val = 0;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ c = string[i] & 0xff;
+ val |= (c << ((4 - i) * 8));
+ }
+
+ return val;
+}
+
+static char decode_string_elem(uint8 c, bool capital, bool special) {
+ if (special) {
+ if (c < sizeof(special_charset) - 1)
+ return special_charset[c];
+ } else {
+ if (c < sizeof(charset) - 1) {
+ c = charset[c];
+ if (capital) {
+ /*
+ * A capital space means that the character
+ * is dynamically replaced by at runtime.
+ * We use the character '@' since it cannot
+ * otherwise appear in strings.
+ */
+ if (c == ' ')
+ return '@';
+ return c - 0x20;
+ } else {
+ return c;
+ }
+ }
+ }
+
+ /* Unknown character */
+ printf("Unknown char %d, caps=%d, special=%d\n", c, capital, special);
+ return '*';
+}
+
+/*
+ * Game strings are stored using 5-bit characters. By default a character
+ * value maps to the lower-case letter table. If a character has the value 0x1e
+ * then the next character is upper-case. An upper-case space is used to
+ * specify that the character should be replaced at runtime (like a '%s'
+ * specifier). If a character has the value 0x1f then the next character is
+ * taken from the symbols table.
+ */
+static char *parse_string(struct file_buf *fb) {
+ bool capital_next = false, special_next = false;
+ unsigned i, j, k = 0;
+ uint64 chunk;
+ uint8 elem, *encoded;
+ char *string, c;
+ size_t encoded_len;
+
+ encoded_len = file_buf_strlen(fb, NULL);
+ string = (char *)xmalloc(encoded_len * 2);
+
+ /* Get the encoded string */
+ encoded = (uint8 *)xmalloc(encoded_len + 5);
+ memset(encoded, 0, encoded_len);
+ file_buf_get_data(fb, encoded, encoded_len);
+
+ /* Skip over the zero byte */
+ if (file_buf_get_pos(fb) < fb->size)
+ file_buf_get_u8(fb, NULL);
+
+ for (i = 0; i < encoded_len; i += 5) {
+ chunk = string_get_chunk(&encoded[i]);
+
+ for (j = 0; j < 8; j++) {
+ elem = (chunk >> (35 - (5 * j))) & 0x1f;
+
+ if (elem == 0)
+ goto done;
+ if (elem == 0x1e) {
+ capital_next = true;
+ } else if (elem == 0x1f) {
+ special_next = true;
+ } else {
+ c = decode_string_elem(elem, capital_next,
+ special_next);
+ special_next = false;
+ capital_next = false;
+ string[k++] = c;
+ }
+ }
+ }
+
+done:
+ string[k] = '\0';
+ free(encoded);
+
+ return string;
+}
+
+static void parse_string_table(struct file_buf *fb, unsigned start_addr,
+ uint32 end_addr, struct string_table *table) {
+ file_buf_set_pos(fb, start_addr);
+ while (1) {
+ table->strings[table->nr_strings++] = parse_string(fb);
+ if (file_buf_get_pos(fb) >= end_addr)
+ break;
+ }
+}
+
+static void parse_variables(struct comprehend_game *game, struct file_buf *fb) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
+ file_buf_get_le16(fb, &game->info->variable[i]);
+}
+
+static void parse_flags(struct comprehend_game *game, struct file_buf *fb) {
+ int i, bit, flag_index = 0;
+ uint8 bitmask;
+
+ for (i = 0; i < ARRAY_SIZE(game->info->flags) / 8; i++) {
+ file_buf_get_u8(fb, &bitmask);
+ for (bit = 7; bit >= 0; bit--) {
+ game->info->flags[flag_index] = !!(bitmask & (1 << bit));
+ flag_index++;
+ }
+ }
+}
+
+static void parse_replace_words(struct comprehend_game *game,
+ struct file_buf *fb) {
+ uint16 dummy;
+ size_t len;
+ bool eof;
+ int i;
+
+ /* FIXME - Rename addr_strings_end */
+ file_buf_set_pos(fb, game->info->header.addr_strings_end);
+
+ /* FIXME - what is this for */
+ file_buf_get_le16(fb, &dummy);
+
+ for (i = 0;; i++) {
+ len = file_buf_strlen(fb, &eof);
+ if (len == 0)
+ break;
+
+ game->info->replace_words[i] = xstrndup((char *)fb->p, len);
+ file_buf_get_data(fb, NULL, len + (eof ? 0 : 1));
+ if (eof)
+ break;
+ }
+ game->info->nr_replace_words = i;
+}
+
+/*
+ * The main game data file header has the offsets for where each bit of
+ * game data is. The offsets have a magic constant value added to them.
+ */
+static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
+ struct game_header *header = &game->info->header;
+ uint16 dummy, addr_dictionary_end;
+ uint8 dummy8;
+
+ file_buf_set_pos(fb, 0);
+ file_buf_get_le16(fb, &header->magic);
+ switch (header->magic) {
+ case 0x2000: /* Transylvania, Crimson Crown disk one */
+ case 0x4800: /* Crimson Crown disk two */
+ game->info->comprehend_version = 1;
+ magic_offset = (uint16)(-0x5a00 + 0x4);
+ break;
+
+ case 0x93f0: /* OO-Topos */
+ game->info->comprehend_version = 2;
+ magic_offset = (uint16)-0x5a00;
+ break;
+
+ case 0xa429: /* Talisman */
+ game->info->comprehend_version = 2;
+ magic_offset = (uint16)-0x5a00;
+ break;
+
+ default:
+ fatal_error("Unknown game_data magic %.4x\n", header->magic);
+ break;
+ }
+
+ /* FIXME - Second word in header has unknown usage */
+ parse_header_le16(fb, &dummy);
+
+ /*
+ * Action tables.
+ *
+ * Layout depends on the comprehend version.
+ */
+ if (game->info->comprehend_version == 1) {
+ parse_header_le16(fb, &header->addr_actions_vvnn);
+ parse_header_le16(fb, &header->addr_actions_unknown);
+ parse_header_le16(fb, &header->addr_actions_vnjn);
+ parse_header_le16(fb, &header->addr_actions_vjn);
+ parse_header_le16(fb, &header->addr_actions_vdn);
+ }
+ if (game->info->comprehend_version >= 2) {
+ parse_header_le16(fb, &header->addr_actions_vnjn);
+ parse_header_le16(fb, &header->addr_actions_vjn);
+ parse_header_le16(fb, &header->addr_actions_vnn);
+ }
+ parse_header_le16(fb, &header->addr_actions_vn);
+ parse_header_le16(fb, &header->addr_actions_v);
+
+ parse_header_le16(fb, &header->addr_vm);
+ parse_header_le16(fb, &header->addr_dictionary);
+
+ parse_header_le16(fb, &header->addr_word_map);
+ /* FIXME - what is this for? */
+ parse_header_le16(fb, &dummy);
+ addr_dictionary_end = header->addr_word_map;
+
+ /* Rooms */
+ parse_header_le16(fb, &header->room_desc_table);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_NORTH]);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_SOUTH]);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_EAST]);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_WEST]);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_UP]);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_DOWN]);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_IN]);
+ parse_header_le16(fb, &header->room_direction_table[DIRECTION_OUT]);
+ parse_header_le16(fb, &header->room_flags_table);
+ parse_header_le16(fb, &header->room_graphics_table);
+
+ /*
+ * Objects.
+ *
+ * Layout is dependent on comprehend version.
+ */
+ if (game->info->comprehend_version == 1) {
+ parse_header_le16(fb, &header->addr_item_locations);
+ parse_header_le16(fb, &header->addr_item_flags);
+ parse_header_le16(fb, &header->addr_item_word);
+ parse_header_le16(fb, &header->addr_item_strings);
+ parse_header_le16(fb, &header->addr_item_graphics);
+
+ header->nr_items = (header->addr_item_word -
+ header->addr_item_flags);
+
+ } else {
+ parse_header_le16(fb, &header->addr_item_strings);
+ parse_header_le16(fb, &header->addr_item_word);
+ parse_header_le16(fb, &header->addr_item_locations);
+ parse_header_le16(fb, &header->addr_item_flags);
+ parse_header_le16(fb, &header->addr_item_graphics);
+
+ header->nr_items = (header->addr_item_flags -
+ header->addr_item_locations);
+ }
+
+ parse_header_le16(fb, &header->addr_strings);
+ parse_header_le16(fb, &dummy);
+ parse_header_le16(fb, &header->addr_strings_end);
+
+ file_buf_get_u8(fb, &dummy8);
+ file_buf_get_u8(fb, &game->info->start_room);
+ file_buf_get_u8(fb, &dummy8);
+
+ parse_variables(game, fb);
+ parse_flags(game, fb);
+
+ game->info->nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
+ header->room_direction_table[DIRECTION_NORTH];
+
+ game->info->nr_words = (addr_dictionary_end -
+ header->addr_dictionary) /
+ 8;
+}
+
+static void load_extra_string_file(struct comprehend_game *game,
+ const char *dirname,
+ struct string_file *string_file) {
+ char filename[PATH_MAX];
+ struct file_buf fb;
+ unsigned end;
+
+ snprintf(filename, sizeof(filename), "%s/%s", dirname,
+ string_file->filename);
+ file_buf_map(filename, &fb);
+
+ if (string_file->end_offset)
+ end = string_file->end_offset;
+ else
+ end = fb.size;
+
+ parse_string_table(&fb, string_file->base_offset,
+ end, &game->info->strings2);
+
+ file_buf_unmap(&fb);
+}
+
+static void load_extra_string_files(struct comprehend_game *game,
+ const char *dirname) {
+ int i;
+
+ memset(&game->info->strings2, 0, sizeof(game->info->strings2));
+
+ for (i = 0; i < ARRAY_SIZE(game->string_files); i++) {
+ if (!game->string_files[i].filename)
+ break;
+
+ // HACK - get string offsets correct
+ game->info->strings2.nr_strings = 0x40 * i;
+ if (game->info->strings2.nr_strings == 0)
+ game->info->strings2.nr_strings++;
+
+ load_extra_string_file(game, dirname, &game->string_files[i]);
+ }
+}
+
+static void load_game_data(struct comprehend_game *game, const char *dirname) {
+ char data_file[PATH_MAX];
+ struct file_buf fb;
+
+ snprintf(data_file, sizeof(data_file), "%s/%s",
+ dirname, game->game_data_file);
+
+ memset(game->info, 0, sizeof(*game->info));
+
+ file_buf_map(data_file, &fb);
+
+ parse_header(game, &fb);
+ parse_rooms(game, &fb);
+ parse_items(game, &fb);
+ parse_dictionary(game, &fb);
+ parse_word_map(game, &fb);
+ memset(&game->info->strings, 0, sizeof(game->info->strings));
+ parse_string_table(&fb, game->info->header.addr_strings,
+ game->info->header.addr_strings_end,
+ &game->info->strings);
+ load_extra_string_files(game, dirname);
+ parse_vm(game, &fb);
+ parse_action_table(game, &fb);
+ parse_replace_words(game, &fb);
+
+ file_buf_unmap(&fb);
+}
+
+void comprehend_load_game(struct comprehend_game *game, const char *dirname) {
+ game->game_dir = dirname;
+
+ /* Load the main game data file */
+ load_game_data(game, dirname);
+
+ if (g_enabled()) {
+ comprehend_load_images(game, dirname);
+ if (game->color_table)
+ g_set_color_table(game->color_table);
+ }
+
+ /* FIXME - This can be merged, don't need to keep start room around */
+ game->info->current_room = game->info->start_room;
+}
+
+#ifdef TODO
+static void patch_string_desc(uint16 *desc) {
+ /*
+ * String descriptors in the save file sometimes are encoded as a
+ * table/index value like the instruction opcodes used, and other
+ * times the are encoded as an absolute index. We fix them up to
+ * all be the former type.
+ */
+ if (!(*desc & 0x8000) && *desc >= 0x100) {
+ *desc -= 0x100;
+ *desc |= 0x8100;
+ }
+}
+#endif
+
+void comprehend_save_game(struct comprehend_game *game, const char *filename) {
+#ifdef TODO
+ FILE *fd;
+ uint8 bitmask;
+ int dir, bit, flag_index, i;
+ size_t nr_rooms, nr_items;
+
+ fd = fopen(filename, "w");
+ if (!fd) {
+ printf("Error: Failed to open save file '%s': %s\n",
+ filename, strerror(errno));
+ return;
+ }
+
+ nr_rooms = game->info->nr_rooms;
+ nr_items = game->info->header.nr_items;
+
+ file_buf_put_u8(fd, 0);
+ file_buf_put_u8(fd, game->info->current_room);
+ file_buf_put_u8(fd, 0);
+
+ /* Variables */
+ for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
+ file_buf_put_le16(fd, game->info->variable[i]);
+
+ /* Flags */
+ for (flag_index = 0, i = 0; i < ARRAY_SIZE(game->info->flags) / 8; i++) {
+ bitmask = 0;
+ for (bit = 7; bit >= 0; bit--) {
+ bitmask |= (!!game->info->flags[flag_index]) << bit;
+ flag_index++;
+ }
+
+ file_buf_put_u8(fd, bitmask);
+ }
+
+ /*
+ * Re-Comprehend doesn't need this since the number of items is
+ * determined by the currently loaded game, but the original games
+ * won't load the file properly without it.
+ */
+ file_buf_put_skip(fd, 0x12c - ftell(fd));
+ file_buf_put_u8(fd, nr_items);
+
+ if (game->info->comprehend_version == 1)
+ file_buf_put_skip(fd, 0x230 - ftell(fd));
+ else
+ file_buf_put_skip(fd, 0x130 - ftell(fd));
+
+ /* Rooms */
+ file_buf_put_array_le16(fd, 1, game->info->rooms,
+ string_desc, nr_rooms);
+ for (dir = 0; dir < NR_DIRECTIONS; dir++)
+ file_buf_put_array_u8(fd, 1, game->info->rooms,
+ direction[dir], nr_rooms);
+ file_buf_put_array_u8(fd, 1, game->info->rooms, flags, nr_rooms);
+ file_buf_put_array_u8(fd, 1, game->info->rooms, graphic, nr_rooms);
+
+ /*
+ * Objects
+ *
+ * Layout differs depending on Comprehend version. Version 2 also
+ * has long string descriptions for each object.
+ */
+ file_buf_put_array_le16(fd, 0, game->info->item, string_desc, nr_items);
+ if (game->info->comprehend_version == 1) {
+ file_buf_put_array_u8(fd, 0, game->info->item, room, nr_items);
+ file_buf_put_array_u8(fd, 0, game->info->item, flags, nr_items);
+ file_buf_put_array_u8(fd, 0, game->info->item, word, nr_items);
+ file_buf_put_array_u8(fd, 0, game->info->item, graphic, nr_items);
+ } else {
+ file_buf_put_array_le16(fd, 0, game->info->item, long_string, nr_items);
+ file_buf_put_array_u8(fd, 0, game->info->item, word, nr_items);
+ file_buf_put_array_u8(fd, 0, game->info->item, room, nr_items);
+ file_buf_put_array_u8(fd, 0, game->info->item, flags, nr_items);
+ file_buf_put_array_u8(fd, 0, game->info->item, graphic, nr_items);
+ }
+
+ fclose(fd);
+#else
+ error("Save");
+#endif
+}
+
+void comprehend_restore_game(struct comprehend_game *game, const char *filename) {
+#ifdef TODO
+ struct file_buf fb;
+ size_t nr_rooms, nr_items;
+ uint err, dir, i;
+
+ err = file_buf_map_may_fail(filename, &fb);
+ if (err) {
+ printf("Error: Failed to open save file '%s': %s\n",
+ filename, strerror(-err));
+ return;
+ }
+
+ nr_rooms = game->info->nr_rooms;
+ nr_items = game->info->header.nr_items;
+
+ /* Restore starting room */
+ file_buf_set_pos(&fb, 1);
+ file_buf_get_u8(&fb, &game->info->current_room);
+
+ /* Restore flags and variables */
+ file_buf_set_pos(&fb, 3);
+ parse_variables(game, &fb);
+ parse_flags(game, &fb);
+
+ /* FIXME - unknown restore data, skip over it */
+ if (game->info->comprehend_version == 1)
+ file_buf_set_pos(&fb, 0x230);
+ else
+ file_buf_set_pos(&fb, 0x130);
+
+ /* Restore rooms */
+ file_buf_get_array_le16(&fb, 1, game->info->rooms,
+ string_desc, nr_rooms);
+ for (dir = 0; dir < NR_DIRECTIONS; dir++)
+ file_buf_get_array_u8(&fb, 1, game->info->rooms,
+ direction[dir], nr_rooms);
+ file_buf_get_array_u8(&fb, 1, game->info->rooms, flags, nr_rooms);
+ file_buf_get_array_u8(&fb, 1, game->info->rooms, graphic, nr_rooms);
+
+ /*
+ * Restore objects
+ *
+ * Layout differs depending on Comprehend version. Version 2 also
+ * has long string descriptions for each object.
+ */
+ file_buf_get_array_le16(&fb, 0, game->info->item, string_desc, nr_items);
+ if (game->info->comprehend_version == 1) {
+ file_buf_get_array_u8(&fb, 0, game->info->item, room, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->info->item, flags, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->info->item, word, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->info->item, graphic, nr_items);
+ } else {
+ file_buf_get_array_le16(&fb, 0, game->info->item, long_string, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->info->item, word, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->info->item, room, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->info->item, flags, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->info->item, graphic, nr_items);
+ }
+
+ /*
+ * FIXME - The save file has some string descriptors masked with 0x8000.
+ * Not sure what this means, so just mask it out for now.
+ */
+ for (i = 1; i <= nr_rooms; i++)
+ patch_string_desc(&game->info->rooms[i].string_desc);
+ for (i = 0; i < nr_items; i++)
+ patch_string_desc(&game->info->item[i].string_desc);
+
+ file_buf_unmap(&fb);
+#else
+ error("load");
+#endif
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
new file mode 100644
index 0000000000..2892bd29c7
--- /dev/null
+++ b/engines/glk/comprehend/game_data.h
@@ -0,0 +1,318 @@
+/* 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_COMPREHEND_GAME_DATA_H
+#define GLK_COMPREHEND_GAME_DATA_H
+
+#include "glk/comprehend/image_data.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#define MAX_FLAGS 64
+#define MAX_VARIABLES 128
+
+enum {
+ DIRECTION_NORTH,
+ DIRECTION_SOUTH,
+ DIRECTION_EAST,
+ DIRECTION_WEST,
+ DIRECTION_UP,
+ DIRECTION_DOWN,
+ DIRECTION_IN,
+ DIRECTION_OUT,
+ NR_DIRECTIONS,
+};
+
+struct function_state {
+ bool test_result;
+ bool else_result;
+ unsigned or_count;
+ bool _and;
+ bool in_command;
+ bool executed;
+};
+
+struct room {
+ uint8 direction[NR_DIRECTIONS];
+ uint8 flags;
+ uint8 graphic;
+ uint16 string_desc;
+};
+
+struct item {
+ uint16 string_desc;
+ uint16 long_string; /* Only used by version 2 */
+ uint8 room;
+ uint8 flags;
+ uint8 word;
+ uint8 graphic;
+};
+
+struct word {
+ char word[7];
+ uint8 index;
+ uint8 type;
+};
+
+struct word_index {
+ uint8 index;
+ uint8 type;
+};
+
+struct word_map {
+ /* <word[0]>, <word[1]> == <word[2]> */
+ struct word_index word[3];
+ uint8 flags;
+};
+
+struct action {
+ int type;
+ size_t nr_words;
+ // FIXME - use struct word_index here.
+ uint8 word[4];
+ uint8 word_type[4];
+ uint16 function;
+};
+
+struct instruction {
+ uint8 opcode;
+ size_t nr_operands;
+ uint8 operand[3];
+ bool is_command;
+};
+
+struct function {
+ struct instruction instructions[0x100];
+ size_t nr_instructions;
+};
+
+struct string_table {
+ char *strings[0xffff];
+ size_t nr_strings;
+};
+
+struct game_header {
+ uint16 magic;
+
+ uint16 room_desc_table;
+ uint16 room_direction_table[NR_DIRECTIONS];
+ uint16 room_flags_table;
+ uint16 room_graphics_table;
+
+ size_t nr_items;
+ uint16 addr_item_locations;
+ uint16 addr_item_flags;
+ uint16 addr_item_word;
+ uint16 addr_item_strings;
+ uint16 addr_item_graphics;
+
+ uint16 addr_dictionary;
+ uint16 addr_word_map;
+
+ uint16 addr_strings;
+ uint16 addr_strings_end;
+
+ uint16 addr_actions_vvnn;
+ uint16 addr_actions_unknown;
+ uint16 addr_actions_vnjn;
+ uint16 addr_actions_vjn;
+ uint16 addr_actions_vdn;
+ uint16 addr_actions_vnn;
+ uint16 addr_actions_vn;
+ uint16 addr_actions_v;
+
+ uint16 addr_vm; // FIXME - functions
+};
+
+struct game_info {
+ struct game_header header;
+
+ unsigned comprehend_version;
+
+ uint8 start_room;
+
+ struct room rooms[0x100];
+ size_t nr_rooms;
+ uint8 current_room;
+
+ struct item item[0xff];
+
+ struct word *words;
+ size_t nr_words;
+
+ struct word_map word_map[0xff];
+ size_t nr_word_maps;
+
+ struct string_table strings;
+ struct string_table strings2;
+
+ struct action action[0xffff];
+ size_t nr_actions;
+
+ struct function functions[0xffff];
+ size_t nr_functions;
+
+ struct image_data room_images;
+ struct image_data item_images;
+
+ bool flags[MAX_FLAGS];
+ uint16 variable[MAX_VARIABLES];
+
+ char *replace_words[256];
+ size_t nr_replace_words;
+
+ uint8 current_replace_word;
+ unsigned update_flags;
+};
+
+enum {
+ OPCODE_UNKNOWN,
+ OPCODE_TEST_FALSE,
+ OPCODE_HAVE_OBJECT,
+ OPCODE_OR,
+ OPCODE_IN_ROOM,
+ OPCODE_VAR_EQ,
+ OPCODE_CURRENT_OBJECT_TAKEABLE,
+ OPCODE_OBJECT_PRESENT,
+ OPCODE_ELSE,
+ OPCODE_OBJECT_IN_ROOM,
+ OPCODE_OBJECT_NOT_VALID,
+ OPCODE_INVENTORY_FULL,
+ OPCODE_TEST_FLAG,
+ OPCODE_CURRENT_OBJECT_IN_ROOM,
+ OPCODE_HAVE_CURRENT_OBJECT,
+ OPCODE_OBJECT_IS_NOT_NOWHERE,
+ OPCODE_CURRENT_OBJECT_PRESENT,
+ OPCODE_TEST_ROOM_FLAG,
+ OPCODE_NOT_HAVE_OBJECT,
+ OPCODE_NOT_IN_ROOM,
+ OPCODE_CURRENT_OBJECT_IS_NOWHERE,
+ OPCODE_OBJECT_NOT_PRESENT,
+ OPCODE_OBJECT_NOT_IN_ROOM,
+ OPCODE_TEST_NOT_FLAG,
+ OPCODE_NOT_HAVE_CURRENT_OBJECT,
+ OPCODE_OBJECT_IS_NOWHERE,
+ OPCODE_CURRENT_OBJECT_NOT_PRESENT,
+ OPCODE_CURRENT_OBJECT_NOT_TAKEABLE,
+ OPCODE_TEST_NOT_ROOM_FLAG,
+ OPCODE_INVENTORY,
+ OPCODE_TAKE_OBJECT,
+ OPCODE_MOVE_OBJECT_TO_ROOM,
+ OPCODE_SAVE_ACTION,
+ OPCODE_MOVE_TO_ROOM,
+ OPCODE_VAR_ADD,
+ OPCODE_SET_ROOM_DESCRIPTION,
+ OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM,
+ OPCODE_VAR_SUB,
+ OPCODE_SET_OBJECT_DESCRIPTION,
+ OPCODE_SET_OBJECT_LONG_DESCRIPTION,
+ OPCODE_MOVE,
+ OPCODE_MOVE_DIRECTION,
+ OPCODE_PRINT,
+ OPCODE_REMOVE_OBJECT,
+ OPCODE_SET_FLAG,
+ OPCODE_CALL_FUNC,
+ OPCODE_TURN_TICK,
+ OPCODE_CLEAR_FLAG,
+ OPCODE_INVENTORY_ROOM,
+ OPCODE_TAKE_CURRENT_OBJECT,
+ OPCODE_SPECIAL,
+ OPCODE_DROP_OBJECT,
+ OPCODE_DROP_CURRENT_OBJECT,
+ OPCODE_SET_ROOM_GRAPHIC,
+ OPCODE_SET_OBJECT_GRAPHIC,
+ OPCODE_REMOVE_CURRENT_OBJECT,
+ OPCODE_DO_VERB,
+ OPCODE_VAR_INC,
+ OPCODE_VAR_DEC,
+ OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM,
+ OPCODE_DESCRIBE_CURRENT_OBJECT,
+ OPCODE_SET_STRING_REPLACEMENT,
+ OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT,
+ OPCODE_CURRENT_NOT_OBJECT,
+ OPCODE_CURRENT_IS_OBJECT,
+ OPCODE_DRAW_ROOM,
+ OPCODE_DRAW_OBJECT,
+ OPCODE_WAIT_KEY,
+};
+
+/* Game state update flags */
+#define UPDATE_GRAPHICS (1 << 0) /* Implies UPDATE_GRAPHICS_ITEMS */
+#define UPDATE_GRAPHICS_ITEMS (1 << 1)
+#define UPDATE_ROOM_DESC (1 << 2)
+#define UPDATE_ITEM_LIST (1 << 3)
+#define UPDATE_ALL (~0U)
+
+/* Action types */
+enum {
+ ACTION_VERB_VERB_NOUN_NOUN,
+ ACTION_VERB_NOUN_JOIN_NOUN,
+ ACTION_VERB_JOIN_NOUN,
+ ACTION_VERB_DIR_NOUN,
+ ACTION_VERB_NOUN_NOUN,
+ ACTION_VERB_NOUN,
+ ACTION_VERB_OPT_NOUN,
+};
+
+/* Standard strings (main string table) */
+#define STRING_CANT_GO 0
+#define STRING_DONT_UNDERSTAND 1
+#define STRING_YOU_SEE 2
+#define STRING_INVENTORY 3
+#define STRING_INVENTORY_EMPTY 4
+#define STRING_BEFORE_CONTINUE 5
+#define STRING_SAVE_GAME 6
+#define STRING_RESTORE_GAME 7
+
+/* Special variables */
+#define VAR_INVENTORY_WEIGHT 0
+#define VAR_INVENTORY_LIMIT 1
+#define VAR_TURN_COUNT 2
+
+/* Special rooms */
+#define ROOM_INVENTORY 0x00
+#define ROOM_NOWHERE 0xff
+
+/* Item flags */
+#define ITEMF_WEIGHT_MASK (0x3)
+#define ITEMF_CAN_TAKE (1 << 3)
+
+/* Word types */
+#define WORD_TYPE_VERB 0x01
+#define WORD_TYPE_JOIN 0x02
+#define WORD_TYPE_FEMALE 0x10
+#define WORD_TYPE_MALE 0x20
+#define WORD_TYPE_NOUN 0x40
+#define WORD_TYPE_NOUN_PLURAL 0x80
+#define WORD_TYPE_NOUN_MASK (WORD_TYPE_FEMALE | WORD_TYPE_MALE | \
+ WORD_TYPE_NOUN | WORD_TYPE_NOUN_PLURAL)
+
+void comprehend_load_game(struct comprehend_game *game, const char *dirname);
+void comprehend_restore_game(struct comprehend_game *game,
+ const char *filename);
+void comprehend_save_game(struct comprehend_game *game, const char *filename);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
new file mode 100644
index 0000000000..d1d524c116
--- /dev/null
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -0,0 +1,149 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/graphics.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#define OO_ROOM_FLAG_DARK 0x02
+
+#define OO_BRIGHT_ROOM 0x19
+
+#define OO_FLAG_WEARING_GOGGLES 0x1b
+#define OO_FLAG_FLASHLIGHT_ON 0x27
+
+static int oo_room_is_special(struct comprehend_game *game,
+ unsigned room_index,
+ unsigned *room_desc_string)
+{
+ struct room *room = &game->info->rooms[room_index];
+
+ /* Is the room dark */
+ if ((room->flags & OO_ROOM_FLAG_DARK) &&
+ !(game->info->flags[OO_FLAG_FLASHLIGHT_ON])) {
+ if (room_desc_string)
+ *room_desc_string = 0xb3;
+ return ROOM_IS_DARK;
+ }
+
+ /* Is the room too bright */
+ if (room_index == OO_BRIGHT_ROOM &&
+ !game->info->flags[OO_FLAG_WEARING_GOGGLES]) {
+ if (room_desc_string)
+ *room_desc_string = 0x1c;
+ return ROOM_IS_TOO_BRIGHT;
+ }
+
+ return ROOM_IS_NORMAL;
+}
+
+static bool oo_before_turn(struct comprehend_game *game)
+{
+ /* FIXME - probably doesn't work correctly with restored games */
+ static bool flashlight_was_on = false, googles_were_worn = false;
+ struct room *room = &game->info->rooms[game->info->current_room];
+
+ /*
+ * Check if the room needs to be redrawn because the flashlight
+ * was switch off or on.
+ */
+ if (game->info->flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
+ (room->flags & OO_ROOM_FLAG_DARK)) {
+ flashlight_was_on = game->info->flags[OO_FLAG_FLASHLIGHT_ON];
+ game->info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ }
+
+ /*
+ * Check if the room needs to be redrawn because the goggles were
+ * put on or removed.
+ */
+ if (game->info->flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
+ game->info->current_room == OO_BRIGHT_ROOM) {
+ googles_were_worn = game->info->flags[OO_FLAG_WEARING_GOGGLES];
+ game->info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ }
+
+ return false;
+}
+
+static void oo_handle_special_opcode(struct comprehend_game *game,
+ uint8 operand)
+{
+ switch (operand) {
+ case 0x03:
+ /* Game over - failure */
+ case 0x05:
+ /* Won the game */
+ case 0x04:
+ /* Restart game */
+ game_restart(game);
+ break;
+
+ case 0x06:
+ /* Save game */
+ game_save(game);
+ break;
+
+ case 0x07:
+ /* Restore game */
+ game_restore(game);
+ break;
+ }
+}
+
+static struct game_ops oo_ops = {
+ nullptr,
+ nullptr,
+ oo_before_turn,
+ nullptr,
+ oo_room_is_special,
+ oo_handle_special_opcode
+};
+
+struct comprehend_game game_oo_topos = {
+ "Oo-Topos",
+ "oo",
+ nullptr,
+ "G0",
+ {
+ // Extra strings are (annoyingly) stored in the game binary
+ {"NOVEL.EXE", 0x16564, 0x17640},
+ {"NOVEL.EXE", 0x17702, 0x18600},
+ {"NOVEL.EXE", 0x186b2, 0x19b80},
+ {"NOVEL.EXE", 0x19c62, 0x1a590},
+ {"NOVEL.EXE", 0x1a634, 0x1b080},
+ },
+ {"RA", "RB", "RC", "RD", "RE"},
+ {"OA", "OB", "OC", "OD"},
+ "G%d",
+ 1,
+ nullptr,
+ &oo_ops,
+ nullptr
+};
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/game_tm.cpp b/engines/glk/comprehend/game_tm.cpp
new file mode 100644
index 0000000000..1b8b54690a
--- /dev/null
+++ b/engines/glk/comprehend/game_tm.cpp
@@ -0,0 +1,50 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/game_data.h"
+
+namespace Glk {
+namespace Comprehend {
+
+static struct game_ops tm_ops = {};
+
+/* FIXME - This is broken */
+struct comprehend_game game_talisman = {
+ "Talisman, Challenging the Sands of Time (broken)",
+ "tm",
+ nullptr,
+ "G0",
+ {},
+ {"RA", "RB", "RC", "RD", "RE", "RF", "RG"},
+ {"OA", "OB", "OE", "OF"},
+ nullptr,
+ 0,
+
+ nullptr,
+ &tm_ops,
+ nullptr
+};
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
new file mode 100644
index 0000000000..fc8ad72943
--- /dev/null
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -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.
+ *
+ */
+
+#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/util.h"
+
+namespace Glk {
+namespace Comprehend {
+
+struct tr_monster {
+ uint8 object;
+ uint8 dead_flag;
+ unsigned min_turns_before;
+ unsigned room_allow_flag;
+ unsigned randomness;
+};
+
+static struct tr_monster tr_werewolf = {
+ 0x21, 7, (1 << 6), 5, 5
+};
+
+static struct tr_monster tr_vampire = {
+ 0x26, 5, (1 << 7), 0, 5
+};
+
+static void tr_update_monster(struct comprehend_game *game,
+ struct tr_monster *monster_info)
+{
+ struct item *monster;
+ struct room *room;
+ uint16 turn_count;
+
+ room = &game->info->rooms[game->info->current_room];
+ turn_count = game->info->variable[VAR_TURN_COUNT];
+
+ monster = get_item(game, monster_info->object);
+ if (monster->room == game->info->current_room) {
+ /* The monster is in the current room - leave it there */
+ return;
+ }
+
+ if ((room->flags & monster_info->room_allow_flag) &&
+ !game->info->flags[monster_info->dead_flag] &&
+ turn_count > monster_info->min_turns_before) {
+ /*
+ * The monster is alive and allowed to move to the current
+ * room. Randomly decide whether on not to. If not, move
+ * it back to limbo.
+ */
+ if ((g_comprehend->getRandomNumber(0x7fffffff) % monster_info->randomness) == 0) {
+ move_object(game, monster, game->info->current_room);
+ game->info->variable[0xf] = turn_count + 1;
+ } else {
+ move_object(game, monster, ROOM_NOWHERE);
+ }
+ }
+}
+
+static int tr_room_is_special(struct comprehend_game *game, unsigned room_index,
+ unsigned *room_desc_string)
+{
+ struct room *room = &game->info->rooms[room_index];
+
+ if (room_index == 0x28) {
+ if (room_desc_string)
+ *room_desc_string = room->string_desc;
+ return ROOM_IS_DARK;
+ }
+
+ return ROOM_IS_NORMAL;
+}
+
+static bool tr_before_turn(struct comprehend_game *game)
+{
+ tr_update_monster(game, &tr_werewolf);
+ tr_update_monster(game, &tr_vampire);
+ return false;
+}
+
+static void tr_handle_special_opcode(struct comprehend_game *game,
+ uint8 operand)
+{
+ switch (operand) {
+ case 0x01:
+ /*
+ * FIXME - Called when the mice are dropped and the cat chases
+ * them.
+ */
+ break;
+
+ case 0x02:
+ /* FIXME - Called when the gun is fired */
+ break;
+
+ case 0x06:
+ game_save(game);
+ break;
+
+ case 0x07:
+ game_restore(game);
+ break;
+
+ case 0x03:
+ /* Game over - failure */
+ case 0x05:
+ /* Won the game */
+ case 0x08:
+ /* Restart game */
+ game_restart(game);
+ break;
+
+ case 0x09:
+ /*
+ * Show the Zin screen in reponse to doing 'sing some enchanted
+ * evening' in his cabin.
+ */
+ draw_location_image(&game->info->room_images, 41);
+ console_get_key();
+ game->info->update_flags |= UPDATE_GRAPHICS;
+ break;
+ }
+}
+
+static void read_string(char *buffer, size_t size)
+{
+#ifdef TODO
+ char *p;
+
+ printf("> ");
+ fgets(buffer, size, stdin);
+
+ /* Remove trailing newline */
+ p = strchr(buffer, '\n');
+ if (p)
+ *p = '\0';
+#else
+ error("TODO");
+#endif
+}
+
+static void tr_before_game(struct comprehend_game *game)
+{
+ char buffer[128];
+
+ /* Welcome to Transylvania - sign your name */
+ console_println(game, game->info->strings.strings[0x20]);
+ read_string(buffer, sizeof(buffer));
+
+ /*
+ * Transylvania uses replace word 0 as the player's name, the game
+ * data file stores a bunch of dummy characters, so the length is
+ * limited (the original game will break if you put a name in that
+ * is too long).
+ */
+ if (!game->info->replace_words[0])
+ game->info->replace_words[0] = xstrndup(buffer, strlen(buffer));
+ else
+ snprintf(game->info->replace_words[0],
+ strlen(game->info->replace_words[0]),
+ "%s", buffer);
+
+ /* And your next of kin - This isn't store by the game */
+ console_println(game, game->info->strings.strings[0x21]);
+ read_string(buffer, sizeof(buffer));
+}
+
+static struct game_strings tr_strings = {
+ EXTRA_STRING_TABLE(0x8a)
+};
+
+static struct game_ops tr_ops = {
+ tr_before_game,
+ nullptr,
+ tr_before_turn,
+ nullptr,
+ tr_room_is_special,
+ tr_handle_special_opcode,
+};
+
+struct comprehend_game game_transylvania = {
+ "Transylvania",
+ "tr",
+ nullptr,
+ "TR.GDA",
+ {
+ {"MA.MS1", 0x88},
+ {"MB.MS1", 0x88},
+ {"MC.MS1", 0x88},
+ {"MD.MS1", 0x88},
+ {"ME.MS1", 0x88},
+ },
+ {"RA.MS1", "RB.MS1", "RC.MS1"},
+ {"OA.MS1", "OB.MS1", "OC.MS1"},
+ "G%d.MS0",
+ 0,
+ &tr_strings,
+ &tr_ops,
+ nullptr
+};
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/graphics.cpp
new file mode 100644
index 0000000000..b62df4d2fc
--- /dev/null
+++ b/engines/glk/comprehend/graphics.cpp
@@ -0,0 +1,686 @@
+/* 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/comprehend/graphics.h"
+#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/image_data.h"
+#include "glk/comprehend/util.h"
+#include "glk/window_graphics.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#define RENDER_X_MAX 278
+#define RENDER_Y_MAX 162
+
+#define RENDERER_SCREEN 0
+#define RENDERER_PIXEL_DATA 1
+
+static bool graphics_enabled;
+
+static unsigned pen_colors[] = {
+ G_COLOR_BLACK,
+ RGB(0x00, 0x66, 0x00),
+ RGB(0x00, 0xff, 0x00),
+ G_COLOR_WHITE,
+ G_COLOR_BLACK,
+ RGB(0x00, 0xff, 0xff),
+ RGB(0xff, 0x00, 0xff),
+ RGB(0xff, 0x00, 0x00),
+};
+
+struct graphics_context {
+ Window *screen;
+
+ /*
+ * FIXME - Currently using two renderers. One for drawing the (possibly
+ * scaled) image to the screen and the other for getting pixel
+ * data for floodfill boundaries. This is almost certainly not
+ * the best way to do this.
+ */
+ // SDL_Renderer *renderer[2];
+
+ /* Used for pixel access for flood fills */
+ // SDL_Surface *surface;
+};
+
+static struct graphics_context ctx;
+
+unsigned g_set_pen_color(uint8 opcode) {
+ return pen_colors[opcode - IMAGE_OP_PEN_COLOR_A];
+}
+
+/* Used by Transylvania and Crimson Crown */
+static unsigned default_color_table[] = {
+ G_COLOR_WHITE, // 00
+ G_COLOR_DARK_BLUE, // 01
+ G_COLOR_GRAY1, // 02
+ G_COLOR_DARK_RED, // 03
+ G_COLOR_GRAY2, // 04
+ 0, G_COLOR_GRAY3, 0, 0, 0, 0, 0, 0,
+ G_COLOR_BROWN1, G_COLOR_DARK_PURPLE, 0,
+
+ 0, 0, G_COLOR_DARK_RED, G_COLOR_BROWN2, 0, 0, 0,
+ G_COLOR_DARK_BLUE, G_COLOR_BLACK, 0, 0, 0, 0, 0, 0, G_COLOR_DARK_PURPLE,
+
+ G_COLOR_DARK_PURPLE, 0, G_COLOR_DARK_RED, 0, 0, 0, 0, 0,
+ 0, 0, 0, G_COLOR_DARK_PURPLE, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, G_COLOR_WHITE, G_COLOR_GRAY0, RGB(0xb5, 0x6c, 0x47),
+ 0, 0, 0, 0, 0, G_COLOR_CYAN, G_COLOR_DARK_RED,
+ G_COLOR_DARK_GREEN1, G_COLOR_DARK_GREEN2,
+
+ G_COLOR_DARK_PURPLE, 0, G_COLOR_DITHERED_PINK, 0, 0,
+ G_COLOR_BROWN2, G_COLOR_DARK_RED, G_COLOR_DARK_BLUE,
+ G_COLOR_DARK_BLUE, G_COLOR_DARK_BLUE, 0, 0, 0,
+ G_COLOR_WHITE, G_COLOR_BROWN2, G_COLOR_BROWN2,
+
+ G_COLOR_BLACK, G_COLOR_DARK_PURPLE, 0, G_COLOR_GRAY2,
+ G_COLOR_BROWN2, 0, 0, G_COLOR_AQUA, 0, 0, G_COLOR_GREEN,
+ G_COLOR_DARK_BLUE, G_COLOR_DARK_PURPLE, G_COLOR_BROWN1,
+ G_COLOR_BROWN2, 0,
+
+ G_COLOR_DARK_PURPLE, G_COLOR_LIGHT_ORANGE, 0, 0,
+ G_COLOR_ORANGE, G_COLOR_RED, G_COLOR_DARK_RED, 0, 0, 0,
+ G_COLOR_DARK_BLUE, G_COLOR_DARK_PURPLE, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ G_COLOR_BLACK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+/* Used by OO-topos */
+/* FIXME - incomplete */
+static unsigned color_table_1[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ RGB(0x80, 0x00, 0x00),
+ 0,
+ RGB(0xe6, 0xe6, 0x00),
+ 0,
+ 0,
+ 0,
+ 0,
+ RGB(0xc0, 0x00, 0x00),
+ RGB(0x80, 0x00, 0x00),
+ G_COLOR_ORANGE,
+ 0,
+
+ 0,
+ G_COLOR_BROWN1,
+ RGB(0x00, 0x00, 0x66),
+ RGB(0x33, 0x99, 0xff),
+ 0,
+ RGB(0xe8, 0xe8, 0xe8),
+ RGB(0x99, 0xcc, 0xff),
+ 0,
+ RGB(0x99, 0x33, 0x33),
+ RGB(0xcc, 0x66, 0x00),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+
+ G_COLOR_GRAY3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ RGB(0x99, 0x33, 0x00),
+ G_COLOR_CYAN,
+ 0,
+ 0,
+ RGB(0x66, 0x00, 0x33),
+ 0,
+ 0,
+ 0,
+ 0,
+
+ G_COLOR_AQUA,
+ G_COLOR_GRAY2,
+ 0,
+ 0,
+ 0,
+ G_COLOR_DARK_BLUE,
+ 0,
+ 0,
+ 0,
+ 0,
+ G_COLOR_GRAY1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+static unsigned *color_tables[] = {
+ default_color_table,
+ color_table_1,
+};
+
+static unsigned *color_table = default_color_table;
+
+void g_set_color_table(unsigned index) {
+ if (index >= ARRAY_SIZE(color_tables)) {
+ printf("Bad color table %d - using default\n", index);
+ color_table = default_color_table;
+ }
+
+ color_table = color_tables[index];
+}
+
+unsigned g_set_fill_color(uint8 index) {
+ unsigned color;
+
+ color = color_table[index];
+ if (!color) {
+ /* Unknown color - use ugly purple */
+ debug_printf(DEBUG_IMAGE_DRAW, "Unknown color %.2x\n", index);
+ return RGB(0xff, 0x00, 0xff);
+ }
+
+ return color;
+}
+
+#ifdef TODO
+static void set_color(unsigned color) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
+ SDL_SetRenderDrawColor(ctx.renderer[i],
+ (color >> 24) & 0xff,
+ (color >> 16) & 0xff,
+ (color >> 8) & 0xff,
+ (color >> 0) & 0xff);
+}
+#endif
+
+void g_draw_box(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+ unsigned color) {
+#ifdef TODO
+ SDL_Rect rect;
+ int i;
+
+ rect.x = x1;
+ rect.y = y1;
+ rect.w = x2 - x1;
+ rect.h = y2 - y1;
+
+ set_color(color);
+ for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
+ SDL_RenderDrawRect(ctx.renderer[i], &rect);
+#endif
+}
+
+static void g_draw_filled_box(unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2, unsigned color) {
+#ifdef TODO
+ SDL_Rect rect;
+ int i;
+
+ rect.x = x1;
+ rect.y = y1;
+ rect.w = x2 - x1;
+ rect.h = y2 - y1;
+
+ set_color(color);
+ for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
+ SDL_RenderFillRect(ctx.renderer[i], &rect);
+#endif
+}
+
+unsigned g_get_pixel_color(int x, int y) {
+#ifdef TODO
+ uint32 *pixels, val;
+
+ pixels = ctx.surface->pixels;
+ val = pixels[(y * G_RENDER_WIDTH) + x];
+
+ /* FIXME - correct endianess on all platforms? */
+ return be32toh(val);
+#else
+ return 0;
+#endif
+}
+
+void g_draw_pixel(unsigned x, unsigned y, unsigned color) {
+#ifdef TODO
+ int i;
+
+ set_color(color);
+ for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
+ SDL_RenderDrawPoint(ctx.renderer[i], x, y);
+#endif
+}
+
+void g_draw_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+ unsigned color)
+{
+#ifdef TODO
+ int i;
+
+ set_color(color);
+ for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
+ SDL_RenderDrawLine(ctx.renderer[i], x1, y1, x2, y2);
+#endif
+}
+
+void g_draw_shape(int x, int y, int shape_type, unsigned fill_color)
+{
+ int i, j;
+
+ switch (shape_type) {
+ case IMAGE_OP_SHAPE_PIXEL:
+ x += 7; y += 7;
+ g_draw_pixel(x, y, fill_color);
+ break;
+
+ case IMAGE_OP_SHAPE_BOX:
+ x += 6; y += 7;
+ g_draw_filled_box(x, y, x + 2, y + 2, fill_color);
+ break;
+
+ case IMAGE_OP_SHAPE_CIRCLE_TINY:
+ x += 5;
+ y += 5;
+ g_draw_filled_box(x + 1, y, x + 3, y + 4, fill_color);
+ g_draw_filled_box(x, y + 1, x + 4, y + 3, fill_color);
+ break;
+
+ case IMAGE_OP_SHAPE_CIRCLE_SMALL:
+ x += 4; y += 4;
+ g_draw_filled_box(x + 1, y, x + 5, y + 6, fill_color);
+ g_draw_filled_box(x, y + 1, x + 6, y + 5, fill_color);
+ break;
+
+ case IMAGE_OP_SHAPE_CIRCLE_MED:
+ x += 1; y += 1;
+ g_draw_filled_box(x + 1,
+ y + 1,
+ x + 1 + (2 + 4 + 2),
+ y + 1 + (2 + 4 + 2),
+ fill_color);
+ g_draw_filled_box(x + 3,
+ y,
+ x + 3 + 4,
+ y + (1 + 2 + 4 + 2 + 1),
+ fill_color);
+ g_draw_filled_box(x,
+ y + 3,
+ x + (1 + 2 + 4 + 2 + 1),
+ y + 3 + 4,
+ fill_color);
+ break;
+
+ case IMAGE_OP_SHAPE_CIRCLE_LARGE:
+ g_draw_filled_box(x + 2,
+ y + 1,
+ x + 2 + (3 + 4 + 3),
+ y + 1 + (1 + 3 + 4 + 3 + 1),
+ fill_color);
+ g_draw_filled_box(x + 1,
+ y + 2,
+ x + 1 + (1 + 3 + 4 + 3 + 1),
+ y + 2 + (3 + 4 + 3),
+ fill_color);
+ g_draw_filled_box(x + 5,
+ y,
+ x + 5 + 4,
+ y + 1 + 1 + 3 + 4 + 3 + 1 + 1,
+ fill_color);
+ g_draw_filled_box(x,
+ y + 5,
+ x + 1 + 1 + 3 + 4 + 3 + 1 + 1,
+ y + 5 + 4,
+ fill_color);
+ break;
+
+ case IMAGE_OP_SHAPE_A:
+ /* FIXME - very large circle? */
+ break;
+
+ case IMAGE_OP_SHAPE_SPRAY:
+ {
+ char spray[13][13] = {
+ {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+ {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1},
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0},
+ {0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0},
+ {1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0},
+ {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0},
+ {1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0},
+ {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0},
+ };
+ for (i = 0; i < 13; i++)
+ for (j = 0; j < 13; j++)
+ if (spray[i][j])
+ g_draw_pixel(x + i, y + j, fill_color);
+ break;
+ }
+
+ default:
+ /* Unknown shape */
+ break;
+ }
+}
+
+void g_floodfill(int x, int y, unsigned fill_color,
+ unsigned old_color)
+{
+ int x1, x2, i;
+
+ if (g_get_pixel_color(x, y) != old_color || fill_color == old_color)
+ return;
+
+ /* Left end of scanline */
+ for (x1 = x; x1 > 0; x1--)
+ if (g_get_pixel_color(x1 - 1, y) != old_color)
+ break;
+
+ /* Right end of scanline */
+ for (x2 = x; x2 < RENDER_X_MAX; x2++)
+ if (g_get_pixel_color(x2 + 1, y) != old_color)
+ break;
+
+ g_draw_line(x1, y, x2, y, fill_color);
+#ifdef TODO
+ SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
+#endif
+ /* Scanline above */
+ for (i = x1; i < x2; i++)
+ if (y > 0 && g_get_pixel_color(i, y - 1) == old_color)
+ g_floodfill(i, y - 1, fill_color, old_color);
+
+ /* Scanline below */
+ for (i = x1; i < x2; i++)
+ if (y < RENDER_Y_MAX && g_get_pixel_color(i, y + 1) == old_color)
+ g_floodfill(i, y + 1, fill_color, old_color);
+
+}
+
+void g_flip_buffers(void)
+{
+#ifdef TODO
+ SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
+#endif
+}
+
+void g_clear_screen(unsigned color) {
+ #ifdef TODO
+ int i;
+
+ set_color(color);
+ for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
+ SDL_RenderClear(ctx.renderer[i]);
+
+ SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
+#endif
+}
+
+void g_init(unsigned width, unsigned height)
+{
+ #ifdef TODO
+ int err;
+
+ err = SDL_Init(SDL_INIT_VIDEO);
+ if (err == -1)
+ fatal_error("Failed to initialize graphics\n");
+
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
+
+ ctx.screen = SDL_CreateWindow("Re-Comprehend",
+ SDL_WINDOWPOS_CENTERED,
+ SDL_WINDOWPOS_CENTERED,
+ width, height, 0);
+
+ ctx.renderer[RENDERER_SCREEN] =
+ SDL_CreateRenderer(ctx.screen, -1, SDL_RENDERER_ACCELERATED);
+ SDL_RenderSetLogicalSize(ctx.renderer[RENDERER_SCREEN],
+ G_RENDER_WIDTH, G_RENDER_HEIGHT);
+
+ ctx.surface = SDL_CreateRGBSurface(0, G_RENDER_WIDTH, G_RENDER_HEIGHT,
+ 32, 0x000000ff, 0x0000ff00,
+ 0x00ff0000, 0xff000000);
+ ctx.renderer[RENDERER_PIXEL_DATA] =
+ SDL_CreateSoftwareRenderer(ctx.surface);
+#endif
+ graphics_enabled = true;
+}
+
+bool g_enabled(void)
+{
+ return graphics_enabled;
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/graphics.h b/engines/glk/comprehend/graphics.h
new file mode 100644
index 0000000000..414850cbc1
--- /dev/null
+++ b/engines/glk/comprehend/graphics.h
@@ -0,0 +1,88 @@
+/* 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_COMPREHEND_GRAPHICS_H
+#define GLK_COMPREHEND_GRAPHICS_H
+
+#include "common/scummsys.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#define G_RENDER_WIDTH 320
+#define G_RENDER_HEIGHT 240
+
+#define RGB(r, g, b) (uint32)(((r) << 24) | ((g) << 16) | ((b) << 8) | 0xff)
+
+#define G_COLOR_BLACK 0x000000ff
+#define G_COLOR_WHITE 0xffffffff
+#define G_COLOR_CYAN 0x3366ffff
+#define G_COLOR_YELLOW 0xffff00ff
+#define G_COLOR_RED 0xff0000ff
+
+#define G_COLOR_GRAY0 0x202020ff
+#define G_COLOR_GRAY1 0x404040ff
+#define G_COLOR_GRAY2 0x808080ff
+#define G_COLOR_GRAY3 0xc0c0c0ff
+
+#define G_COLOR_LIGHT_ORANGE 0xff9966ff
+#define G_COLOR_ORANGE 0xff9900ff
+#define G_COLOR_DARK_PURPLE 0x666699ff
+#define G_COLOR_DARK_BLUE 0x000099ff
+
+#define G_COLOR_DARK_RED 0xcc0033ff
+#define G_COLOR_DITHERED_PINK 0xff6699ff
+
+#define G_COLOR_DARK_GREEN1 0x009966ff
+#define G_COLOR_DARK_GREEN2 0x003300ff
+
+#define G_COLOR_AQUA 0x33ccccff
+
+#define G_COLOR_GREEN 0x33cc00ff
+
+#define G_COLOR_BROWN1 0x7a5200ff
+#define G_COLOR_BROWN2 0x663300ff
+
+void g_set_color_table(unsigned index);
+
+unsigned g_set_fill_color(uint8 index);
+unsigned g_set_pen_color(uint8 opcode);
+
+unsigned g_get_pixel_color(int x, int y);
+
+void g_draw_pixel(unsigned x, unsigned y, unsigned color);
+void g_draw_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+ unsigned color);
+void g_draw_box(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+ unsigned color);
+void g_draw_shape(int x, int y, int shape_type, unsigned fill_color);
+void g_floodfill(int x, int y, unsigned fill_color, unsigned old_color);
+
+void g_clear_screen(unsigned color);
+void g_flip_buffers(void);
+void g_init(unsigned width, unsigned height);
+bool g_enabled(void);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
new file mode 100644
index 0000000000..21cfa44db1
--- /dev/null
+++ b/engines/glk/comprehend/image_data.cpp
@@ -0,0 +1,397 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/file_buf.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/image_data.h"
+#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/util.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#define IMAGES_PER_FILE 16
+
+struct image_context {
+ unsigned x;
+ unsigned y;
+ unsigned pen_color;
+ unsigned fill_color;
+ unsigned shape;
+
+ unsigned text_x;
+ unsigned text_y;
+};
+
+static unsigned draw_flags;
+
+void image_set_draw_flags(unsigned flags)
+{
+ draw_flags |= flags;
+}
+
+static uint16 image_get_operand(struct file_buf *fb)
+{
+ uint8 val;
+
+ file_buf_get_u8(fb, &val);
+ return val;
+}
+
+static bool do_image_op(struct file_buf *fb, struct image_context *ctx)
+{
+ uint8 opcode;
+ uint16 a, b;
+
+ file_buf_get_u8(fb, &opcode);
+ debug_printf(DEBUG_IMAGE_DRAW,
+ " %.4x [%.2x]: ", file_buf_get_pos(fb) - 1, opcode);
+
+ switch (opcode) {
+ case IMAGE_OP_SCENE_END:
+ case IMAGE_OP_EOF:
+ debug_printf(DEBUG_IMAGE_DRAW, "end\n");
+ return true;
+
+ case IMAGE_OP_PEN_COLOR_A:
+ case IMAGE_OP_PEN_COLOR_B:
+ case IMAGE_OP_PEN_COLOR_C:
+ case IMAGE_OP_PEN_COLOR_D:
+ case IMAGE_OP_PEN_COLOR_E:
+ case IMAGE_OP_PEN_COLOR_F:
+ case IMAGE_OP_PEN_COLOR_G:
+ case IMAGE_OP_PEN_COLOR_H:
+ debug_printf(DEBUG_IMAGE_DRAW, "set_pen_color(%.2x)\n", opcode);
+ ctx->pen_color = g_set_pen_color(opcode);
+ break;
+
+ case IMAGE_OP_DRAW_LINE:
+ case IMAGE_OP_DRAW_LINE_FAR:
+ a = image_get_operand(fb);
+ b = image_get_operand(fb);
+
+ if (opcode & 0x1)
+ a += 255;
+
+ debug_printf(DEBUG_IMAGE_DRAW,
+ "draw_line (%d, %d) - (%d, %d)\n", opcode,
+ ctx->x, ctx->y, a, b);
+ g_draw_line(ctx->x, ctx->y, a, b, ctx->pen_color);
+
+ ctx->x = a;
+ ctx->y = b;
+ break;
+
+ case IMAGE_OP_DRAW_BOX:
+ case IMAGE_OP_DRAW_BOX_FAR:
+ a = image_get_operand(fb);
+ b = image_get_operand(fb);
+
+ if (opcode & 0x1)
+ a += 255;
+
+ debug_printf(DEBUG_IMAGE_DRAW,
+ "draw_box (%d, %d) - (%d, %d)\n", opcode,
+ ctx->x, ctx->y, a, b);
+
+ g_draw_box(ctx->x, ctx->y, a, b, ctx->pen_color);
+ break;
+
+ case IMAGE_OP_MOVE_TO:
+ case IMAGE_OP_MOVE_TO_FAR:
+ /* Move to */
+ a = image_get_operand(fb);
+ b = image_get_operand(fb);
+
+ if (opcode & 0x1)
+ a += 255;
+
+ debug_printf(DEBUG_IMAGE_DRAW, "move_to(%d, %d)\n", a, b);
+ ctx->x = a;
+ ctx->y = b;
+ break;
+
+ case IMAGE_OP_SHAPE_PIXEL:
+ case IMAGE_OP_SHAPE_BOX:
+ case IMAGE_OP_SHAPE_CIRCLE_TINY:
+ case IMAGE_OP_SHAPE_CIRCLE_SMALL:
+ case IMAGE_OP_SHAPE_CIRCLE_MED:
+ case IMAGE_OP_SHAPE_CIRCLE_LARGE:
+ case IMAGE_OP_SHAPE_A:
+ case IMAGE_OP_SHAPE_SPRAY:
+ debug_printf(DEBUG_IMAGE_DRAW,
+ "set_shape_type(%.2x)\n", opcode - 0x40);
+ ctx->shape = opcode;
+ break;
+
+ case 0x48:
+ /*
+ * FIXME - This appears to be a shape type. Only used by
+ * OO-Topos.
+ */
+ debug_printf(DEBUG_IMAGE_DRAW, "shape_unknown()\n");
+ ctx->shape = IMAGE_OP_SHAPE_PIXEL;
+ break;
+
+ case IMAGE_OP_DRAW_SHAPE:
+ case IMAGE_OP_DRAW_SHAPE_FAR:
+ a = image_get_operand(fb);
+ b = image_get_operand(fb);
+
+ if (opcode & 0x1)
+ a += 255;
+
+ debug_printf(DEBUG_IMAGE_DRAW,
+ "draw_shape(%d, %d), style=%.2x, fill=%.2x\n",
+ a, b, ctx->shape, ctx->fill_color);
+
+ g_draw_shape(a, b, ctx->shape, ctx->fill_color);
+ break;
+
+ case IMAGE_OP_PAINT:
+ case IMAGE_OP_PAINT_FAR:
+ /* Paint */
+ a = image_get_operand(fb);
+ b = image_get_operand(fb);
+
+ if (opcode & 0x1)
+ a += 255;
+
+ debug_printf(DEBUG_IMAGE_DRAW, "paint(%d, %d)\n", a, b);
+ if (!(draw_flags & IMAGEF_NO_FLOODFILL))
+ g_floodfill(a, b, ctx->fill_color,
+ g_get_pixel_color(a, b));
+ break;
+
+ case IMAGE_OP_FILL_COLOR:
+ a = image_get_operand(fb);
+ debug_printf(DEBUG_IMAGE_DRAW, "set_fill_color(%.2x)\n", a);
+ ctx->fill_color = g_set_fill_color(a);
+ break;
+
+ case IMAGE_OP_SET_TEXT_POS:
+ a = image_get_operand(fb);
+ b = image_get_operand(fb);
+ debug_printf(DEBUG_IMAGE_DRAW, "set_text_pos(%d, %d)\n", a, b);
+
+ ctx->text_x = a;
+ ctx->text_y = b;
+ break;
+
+ case IMAGE_OP_DRAW_CHAR:
+ a = image_get_operand(fb);
+ debug_printf(DEBUG_IMAGE_DRAW, "draw_char(%c)\n",
+ a >= 0x20 && a < 0x7f ? a : '?');
+
+ g_draw_box(ctx->text_x, ctx->text_y,
+ ctx->text_x + 6, ctx->text_y + 7, ctx->fill_color);
+ ctx->text_x += 8;
+ break;
+
+ case 0xf3:
+ /*
+ * FIXME - Oo-Topos uses this at the beginning of some room
+ * images.
+ */
+ debug_printf(DEBUG_IMAGE_DRAW, "unknown()\n");
+ break;
+
+ case 0xb5:
+ case 0x82:
+ case 0x50:
+ /* FIXME - unknown, no arguments */
+ debug_printf(DEBUG_IMAGE_DRAW, "unknown\n");
+ break;
+
+ case 0x73:
+ case 0xb0:
+ case 0xd0:
+ /* FIXME - unknown, one argument */
+ a = image_get_operand(fb);
+ debug_printf(DEBUG_IMAGE_DRAW, "unknown %.2x: (%.2x) '%c'\n",
+ opcode, a,
+ a >= 0x20 && a < 0x7f ? a : '?');
+ break;
+
+ default:
+ /* FIXME - Unknown, two arguments */
+ a = image_get_operand(fb);
+ b = image_get_operand(fb);
+
+ debug_printf(DEBUG_IMAGE_DRAW,
+ "unknown(%.2x, %.2x)\n", a, b);
+ g_draw_pixel(a, b, 0x00ff00ff);
+ break;
+ }
+
+ return false;
+}
+
+void draw_image(struct image_data *info, unsigned index)
+{
+ unsigned file_num;
+ struct file_buf *fb;
+ bool done = false;
+ image_context ctx = {
+ 0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE
+ };
+
+ file_num = index / IMAGES_PER_FILE;
+ fb = &info->fb[file_num];
+
+ if (index >= info->nr_images) {
+ printf("WARNING: Bad image index %.8x (max=%.8zx)\n", index,
+ info->nr_images);
+ return;
+ }
+
+ file_buf_set_pos(fb, info->image_offsets[index]);
+ while (!done) {
+ done = do_image_op(fb, &ctx);
+ if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
+ getchar();
+ g_flip_buffers();
+ }
+ }
+
+ g_flip_buffers();
+}
+
+void draw_dark_room(void)
+{
+ g_clear_screen(G_COLOR_BLACK);
+}
+
+void draw_bright_room(void)
+{
+ g_clear_screen(G_COLOR_WHITE);
+}
+
+void draw_location_image(struct image_data *info, unsigned index)
+{
+ g_clear_screen(G_COLOR_WHITE);
+ draw_image(info, index);
+}
+
+static void load_image_file(struct image_data *info, const char *filename,
+ unsigned file_num)
+{
+ unsigned base = file_num * IMAGES_PER_FILE;
+ struct file_buf *fb;
+ uint16 version;
+ int i;
+
+ fb = &info->fb[file_num];
+ file_buf_map(filename, fb);
+
+ /*
+ * In earlier versions of Comprehend the first word is 0x1000 and
+ * the image offsets start four bytes in. In newer versions the
+ * image offsets start at the beginning of the image file.
+ */
+ file_buf_get_le16(fb, &version);
+ if (version == 0x1000)
+ file_buf_set_pos(fb, 4);
+ else
+ file_buf_set_pos(fb, 0);
+
+ /* Get the image offsets in the file */
+ for (i = 0; i < IMAGES_PER_FILE; i++) {
+ file_buf_get_le16(fb, &info->image_offsets[base + i]); {
+ if (version == 0x1000)
+ info->image_offsets[base + i] += 4;
+ }
+ }
+}
+
+static void load_image_files(struct image_data *info, const char *game_dir,
+ const char **filenames, size_t nr_files)
+{
+ char path[256];
+ uint i;
+
+ memset(info, 0, sizeof(*info));
+
+ info->nr_images = nr_files * IMAGES_PER_FILE;
+ info->fb = (file_buf *)xmalloc(info->nr_images * sizeof(*info->fb));
+ info->image_offsets = (uint16 *)xmalloc(info->nr_images * sizeof(uint16));
+
+ for (i = 0; i < nr_files; i++) {
+ snprintf(path, sizeof(path), "%s/%s", game_dir, filenames[i]);
+ load_image_file(info, path, i);
+ }
+}
+
+static size_t graphic_array_count(const char **filenames, size_t max)
+{
+ size_t count;
+
+ for (count = 0; count < max && filenames[count]; count++)
+ ;
+ return count;
+}
+
+static void split_path(const char *filename, char **dir, char **base)
+{
+ const char *p;
+
+ p = strrchr(filename, '/');
+ if (!p) {
+ *base = xstrndup(filename, strlen(filename));
+ *dir = xstrndup(".", 1);
+ } else {
+ *base = xstrndup(p, strlen(p));
+ *dir = xstrndup(filename, p - filename);
+ }
+}
+
+void comprehend_load_image_file(const char *filename, struct image_data *info)
+{
+ char *dir, *base;
+
+ split_path(filename, &dir, &base);
+ load_image_files(info, dir, (const char **)&base, 1);
+ free(dir);
+ free(base);
+}
+
+void comprehend_load_images(comprehend_game *game, const char *game_dir)
+{
+ size_t nr_item_files, nr_room_files;
+
+ nr_room_files =
+ graphic_array_count(game->location_graphic_files,
+ ARRAY_SIZE(game->location_graphic_files));
+ nr_item_files =
+ graphic_array_count(game->item_graphic_files,
+ ARRAY_SIZE(game->item_graphic_files));
+
+ load_image_files(&game->info->room_images, game_dir,
+ game->location_graphic_files, nr_room_files);
+
+ load_image_files(&game->info->item_images, game_dir,
+ game->item_graphic_files, nr_item_files);
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
new file mode 100644
index 0000000000..796e81333e
--- /dev/null
+++ b/engines/glk/comprehend/image_data.h
@@ -0,0 +1,99 @@
+/* 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_COMPREHEND_IMAGE_DATA_H
+#define GLK_COMPREHEND_IMAGE_DATA_H
+
+#include "glk/comprehend/game.h"
+#include "common/scummsys.h"
+
+namespace Glk {
+namespace Comprehend {
+
+struct file_buf;
+
+struct image_data {
+ file_buf *fb;
+ uint16 *image_offsets;
+ size_t nr_images;
+};
+
+#define IMAGEF_OP_WAIT_KEYPRESS (1 << 0)
+#define IMAGEF_NO_FLOODFILL (1 << 1)
+
+#define IMAGE_OP_SCENE_END 0x00
+
+#define IMAGE_OP_SET_TEXT_POS 0x10
+
+#define IMAGE_OP_PEN_COLOR_A 0x20
+#define IMAGE_OP_PEN_COLOR_B 0x21
+#define IMAGE_OP_PEN_COLOR_C 0x22
+#define IMAGE_OP_PEN_COLOR_D 0x23
+#define IMAGE_OP_PEN_COLOR_E 0x24
+#define IMAGE_OP_PEN_COLOR_F 0x25
+#define IMAGE_OP_PEN_COLOR_G 0x26
+#define IMAGE_OP_PEN_COLOR_H 0x27
+
+#define IMAGE_OP_DRAW_CHAR 0x30
+
+#define IMAGE_OP_SHAPE_PIXEL 0x40
+#define IMAGE_OP_SHAPE_BOX 0x41
+#define IMAGE_OP_SHAPE_CIRCLE_TINY 0x42
+#define IMAGE_OP_SHAPE_CIRCLE_SMALL 0x43
+#define IMAGE_OP_SHAPE_CIRCLE_MED 0x44
+#define IMAGE_OP_SHAPE_CIRCLE_LARGE 0x45
+#define IMAGE_OP_SHAPE_A 0x46
+#define IMAGE_OP_SHAPE_SPRAY 0x47
+
+#define IMAGE_OP_EOF 0x55
+
+#define IMAGE_OP_FILL_COLOR 0x60
+
+#define IMAGE_OP_MOVE_TO 0x80
+#define IMAGE_OP_MOVE_TO_FAR 0x81
+
+#define IMAGE_OP_DRAW_BOX 0x90
+#define IMAGE_OP_DRAW_BOX_FAR 0x91
+
+#define IMAGE_OP_DRAW_LINE 0xa0
+#define IMAGE_OP_DRAW_LINE_FAR 0xa1
+
+#define IMAGE_OP_DRAW_SHAPE 0xc0
+#define IMAGE_OP_DRAW_SHAPE_FAR 0xc1
+
+#define IMAGE_OP_PAINT 0xe0
+#define IMAGE_OP_PAINT_FAR 0xe1
+
+void image_set_draw_flags(unsigned flags);
+
+void draw_dark_room(void);
+void draw_bright_room(void);
+void draw_image(image_data *info, unsigned index);
+void draw_location_image(image_data *info, unsigned index);
+
+void comprehend_load_image_file(const char *filename, image_data *info);
+void comprehend_load_images(comprehend_game *game, const char *game_dir);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/image_view.cpp b/engines/glk/comprehend/image_view.cpp
new file mode 100644
index 0000000000..c056e4b27d
--- /dev/null
+++ b/engines/glk/comprehend/image_view.cpp
@@ -0,0 +1,147 @@
+/* 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/comprehend/image_data.h"
+#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/util.h"
+#include "glk/comprehend/comprehend.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#ifdef TODO
+static void usage(const char *progname)
+{
+ printf("%s: [OPTION]... FILENAME INDEX\n", progname);
+ printf("\nOptions:\n");
+ printf(" -w, --width=WIDTH Graphics width\n");
+ printf(" -h, --height=HEIGHT Graphics height\n");
+ printf(" -c, --clear=COLOR Graphics clear color\n");
+ printf(" -t, --color-table=INDEX Color table\n");
+ printf(" -s, --sequence Disable sequence of images\n");
+ printf(" -p, --pause Wait for keypress after each draw operation\n");
+ printf(" -f, --floodfill-disable Disable floodfill operation\n");
+ printf(" -d, --debug Enable debugging\n");
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+ struct option long_opts[] = {
+ {"width", required_argument, 0, 'w'},
+ {"height", required_argument, 0, 'h'},
+ {"clear", required_argument, 0, 'c'},
+ {"color-table", required_argument, 0, 't'},
+ {"sequence", no_argument, 0, 's'},
+ {"pause", no_argument, 0, 'p'},
+ {"floodfill-disable", no_argument, 0, 'f'},
+ {"debug", no_argument, 0, 'd'},
+ {"help", no_argument, 0, '?'},
+ {NULL, 0, 0, 0},
+ };
+ const char *short_opts = "w:h:c:t:spfd?";
+ struct image_data info;
+ const char *filename;
+ unsigned index, clear_color = G_COLOR_WHITE,
+ graphics_width = G_RENDER_WIDTH,
+ graphics_height = G_RENDER_HEIGHT,
+ color_table = 0;
+ bool sequence = false;
+ int c, opt_index;
+
+ while (1) {
+ c = getopt_long(argc, argv, short_opts, long_opts, &opt_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'w':
+ graphics_width = strtoul(optarg, NULL, 0);
+ break;
+
+ case 'h':
+ graphics_height = strtoul(optarg, NULL, 0);
+ break;
+
+ case 'c':
+ clear_color = strtoul(optarg, NULL, 0);
+ break;
+
+ case 't':
+ color_table = strtoul(optarg, NULL, 0);
+ break;
+
+ case 's':
+ sequence = true;
+ break;
+
+ case 'p':
+ image_set_draw_flags(IMAGEF_OP_WAIT_KEYPRESS);
+ break;
+
+ case 'f':
+ image_set_draw_flags(IMAGEF_NO_FLOODFILL);
+ break;
+
+ case 'd':
+ debug_enable(DEBUG_IMAGE_DRAW);
+ break;
+
+ case '?':
+ usage(argv[0]);
+ break;
+
+ default:
+ printf("Invalid option\n");
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind >= argc || argc - optind != 2)
+ usage(argv[0]);
+
+ filename = argv[optind++];
+ index = strtoul(argv[optind++], NULL, 0);
+
+ g_init(graphics_width, graphics_height);
+ g_set_color_table(color_table);
+ comprehend_load_image_file(filename, &info);
+
+ while (index < 16) {
+ g_clear_screen(clear_color);
+ draw_image(&info, index);
+
+ c = getchar();
+ if (!sequence || c == 'q' || c == 'Q')
+ break;
+
+ index++;
+ printf("Image %d\n", index);
+ }
+
+ exit(EXIT_SUCCESS);
+}
+#endif
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/opcode_map.cpp b/engines/glk/comprehend/opcode_map.cpp
new file mode 100644
index 0000000000..f3a2eccce1
--- /dev/null
+++ b/engines/glk/comprehend/opcode_map.cpp
@@ -0,0 +1,193 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/util.h"
+
+namespace Glk {
+namespace Comprehend {
+
+/*
+ * Version 2 of the Comprehend engine (OO-Topos) changes some of the opcode
+ * numbers and adds new opcodes. Use tables to translate the opcodes used
+ * in the original games into a generic version used by Re-Comprehend.
+ *
+ * FIXME - unimplemented/unknown ocpodes:
+ *
+ * d5(obj): Make object visible. This will print a "you see: object" when the
+ * object is in the room.
+ */
+static uint8 opcode_map_v1[0x100] = {
+#ifdef TODO
+ [0x01] = OPCODE_HAVE_OBJECT,
+ [0x04] = OPCODE_OR,
+ [0x05] = OPCODE_IN_ROOM,
+ [0x06] = OPCODE_VAR_EQ,
+ [0x08] = OPCODE_CURRENT_OBJECT_TAKEABLE,
+ [0x09] = OPCODE_OBJECT_PRESENT,
+ [0x0c] = OPCODE_ELSE,
+ [0x0e] = OPCODE_OBJECT_IN_ROOM,
+ [0x14] = OPCODE_OBJECT_NOT_VALID,
+ [0x18] = OPCODE_INVENTORY_FULL,
+ [0x19] = OPCODE_TEST_FLAG,
+ [0x1d] = OPCODE_CURRENT_OBJECT_IN_ROOM,
+ [0x20] = OPCODE_HAVE_CURRENT_OBJECT,
+ [0x21] = OPCODE_OBJECT_IS_NOT_NOWHERE,
+ [0x24] = OPCODE_CURRENT_OBJECT_PRESENT,
+ [0x31] = OPCODE_TEST_ROOM_FLAG,
+ [0x41] = OPCODE_NOT_HAVE_OBJECT,
+ [0x45] = OPCODE_NOT_IN_ROOM,
+ [0x48] = OPCODE_CURRENT_OBJECT_IS_NOWHERE,
+ [0x49] = OPCODE_OBJECT_NOT_PRESENT,
+ [0x43] = OPCODE_OBJECT_NOT_IN_ROOM,
+ [0x50] = OPCODE_TEST_FALSE,
+ [0x59] = OPCODE_TEST_NOT_FLAG,
+ [0x60] = OPCODE_NOT_HAVE_CURRENT_OBJECT,
+ [0x61] = OPCODE_OBJECT_IS_NOWHERE,
+ [0x64] = OPCODE_CURRENT_OBJECT_NOT_PRESENT,
+ [0x68] = OPCODE_CURRENT_OBJECT_NOT_TAKEABLE,
+ [0x71] = OPCODE_TEST_NOT_ROOM_FLAG,
+ [0x80] = OPCODE_INVENTORY,
+ [0x81] = OPCODE_TAKE_OBJECT,
+ [0x82] = OPCODE_MOVE_OBJECT_TO_ROOM,
+ [0x84] = OPCODE_SAVE_ACTION,
+ [0x85] = OPCODE_MOVE_TO_ROOM,
+ [0x86] = OPCODE_VAR_ADD,
+ [0x87] = OPCODE_SET_ROOM_DESCRIPTION,
+ [0x89] = OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM,
+ [0x8a] = OPCODE_VAR_SUB,
+ [0x8b] = OPCODE_SET_OBJECT_DESCRIPTION,
+ [0x8c] = OPCODE_MOVE,
+ [0x8e] = OPCODE_PRINT,
+ [0x95] = OPCODE_REMOVE_OBJECT,
+ [0x99] = OPCODE_SET_FLAG,
+ [0x92] = OPCODE_CALL_FUNC,
+ [0x98] = OPCODE_TURN_TICK,
+ [0x9d] = OPCODE_CLEAR_FLAG,
+ [0x9e] = OPCODE_INVENTORY_ROOM,
+ [0xa0] = OPCODE_TAKE_CURRENT_OBJECT,
+ [0xa1] = OPCODE_SPECIAL,
+ [0xa4] = OPCODE_DROP_CURRENT_OBJECT,
+ [0xa2] = OPCODE_SET_ROOM_GRAPHIC,
+ [0xb0] = OPCODE_REMOVE_CURRENT_OBJECT,
+ [0xb1] = OPCODE_DO_VERB,
+ [0xb9] = OPCODE_SET_STRING_REPLACEMENT,
+ [0xbd] = OPCODE_VAR_INC,
+ [0xc1] = OPCODE_VAR_DEC,
+ [0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM
+#else
+ 0
+ #endif
+};
+
+static uint8 opcode_map_v2[0x100] = {
+#ifdef TODO
+ [0x01] = OPCODE_HAVE_OBJECT,
+ [0x04] = OPCODE_OR,
+ [0x05] = OPCODE_IN_ROOM,
+ [0x06] = OPCODE_VAR_EQ,
+ [0x08] = OPCODE_CURRENT_IS_OBJECT,
+ [0x09] = OPCODE_OBJECT_PRESENT,
+ [0x0c] = OPCODE_ELSE,
+ [0x11] = OPCODE_OBJECT_IS_NOWHERE,
+ [0x14] = OPCODE_OBJECT_NOT_VALID,
+ [0x19] = OPCODE_TEST_FLAG,
+ [0x1d] = OPCODE_TEST_ROOM_FLAG,
+ [0x20] = OPCODE_HAVE_CURRENT_OBJECT,
+ [0x21] = OPCODE_OBJECT_PRESENT,
+ [0x22] = OPCODE_OBJECT_IN_ROOM,
+ [0x30] = OPCODE_CURRENT_OBJECT_PRESENT,
+ [0x31] = OPCODE_TEST_ROOM_FLAG,
+ [0x38] = OPCODE_INVENTORY_FULL,
+ [0x41] = OPCODE_NOT_HAVE_OBJECT,
+ [0x45] = OPCODE_NOT_IN_ROOM,
+ [0x48] = OPCODE_CURRENT_OBJECT_IS_NOWHERE,
+ [0x43] = OPCODE_OBJECT_NOT_IN_ROOM,
+ [0x59] = OPCODE_TEST_NOT_FLAG,
+ [0x5d] = OPCODE_TEST_NOT_ROOM_FLAG,
+ [0x60] = OPCODE_NOT_HAVE_CURRENT_OBJECT,
+ [0x61] = OPCODE_OBJECT_NOT_PRESENT,
+ [0x70] = OPCODE_CURRENT_OBJECT_NOT_PRESENT,
+ [0x74] = OPCODE_CURRENT_NOT_OBJECT,
+ [0x80] = OPCODE_INVENTORY,
+ [0x81] = OPCODE_TAKE_OBJECT,
+ [0x82] = OPCODE_MOVE_OBJECT_TO_ROOM,
+ [0x84] = OPCODE_SAVE_ACTION,
+ [0x85] = OPCODE_MOVE_TO_ROOM,
+ [0x86] = OPCODE_VAR_ADD,
+ [0x87] = OPCODE_SET_ROOM_DESCRIPTION,
+ [0x89] = OPCODE_SPECIAL,
+ [0x8a] = OPCODE_VAR_SUB,
+ [0x8b] = OPCODE_SET_OBJECT_DESCRIPTION,
+ [0x8c] = OPCODE_MOVE,
+ [0x8e] = OPCODE_PRINT,
+ [0x8f] = OPCODE_SET_OBJECT_LONG_DESCRIPTION,
+ [0x90] = OPCODE_WAIT_KEY,
+ [0x92] = OPCODE_CALL_FUNC,
+ [0x95] = OPCODE_REMOVE_OBJECT,
+ [0x98] = OPCODE_TURN_TICK,
+ [0x99] = OPCODE_SET_FLAG,
+ [0x9d] = OPCODE_CLEAR_FLAG,
+ [0x9e] = OPCODE_INVENTORY_ROOM,
+ [0xa0] = OPCODE_TAKE_CURRENT_OBJECT,
+ [0xa2] = OPCODE_SET_OBJECT_GRAPHIC,
+ [0xb1] = OPCODE_DO_VERB,
+ [0xb5] = OPCODE_DESCRIBE_CURRENT_OBJECT,
+ [0xc1] = OPCODE_VAR_DEC,
+ [0xc2] = OPCODE_SET_ROOM_GRAPHIC,
+ [0xc5] = OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT,
+ [0xc6] = OPCODE_SET_OBJECT_GRAPHIC,
+ [0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM,
+ [0xcd] = OPCODE_SET_STRING_REPLACEMENT,
+ [0xd1] = OPCODE_MOVE_DIRECTION,
+ [0xd5] = OPCODE_DRAW_ROOM,
+ [0xd9] = OPCODE_DRAW_OBJECT,
+ [0xdd] = OPCODE_VAR_INC,
+ [0xe1] = OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM,
+ [0xed] = OPCODE_REMOVE_OBJECT,
+ [0xf0] = OPCODE_DROP_CURRENT_OBJECT,
+ [0xfc] = OPCODE_REMOVE_CURRENT_OBJECT
+#else
+ 0
+ #endif
+};
+
+uint8 *get_opcode_map(comprehend_game *game)
+{
+ switch (game->info->comprehend_version) {
+ case 1:
+ return opcode_map_v1;
+ break;
+ case 2:
+ return opcode_map_v2;
+ default:
+ fatal_error("Unsupported Comprehend version %d\n",
+ game->info->comprehend_version);
+
+ /* Not reached */
+ return NULL;
+ }
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/opcode_map.h b/engines/glk/comprehend/opcode_map.h
new file mode 100644
index 0000000000..73eb5eb014
--- /dev/null
+++ b/engines/glk/comprehend/opcode_map.h
@@ -0,0 +1,36 @@
+/* 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_COMPREHEND_OPCODE_MAP_H
+#define GLK_COMPREHEND_OPCODE_MAP_H
+
+#include "glk/comprehend/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+uint8 *get_opcode_map(comprehend_game *game);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/recomprehend.cpp b/engines/glk/comprehend/recomprehend.cpp
new file mode 100644
index 0000000000..a6646c0798
--- /dev/null
+++ b/engines/glk/comprehend/recomprehend.cpp
@@ -0,0 +1,201 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/dump_game_data.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/util.h"
+
+namespace Glk {
+namespace Comprehend {
+
+extern struct comprehend_game game_transylvania;
+extern struct comprehend_game game_crimson_crown_1;
+extern struct comprehend_game game_crimson_crown_2;
+extern struct comprehend_game game_oo_topos;
+extern struct comprehend_game game_talisman;
+
+static struct comprehend_game *comprehend_games[] = {
+ &game_transylvania,
+ &game_crimson_crown_1,
+ &game_crimson_crown_2,
+ &game_oo_topos,
+ &game_talisman,
+};
+
+struct dump_option {
+ const char *option;
+ unsigned flag;
+};
+
+static struct dump_option dump_options[] = {
+ {"strings", DUMP_STRINGS},
+ {"extra-strings", DUMP_EXTRA_STRINGS},
+ {"rooms", DUMP_ROOMS},
+ {"items", DUMP_ITEMS},
+ {"dictionary", DUMP_DICTIONARY},
+ {"word-pairs", DUMP_WORD_PAIRS},
+ {"actions", DUMP_ACTIONS},
+ {"functions", DUMP_FUNCTIONS},
+ {"replace-words", DUMP_REPLACE_WORDS},
+ {"header", DUMP_HEADER},
+ {"all", DUMP_ALL},
+};
+
+static void usage(const char *progname)
+{
+ int i;
+
+ printf("Usage %s [OPTION]... GAME_NAME GAME_DIR\n", progname);
+ printf("\nOptions:\n");
+ printf(" -d, --debug Enable debugging\n");
+ printf(" -D, --dump=OPTION Dump game data\n");
+ for (i = 0; i < ARRAY_SIZE(dump_options); i++)
+ printf(" %s\n", dump_options[i].option);
+ printf(" -p, --no-play Don't run the interpreter\n");
+ printf(" -g, --no-graphics Disable graphics\n");
+ printf(" -f, --no-floodfill Disable floodfill\n");
+ printf(" -w, --graphics-width=WIDTH Graphics width\n");
+ printf(" -h, --graphics-height=HEIGHT Graphics height\n");
+
+ printf("\nSupported games:\n");
+ for (i = 0; i < ARRAY_SIZE(comprehend_games); i++)
+ printf(" %-10s %s\n", comprehend_games[i]->short_name,
+ comprehend_games[i]->game_name);
+
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+ struct option long_opts[] = {
+ {"debug", no_argument, 0, 'd'},
+ {"dump", required_argument, 0, 'D'},
+ {"no-play", no_argument, 0, 'p'},
+ {"no-graphics", no_argument, 0, 'g'},
+ {"no-floodfill", no_argument, 0, 'f'},
+ {"graphics-width", required_argument, 0, 'w'},
+ {"graphics-height", required_argument, 0, 'h'},
+ {"help", no_argument, 0, '?'},
+ {NULL, 0, 0, 0},
+ };
+ const char *short_opts = "dD:pgfw:h:?";
+ struct comprehend_game *game;
+ const char *game_name, *game_dir;
+ unsigned dump_flags = 0;
+ int i, c, opt_index;
+ unsigned graphics_width = G_RENDER_WIDTH,
+ graphics_height = G_RENDER_HEIGHT;
+ bool play_game = true, graphics_enabled = true;
+
+ while (1) {
+ c = getopt_long(argc, argv, short_opts, long_opts, &opt_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'd':
+ // FIXME
+ debug_enable(DEBUG_FUNCTIONS);
+ break;
+
+ case 'D':
+ for (i = 0; i < ARRAY_SIZE(dump_options); i++)
+ if (strcmp(optarg, dump_options[i].option) == 0)
+ break;
+ if (i == ARRAY_SIZE(dump_options)) {
+ printf("Invalid dump option '%s'\n", optarg);
+ usage(argv[0]);
+ }
+
+ dump_flags |= dump_options[i].flag;
+ break;
+
+ case 'p':
+ play_game = false;
+ break;
+
+ case 'g':
+ graphics_enabled = false;
+ break;
+
+ case 'f':
+ image_set_draw_flags(IMAGEF_NO_FLOODFILL);
+ break;
+
+ case 'w':
+ graphics_width = strtoul(optarg, NULL, 0);
+ break;
+
+ case 'h':
+ graphics_height = strtoul(optarg, NULL, 0);
+ break;
+
+ case '?':
+ usage(argv[0]);
+ break;
+
+ default:
+ printf("Invalid option\n");
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind >= argc || argc - optind != 2)
+ usage(argv[0]);
+
+ game_name = argv[optind++];
+ game_dir = argv[optind++];
+
+ /* Lookup game */
+ game = NULL;
+ for (i = 0; i < ARRAY_SIZE(comprehend_games); i++) {
+ if (strcmp(game_name, comprehend_games[i]->short_name) == 0) {
+ game = comprehend_games[i];
+ break;
+ }
+ }
+ if (!game) {
+ printf("Unknown game '%s'\n", game_name);
+ usage(argv[0]);
+ }
+
+ if (graphics_enabled)
+ g_init(graphics_width, graphics_height);
+
+ game->info = xmalloc(sizeof(*game->info));
+ comprehend_load_game(game, game_dir);
+
+ if (dump_flags)
+ dump_game_data(game, dump_flags);
+
+ if (play_game)
+ comprehend_play_game(game);
+
+ exit(EXIT_SUCCESS);
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/recomprehend.h b/engines/glk/comprehend/recomprehend.h
new file mode 100644
index 0000000000..fd0fe31f80
--- /dev/null
+++ b/engines/glk/comprehend/recomprehend.h
@@ -0,0 +1,32 @@
+/* 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_COMPREHEND_RECOMPREHEND_H
+#define GLK_COMPREHEND_RECOMPREHEND_H
+
+namespace Glk {
+namespace Comprehend {
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/strings.cpp b/engines/glk/comprehend/strings.cpp
new file mode 100644
index 0000000000..9bae241f97
--- /dev/null
+++ b/engines/glk/comprehend/strings.cpp
@@ -0,0 +1,83 @@
+/* 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/comprehend/comprehend.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/strings.h"
+
+namespace Glk {
+namespace Comprehend {
+
+static char bad_string[128];
+
+const char *string_lookup(comprehend_game *game, uint16 index)
+{
+ uint16 string;
+ uint8 table;
+
+ /*
+ * There are two tables of strings. The first is stored in the main
+ * game data file, and the second is stored in multiple string files.
+ *
+ * In instructions string indexes are split into a table and index
+ * value. In other places such as the save files strings from the
+ * main table are occasionally just a straight 16-bit index. We
+ * convert all string indexes to the former case so that we can handle
+ * them the same everywhere.
+ */
+ table = (index >> 8) & 0xff;
+ string = index & 0xff;
+
+ switch (table) {
+ case 0x81:
+ case 0x01:
+ string += 0x100;
+ /* Fall-through */
+ case 0x00:
+ case 0x80:
+ if (string < game->info->strings.nr_strings)
+ return game->info->strings.strings[string];
+ break;
+
+ case 0x83:
+ string += 0x100;
+ /* Fall-through */
+ case 0x02:
+ case 0x82:
+ if (string < game->info->strings2.nr_strings)
+ return game->info->strings2.strings[string];
+ break;
+ }
+
+ snprintf(bad_string, sizeof(bad_string), "BAD_STRING(%.4x)", index);
+ return bad_string;
+}
+
+const char *instr_lookup_string(struct comprehend_game *game, uint8 index,
+ uint8 table)
+{
+ return string_lookup(game, table << 8 | index);
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/strings.h b/engines/glk/comprehend/strings.h
new file mode 100644
index 0000000000..b3994cc257
--- /dev/null
+++ b/engines/glk/comprehend/strings.h
@@ -0,0 +1,38 @@
+/* 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_COMPREHEND_STRINGS_H
+#define GLK_COMPREHEND_STRINGS_H
+
+namespace Glk {
+namespace Comprehend {
+
+struct comprehend_game;
+
+const char *string_lookup(struct comprehend_game *game, uint16 index);
+const char *instr_lookup_string(struct comprehend_game *game, uint8 index,
+ uint8 table);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/util.cpp b/engines/glk/comprehend/util.cpp
new file mode 100644
index 0000000000..5740b69215
--- /dev/null
+++ b/engines/glk/comprehend/util.cpp
@@ -0,0 +1,88 @@
+/* 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/comprehend/util.h"
+#include "common/debug.h"
+#include "common/str.h"
+#include "common/textconsole.h"
+
+namespace Glk {
+namespace Comprehend {
+
+static unsigned debug_flags;
+
+void __fatal_error(const char *func, unsigned line, const char *fmt, ...) {
+ error("TODO");
+}
+
+void fatal_strerror(int err, const char *fmt, ...) {
+ error("TODO");
+}
+
+void *xmalloc(size_t size) {
+ void *p;
+
+ p = malloc(size);
+ if (!p)
+ fatal_error("Out of memory");
+
+ memset(p, 0, size);
+ return p;
+}
+
+char *xstrndup(const char *str, size_t len) {
+ char *p;
+
+ Common::String s(str, len);
+ p = scumm_strdup(s.c_str());
+ if (!p)
+ fatal_error("Out of memory");
+ return p;
+}
+
+void debug_printf(unsigned flags, const char *fmt, ...) {
+ va_list args;
+
+ if (debug_flags & flags) {
+ va_start(args, fmt);
+ Common::String msg = Common::String(fmt, args);
+ va_end(args);
+
+ debug(1, "%s", msg.c_str());
+ }
+}
+
+void debug_enable(unsigned flags) {
+ debug_flags |= flags;
+}
+
+void debug_disable(unsigned flags) {
+ debug_flags &= ~flags;
+}
+
+bool debugging_enabled(void) {
+ // FIXME
+ return debug_flags;
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/util.h b/engines/glk/comprehend/util.h
new file mode 100644
index 0000000000..947317aa71
--- /dev/null
+++ b/engines/glk/comprehend/util.h
@@ -0,0 +1,51 @@
+/* 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_COMPREHEND_UTIL_H
+#define GLK_COMPREHEND_UTIL_H
+
+namespace Glk {
+namespace Comprehend {
+
+#define DEBUG_IMAGE_DRAW (1 << 0)
+#define DEBUG_GAME_STATE (1 << 1)
+#define DEBUG_FUNCTIONS (1 << 2)
+#define DEBUG_ALL (~0U)
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+#define fatal_error error
+
+void __fatal_error(const char *func, unsigned line, const char *fmt, ...);
+void fatal_strerror(int err, const char *fmt, ...);
+void *xmalloc(size_t size);
+char *xstrndup(const char *str, size_t size);
+
+void debug_printf(unsigned flags, const char *fmt, ...);
+void debug_enable(unsigned flags);
+void debug_disable(unsigned flags);
+bool debugging_enabled(void);
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index edffd13a06..d4fb6f873d 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -168,6 +168,21 @@ MODULE_OBJS := \
archetype/token.o \
comprehend/comprehend.o \
comprehend/detection.o \
+ comprehend/dictionary.o \
+ comprehend/dump_game_data.o \
+ comprehend/file_buf.o \
+ comprehend/game.o \
+ comprehend/game_cc.o \
+ comprehend/game_data.o \
+ comprehend/game_oo.o \
+ comprehend/game_tm.o \
+ comprehend/game_tr.o \
+ comprehend/graphics.o \
+ comprehend/image_data.o \
+ comprehend/image_view.o \
+ comprehend/opcode_map.o \
+ comprehend/strings.o \
+ comprehend/util.o \
frotz/bitmap_font.o \
frotz/config.o \
frotz/detection.o \
Commit: 8a9ef1a5a1eb9b2671bc4799d6c73d300db29c98
https://github.com/scummvm/scummvm/commit/8a9ef1a5a1eb9b2671bc4799d6c73d300db29c98
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:08-07:00
Commit Message:
GLK: COMPREHEND: Adding startup code, cleanup
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/dump_game_data.h
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index a353c2c5cd..5ba1aa14f1 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -22,6 +22,8 @@
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/dump_game_data.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/game_data.h"
#include "glk/quetzal.h"
#include "common/config-manager.h"
#include "common/translation.h"
@@ -31,18 +33,18 @@ namespace Comprehend {
Comprehend *g_comprehend;
-extern struct comprehend_game game_transylvania;
-extern struct comprehend_game game_crimson_crown_1;
-extern struct comprehend_game game_crimson_crown_2;
-extern struct comprehend_game game_oo_topos;
-extern struct comprehend_game game_talisman;
+extern comprehend_game game_transylvania;
+extern comprehend_game game_crimson_crown_1;
+extern comprehend_game game_crimson_crown_2;
+extern comprehend_game game_oo_topos;
+extern comprehend_game game_talisman;
-static struct comprehend_game *comprehend_games[] = {
+static comprehend_game *comprehend_games[] = {
&game_transylvania,
&game_crimson_crown_1,
&game_crimson_crown_2,
&game_oo_topos,
- &game_talisman,
+ &game_talisman
};
struct dump_option {
@@ -145,31 +147,6 @@ int main(int argc, char **argv) {
game_name = argv[optind++];
game_dir = argv[optind++];
-
- /* Lookup game */
- game = NULL;
- for (i = 0; i < ARRAY_SIZE(comprehend_games); i++) {
- if (strcmp(game_name, comprehend_games[i]->short_name) == 0) {
- game = comprehend_games[i];
- break;
- }
- }
- if (!game) {
- printf("Unknown game '%s'\n", game_name);
- usage(argv[0]);
- }
-
- if (graphics_enabled)
- g_init(graphics_width, graphics_height);
-
- game->info = xmalloc(sizeof(*game->info));
- comprehend_load_game(game, game_dir);
-
- if (dump_flags)
- dump_game_data(game, dump_flags);
-
- if (play_game)
- comprehend_play_game(game);
}
#endif
@@ -184,7 +161,28 @@ Comprehend::~Comprehend() {
void Comprehend::runGame() {
initialize();
- #ifdef TODO
+
+ // Lookup game
+ Common::String filename = getFilename();
+ comprehend_game *game = NULL;
+ for (uint i = 0; i < 5; ++i) {
+ if (filename.equalsIgnoreCase(comprehend_games[i]->short_name) == 0) {
+ game = comprehend_games[i];
+ break;
+ }
+ }
+ assert(game);
+
+ game->info = (game_info *)malloc(sizeof(*game->info));
+ comprehend_load_game(game, nullptr);
+
+ comprehend_play_game(game);
+}
+
+void Comprehend::initialize() {
+
+
+#ifdef TODO
_bottomWindow = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
if (_bottomWindow == nullptr) {
glk_exit();
@@ -194,8 +192,5 @@ void Comprehend::runGame() {
#endif
}
-void Comprehend::initialize() {
-}
-
} // End of namespace Comprehend
} // End of namespace Glk
diff --git a/engines/glk/comprehend/dump_game_data.h b/engines/glk/comprehend/dump_game_data.h
index dbcaf52022..361a47f969 100644
--- a/engines/glk/comprehend/dump_game_data.h
+++ b/engines/glk/comprehend/dump_game_data.h
@@ -40,7 +40,7 @@ struct instruction;
#define DUMP_FUNCTIONS (1 << 7)
#define DUMP_REPLACE_WORDS (1 << 8)
#define DUMP_HEADER (1 << 9)
-#define DUMP_ALL (~0)
+#define DUMP_ALL (~0U)
void dump_instruction(struct comprehend_game *game,
struct function_state *func_state,
Commit: 2ecbd720ea93345adcfc64f8866b2e45dce95e77
https://github.com/scummvm/scummvm/commit/2ecbd720ea93345adcfc64f8866b2e45dce95e77
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:08-07:00
Commit Message:
GLK: COMPREHEND: Work on startup
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tm.cpp
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 5ba1aa14f1..cdf52a95db 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -21,12 +21,12 @@
*/
#include "glk/comprehend/comprehend.h"
+#include "common/config-manager.h"
+#include "common/translation.h"
#include "glk/comprehend/dump_game_data.h"
#include "glk/comprehend/game.h"
#include "glk/comprehend/game_data.h"
#include "glk/quetzal.h"
-#include "common/config-manager.h"
-#include "common/translation.h"
namespace Glk {
namespace Comprehend {
@@ -44,8 +44,7 @@ static comprehend_game *comprehend_games[] = {
&game_crimson_crown_1,
&game_crimson_crown_2,
&game_oo_topos,
- &game_talisman
-};
+ &game_talisman};
struct dump_option {
const char *const option;
@@ -151,7 +150,7 @@ int main(int argc, char **argv) {
#endif
Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
- _saveSlot(-1) {
+ _saveSlot(-1) {
g_comprehend = this;
}
@@ -174,22 +173,23 @@ void Comprehend::runGame() {
assert(game);
game->info = (game_info *)malloc(sizeof(*game->info));
- comprehend_load_game(game, nullptr);
+ comprehend_load_game(game);
comprehend_play_game(game);
+
+ deinitialize();
}
void Comprehend::initialize() {
+ _textBufferWindow = (TextBufferWindow *)glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
+ _graphicsWindow = (GraphicsWindow *)glk_window_open(
+ _textBufferWindow, winmethod_Above | winmethod_Proportional,
+ 160, wintype_Graphics, 0);
+}
-
-#ifdef TODO
- _bottomWindow = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
- if (_bottomWindow == nullptr) {
- glk_exit();
- return;
- }
- glk_set_window(_bottomWindow);
-#endif
+void Comprehend::deinitialize() {
+ glk_window_close(_graphicsWindow);
+ glk_window_close(_textBufferWindow);
}
} // End of namespace Comprehend
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index f890dd5c80..045412137a 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -25,6 +25,8 @@
#include "common/scummsys.h"
#include "glk/glk_api.h"
+#include "glk/window_graphics.h"
+#include "glk/window_text_buffer.h"
namespace Glk {
namespace Comprehend {
@@ -68,11 +70,19 @@ struct game_ops {
class Comprehend : public GlkAPI {
private:
int _saveSlot; ///< Save slot when loading savegame from launcher
+public:
+ GraphicsWindow *_graphicsWindow;
+ TextBufferWindow *_textBufferWindow;
private:
/**
* Initialization code
*/
void initialize();
+
+ /**
+ * Deinitialization
+ */
+ void deinitialize();
public:
/**
* Constructor
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 8dd1b9d789..8291e7dd27 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -165,7 +165,7 @@ struct item *get_item(comprehend_game *game, uint16 index) {
}
void game_save(comprehend_game *game) {
- char path[PATH_MAX], filename[32];
+ char filename[32];
int c;
console_println(game, game->info->strings.strings[STRING_SAVE_GAME]);
@@ -181,12 +181,11 @@ void game_save(comprehend_game *game) {
}
snprintf(filename, sizeof(filename), game->save_game_file_fmt, c - '0');
- snprintf(path, sizeof(path), "%s%s", game->game_dir, filename);
- comprehend_save_game(game, path);
+ comprehend_save_game(game, filename);
}
void game_restore(comprehend_game *game) {
- char path[PATH_MAX], filename[32];
+ char filename[32];
int c;
console_println(game, game->info->strings.strings[STRING_RESTORE_GAME]);
@@ -202,8 +201,7 @@ void game_restore(comprehend_game *game) {
}
snprintf(filename, sizeof(filename), game->save_game_file_fmt, c - '0');
- snprintf(path, sizeof(path), "%s%s", game->game_dir, filename);
- comprehend_restore_game(game, path);
+ comprehend_restore_game(game, filename);
game->info->update_flags = UPDATE_ALL;
}
@@ -212,7 +210,7 @@ void game_restart(comprehend_game *game) {
console_println(game, string_lookup(game, game->strings->game_restart));
console_get_key();
- comprehend_load_game(game, game->game_dir);
+ comprehend_load_game(game);
game->info->update_flags = UPDATE_ALL;
}
@@ -1013,6 +1011,7 @@ static void skip_non_whitespace(char **p) {
(*p)++;
}
+#ifdef TODO
static void handle_debug_command(comprehend_game *game,
const char *line) {
int i;
@@ -1052,6 +1051,7 @@ static void handle_debug_command(comprehend_game *game,
printf("\n");
}
}
+#endif
static bool handle_sentence(comprehend_game *game,
struct sentence *sentence) {
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 627f7c925b..026f4c9ad5 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -44,8 +44,6 @@ struct comprehend_game {
const char *game_name;
const char *short_name;
- const char *game_dir;
-
const char *game_data_file;
struct string_file string_files[MAX_FILES];
const char *location_graphic_files[MAX_FILES];
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index 070dbf9c88..208d77be19 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -138,7 +138,6 @@ static struct game_ops cc2_ops = {
struct comprehend_game game_crimson_crown_1 = {
"Crimson Crown (Part 1/2)",
"cc1",
- nullptr,
"CC1.GDA",
{ {"MA.MS1", 0x89} },
{"RA.MS1", "RB.MS1", "RC.MS1"},
@@ -153,7 +152,6 @@ struct comprehend_game game_crimson_crown_1 = {
struct comprehend_game game_crimson_crown_2 = {
"Crimson Crown (Part 2/2)",
"cc2",
- nullptr,
"CC2.GDA",
{ {"MA.MS2", 0x89} },
{"RA.MS2", "RB.MS2"},
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 70125ff369..c06b2813c8 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -821,16 +821,12 @@ static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
8;
}
-static void load_extra_string_file(struct comprehend_game *game,
- const char *dirname,
- struct string_file *string_file) {
- char filename[PATH_MAX];
+static void load_extra_string_file(comprehend_game *game,
+ string_file *string_file) {
struct file_buf fb;
unsigned end;
- snprintf(filename, sizeof(filename), "%s/%s", dirname,
- string_file->filename);
- file_buf_map(filename, &fb);
+ file_buf_map(string_file->filename, &fb);
if (string_file->end_offset)
end = string_file->end_offset;
@@ -843,8 +839,7 @@ static void load_extra_string_file(struct comprehend_game *game,
file_buf_unmap(&fb);
}
-static void load_extra_string_files(struct comprehend_game *game,
- const char *dirname) {
+static void load_extra_string_files(comprehend_game *game) {
int i;
memset(&game->info->strings2, 0, sizeof(game->info->strings2));
@@ -858,20 +853,15 @@ static void load_extra_string_files(struct comprehend_game *game,
if (game->info->strings2.nr_strings == 0)
game->info->strings2.nr_strings++;
- load_extra_string_file(game, dirname, &game->string_files[i]);
+ load_extra_string_file(game, &game->string_files[i]);
}
}
-static void load_game_data(struct comprehend_game *game, const char *dirname) {
- char data_file[PATH_MAX];
+static void load_game_data(struct comprehend_game *game) {
struct file_buf fb;
- snprintf(data_file, sizeof(data_file), "%s/%s",
- dirname, game->game_data_file);
-
memset(game->info, 0, sizeof(*game->info));
-
- file_buf_map(data_file, &fb);
+ file_buf_map(game->game_data_file, &fb);
parse_header(game, &fb);
parse_rooms(game, &fb);
@@ -882,7 +872,7 @@ static void load_game_data(struct comprehend_game *game, const char *dirname) {
parse_string_table(&fb, game->info->header.addr_strings,
game->info->header.addr_strings_end,
&game->info->strings);
- load_extra_string_files(game, dirname);
+ load_extra_string_files(game);
parse_vm(game, &fb);
parse_action_table(game, &fb);
parse_replace_words(game, &fb);
@@ -890,14 +880,12 @@ static void load_game_data(struct comprehend_game *game, const char *dirname) {
file_buf_unmap(&fb);
}
-void comprehend_load_game(struct comprehend_game *game, const char *dirname) {
- game->game_dir = dirname;
-
+void comprehend_load_game(struct comprehend_game *game) {
/* Load the main game data file */
- load_game_data(game, dirname);
+ load_game_data(game);
if (g_enabled()) {
- comprehend_load_images(game, dirname);
+ comprehend_load_images(game);
if (game->color_table)
g_set_color_table(game->color_table);
}
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 2892bd29c7..42aac38dc4 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -307,7 +307,7 @@ enum {
#define WORD_TYPE_NOUN_MASK (WORD_TYPE_FEMALE | WORD_TYPE_MALE | \
WORD_TYPE_NOUN | WORD_TYPE_NOUN_PLURAL)
-void comprehend_load_game(struct comprehend_game *game, const char *dirname);
+void comprehend_load_game(struct comprehend_game *game);
void comprehend_restore_game(struct comprehend_game *game,
const char *filename);
void comprehend_save_game(struct comprehend_game *game, const char *filename);
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index d1d524c116..d04c9fc2d9 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -126,7 +126,6 @@ static struct game_ops oo_ops = {
struct comprehend_game game_oo_topos = {
"Oo-Topos",
"oo",
- nullptr,
"G0",
{
// Extra strings are (annoyingly) stored in the game binary
diff --git a/engines/glk/comprehend/game_tm.cpp b/engines/glk/comprehend/game_tm.cpp
index 1b8b54690a..dc5ae64a9d 100644
--- a/engines/glk/comprehend/game_tm.cpp
+++ b/engines/glk/comprehend/game_tm.cpp
@@ -33,7 +33,6 @@ static struct game_ops tm_ops = {};
struct comprehend_game game_talisman = {
"Talisman, Challenging the Sands of Time (broken)",
"tm",
- nullptr,
"G0",
{},
{"RA", "RB", "RC", "RD", "RE", "RF", "RG"},
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index fc8ad72943..84ea764848 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -201,7 +201,6 @@ static struct game_ops tr_ops = {
struct comprehend_game game_transylvania = {
"Transylvania",
"tr",
- nullptr,
"TR.GDA",
{
{"MA.MS1", 0x88},
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 21cfa44db1..3407a55b6e 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -324,10 +324,9 @@ static void load_image_file(struct image_data *info, const char *filename,
}
}
-static void load_image_files(struct image_data *info, const char *game_dir,
+static void load_image_files(struct image_data *info,
const char **filenames, size_t nr_files)
{
- char path[256];
uint i;
memset(info, 0, sizeof(*info));
@@ -337,8 +336,7 @@ static void load_image_files(struct image_data *info, const char *game_dir,
info->image_offsets = (uint16 *)xmalloc(info->nr_images * sizeof(uint16));
for (i = 0; i < nr_files; i++) {
- snprintf(path, sizeof(path), "%s/%s", game_dir, filenames[i]);
- load_image_file(info, path, i);
+ load_image_file(info, filenames[i], i);
}
}
@@ -351,31 +349,12 @@ static size_t graphic_array_count(const char **filenames, size_t max)
return count;
}
-static void split_path(const char *filename, char **dir, char **base)
-{
- const char *p;
-
- p = strrchr(filename, '/');
- if (!p) {
- *base = xstrndup(filename, strlen(filename));
- *dir = xstrndup(".", 1);
- } else {
- *base = xstrndup(p, strlen(p));
- *dir = xstrndup(filename, p - filename);
- }
-}
-
void comprehend_load_image_file(const char *filename, struct image_data *info)
{
- char *dir, *base;
-
- split_path(filename, &dir, &base);
- load_image_files(info, dir, (const char **)&base, 1);
- free(dir);
- free(base);
+ load_image_files(info, (const char **)&filename, 1);
}
-void comprehend_load_images(comprehend_game *game, const char *game_dir)
+void comprehend_load_images(comprehend_game *game)
{
size_t nr_item_files, nr_room_files;
@@ -386,10 +365,10 @@ void comprehend_load_images(comprehend_game *game, const char *game_dir)
graphic_array_count(game->item_graphic_files,
ARRAY_SIZE(game->item_graphic_files));
- load_image_files(&game->info->room_images, game_dir,
+ load_image_files(&game->info->room_images,
game->location_graphic_files, nr_room_files);
- load_image_files(&game->info->item_images, game_dir,
+ load_image_files(&game->info->item_images,
game->item_graphic_files, nr_item_files);
}
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index 796e81333e..e85313eaf4 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -91,7 +91,7 @@ void draw_image(image_data *info, unsigned index);
void draw_location_image(image_data *info, unsigned index);
void comprehend_load_image_file(const char *filename, image_data *info);
-void comprehend_load_images(comprehend_game *game, const char *game_dir);
+void comprehend_load_images(comprehend_game *game);
} // namespace Comprehend
} // namespace Glk
Commit: 10aa0e48fead7caf43b612537c789d6650c08337
https://github.com/scummvm/scummvm/commit/10aa0e48fead7caf43b612537c789d6650c08337
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:08-07:00
Commit Message:
GLK: COMPREHEND: Cleaning up some structure dependencies
Changed paths:
engines/glk/comprehend/dictionary.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_data.h
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
engines/glk/comprehend/opcode_map.cpp
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
index 584d2d4f77..a25f91f240 100644
--- a/engines/glk/comprehend/dictionary.cpp
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -21,6 +21,7 @@
*/
#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/game.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/dictionary.h"
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 026f4c9ad5..b8d78d5371 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -23,6 +23,7 @@
#ifndef GLK_COMPREHEND_GAME_H
#define GLK_COMPREHEND_GAME_H
+#include "glk/comprehend/game_data.h"
#include "common/scummsys.h"
namespace Glk {
@@ -30,16 +31,6 @@ namespace Comprehend {
#define MAX_FILES 10
-struct function;
-struct item;
-struct word;
-
-struct string_file {
- const char *filename;
- uint32 base_offset;
- uint32 end_offset;
-};
-
struct comprehend_game {
const char *game_name;
const char *short_name;
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 42aac38dc4..6890f6fe74 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -185,6 +185,12 @@ struct game_info {
unsigned update_flags;
};
+struct string_file {
+ const char *filename;
+ uint32 base_offset;
+ uint32 end_offset;
+};
+
enum {
OPCODE_UNKNOWN,
OPCODE_TEST_FALSE,
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 3407a55b6e..4059b6ea89 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -22,6 +22,7 @@
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/file_buf.h"
+#include "glk/comprehend/game.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/image_data.h"
#include "glk/comprehend/graphics.h"
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index e85313eaf4..9a2c1882c1 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -23,12 +23,12 @@
#ifndef GLK_COMPREHEND_IMAGE_DATA_H
#define GLK_COMPREHEND_IMAGE_DATA_H
-#include "glk/comprehend/game.h"
#include "common/scummsys.h"
namespace Glk {
namespace Comprehend {
+struct comprehend_game;
struct file_buf;
struct image_data {
diff --git a/engines/glk/comprehend/opcode_map.cpp b/engines/glk/comprehend/opcode_map.cpp
index f3a2eccce1..30d1932a70 100644
--- a/engines/glk/comprehend/opcode_map.cpp
+++ b/engines/glk/comprehend/opcode_map.cpp
@@ -21,6 +21,7 @@
*/
#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/game.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/util.h"
Commit: 20533b4a1adc37eb33c6f4dd459a99df2cb73145
https://github.com/scummvm/scummvm/commit/20533b4a1adc37eb33c6f4dd459a99df2cb73145
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:08-07:00
Commit Message:
GLK: COMPREHEND: Start of sub-classes for each different game
Changed paths:
A engines/glk/comprehend/game_cc.h
A engines/glk/comprehend/game_oo.h
A engines/glk/comprehend/game_tm.h
A engines/glk/comprehend/game_tr.h
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/detection_tables.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tm.cpp
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/image_data.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index cdf52a95db..cf1eb2933d 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -25,7 +25,11 @@
#include "common/translation.h"
#include "glk/comprehend/dump_game_data.h"
#include "glk/comprehend/game.h"
+#include "glk/comprehend/game_cc.h"
#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/game_oo.h"
+#include "glk/comprehend/game_tm.h"
+#include "glk/comprehend/game_tr.h"
#include "glk/quetzal.h"
namespace Glk {
@@ -33,19 +37,6 @@ namespace Comprehend {
Comprehend *g_comprehend;
-extern comprehend_game game_transylvania;
-extern comprehend_game game_crimson_crown_1;
-extern comprehend_game game_crimson_crown_2;
-extern comprehend_game game_oo_topos;
-extern comprehend_game game_talisman;
-
-static comprehend_game *comprehend_games[] = {
- &game_transylvania,
- &game_crimson_crown_1,
- &game_crimson_crown_2,
- &game_oo_topos,
- &game_talisman};
-
struct dump_option {
const char *const option;
unsigned flag;
@@ -162,19 +153,9 @@ void Comprehend::runGame() {
initialize();
// Lookup game
- Common::String filename = getFilename();
- comprehend_game *game = NULL;
- for (uint i = 0; i < 5; ++i) {
- if (filename.equalsIgnoreCase(comprehend_games[i]->short_name) == 0) {
- game = comprehend_games[i];
- break;
- }
- }
- assert(game);
+ comprehend_game *game = createGame();
- game->info = (game_info *)malloc(sizeof(*game->info));
comprehend_load_game(game);
-
comprehend_play_game(game);
deinitialize();
@@ -192,5 +173,18 @@ void Comprehend::deinitialize() {
glk_window_close(_textBufferWindow);
}
-} // End of namespace Comprehend
-} // End of namespace Glk
+comprehend_game *Comprehend::createGame() {
+ if (_gameDescription._gameId == "crimsoncrown")
+ return new CrimsonCrownGame();
+ if (_gameDescription._gameId == "ootopis")
+ return new OOToposGame();
+ if (_gameDescription._gameId == "talisman")
+ return new OOToposGame();
+ if (_gameDescription._gameId == "transylvania")
+ return new TransylvaniaGame();
+
+ error("Unknown game");
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 045412137a..351ccef491 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -83,6 +83,9 @@ private:
* Deinitialization
*/
void deinitialize();
+
+ comprehend_game *createGame();
+
public:
/**
* Constructor
diff --git a/engines/glk/comprehend/detection_tables.h b/engines/glk/comprehend/detection_tables.h
index aa8185eeef..cd884b90b7 100644
--- a/engines/glk/comprehend/detection_tables.h
+++ b/engines/glk/comprehend/detection_tables.h
@@ -29,9 +29,11 @@ namespace Comprehend {
const PlainGameDescriptor COMPREHEND_GAME_LIST[] = {
{"crimsoncrown", "Crimson Crown"},
+ {"ootopis", "OO-Topos"},
{"transylvania", "Transylvania"},
-
- {nullptr, nullptr}};
+ {"talisman", "Talisman"},
+ {nullptr, nullptr}
+};
struct ComprehendDetectionEntry {
const char *const _gameId;
@@ -44,8 +46,7 @@ const ComprehendDetectionEntry COMPREHEND_GAMES[] = {
{"crimsoncrown", "cc1.gda", "f2abf019675ac5c9bcfd81032bc7787b"},
{"transylvania", "tr.gda", "22e08633eea02ceee49b909dfd982d22"},
- {nullptr, nullptr, nullptr}
-};
+ {nullptr, nullptr, nullptr}};
} // End of namespace Comprehend
} // End of namespace Glk
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 8291e7dd27..4cd28e9b20 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -43,6 +43,20 @@ struct winsize {
};
static struct winsize console_winsize;
+comprehend_game::comprehend_game() : game_name(nullptr),
+ short_name(nullptr),
+ game_data_file(nullptr),
+ save_game_file_fmt(nullptr),
+ color_table(0),
+ strings(nullptr),
+ ops(nullptr) {
+ info = (game_info *)malloc(sizeof(*info));
+}
+
+comprehend_game::~comprehend_game() {
+ free(info);
+}
+
static void console_init(void) {
// ioctl(STDOUT_FILENO, TIOCGWINSZ, &console_winsize);
}
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index b8d78d5371..cfd5133666 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -24,21 +24,20 @@
#define GLK_COMPREHEND_GAME_H
#include "glk/comprehend/game_data.h"
-#include "common/scummsys.h"
+#include "common/array.h"
namespace Glk {
namespace Comprehend {
-#define MAX_FILES 10
-
struct comprehend_game {
+public:
const char *game_name;
const char *short_name;
const char *game_data_file;
- struct string_file string_files[MAX_FILES];
- const char *location_graphic_files[MAX_FILES];
- const char *item_graphic_files[MAX_FILES];
+ Common::Array<string_file> string_files;
+ Common::Array <const char *> location_graphic_files;
+ Common::Array <const char *> item_graphic_files;
const char *save_game_file_fmt;
unsigned color_table;
@@ -46,6 +45,10 @@ struct comprehend_game {
struct game_ops *ops;
struct game_info *info;
+
+public:
+ comprehend_game();
+ ~comprehend_game();
};
void console_println(struct comprehend_game *game, const char *text);
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index 208d77be19..bed5603cce 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -20,23 +20,72 @@
*
*/
+#include "glk/comprehend/game_cc.h"
#include "glk/comprehend/comprehend.h"
-#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/game.h"
namespace Glk {
namespace Comprehend {
-static void cc_clear_companion_flags(struct comprehend_game *game)
-{
+static struct game_strings cc1_strings = {0x9};
+
+static struct game_ops cc1_ops = {
+ nullptr,
+ CrimsonCrownGame::cc1_before_prompt,
+ nullptr,
+ nullptr,
+ nullptr,
+ CrimsonCrownGame::cc1_handle_special_opcode};
+
+#ifdef TODO
+static struct game_ops cc2_ops = {
+ nullptr,
+ cc2_before_prompt,
+ nullptr,
+ nullptr,
+ nullptr,
+ cc2_handle_special_opcode};
+#endif
+
+CrimsonCrownGame::CrimsonCrownGame() : comprehend_game() {
+ game_name = "Crimson Crown";
+ short_name = "cc1";
+ game_data_file = "cc1.gda";
+
+ string_files.push_back(string_file("ma.ms1", 0x89));
+ location_graphic_files.push_back("RA.MS1");
+ location_graphic_files.push_back("RB.MS1");
+ location_graphic_files.push_back("RC.MS1");
+ item_graphic_files.push_back("OA.MS1");
+ item_graphic_files.push_back("OB.MS1");
+
+ save_game_file_fmt = "G%d.MS0";
+ strings = &cc1_strings;
+ ops = &cc1_ops;
+}
+
+#ifdef TODO
+struct comprehend_game game_crimson_crown_2 = {
+ "Crimson Crown (Part 2/2)",
+ "cc2",
+ "CC2.GDA",
+ {{"MA.MS2", 0x89}},
+ {"RA.MS2", "RB.MS2"},
+ {"OA.MS2", "OB.MS2"},
+ "G%d.MS0",
+ 0,
+ nullptr,
+ &cc2_ops,
+ nullptr};
+#endif
+
+static void cc_clear_companion_flags(struct comprehend_game *game) {
/* Clear the Sabrina/Erik action flags */
game->info->flags[0xa] = 0;
game->info->flags[0xb] = 0;
}
static bool cc_common_handle_special_opcode(struct comprehend_game *game,
- uint8 operand)
-{
+ uint8 operand) {
switch (operand) {
case 0x03:
/*
@@ -64,9 +113,8 @@ static bool cc_common_handle_special_opcode(struct comprehend_game *game,
return false;
}
-static void cc1_handle_special_opcode(struct comprehend_game *game,
- uint8 operand)
-{
+void CrimsonCrownGame::cc1_handle_special_opcode(comprehend_game *game,
+ uint8 operand) {
if (cc_common_handle_special_opcode(game, operand))
return;
@@ -83,8 +131,7 @@ static void cc1_handle_special_opcode(struct comprehend_game *game,
}
static void cc2_handle_special_opcode(struct comprehend_game *game,
- uint8 operand)
-{
+ uint8 operand) {
if (cc_common_handle_special_opcode(game, operand))
return;
@@ -105,63 +152,13 @@ static void cc2_handle_special_opcode(struct comprehend_game *game,
}
}
-static void cc2_before_prompt(struct comprehend_game *game)
-{
+static void cc2_before_prompt(struct comprehend_game *game) {
cc_clear_companion_flags(game);
}
-static void cc1_before_prompt(struct comprehend_game *game)
-{
+void CrimsonCrownGame::cc1_before_prompt(comprehend_game *game) {
cc_clear_companion_flags(game);
}
-static struct game_strings cc1_strings = { 0x9 };
-
-static struct game_ops cc1_ops = {
- nullptr,
- cc1_before_prompt,
- nullptr,
- nullptr,
- nullptr,
- cc1_handle_special_opcode
-};
-
-static struct game_ops cc2_ops = {
- nullptr,
- cc2_before_prompt,
- nullptr,
- nullptr,
- nullptr,
- cc2_handle_special_opcode
-};
-
-struct comprehend_game game_crimson_crown_1 = {
- "Crimson Crown (Part 1/2)",
- "cc1",
- "CC1.GDA",
- { {"MA.MS1", 0x89} },
- {"RA.MS1", "RB.MS1", "RC.MS1"},
- {"OA.MS1", "OB.MS1"},
- "G%d.MS0",
- 0,
- &cc1_strings,
- &cc1_ops,
- nullptr
-};
-
-struct comprehend_game game_crimson_crown_2 = {
- "Crimson Crown (Part 2/2)",
- "cc2",
- "CC2.GDA",
- { {"MA.MS2", 0x89} },
- {"RA.MS2", "RB.MS2"},
- {"OA.MS2", "OB.MS2"},
- "G%d.MS0",
- 0,
- nullptr,
- &cc2_ops,
- nullptr
-};
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_cc.h b/engines/glk/comprehend/game_cc.h
new file mode 100644
index 0000000000..00ba334b5a
--- /dev/null
+++ b/engines/glk/comprehend/game_cc.h
@@ -0,0 +1,44 @@
+/* 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_COMPREHEND_GAME_CC_H
+#define GLK_COMPREHEND_GAME_CC_H
+
+#include "glk/comprehend/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class CrimsonCrownGame : public comprehend_game {
+public:
+ CrimsonCrownGame();
+
+public:
+ static void cc1_before_prompt(comprehend_game *game);
+ static void cc1_handle_special_opcode(comprehend_game *game,
+ uint8 operand);
+};
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 6890f6fe74..d48b6f68fe 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -28,8 +28,8 @@
namespace Glk {
namespace Comprehend {
-#define MAX_FLAGS 64
-#define MAX_VARIABLES 128
+#define MAX_FLAGS 64
+#define MAX_VARIABLES 128
enum {
DIRECTION_NORTH,
@@ -44,151 +44,156 @@ enum {
};
struct function_state {
- bool test_result;
- bool else_result;
- unsigned or_count;
- bool _and;
- bool in_command;
- bool executed;
+ bool test_result;
+ bool else_result;
+ unsigned or_count;
+ bool _and;
+ bool in_command;
+ bool executed;
};
struct room {
- uint8 direction[NR_DIRECTIONS];
- uint8 flags;
- uint8 graphic;
- uint16 string_desc;
+ uint8 direction[NR_DIRECTIONS];
+ uint8 flags;
+ uint8 graphic;
+ uint16 string_desc;
};
struct item {
- uint16 string_desc;
- uint16 long_string; /* Only used by version 2 */
- uint8 room;
- uint8 flags;
- uint8 word;
- uint8 graphic;
+ uint16 string_desc;
+ uint16 long_string; /* Only used by version 2 */
+ uint8 room;
+ uint8 flags;
+ uint8 word;
+ uint8 graphic;
};
struct word {
- char word[7];
- uint8 index;
- uint8 type;
+ char word[7];
+ uint8 index;
+ uint8 type;
};
struct word_index {
- uint8 index;
- uint8 type;
+ uint8 index;
+ uint8 type;
};
struct word_map {
/* <word[0]>, <word[1]> == <word[2]> */
- struct word_index word[3];
- uint8 flags;
+ struct word_index word[3];
+ uint8 flags;
};
struct action {
- int type;
- size_t nr_words;
+ int type;
+ size_t nr_words;
// FIXME - use struct word_index here.
- uint8 word[4];
- uint8 word_type[4];
- uint16 function;
+ uint8 word[4];
+ uint8 word_type[4];
+ uint16 function;
};
struct instruction {
- uint8 opcode;
- size_t nr_operands;
- uint8 operand[3];
- bool is_command;
+ uint8 opcode;
+ size_t nr_operands;
+ uint8 operand[3];
+ bool is_command;
};
struct function {
- struct instruction instructions[0x100];
- size_t nr_instructions;
+ struct instruction instructions[0x100];
+ size_t nr_instructions;
};
struct string_table {
- char *strings[0xffff];
- size_t nr_strings;
+ char *strings[0xffff];
+ size_t nr_strings;
};
struct game_header {
- uint16 magic;
-
- uint16 room_desc_table;
- uint16 room_direction_table[NR_DIRECTIONS];
- uint16 room_flags_table;
- uint16 room_graphics_table;
-
- size_t nr_items;
- uint16 addr_item_locations;
- uint16 addr_item_flags;
- uint16 addr_item_word;
- uint16 addr_item_strings;
- uint16 addr_item_graphics;
-
- uint16 addr_dictionary;
- uint16 addr_word_map;
-
- uint16 addr_strings;
- uint16 addr_strings_end;
-
- uint16 addr_actions_vvnn;
- uint16 addr_actions_unknown;
- uint16 addr_actions_vnjn;
- uint16 addr_actions_vjn;
- uint16 addr_actions_vdn;
- uint16 addr_actions_vnn;
- uint16 addr_actions_vn;
- uint16 addr_actions_v;
-
- uint16 addr_vm; // FIXME - functions
+ uint16 magic;
+
+ uint16 room_desc_table;
+ uint16 room_direction_table[NR_DIRECTIONS];
+ uint16 room_flags_table;
+ uint16 room_graphics_table;
+
+ size_t nr_items;
+ uint16 addr_item_locations;
+ uint16 addr_item_flags;
+ uint16 addr_item_word;
+ uint16 addr_item_strings;
+ uint16 addr_item_graphics;
+
+ uint16 addr_dictionary;
+ uint16 addr_word_map;
+
+ uint16 addr_strings;
+ uint16 addr_strings_end;
+
+ uint16 addr_actions_vvnn;
+ uint16 addr_actions_unknown;
+ uint16 addr_actions_vnjn;
+ uint16 addr_actions_vjn;
+ uint16 addr_actions_vdn;
+ uint16 addr_actions_vnn;
+ uint16 addr_actions_vn;
+ uint16 addr_actions_v;
+
+ uint16 addr_vm; // FIXME - functions
};
struct game_info {
- struct game_header header;
+ struct game_header header;
- unsigned comprehend_version;
+ unsigned comprehend_version;
- uint8 start_room;
+ uint8 start_room;
- struct room rooms[0x100];
- size_t nr_rooms;
- uint8 current_room;
+ struct room rooms[0x100];
+ size_t nr_rooms;
+ uint8 current_room;
- struct item item[0xff];
+ struct item item[0xff];
- struct word *words;
- size_t nr_words;
+ struct word *words;
+ size_t nr_words;
- struct word_map word_map[0xff];
- size_t nr_word_maps;
+ struct word_map word_map[0xff];
+ size_t nr_word_maps;
- struct string_table strings;
- struct string_table strings2;
+ struct string_table strings;
+ struct string_table strings2;
- struct action action[0xffff];
- size_t nr_actions;
+ struct action action[0xffff];
+ size_t nr_actions;
- struct function functions[0xffff];
- size_t nr_functions;
+ struct function functions[0xffff];
+ size_t nr_functions;
- struct image_data room_images;
- struct image_data item_images;
+ struct image_data room_images;
+ struct image_data item_images;
- bool flags[MAX_FLAGS];
- uint16 variable[MAX_VARIABLES];
+ bool flags[MAX_FLAGS];
+ uint16 variable[MAX_VARIABLES];
- char *replace_words[256];
- size_t nr_replace_words;
+ char *replace_words[256];
+ size_t nr_replace_words;
- uint8 current_replace_word;
- unsigned update_flags;
+ uint8 current_replace_word;
+ unsigned update_flags;
};
struct string_file {
const char *filename;
uint32 base_offset;
uint32 end_offset;
+
+ string_file() : filename(nullptr), base_offset(0), end_offset(0) {}
+ string_file(const char *fname, uint32 baseOfs, uint32 endO = 0) :
+ filename(fname), base_offset(baseOfs), end_offset(endO) {
+ }
};
enum {
@@ -263,11 +268,11 @@ enum {
};
/* Game state update flags */
-#define UPDATE_GRAPHICS (1 << 0) /* Implies UPDATE_GRAPHICS_ITEMS */
-#define UPDATE_GRAPHICS_ITEMS (1 << 1)
-#define UPDATE_ROOM_DESC (1 << 2)
-#define UPDATE_ITEM_LIST (1 << 3)
-#define UPDATE_ALL (~0U)
+#define UPDATE_GRAPHICS (1 << 0) /* Implies UPDATE_GRAPHICS_ITEMS */
+#define UPDATE_GRAPHICS_ITEMS (1 << 1)
+#define UPDATE_ROOM_DESC (1 << 2)
+#define UPDATE_ITEM_LIST (1 << 3)
+#define UPDATE_ALL (~0U)
/* Action types */
enum {
@@ -281,41 +286,41 @@ enum {
};
/* Standard strings (main string table) */
-#define STRING_CANT_GO 0
-#define STRING_DONT_UNDERSTAND 1
-#define STRING_YOU_SEE 2
-#define STRING_INVENTORY 3
-#define STRING_INVENTORY_EMPTY 4
-#define STRING_BEFORE_CONTINUE 5
-#define STRING_SAVE_GAME 6
-#define STRING_RESTORE_GAME 7
+#define STRING_CANT_GO 0
+#define STRING_DONT_UNDERSTAND 1
+#define STRING_YOU_SEE 2
+#define STRING_INVENTORY 3
+#define STRING_INVENTORY_EMPTY 4
+#define STRING_BEFORE_CONTINUE 5
+#define STRING_SAVE_GAME 6
+#define STRING_RESTORE_GAME 7
/* Special variables */
-#define VAR_INVENTORY_WEIGHT 0
-#define VAR_INVENTORY_LIMIT 1
-#define VAR_TURN_COUNT 2
+#define VAR_INVENTORY_WEIGHT 0
+#define VAR_INVENTORY_LIMIT 1
+#define VAR_TURN_COUNT 2
/* Special rooms */
-#define ROOM_INVENTORY 0x00
-#define ROOM_NOWHERE 0xff
+#define ROOM_INVENTORY 0x00
+#define ROOM_NOWHERE 0xff
/* Item flags */
-#define ITEMF_WEIGHT_MASK (0x3)
-#define ITEMF_CAN_TAKE (1 << 3)
+#define ITEMF_WEIGHT_MASK (0x3)
+#define ITEMF_CAN_TAKE (1 << 3)
/* Word types */
-#define WORD_TYPE_VERB 0x01
-#define WORD_TYPE_JOIN 0x02
-#define WORD_TYPE_FEMALE 0x10
-#define WORD_TYPE_MALE 0x20
-#define WORD_TYPE_NOUN 0x40
-#define WORD_TYPE_NOUN_PLURAL 0x80
-#define WORD_TYPE_NOUN_MASK (WORD_TYPE_FEMALE | WORD_TYPE_MALE | \
- WORD_TYPE_NOUN | WORD_TYPE_NOUN_PLURAL)
+#define WORD_TYPE_VERB 0x01
+#define WORD_TYPE_JOIN 0x02
+#define WORD_TYPE_FEMALE 0x10
+#define WORD_TYPE_MALE 0x20
+#define WORD_TYPE_NOUN 0x40
+#define WORD_TYPE_NOUN_PLURAL 0x80
+#define WORD_TYPE_NOUN_MASK (WORD_TYPE_FEMALE | WORD_TYPE_MALE | \
+ WORD_TYPE_NOUN | WORD_TYPE_NOUN_PLURAL)
void comprehend_load_game(struct comprehend_game *game);
void comprehend_restore_game(struct comprehend_game *game,
- const char *filename);
+ const char *filename);
void comprehend_save_game(struct comprehend_game *game, const char *filename);
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index d04c9fc2d9..3926b42192 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -20,37 +20,70 @@
*
*/
+#include "glk/comprehend/game_oo.h"
#include "glk/comprehend/comprehend.h"
-#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/game.h"
#include "glk/comprehend/graphics.h"
namespace Glk {
namespace Comprehend {
-#define OO_ROOM_FLAG_DARK 0x02
+#define OO_ROOM_FLAG_DARK 0x02
-#define OO_BRIGHT_ROOM 0x19
+#define OO_BRIGHT_ROOM 0x19
-#define OO_FLAG_WEARING_GOGGLES 0x1b
-#define OO_FLAG_FLASHLIGHT_ON 0x27
+#define OO_FLAG_WEARING_GOGGLES 0x1b
+#define OO_FLAG_FLASHLIGHT_ON 0x27
-static int oo_room_is_special(struct comprehend_game *game,
- unsigned room_index,
- unsigned *room_desc_string)
-{
+static struct game_ops oo_ops = {
+ nullptr,
+ nullptr,
+ OOToposGame::oo_before_turn,
+ nullptr,
+ OOToposGame::oo_room_is_special,
+ OOToposGame::oo_handle_special_opcode
+};
+
+OOToposGame::OOToposGame() : comprehend_game() {
+ game_name = "Oo-Topos";
+ short_name = "oo";
+ game_data_file = "g0";
+
+ // Extra strings are (annoyingly) stored in the game binary
+ string_files.push_back(string_file("NOVEL.EXE", 0x16564, 0x17640));
+ string_files.push_back(string_file("NOVEL.EXE", 0x17702, 0x18600));
+ string_files.push_back(string_file("NOVEL.EXE", 0x186b2, 0x19b80));
+ string_files.push_back(string_file("NOVEL.EXE", 0x19c62, 0x1a590));
+ string_files.push_back(string_file("NOVEL.EXE", 0x1a634, 0x1b080));
+ location_graphic_files.push_back("RA");
+ location_graphic_files.push_back("RB");
+ location_graphic_files.push_back("RC");
+ location_graphic_files.push_back("RD");
+ location_graphic_files.push_back("RE");
+ item_graphic_files.push_back("OA");
+ item_graphic_files.push_back("OB");
+ item_graphic_files.push_back("OC");
+ item_graphic_files.push_back("OD");
+
+ save_game_file_fmt = "G%d";
+ color_table = 1;
+ ops = &oo_ops;
+}
+
+int OOToposGame::oo_room_is_special(comprehend_game *game,
+ unsigned room_index,
+ unsigned *room_desc_string) {
struct room *room = &game->info->rooms[room_index];
/* Is the room dark */
if ((room->flags & OO_ROOM_FLAG_DARK) &&
!(game->info->flags[OO_FLAG_FLASHLIGHT_ON])) {
if (room_desc_string)
- *room_desc_string = 0xb3;
+ *room_desc_string = 0xb3;
return ROOM_IS_DARK;
}
/* Is the room too bright */
- if (room_index == OO_BRIGHT_ROOM &&
+ if (room_index == OO_BRIGHT_ROOM &&
!game->info->flags[OO_FLAG_WEARING_GOGGLES]) {
if (room_desc_string)
*room_desc_string = 0x1c;
@@ -60,8 +93,7 @@ static int oo_room_is_special(struct comprehend_game *game,
return ROOM_IS_NORMAL;
}
-static bool oo_before_turn(struct comprehend_game *game)
-{
+bool OOToposGame::oo_before_turn(comprehend_game *game) {
/* FIXME - probably doesn't work correctly with restored games */
static bool flashlight_was_on = false, googles_were_worn = false;
struct room *room = &game->info->rooms[game->info->current_room];
@@ -89,9 +121,8 @@ static bool oo_before_turn(struct comprehend_game *game)
return false;
}
-static void oo_handle_special_opcode(struct comprehend_game *game,
- uint8 operand)
-{
+void OOToposGame::oo_handle_special_opcode(comprehend_game *game,
+ uint8 operand) {
switch (operand) {
case 0x03:
/* Game over - failure */
@@ -114,35 +145,5 @@ static void oo_handle_special_opcode(struct comprehend_game *game,
}
}
-static struct game_ops oo_ops = {
- nullptr,
- nullptr,
- oo_before_turn,
- nullptr,
- oo_room_is_special,
- oo_handle_special_opcode
-};
-
-struct comprehend_game game_oo_topos = {
- "Oo-Topos",
- "oo",
- "G0",
- {
- // Extra strings are (annoyingly) stored in the game binary
- {"NOVEL.EXE", 0x16564, 0x17640},
- {"NOVEL.EXE", 0x17702, 0x18600},
- {"NOVEL.EXE", 0x186b2, 0x19b80},
- {"NOVEL.EXE", 0x19c62, 0x1a590},
- {"NOVEL.EXE", 0x1a634, 0x1b080},
- },
- {"RA", "RB", "RC", "RD", "RE"},
- {"OA", "OB", "OC", "OD"},
- "G%d",
- 1,
- nullptr,
- &oo_ops,
- nullptr
-};
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_oo.h b/engines/glk/comprehend/game_oo.h
new file mode 100644
index 0000000000..fe475cb2c2
--- /dev/null
+++ b/engines/glk/comprehend/game_oo.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_COMPREHEND_GAME_OO_H
+#define GLK_COMPREHEND_GAME_OO_H
+
+#include "glk/comprehend/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class OOToposGame : public comprehend_game {
+public:
+ OOToposGame();
+
+public:
+ static bool oo_before_turn(comprehend_game *game);
+ static int oo_room_is_special(comprehend_game *game,
+ unsigned room_index, unsigned *room_desc_string);
+ static void oo_handle_special_opcode(comprehend_game *game,
+ uint8 operand);
+};
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/game_tm.cpp b/engines/glk/comprehend/game_tm.cpp
index dc5ae64a9d..35b1f03a9e 100644
--- a/engines/glk/comprehend/game_tm.cpp
+++ b/engines/glk/comprehend/game_tm.cpp
@@ -21,29 +21,30 @@
*/
#include "glk/comprehend/comprehend.h"
-#include "glk/comprehend/game.h"
-#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/game_tm.h"
namespace Glk {
namespace Comprehend {
-static struct game_ops tm_ops = {};
-
/* FIXME - This is broken */
-struct comprehend_game game_talisman = {
- "Talisman, Challenging the Sands of Time (broken)",
- "tm",
- "G0",
- {},
- {"RA", "RB", "RC", "RD", "RE", "RF", "RG"},
- {"OA", "OB", "OE", "OF"},
- nullptr,
- 0,
- nullptr,
- &tm_ops,
- nullptr
-};
+TalismanGame::TalismanGame() : comprehend_game() {
+ game_name = "Talisman, Challenging the Sands of Time (broken)";
+ short_name = "tm";
+ game_data_file = "G0";
+
+ location_graphic_files.push_back("RA");
+ location_graphic_files.push_back("RB");
+ location_graphic_files.push_back("RC");
+ location_graphic_files.push_back("RD");
+ location_graphic_files.push_back("RE");
+ location_graphic_files.push_back("RF");
+ location_graphic_files.push_back("RG");
+ item_graphic_files.push_back("OA");
+ item_graphic_files.push_back("OB");
+ item_graphic_files.push_back("OE");
+ item_graphic_files.push_back("OF");
+}
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_tm.h b/engines/glk/comprehend/game_tm.h
new file mode 100644
index 0000000000..a1cb8f8086
--- /dev/null
+++ b/engines/glk/comprehend/game_tm.h
@@ -0,0 +1,39 @@
+/* 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_COMPREHEND_GAME_TM_H
+#define GLK_COMPREHEND_GAME_TM_H
+
+#include "glk/comprehend/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class TalismanGame : public comprehend_game {
+public:
+ TalismanGame();
+};
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 84ea764848..5b7d841089 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -22,7 +22,7 @@
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/game.h"
+#include "glk/comprehend/game_tr.h"
#include "glk/comprehend/util.h"
namespace Glk {
@@ -44,6 +44,45 @@ static struct tr_monster tr_vampire = {
0x26, 5, (1 << 7), 0, 5
};
+static struct game_strings tr_strings = {
+ EXTRA_STRING_TABLE(0x8a)
+};
+
+static struct game_ops tr_ops = {
+ TransylvaniaGame::tr_before_game,
+ nullptr,
+ TransylvaniaGame::tr_before_turn,
+ nullptr,
+ TransylvaniaGame::tr_room_is_special,
+ TransylvaniaGame::tr_handle_special_opcode,
+};
+
+
+TransylvaniaGame::TransylvaniaGame() : comprehend_game() {
+ game_name = "Transylvania";
+ short_name = "tr";
+ game_data_file = "tr.gda";
+
+ string_files.push_back(string_file("MA.MS1", 0x88));
+ string_files.push_back(string_file("MB.MS1", 0x88));
+ string_files.push_back(string_file("MC.MS1", 0x88));
+ string_files.push_back(string_file("MD.MS1", 0x88));
+ string_files.push_back(string_file("ME.MS1", 0x88));
+
+ location_graphic_files.push_back("RA.MS1");
+ location_graphic_files.push_back("RB.MS1");
+ location_graphic_files.push_back("RC.MS1");
+
+ item_graphic_files.push_back("OA.MS1");
+ item_graphic_files.push_back("OB.MS1");
+ item_graphic_files.push_back("OC.MS1");
+
+ save_game_file_fmt = "G%d.MS0";
+ strings = &tr_strings;
+ ops = &tr_ops;
+};
+
+
static void tr_update_monster(struct comprehend_game *game,
struct tr_monster *monster_info)
{
@@ -77,7 +116,7 @@ static void tr_update_monster(struct comprehend_game *game,
}
}
-static int tr_room_is_special(struct comprehend_game *game, unsigned room_index,
+int TransylvaniaGame::tr_room_is_special(comprehend_game *game, unsigned room_index,
unsigned *room_desc_string)
{
struct room *room = &game->info->rooms[room_index];
@@ -91,14 +130,14 @@ static int tr_room_is_special(struct comprehend_game *game, unsigned room_index,
return ROOM_IS_NORMAL;
}
-static bool tr_before_turn(struct comprehend_game *game)
+bool TransylvaniaGame::tr_before_turn(comprehend_game *game)
{
tr_update_monster(game, &tr_werewolf);
tr_update_monster(game, &tr_vampire);
return false;
}
-static void tr_handle_special_opcode(struct comprehend_game *game,
+void TransylvaniaGame::tr_handle_special_opcode(comprehend_game *game,
uint8 operand)
{
switch (operand) {
@@ -159,8 +198,7 @@ static void read_string(char *buffer, size_t size)
#endif
}
-static void tr_before_game(struct comprehend_game *game)
-{
+void TransylvaniaGame::tr_before_game(struct comprehend_game *game) {
char buffer[128];
/* Welcome to Transylvania - sign your name */
@@ -185,38 +223,5 @@ static void tr_before_game(struct comprehend_game *game)
read_string(buffer, sizeof(buffer));
}
-static struct game_strings tr_strings = {
- EXTRA_STRING_TABLE(0x8a)
-};
-
-static struct game_ops tr_ops = {
- tr_before_game,
- nullptr,
- tr_before_turn,
- nullptr,
- tr_room_is_special,
- tr_handle_special_opcode,
-};
-
-struct comprehend_game game_transylvania = {
- "Transylvania",
- "tr",
- "TR.GDA",
- {
- {"MA.MS1", 0x88},
- {"MB.MS1", 0x88},
- {"MC.MS1", 0x88},
- {"MD.MS1", 0x88},
- {"ME.MS1", 0x88},
- },
- {"RA.MS1", "RB.MS1", "RC.MS1"},
- {"OA.MS1", "OB.MS1", "OC.MS1"},
- "G%d.MS0",
- 0,
- &tr_strings,
- &tr_ops,
- nullptr
-};
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_tr.h b/engines/glk/comprehend/game_tr.h
new file mode 100644
index 0000000000..a4d5f3db46
--- /dev/null
+++ b/engines/glk/comprehend/game_tr.h
@@ -0,0 +1,47 @@
+/* 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_COMPREHEND_GAME_TR_H
+#define GLK_COMPREHEND_GAME_TR_H
+
+#include "glk/comprehend/game.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class TransylvaniaGame : public comprehend_game {
+public:
+ TransylvaniaGame();
+
+public:
+ static void tr_before_game(comprehend_game *game);
+ static bool tr_before_turn(comprehend_game *game);
+ static int tr_room_is_special(comprehend_game *game,
+ unsigned room_index, unsigned *room_desc_string);
+ static void tr_handle_special_opcode(comprehend_game *game,
+ uint8 operand);
+};
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 4059b6ea89..d5751d3038 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -326,51 +326,34 @@ static void load_image_file(struct image_data *info, const char *filename,
}
static void load_image_files(struct image_data *info,
- const char **filenames, size_t nr_files)
-{
+ const Common::Array<const char *> filenames) {
uint i;
memset(info, 0, sizeof(*info));
- info->nr_images = nr_files * IMAGES_PER_FILE;
+ info->nr_images = filenames.size() * IMAGES_PER_FILE;
info->fb = (file_buf *)xmalloc(info->nr_images * sizeof(*info->fb));
info->image_offsets = (uint16 *)xmalloc(info->nr_images * sizeof(uint16));
- for (i = 0; i < nr_files; i++) {
+ for (i = 0; i < filenames.size(); i++) {
load_image_file(info, filenames[i], i);
}
}
-static size_t graphic_array_count(const char **filenames, size_t max)
-{
- size_t count;
-
- for (count = 0; count < max && filenames[count]; count++)
- ;
- return count;
-}
-
void comprehend_load_image_file(const char *filename, struct image_data *info)
{
- load_image_files(info, (const char **)&filename, 1);
-}
-
-void comprehend_load_images(comprehend_game *game)
-{
- size_t nr_item_files, nr_room_files;
+ Common::Array<const char *> filenames;
+ filenames.push_back(filename);
- nr_room_files =
- graphic_array_count(game->location_graphic_files,
- ARRAY_SIZE(game->location_graphic_files));
- nr_item_files =
- graphic_array_count(game->item_graphic_files,
- ARRAY_SIZE(game->item_graphic_files));
+ load_image_files(info, filenames);
+}
+void comprehend_load_images(comprehend_game *game) {
load_image_files(&game->info->room_images,
- game->location_graphic_files, nr_room_files);
+ game->location_graphic_files);
load_image_files(&game->info->item_images,
- game->item_graphic_files, nr_item_files);
+ game->item_graphic_files);
}
} // namespace Comprehend
Commit: 7e7e6a5fab134d36a7d0fcdfab40fc162af98560
https://github.com/scummvm/scummvm/commit/7e7e6a5fab134d36a7d0fcdfab40fc162af98560
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:08-07:00
Commit Message:
GLK: COMPREHEND: Changing operation methods to virtual methods
Changed paths:
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_cc.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_oo.h
engines/glk/comprehend/game_tm.h
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/game_tr.h
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 351ccef491..49b80efdb6 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -48,22 +48,6 @@ struct game_strings {
uint16 game_restart;
};
-#define ROOM_IS_NORMAL 0
-#define ROOM_IS_DARK 1
-#define ROOM_IS_TOO_BRIGHT 2
-
-struct game_ops {
- void (*before_game)(struct comprehend_game *game);
- void (*before_prompt)(struct comprehend_game *game);
- bool (*before_turn)(struct comprehend_game *game);
- bool (*after_turn)(struct comprehend_game *game);
- int (*room_is_special)(struct comprehend_game *game,
- unsigned room_index,
- unsigned *room_desc_string);
- void (*handle_special_opcode)(struct comprehend_game *game,
- uint8 operand);
-};
-
/**
* Comprehend engine
*/
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 4cd28e9b20..6eff98ffc2 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -48,8 +48,7 @@ comprehend_game::comprehend_game() : game_name(nullptr),
game_data_file(nullptr),
save_game_file_fmt(nullptr),
color_table(0),
- strings(nullptr),
- ops(nullptr) {
+ strings(nullptr) {
info = (game_info *)malloc(sizeof(*info));
}
@@ -275,9 +274,7 @@ static void update_graphics(comprehend_game *game) {
if (!g_enabled())
return;
- type = ROOM_IS_NORMAL;
- if (game->ops->room_is_special)
- type = game->ops->room_is_special(game, game->info->current_room, NULL);
+ type = game->room_is_special(game->info->current_room, NULL);
switch (type) {
case ROOM_IS_DARK:
@@ -345,12 +342,9 @@ static void update(comprehend_game *game) {
update_graphics(game);
/* Check if the room is special (dark, too bright, etc) */
- room_type = ROOM_IS_NORMAL;
room_desc_string = room->string_desc;
- if (game->ops->room_is_special)
- room_type = game->ops->room_is_special(game,
- game->info->current_room,
- &room_desc_string);
+ room_type = game->room_is_special(game->info->current_room,
+ &room_desc_string);
if (game->info->update_flags & UPDATE_ROOM_DESC)
console_println(game, string_lookup(game, room_desc_string));
@@ -962,9 +956,7 @@ static void eval_instruction(comprehend_game *game,
case OPCODE_SPECIAL:
/* Game specific opcode */
- if (game->ops->handle_special_opcode)
- game->ops->handle_special_opcode(game,
- instr->operand[0]);
+ game->handle_special_opcode(instr->operand[0]);
break;
default:
@@ -1174,20 +1166,18 @@ static void read_sentence(comprehend_game *game, char **line,
}
static void before_turn(comprehend_game *game) {
- /* Run the game specific before turn bits */
- if (game->ops->before_turn)
- game->ops->before_turn(game);
+ // Run the game specific before turn bits
+ game->before_turn();
- /* Run the each turn functions */
+ // Run the each turn functions
eval_function(game, &game->info->functions[0], NULL, NULL);
update(game);
}
static void after_turn(comprehend_game *game) {
- /* Do post turn game specific bits */
- if (game->ops->after_turn)
- game->ops->after_turn(game);
+ // Do post turn game specific bits
+ game->after_turn();
}
static void read_input(comprehend_game *game) {
@@ -1205,7 +1195,7 @@ static void read_input(comprehend_game *game) {
line = fgets(buffer, sizeof(buffer), stdin);
}
- /* Re-comprehend special commands start with '!' */
+ // Re-comprehend special commands start with '!'
if (*line == '!') {
handle_debug_command(game, &line[1]);
return;
@@ -1233,11 +1223,10 @@ static void read_input(comprehend_game *game) {
void comprehend_play_game(comprehend_game *game) {
console_init();
- if (game->ops->before_game)
- game->ops->before_game(game);
+ game->before_game();
game->info->update_flags = (uint)UPDATE_ALL;
- while (1)
+ while (!g_comprehend->shouldQuit())
read_input(game);
}
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index cfd5133666..6a3d80b607 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -23,12 +23,16 @@
#ifndef GLK_COMPREHEND_GAME_H
#define GLK_COMPREHEND_GAME_H
-#include "glk/comprehend/game_data.h"
#include "common/array.h"
+#include "glk/comprehend/game_data.h"
namespace Glk {
namespace Comprehend {
+#define ROOM_IS_NORMAL 0
+#define ROOM_IS_DARK 1
+#define ROOM_IS_TOO_BRIGHT 2
+
struct comprehend_game {
public:
const char *game_name;
@@ -36,33 +40,45 @@ public:
const char *game_data_file;
Common::Array<string_file> string_files;
- Common::Array <const char *> location_graphic_files;
- Common::Array <const char *> item_graphic_files;
+ Common::Array<const char *> location_graphic_files;
+ Common::Array<const char *> item_graphic_files;
const char *save_game_file_fmt;
unsigned color_table;
struct game_strings *strings;
- struct game_ops *ops;
-
struct game_info *info;
public:
comprehend_game();
- ~comprehend_game();
+ virtual ~comprehend_game();
+
+ virtual void before_game() {}
+ virtual void before_prompt() {}
+ virtual bool before_turn() {
+ return false;
+ }
+ virtual bool after_turn() {
+ return false;
+ }
+ virtual int room_is_special(unsigned room_index,
+ unsigned *room_desc_string) {
+ return ROOM_IS_NORMAL;
+ }
+ virtual void handle_special_opcode(uint8 operand) {}
};
-void console_println(struct comprehend_game *game, const char *text);
+void console_println(comprehend_game *game, const char *text);
int console_get_key(void);
-struct item *get_item(struct comprehend_game *game, uint16 index);
-void move_object(struct comprehend_game *game, struct item *item, int new_room);
-void eval_function(struct comprehend_game *game, struct function *func,
- struct word *verb, struct word *noun);
+struct item *get_item(comprehend_game *game, uint16 index);
+void move_object(comprehend_game *game, struct item *item, int new_room);
+void eval_function(comprehend_game *game, struct function *func,
+ struct word *verb, struct word *noun);
-void comprehend_play_game(struct comprehend_game *game);
-void game_save(struct comprehend_game *game);
-void game_restore(struct comprehend_game *game);
-void game_restart(struct comprehend_game *game);
+void comprehend_play_game(comprehend_game *game);
+void game_save(comprehend_game *game);
+void game_restore(comprehend_game *game);
+void game_restart(comprehend_game *game);
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index bed5603cce..9bc6a3daa3 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -28,14 +28,6 @@ namespace Comprehend {
static struct game_strings cc1_strings = {0x9};
-static struct game_ops cc1_ops = {
- nullptr,
- CrimsonCrownGame::cc1_before_prompt,
- nullptr,
- nullptr,
- nullptr,
- CrimsonCrownGame::cc1_handle_special_opcode};
-
#ifdef TODO
static struct game_ops cc2_ops = {
nullptr,
@@ -60,7 +52,6 @@ CrimsonCrownGame::CrimsonCrownGame() : comprehend_game() {
save_game_file_fmt = "G%d.MS0";
strings = &cc1_strings;
- ops = &cc1_ops;
}
#ifdef TODO
@@ -113,9 +104,8 @@ static bool cc_common_handle_special_opcode(struct comprehend_game *game,
return false;
}
-void CrimsonCrownGame::cc1_handle_special_opcode(comprehend_game *game,
- uint8 operand) {
- if (cc_common_handle_special_opcode(game, operand))
+void CrimsonCrownGame::handle_special_opcode(uint8 operand) {
+ if (cc_common_handle_special_opcode(this, operand))
return;
switch (operand) {
@@ -156,8 +146,8 @@ static void cc2_before_prompt(struct comprehend_game *game) {
cc_clear_companion_flags(game);
}
-void CrimsonCrownGame::cc1_before_prompt(comprehend_game *game) {
- cc_clear_companion_flags(game);
+void CrimsonCrownGame::before_prompt() {
+ cc_clear_companion_flags(this);
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_cc.h b/engines/glk/comprehend/game_cc.h
index 00ba334b5a..ccbbc147a9 100644
--- a/engines/glk/comprehend/game_cc.h
+++ b/engines/glk/comprehend/game_cc.h
@@ -31,11 +31,10 @@ namespace Comprehend {
class CrimsonCrownGame : public comprehend_game {
public:
CrimsonCrownGame();
+ ~CrimsonCrownGame() override {}
-public:
- static void cc1_before_prompt(comprehend_game *game);
- static void cc1_handle_special_opcode(comprehend_game *game,
- uint8 operand);
+ void before_prompt() override;
+ void handle_special_opcode(uint8 operand) override;
};
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 3926b42192..ab6a67c4bb 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -34,15 +34,6 @@ namespace Comprehend {
#define OO_FLAG_WEARING_GOGGLES 0x1b
#define OO_FLAG_FLASHLIGHT_ON 0x27
-static struct game_ops oo_ops = {
- nullptr,
- nullptr,
- OOToposGame::oo_before_turn,
- nullptr,
- OOToposGame::oo_room_is_special,
- OOToposGame::oo_handle_special_opcode
-};
-
OOToposGame::OOToposGame() : comprehend_game() {
game_name = "Oo-Topos";
short_name = "oo";
@@ -66,17 +57,15 @@ OOToposGame::OOToposGame() : comprehend_game() {
save_game_file_fmt = "G%d";
color_table = 1;
- ops = &oo_ops;
}
-int OOToposGame::oo_room_is_special(comprehend_game *game,
- unsigned room_index,
+int OOToposGame::room_is_special(unsigned room_index,
unsigned *room_desc_string) {
- struct room *room = &game->info->rooms[room_index];
+ room *room = &info->rooms[room_index];
/* Is the room dark */
if ((room->flags & OO_ROOM_FLAG_DARK) &&
- !(game->info->flags[OO_FLAG_FLASHLIGHT_ON])) {
+ !(info->flags[OO_FLAG_FLASHLIGHT_ON])) {
if (room_desc_string)
*room_desc_string = 0xb3;
return ROOM_IS_DARK;
@@ -84,7 +73,7 @@ int OOToposGame::oo_room_is_special(comprehend_game *game,
/* Is the room too bright */
if (room_index == OO_BRIGHT_ROOM &&
- !game->info->flags[OO_FLAG_WEARING_GOGGLES]) {
+ !info->flags[OO_FLAG_WEARING_GOGGLES]) {
if (room_desc_string)
*room_desc_string = 0x1c;
return ROOM_IS_TOO_BRIGHT;
@@ -93,36 +82,35 @@ int OOToposGame::oo_room_is_special(comprehend_game *game,
return ROOM_IS_NORMAL;
}
-bool OOToposGame::oo_before_turn(comprehend_game *game) {
+bool OOToposGame::before_turn() {
/* FIXME - probably doesn't work correctly with restored games */
static bool flashlight_was_on = false, googles_were_worn = false;
- struct room *room = &game->info->rooms[game->info->current_room];
+ struct room *room = &info->rooms[info->current_room];
/*
* Check if the room needs to be redrawn because the flashlight
* was switch off or on.
*/
- if (game->info->flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
+ if (info->flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
(room->flags & OO_ROOM_FLAG_DARK)) {
- flashlight_was_on = game->info->flags[OO_FLAG_FLASHLIGHT_ON];
- game->info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ flashlight_was_on = info->flags[OO_FLAG_FLASHLIGHT_ON];
+ info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
/*
* Check if the room needs to be redrawn because the goggles were
* put on or removed.
*/
- if (game->info->flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
- game->info->current_room == OO_BRIGHT_ROOM) {
- googles_were_worn = game->info->flags[OO_FLAG_WEARING_GOGGLES];
- game->info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ if (info->flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
+ info->current_room == OO_BRIGHT_ROOM) {
+ googles_were_worn = info->flags[OO_FLAG_WEARING_GOGGLES];
+ info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
return false;
}
-void OOToposGame::oo_handle_special_opcode(comprehend_game *game,
- uint8 operand) {
+void OOToposGame::handle_special_opcode(uint8 operand) {
switch (operand) {
case 0x03:
/* Game over - failure */
@@ -130,17 +118,17 @@ void OOToposGame::oo_handle_special_opcode(comprehend_game *game,
/* Won the game */
case 0x04:
/* Restart game */
- game_restart(game);
+ game_restart(this);
break;
case 0x06:
/* Save game */
- game_save(game);
+ game_save(this);
break;
case 0x07:
/* Restore game */
- game_restore(game);
+ game_restore(this);
break;
}
}
diff --git a/engines/glk/comprehend/game_oo.h b/engines/glk/comprehend/game_oo.h
index fe475cb2c2..c1b1f767e4 100644
--- a/engines/glk/comprehend/game_oo.h
+++ b/engines/glk/comprehend/game_oo.h
@@ -31,13 +31,11 @@ namespace Comprehend {
class OOToposGame : public comprehend_game {
public:
OOToposGame();
+ ~OOToposGame() override {}
-public:
- static bool oo_before_turn(comprehend_game *game);
- static int oo_room_is_special(comprehend_game *game,
- unsigned room_index, unsigned *room_desc_string);
- static void oo_handle_special_opcode(comprehend_game *game,
- uint8 operand);
+ bool before_turn() override;
+ int room_is_special(unsigned room_index, unsigned *room_desc_string) override;
+ void handle_special_opcode(uint8 operand) override;
};
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_tm.h b/engines/glk/comprehend/game_tm.h
index a1cb8f8086..70f8537102 100644
--- a/engines/glk/comprehend/game_tm.h
+++ b/engines/glk/comprehend/game_tm.h
@@ -31,6 +31,7 @@ namespace Comprehend {
class TalismanGame : public comprehend_game {
public:
TalismanGame();
+ ~TalismanGame() override {}
};
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 5b7d841089..9596e48b42 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -28,19 +28,11 @@
namespace Glk {
namespace Comprehend {
-struct tr_monster {
- uint8 object;
- uint8 dead_flag;
- unsigned min_turns_before;
- unsigned room_allow_flag;
- unsigned randomness;
-};
-
-static struct tr_monster tr_werewolf = {
+const tr_monster TransylvaniaGame::WEREWOLF = {
0x21, 7, (1 << 6), 5, 5
};
-static struct tr_monster tr_vampire = {
+const tr_monster TransylvaniaGame::VAMPIRE = {
0x26, 5, (1 << 7), 0, 5
};
@@ -48,15 +40,6 @@ static struct game_strings tr_strings = {
EXTRA_STRING_TABLE(0x8a)
};
-static struct game_ops tr_ops = {
- TransylvaniaGame::tr_before_game,
- nullptr,
- TransylvaniaGame::tr_before_turn,
- nullptr,
- TransylvaniaGame::tr_room_is_special,
- TransylvaniaGame::tr_handle_special_opcode,
-};
-
TransylvaniaGame::TransylvaniaGame() : comprehend_game() {
game_name = "Transylvania";
@@ -79,28 +62,24 @@ TransylvaniaGame::TransylvaniaGame() : comprehend_game() {
save_game_file_fmt = "G%d.MS0";
strings = &tr_strings;
- ops = &tr_ops;
};
-
-static void tr_update_monster(struct comprehend_game *game,
- struct tr_monster *monster_info)
-{
+void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
struct item *monster;
struct room *room;
uint16 turn_count;
- room = &game->info->rooms[game->info->current_room];
- turn_count = game->info->variable[VAR_TURN_COUNT];
+ room = &info->rooms[info->current_room];
+ turn_count = info->variable[VAR_TURN_COUNT];
- monster = get_item(game, monster_info->object);
- if (monster->room == game->info->current_room) {
+ monster = get_item(this, monster_info->object);
+ if (monster->room == info->current_room) {
/* The monster is in the current room - leave it there */
return;
}
if ((room->flags & monster_info->room_allow_flag) &&
- !game->info->flags[monster_info->dead_flag] &&
+ !info->flags[monster_info->dead_flag] &&
turn_count > monster_info->min_turns_before) {
/*
* The monster is alive and allowed to move to the current
@@ -108,18 +87,18 @@ static void tr_update_monster(struct comprehend_game *game,
* it back to limbo.
*/
if ((g_comprehend->getRandomNumber(0x7fffffff) % monster_info->randomness) == 0) {
- move_object(game, monster, game->info->current_room);
- game->info->variable[0xf] = turn_count + 1;
+ move_object(this, monster, info->current_room);
+ info->variable[0xf] = turn_count + 1;
} else {
- move_object(game, monster, ROOM_NOWHERE);
+ move_object(this, monster, ROOM_NOWHERE);
}
}
}
-int TransylvaniaGame::tr_room_is_special(comprehend_game *game, unsigned room_index,
+int TransylvaniaGame::room_is_special(unsigned room_index,
unsigned *room_desc_string)
{
- struct room *room = &game->info->rooms[room_index];
+ struct room *room = &info->rooms[room_index];
if (room_index == 0x28) {
if (room_desc_string)
@@ -130,15 +109,13 @@ int TransylvaniaGame::tr_room_is_special(comprehend_game *game, unsigned room_in
return ROOM_IS_NORMAL;
}
-bool TransylvaniaGame::tr_before_turn(comprehend_game *game)
-{
- tr_update_monster(game, &tr_werewolf);
- tr_update_monster(game, &tr_vampire);
+bool TransylvaniaGame::before_turn() {
+ update_monster(&WEREWOLF);
+ update_monster(&VAMPIRE);
return false;
}
-void TransylvaniaGame::tr_handle_special_opcode(comprehend_game *game,
- uint8 operand)
+void TransylvaniaGame::handle_special_opcode(uint8 operand)
{
switch (operand) {
case 0x01:
@@ -153,11 +130,11 @@ void TransylvaniaGame::tr_handle_special_opcode(comprehend_game *game,
break;
case 0x06:
- game_save(game);
+ game_save(this);
break;
case 0x07:
- game_restore(game);
+ game_restore(this);
break;
case 0x03:
@@ -166,7 +143,7 @@ void TransylvaniaGame::tr_handle_special_opcode(comprehend_game *game,
/* Won the game */
case 0x08:
/* Restart game */
- game_restart(game);
+ game_restart(this);
break;
case 0x09:
@@ -174,9 +151,9 @@ void TransylvaniaGame::tr_handle_special_opcode(comprehend_game *game,
* Show the Zin screen in reponse to doing 'sing some enchanted
* evening' in his cabin.
*/
- draw_location_image(&game->info->room_images, 41);
+ draw_location_image(&info->room_images, 41);
console_get_key();
- game->info->update_flags |= UPDATE_GRAPHICS;
+ info->update_flags |= UPDATE_GRAPHICS;
break;
}
}
@@ -198,11 +175,11 @@ static void read_string(char *buffer, size_t size)
#endif
}
-void TransylvaniaGame::tr_before_game(struct comprehend_game *game) {
+void TransylvaniaGame::before_game() {
char buffer[128];
/* Welcome to Transylvania - sign your name */
- console_println(game, game->info->strings.strings[0x20]);
+ console_println(this, info->strings.strings[0x20]);
read_string(buffer, sizeof(buffer));
/*
@@ -211,15 +188,15 @@ void TransylvaniaGame::tr_before_game(struct comprehend_game *game) {
* limited (the original game will break if you put a name in that
* is too long).
*/
- if (!game->info->replace_words[0])
- game->info->replace_words[0] = xstrndup(buffer, strlen(buffer));
+ if (!info->replace_words[0])
+ info->replace_words[0] = xstrndup(buffer, strlen(buffer));
else
- snprintf(game->info->replace_words[0],
- strlen(game->info->replace_words[0]),
+ snprintf(info->replace_words[0],
+ strlen(info->replace_words[0]),
"%s", buffer);
/* And your next of kin - This isn't store by the game */
- console_println(game, game->info->strings.strings[0x21]);
+ console_println(this, info->strings.strings[0x21]);
read_string(buffer, sizeof(buffer));
}
diff --git a/engines/glk/comprehend/game_tr.h b/engines/glk/comprehend/game_tr.h
index a4d5f3db46..74dc09ba55 100644
--- a/engines/glk/comprehend/game_tr.h
+++ b/engines/glk/comprehend/game_tr.h
@@ -28,17 +28,29 @@
namespace Glk {
namespace Comprehend {
+struct tr_monster {
+ uint8 object;
+ uint8 dead_flag;
+ unsigned min_turns_before;
+ unsigned room_allow_flag;
+ unsigned randomness;
+};
+
class TransylvaniaGame : public comprehend_game {
+private:
+ static const tr_monster WEREWOLF;
+ static const tr_monster VAMPIRE;
+
+ void update_monster(const tr_monster *monster_info);
+
public:
TransylvaniaGame();
+ ~TransylvaniaGame() override {}
-public:
- static void tr_before_game(comprehend_game *game);
- static bool tr_before_turn(comprehend_game *game);
- static int tr_room_is_special(comprehend_game *game,
- unsigned room_index, unsigned *room_desc_string);
- static void tr_handle_special_opcode(comprehend_game *game,
- uint8 operand);
+ void before_game() override;
+ bool before_turn() override;
+ int room_is_special(unsigned room_index, unsigned *room_desc_string) override;
+ void handle_special_opcode(uint8 operand) override;
};
} // namespace Comprehend
Commit: 2dd367aa6f4dc9750b4cbfdaba43a3b07189d590
https://github.com/scummvm/scummvm/commit/2dd367aa6f4dc9750b4cbfdaba43a3b07189d590
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Adding initialization defaults for game info
Changed paths:
engines/glk/comprehend/dictionary.cpp
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
index a25f91f240..cbab1ff0c4 100644
--- a/engines/glk/comprehend/dictionary.cpp
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -31,13 +31,13 @@ namespace Comprehend {
static bool word_match(struct word *word, const char *string)
{
/* Words less than 6 characters must match exactly */
- if (strlen(word->word) < 6 && strlen(string) != strlen(word->word))
+ if (strlen(word->_word) < 6 && strlen(string) != strlen(word->_word))
return false;
- return strncmp(word->word, string, strlen(word->word)) == 0;
+ return strncmp(word->_word, string, strlen(word->_word)) == 0;
}
-struct word *dict_find_word_by_string(struct comprehend_game *game,
+word *dict_find_word_by_string(struct comprehend_game *game,
const char *string)
{
uint i;
@@ -58,8 +58,8 @@ struct word *dict_find_word_by_index_type(struct comprehend_game *game,
uint i;
for (i = 0; i < game->info->nr_words; i++) {
- if (game->info->words[i].index == index &&
- game->info->words[i].type == type)
+ if (game->info->words[i]._index == index &&
+ game->info->words[i]._type == type)
return &game->info->words[i];
}
@@ -72,8 +72,8 @@ struct word *find_dict_word_by_index(struct comprehend_game *game,
uint i;
for (i = 0; i < game->info->nr_words; i++) {
- if (game->info->words[i].index == index &&
- (game->info->words[i].type & type_mask) != 0)
+ if (game->info->words[i]._index == index &&
+ (game->info->words[i]._type & type_mask) != 0)
return &game->info->words[i];
}
@@ -86,8 +86,8 @@ bool dict_match_index_type(struct comprehend_game *game, const char *word,
uint i;
for (i = 0; i < game->info->nr_words; i++)
- if (game->info->words[i].index == index &&
- ((game->info->words[i].type & type_mask) != 0) &&
+ if (game->info->words[i]._index == index &&
+ ((game->info->words[i]._type & type_mask) != 0) &&
word_match(&game->info->words[i], word))
return true;
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index 99426a36b5..6ef5a66478 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -219,7 +219,7 @@ static void dump_action_table(struct comprehend_game *game)
word = find_dict_word_by_index(game, action->word[j],
action->word_type[j]);
if (word)
- debugN("%-6s ", word->word);
+ debugN("%-6s ", word->_word);
else
debugN("%.2x:%.2x ", action->word[j],
action->word_type[j]);
@@ -233,9 +233,9 @@ static int word_index_compare(const void *a, const void *b)
{
const word *word_a = (const word *)a, *word_b = (const word *)b;
- if (word_a->index > word_b->index)
+ if (word_a->_index > word_b->_index)
return 1;
- if (word_a->index < word_b->index)
+ if (word_a->_index < word_b->_index)
return -1;
return 0;
}
@@ -256,8 +256,8 @@ static void dump_dictionary(struct comprehend_game *game)
debugN("Dictionary (%zd words)\n", game->info->nr_words);
for (i = 0; i < game->info->nr_words; i++) {
words = &dictionary[i];
- debugN(" [%.2x] %.2x %s\n", words->index, words->type,
- words->word);
+ debugN(" [%.2x] %.2x %s\n", words->_index, words->_type,
+ words->_word);
}
free(dictionary);
@@ -279,7 +279,7 @@ static void dump_word_map(struct comprehend_game *game)
game, map->word[j].index, map->word[j].type);
if (word[j])
snprintf(str[j], sizeof(str[j]),
- "%s", word[j]->word);
+ "%s", word[j]->_word);
else
snprintf(str[j], sizeof(str[j]), "%.2x:%.2x ",
map->word[j].index, map->word[j].type);
@@ -335,9 +335,9 @@ static void dump_items(struct comprehend_game *game)
debugN(" words: ");
for (j = 0; j < game->info->nr_words; j++)
- if (game->info->words[j].index == item->word &&
- (game->info->words[j].type & WORD_TYPE_NOUN_MASK))
- debugN("%s ", game->info->words[j].word);
+ if (game->info->words[j]._index == item->word &&
+ (game->info->words[j]._type & WORD_TYPE_NOUN_MASK))
+ debugN("%s ", game->info->words[j]._word);
debugN("\n");
debugN(" flags=%.2x (takeable=%d, weight=%d)\n",
item->flags, !!(item->flags & ITEMF_CAN_TAKE),
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 6eff98ffc2..c55145f7a2 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -236,10 +236,10 @@ static struct word_index *is_word_pair(comprehend_game *game,
for (i = 0; i < game->info->nr_word_maps; i++) {
map = &game->info->word_map[i];
- if (map->word[0].index == word1->index &&
- map->word[0].type == word1->type &&
- map->word[1].index == word2->index &&
- map->word[1].type == word2->type)
+ if (map->word[0].index == word1->_index &&
+ map->word[0].type == word1->_type &&
+ map->word[1].index == word2->_index &&
+ map->word[1].type == word2->_type)
return &map->word[2];
}
@@ -250,7 +250,7 @@ static struct item *get_item_by_noun(comprehend_game *game,
struct word *noun) {
uint i;
- if (!noun || !(noun->type & WORD_TYPE_NOUN_MASK))
+ if (!noun || !(noun->_type & WORD_TYPE_NOUN_MASK))
return NULL;
/*
@@ -259,7 +259,7 @@ static struct item *get_item_by_noun(comprehend_game *game,
* to drop the latter because this will match the former.
*/
for (i = 0; i < game->info->header.nr_items; i++)
- if (game->info->item[i].word == noun->index)
+ if (game->info->item[i].word == noun->_index)
return &game->info->item[i];
return NULL;
@@ -551,12 +551,12 @@ static void eval_instruction(comprehend_game *game,
case OPCODE_MOVE:
/* Move in the direction dictated by the current verb */
- if (verb->index - 1 >= NR_DIRECTIONS)
+ if (verb->_index - 1 >= NR_DIRECTIONS)
fatal_error("Bad verb %d:%d in move",
- verb->index, verb->type);
+ verb->_index, verb->_type);
- if (room->direction[verb->index - 1])
- move_to(game, room->direction[verb->index - 1]);
+ if (room->direction[verb->_index - 1])
+ move_to(game, room->direction[verb->_index - 1]);
else
console_println(game, string_lookup(game, STRING_CANT_GO));
break;
@@ -619,7 +619,7 @@ static void eval_instruction(comprehend_game *game,
for (i = 0; i < game->info->header.nr_items; i++) {
struct item *itemP = &game->info->item[i];
- if (itemP->word == noun->index &&
+ if (itemP->word == noun->_index &&
itemP->room == instr->operand[0]) {
test = true;
break;
@@ -727,7 +727,7 @@ static void eval_instruction(comprehend_game *game,
case OPCODE_OBJECT_NOT_VALID:
/* FIXME - should be called OPCODE_CURRENT_OBJECT_NOT_VALID */
func_set_test_result(func_state, !noun ||
- (noun->type & WORD_TYPE_NOUN_MASK) == 0);
+ (noun->_type & WORD_TYPE_NOUN_MASK) == 0);
break;
case OPCODE_CURRENT_IS_OBJECT:
@@ -931,11 +931,11 @@ static void eval_instruction(comprehend_game *game,
* FIXME - Not sure what the operand is for,
* maybe capitalisation?
*/
- if (noun && (noun->type & WORD_TYPE_NOUN_PLURAL))
+ if (noun && (noun->_type & WORD_TYPE_NOUN_PLURAL))
game->info->current_replace_word = 3;
- else if (noun && (noun->type & WORD_TYPE_FEMALE))
+ else if (noun && (noun->_type & WORD_TYPE_FEMALE))
game->info->current_replace_word = 0;
- else if (noun && (noun->type & WORD_TYPE_MALE))
+ else if (noun && (noun->_type & WORD_TYPE_MALE))
game->info->current_replace_word = 1;
else
game->info->current_replace_word = 2;
@@ -985,9 +985,7 @@ static void eval_instruction(comprehend_game *game,
*/
void eval_function(comprehend_game *game, struct function *func,
struct word *verb, struct word *noun) {
- struct function_state func_state = {
- true, false, 0, false, false, false
- };
+ struct function_state func_state;
uint i;
func_state.else_result = true;
@@ -1084,8 +1082,8 @@ static bool handle_sentence(comprehend_game *game,
* run that action's function.
*/
for (j = 0; j < action->nr_words; j++) {
- if (sentence->words[j].index == action->word[j] &&
- (sentence->words[j].type & action->word_type[j]))
+ if (sentence->words[j]._index == action->word[j] &&
+ (sentence->words[j]._type & action->word_type[j]))
continue;
/* Word didn't match */
@@ -1149,9 +1147,9 @@ static void read_sentence(comprehend_game *game, char **line,
&sentence->words[index - 2],
&sentence->words[index - 1]);
if (pair) {
- sentence->words[index - 2].index = pair->index;
- sentence->words[index - 2].type = pair->type;
- strcpy(sentence->words[index - 2].word,
+ sentence->words[index - 2]._index = pair->index;
+ sentence->words[index - 2]._type = pair->type;
+ strcpy(sentence->words[index - 2]._word,
"[PAIR]");
sentence->nr_words--;
}
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index c06b2813c8..5c92182e2d 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -38,7 +38,102 @@ static char special_charset[] = "[]\n!\"#$%&'(),-/0123456789:;?<>";
static uint16 magic_offset;
-static void parse_header_le16(struct file_buf *fb, uint16 *val) {
+function_state::function_state() : test_result(true),
+ else_result(false),
+ or_count(0),
+ _and(false),
+ in_command(false),
+ executed(false) {
+}
+
+/*-------------------------------------------------------*/
+
+room::room() : flags(0),
+ graphic(0),
+ string_desc(0) {
+ Common::fill(&direction[0], &direction[NR_DIRECTIONS], 0);
+}
+
+/*-------------------------------------------------------*/
+
+item::item() : string_desc(0),
+ long_string(0),
+ room(0),
+ flags(0),
+ word(0),
+ graphic(0) {
+}
+
+/*-------------------------------------------------------*/
+
+word::word() : _index(0), _type(0) {
+ Common::fill(&_word[0], &_word[7], '\0');
+}
+
+/*-------------------------------------------------------*/
+
+action::action() : type(0), nr_words(0), function(0) {
+ Common::fill(&word[0], &word[4], 0);
+ Common::fill(&word_type[0], &word_type[4], 0);
+}
+
+instruction::instruction() : opcode(0), nr_operands(0),
+ is_command(false) {
+ Common::fill(&operand[0], &operand[3], 0);
+}
+
+/*-------------------------------------------------------*/
+
+string_table::string_table() : nr_strings(0) {
+ Common::fill(&strings[0], &strings[0xffff], nullptr);
+}
+
+/*-------------------------------------------------------*/
+
+game_header::game_header() : magic(0),
+ room_desc_table(0),
+ room_flags_table(0),
+ room_graphics_table(0),
+ nr_items(0),
+ addr_item_locations(0),
+ addr_item_flags(0),
+ addr_item_word(0),
+ addr_item_strings(0),
+ addr_item_graphics(0),
+ addr_dictionary(0),
+ addr_word_map(0),
+ addr_strings(0),
+ addr_strings_end(0),
+ addr_actions_vvnn(0),
+ addr_actions_unknown(0),
+ addr_actions_vnjn(0),
+ addr_actions_vjn(0),
+ addr_actions_vdn(0),
+ addr_actions_vnn(0),
+ addr_actions_vn(0),
+ addr_actions_v(0),
+ addr_vm(0) // FIXME - functions
+{
+ Common::fill(&room_direction_table[0], &room_direction_table[NR_DIRECTIONS], 0);
+}
+
+/*-------------------------------------------------------*/
+
+game_info::game_info() : comprehend_version(0),
+ start_room(0),
+ nr_rooms(0),
+ current_room(0),
+ words(nullptr),
+ nr_words(0),
+ nr_word_maps(0),
+ nr_actions(0),
+ nr_functions(0),
+ nr_replace_words(0),
+ current_replace_word(0),
+ update_flags(0) {
+}
+
+static void parse_header_le16(struct file_buf * fb, uint16 * val) {
file_buf_get_le16(fb, val);
*val += (uint16)magic_offset;
}
@@ -53,8 +148,8 @@ static bool opcode_is_command(uint8 opcode) {
return opcode & 0x80;
}
-static uint8 parse_vm_instruction(struct file_buf *fb,
- struct instruction *instr) {
+static uint8 parse_vm_instruction(struct file_buf * fb,
+ struct instruction * instr) {
uint i;
/* Get the opcode */
@@ -70,12 +165,12 @@ static uint8 parse_vm_instruction(struct file_buf *fb,
return instr->opcode;
}
-static void parse_function(struct file_buf *fb, struct function *func) {
+static void parse_function(struct file_buf * fb, struct function * func) {
struct instruction *instruction;
uint8 *p, opcode;
p = (uint8 *)memchr(file_buf_data_pointer(fb), 0x00,
- fb->size - file_buf_get_pos(fb));
+ fb->size - file_buf_get_pos(fb));
if (!p)
fatal_error("bad function @ %.4x", file_buf_get_pos(fb));
@@ -92,7 +187,7 @@ static void parse_function(struct file_buf *fb, struct function *func) {
}
}
-static void parse_vm(struct comprehend_game *game, struct file_buf *fb) {
+static void parse_vm(struct comprehend_game * game, struct file_buf * fb) {
struct function *func;
file_buf_set_pos(fb, game->info->header.addr_vm);
@@ -107,22 +202,22 @@ static void parse_vm(struct comprehend_game *game, struct file_buf *fb) {
}
}
-static void parse_action_table_vvnn(struct comprehend_game *game,
- struct file_buf *fb, size_t *index) {
+static void parse_action_table_vvnn(struct comprehend_game * game,
+ struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i, j;
/*
- * <verb> <verb> <noun> <noun>
- *
- * u8: verb1
- * u8: count
- * u8: verb2
- * u8: noun1
- * u8: noun2
- * le16: action
- */
+ * <verb> <verb> <noun> <noun>
+ *
+ * u8: verb1
+ * u8: count
+ * u8: verb2
+ * u8: noun1
+ * u8: noun2
+ * le16: action
+ */
file_buf_set_pos(fb, game->info->header.addr_actions_vvnn);
while (1) {
file_buf_get_u8(fb, &verb);
@@ -151,22 +246,22 @@ static void parse_action_table_vvnn(struct comprehend_game *game,
}
}
-static void parse_action_table_vnjn(struct comprehend_game *game,
- struct file_buf *fb, size_t *index) {
+static void parse_action_table_vnjn(struct comprehend_game * game,
+ struct file_buf * fb, size_t * index) {
struct action *action;
uint8 join, count;
int i;
/*
- * <verb> <noun> <join> <noun>
- *
- * u8: join
- * u8: count
- * u8: verb
- * u8: noun1
- * u8: noun2
- * le16: action
- */
+ * <verb> <noun> <join> <noun>
+ *
+ * u8: join
+ * u8: count
+ * u8: verb
+ * u8: noun1
+ * u8: noun2
+ * le16: action
+ */
file_buf_set_pos(fb, game->info->header.addr_actions_vnjn);
while (1) {
file_buf_get_u8(fb, &join);
@@ -196,21 +291,21 @@ static void parse_action_table_vnjn(struct comprehend_game *game,
}
}
-static void parse_action_table_vjn(struct comprehend_game *game,
- struct file_buf *fb, size_t *index) {
+static void parse_action_table_vjn(struct comprehend_game * game,
+ struct file_buf * fb, size_t * index) {
struct action *action;
uint8 join, count;
int i;
/*
- * <verb> <join> <noun>
- *
- * u8: join
- * u8: count
- * u8: verb
- * u8: noun
- * le16: action
- */
+ * <verb> <join> <noun>
+ *
+ * u8: join
+ * u8: count
+ * u8: verb
+ * u8: noun
+ * le16: action
+ */
file_buf_set_pos(fb, game->info->header.addr_actions_vjn);
while (1) {
file_buf_get_u8(fb, &join);
@@ -237,21 +332,21 @@ static void parse_action_table_vjn(struct comprehend_game *game,
}
}
-static void parse_action_table_vdn(struct comprehend_game *game,
- struct file_buf *fb, size_t *index) {
+static void parse_action_table_vdn(struct comprehend_game * game,
+ struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i;
/*
- * <verb> <dir> <noun>
- *
- * u8: verb
- * u8: count
- * u8: dir
- * u8: noun
- * le16: action
- */
+ * <verb> <dir> <noun>
+ *
+ * u8: verb
+ * u8: count
+ * u8: dir
+ * u8: noun
+ * le16: action
+ */
file_buf_set_pos(fb, game->info->header.addr_actions_vdn);
while (1) {
file_buf_get_u8(fb, &verb);
@@ -278,21 +373,21 @@ static void parse_action_table_vdn(struct comprehend_game *game,
}
}
-static void parse_action_table_vnn(struct comprehend_game *game,
- struct file_buf *fb, size_t *index) {
+static void parse_action_table_vnn(struct comprehend_game * game,
+ struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i;
/*
- * <verb> <noun> <noun>
- *
- * u8: verb
- * u8: count
- * u8: noun1
- * u8: noun2
- * le16: action
- */
+ * <verb> <noun> <noun>
+ *
+ * u8: verb
+ * u8: count
+ * u8: noun1
+ * u8: noun2
+ * le16: action
+ */
file_buf_set_pos(fb, game->info->header.addr_actions_vnn);
while (1) {
/* 2-byte header */
@@ -320,20 +415,20 @@ static void parse_action_table_vnn(struct comprehend_game *game,
}
}
-static void parse_action_table_vn(struct comprehend_game *game,
- struct file_buf *fb, size_t *index) {
+static void parse_action_table_vn(struct comprehend_game * game,
+ struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i;
/*
- * <verb> <noun>
- *
- * u8: verb
- * u8: count
- * u8: noun
- * le16: action
- */
+ * <verb> <noun>
+ *
+ * u8: verb
+ * u8: count
+ * u8: noun
+ * le16: action
+ */
file_buf_set_pos(fb, game->info->header.addr_actions_vn);
while (1) {
/* 2-byte header */
@@ -359,20 +454,20 @@ static void parse_action_table_vn(struct comprehend_game *game,
}
}
-static void parse_action_table_v(struct comprehend_game *game,
- struct file_buf *fb, size_t *index) {
+static void parse_action_table_v(struct comprehend_game * game,
+ struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, nr_funcs;
uint16 func;
int i;
/*
- * <verb> [<noun>]
- *
- * u8: verb
- * u8: count (num actions)
- * le16: action
- */
+ * <verb> [<noun>]
+ *
+ * u8: verb
+ * u8: count (num actions)
+ * le16: action
+ */
file_buf_set_pos(fb, game->info->header.addr_actions_v);
while (1) {
file_buf_get_u8(fb, &verb);
@@ -388,9 +483,9 @@ static void parse_action_table_v(struct comprehend_game *game,
action->word_type[0] = WORD_TYPE_VERB;
/*
- * Default actions can have more than one function, but only
- * the first one actually seems to be used?
- */
+ * Default actions can have more than one function, but only
+ * the first one actually seems to be used?
+ */
file_buf_get_u8(fb, &nr_funcs);
for (i = 0; i < nr_funcs; i++) {
file_buf_get_le16(fb, &func);
@@ -402,8 +497,8 @@ static void parse_action_table_v(struct comprehend_game *game,
}
}
-static void parse_action_table(struct comprehend_game *game,
- struct file_buf *fb) {
+static void parse_action_table(struct comprehend_game * game,
+ struct file_buf * fb) {
game->info->nr_actions = 0;
if (game->info->comprehend_version == 1) {
@@ -420,7 +515,7 @@ static void parse_action_table(struct comprehend_game *game,
parse_action_table_v(game, fb, &game->info->nr_actions);
}
-static void parse_dictionary(struct comprehend_game *game, struct file_buf *fb) {
+static void parse_dictionary(struct comprehend_game * game, struct file_buf * fb) {
word *words;
uint i, j;
@@ -431,19 +526,19 @@ static void parse_dictionary(struct comprehend_game *game, struct file_buf *fb)
for (i = 0; i < game->info->nr_words; i++) {
words = &game->info->words[i];
- file_buf_get_data(fb, words->word, 6);
+ file_buf_get_data(fb, words->_word, 6);
/* Decode */
for (j = 0; j < 6; j++)
- words->word[j] ^= 0x8a;
- words->word[6] = '\0';
+ words->_word[j] ^= 0x8a;
+ words->_word[6] = '\0';
- file_buf_get_u8(fb, &words->index);
- file_buf_get_u8(fb, &words->type);
+ file_buf_get_u8(fb, &words->_index);
+ file_buf_get_u8(fb, &words->_type);
}
}
-static void parse_word_map(struct comprehend_game *game, struct file_buf *fb) {
+static void parse_word_map(struct comprehend_game * game, struct file_buf * fb) {
struct word_map *map;
uint8 index, type, dummy;
uint i;
@@ -452,9 +547,9 @@ static void parse_word_map(struct comprehend_game *game, struct file_buf *fb) {
file_buf_set_pos(fb, game->info->header.addr_word_map);
/*
- * Parse the word pair table. Each entry has a pair of dictionary
- * index/type values for a first and second word.
- */
+ * Parse the word pair table. Each entry has a pair of dictionary
+ * index/type values for a first and second word.
+ */
while (1) {
map = &game->info->word_map[game->info->nr_word_maps];
@@ -479,10 +574,10 @@ static void parse_word_map(struct comprehend_game *game, struct file_buf *fb) {
file_buf_get_u8(fb, &dummy);
/*
- * Parse the target word table. Each entry has a dictionary
- * index/type. The first and second words from above map to the
- * target word here. E.g. 'go north' -> 'north'.
- */
+ * Parse the target word table. Each entry has a dictionary
+ * index/type. The first and second words from above map to the
+ * target word here. E.g. 'go north' -> 'north'.
+ */
for (i = 0; i < game->info->nr_word_maps; i++) {
map = &game->info->word_map[i];
@@ -491,7 +586,7 @@ static void parse_word_map(struct comprehend_game *game, struct file_buf *fb) {
}
}
-static void parse_items(struct comprehend_game *game, struct file_buf *fb) {
+static void parse_items(struct comprehend_game * game, struct file_buf * fb) {
size_t nr_items = game->info->header.nr_items;
/* Item descriptions */
@@ -501,7 +596,7 @@ static void parse_items(struct comprehend_game *game, struct file_buf *fb) {
if (game->info->comprehend_version == 2) {
/* Comprehend version 2 adds long string descriptions */
file_buf_set_pos(fb, game->info->header.addr_item_strings +
- (game->info->header.nr_items * sizeof(uint16)));
+ (game->info->header.nr_items * sizeof(uint16)));
file_buf_get_array_le16(fb, 0, game->info->item, long_string, nr_items);
}
@@ -522,7 +617,7 @@ static void parse_items(struct comprehend_game *game, struct file_buf *fb) {
file_buf_get_array_u8(fb, 0, game->info->item, graphic, nr_items);
}
-static void parse_rooms(struct comprehend_game *game, struct file_buf *fb) {
+static void parse_rooms(struct comprehend_game * game, struct file_buf * fb) {
size_t nr_rooms = game->info->nr_rooms;
int i;
@@ -530,7 +625,7 @@ static void parse_rooms(struct comprehend_game *game, struct file_buf *fb) {
for (i = 0; i < NR_DIRECTIONS; i++) {
file_buf_set_pos(fb, game->info->header.room_direction_table[i]);
file_buf_get_array_u8(fb, 1, game->info->rooms,
- direction[i], nr_rooms);
+ direction[i], nr_rooms);
}
/* Room string descriptions */
@@ -546,7 +641,7 @@ static void parse_rooms(struct comprehend_game *game, struct file_buf *fb) {
file_buf_get_array_u8(fb, 1, game->info->rooms, graphic, nr_rooms);
}
-static uint64 string_get_chunk(uint8 *string) {
+static uint64 string_get_chunk(uint8 * string) {
uint64 c, val = 0;
int i;
@@ -567,11 +662,11 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
c = charset[c];
if (capital) {
/*
- * A capital space means that the character
- * is dynamically replaced by at runtime.
- * We use the character '@' since it cannot
- * otherwise appear in strings.
- */
+ * A capital space means that the character
+ * is dynamically replaced by at runtime.
+ * We use the character '@' since it cannot
+ * otherwise appear in strings.
+ */
if (c == ' ')
return '@';
return c - 0x20;
@@ -587,14 +682,14 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
}
/*
- * Game strings are stored using 5-bit characters. By default a character
- * value maps to the lower-case letter table. If a character has the value 0x1e
- * then the next character is upper-case. An upper-case space is used to
- * specify that the character should be replaced at runtime (like a '%s'
- * specifier). If a character has the value 0x1f then the next character is
- * taken from the symbols table.
- */
-static char *parse_string(struct file_buf *fb) {
+* Game strings are stored using 5-bit characters. By default a character
+* value maps to the lower-case letter table. If a character has the value 0x1e
+* then the next character is upper-case. An upper-case space is used to
+* specify that the character should be replaced at runtime (like a '%s'
+* specifier). If a character has the value 0x1f then the next character is
+* taken from the symbols table.
+*/
+static char *parse_string(struct file_buf * fb) {
bool capital_next = false, special_next = false;
unsigned i, j, k = 0;
uint64 chunk;
@@ -628,7 +723,7 @@ static char *parse_string(struct file_buf *fb) {
special_next = true;
} else {
c = decode_string_elem(elem, capital_next,
- special_next);
+ special_next);
special_next = false;
capital_next = false;
string[k++] = c;
@@ -643,8 +738,8 @@ done:
return string;
}
-static void parse_string_table(struct file_buf *fb, unsigned start_addr,
- uint32 end_addr, struct string_table *table) {
+static void parse_string_table(struct file_buf * fb, unsigned start_addr,
+ uint32 end_addr, struct string_table *table) {
file_buf_set_pos(fb, start_addr);
while (1) {
table->strings[table->nr_strings++] = parse_string(fb);
@@ -653,14 +748,14 @@ static void parse_string_table(struct file_buf *fb, unsigned start_addr,
}
}
-static void parse_variables(struct comprehend_game *game, struct file_buf *fb) {
+static void parse_variables(struct comprehend_game * game, struct file_buf * fb) {
int i;
for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
file_buf_get_le16(fb, &game->info->variable[i]);
}
-static void parse_flags(struct comprehend_game *game, struct file_buf *fb) {
+static void parse_flags(struct comprehend_game * game, struct file_buf * fb) {
int i, bit, flag_index = 0;
uint8 bitmask;
@@ -673,8 +768,8 @@ static void parse_flags(struct comprehend_game *game, struct file_buf *fb) {
}
}
-static void parse_replace_words(struct comprehend_game *game,
- struct file_buf *fb) {
+static void parse_replace_words(struct comprehend_game * game,
+ struct file_buf * fb) {
uint16 dummy;
size_t len;
bool eof;
@@ -700,10 +795,10 @@ static void parse_replace_words(struct comprehend_game *game,
}
/*
- * The main game data file header has the offsets for where each bit of
- * game data is. The offsets have a magic constant value added to them.
- */
-static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
+* The main game data file header has the offsets for where each bit of
+* game data is. The offsets have a magic constant value added to them.
+*/
+static void parse_header(struct comprehend_game * game, struct file_buf * fb) {
struct game_header *header = &game->info->header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
@@ -736,10 +831,10 @@ static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
parse_header_le16(fb, &dummy);
/*
- * Action tables.
- *
- * Layout depends on the comprehend version.
- */
+ * Action tables.
+ *
+ * Layout depends on the comprehend version.
+ */
if (game->info->comprehend_version == 1) {
parse_header_le16(fb, &header->addr_actions_vvnn);
parse_header_le16(fb, &header->addr_actions_unknown);
@@ -777,10 +872,10 @@ static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
parse_header_le16(fb, &header->room_graphics_table);
/*
- * Objects.
- *
- * Layout is dependent on comprehend version.
- */
+ * Objects.
+ *
+ * Layout is dependent on comprehend version.
+ */
if (game->info->comprehend_version == 1) {
parse_header_le16(fb, &header->addr_item_locations);
parse_header_le16(fb, &header->addr_item_flags);
@@ -789,7 +884,7 @@ static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
parse_header_le16(fb, &header->addr_item_graphics);
header->nr_items = (header->addr_item_word -
- header->addr_item_flags);
+ header->addr_item_flags);
} else {
parse_header_le16(fb, &header->addr_item_strings);
@@ -799,7 +894,7 @@ static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
parse_header_le16(fb, &header->addr_item_graphics);
header->nr_items = (header->addr_item_flags -
- header->addr_item_locations);
+ header->addr_item_locations);
}
parse_header_le16(fb, &header->addr_strings);
@@ -814,15 +909,15 @@ static void parse_header(struct comprehend_game *game, struct file_buf *fb) {
parse_flags(game, fb);
game->info->nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
- header->room_direction_table[DIRECTION_NORTH];
+ header->room_direction_table[DIRECTION_NORTH];
game->info->nr_words = (addr_dictionary_end -
- header->addr_dictionary) /
- 8;
+ header->addr_dictionary) /
+ 8;
}
-static void load_extra_string_file(comprehend_game *game,
- string_file *string_file) {
+static void load_extra_string_file(comprehend_game * game,
+ string_file * string_file) {
struct file_buf fb;
unsigned end;
@@ -834,12 +929,12 @@ static void load_extra_string_file(comprehend_game *game,
end = fb.size;
parse_string_table(&fb, string_file->base_offset,
- end, &game->info->strings2);
+ end, &game->info->strings2);
file_buf_unmap(&fb);
}
-static void load_extra_string_files(comprehend_game *game) {
+static void load_extra_string_files(comprehend_game * game) {
int i;
memset(&game->info->strings2, 0, sizeof(game->info->strings2));
@@ -857,7 +952,7 @@ static void load_extra_string_files(comprehend_game *game) {
}
}
-static void load_game_data(struct comprehend_game *game) {
+static void load_game_data(struct comprehend_game * game) {
struct file_buf fb;
memset(game->info, 0, sizeof(*game->info));
@@ -870,8 +965,8 @@ static void load_game_data(struct comprehend_game *game) {
parse_word_map(game, &fb);
memset(&game->info->strings, 0, sizeof(game->info->strings));
parse_string_table(&fb, game->info->header.addr_strings,
- game->info->header.addr_strings_end,
- &game->info->strings);
+ game->info->header.addr_strings_end,
+ &game->info->strings);
load_extra_string_files(game);
parse_vm(game, &fb);
parse_action_table(game, &fb);
@@ -880,7 +975,7 @@ static void load_game_data(struct comprehend_game *game) {
file_buf_unmap(&fb);
}
-void comprehend_load_game(struct comprehend_game *game) {
+void comprehend_load_game(struct comprehend_game * game) {
/* Load the main game data file */
load_game_data(game);
@@ -895,13 +990,13 @@ void comprehend_load_game(struct comprehend_game *game) {
}
#ifdef TODO
-static void patch_string_desc(uint16 *desc) {
+static void patch_string_desc(uint16 * desc) {
/*
- * String descriptors in the save file sometimes are encoded as a
- * table/index value like the instruction opcodes used, and other
- * times the are encoded as an absolute index. We fix them up to
- * all be the former type.
- */
+ * String descriptors in the save file sometimes are encoded as a
+ * table/index value like the instruction opcodes used, and other
+ * times the are encoded as an absolute index. We fix them up to
+ * all be the former type.
+ */
if (!(*desc & 0x8000) && *desc >= 0x100) {
*desc -= 0x100;
*desc |= 0x8100;
@@ -909,7 +1004,7 @@ static void patch_string_desc(uint16 *desc) {
}
#endif
-void comprehend_save_game(struct comprehend_game *game, const char *filename) {
+void comprehend_save_game(struct comprehend_game * game, const char *filename) {
#ifdef TODO
FILE *fd;
uint8 bitmask;
@@ -919,7 +1014,7 @@ void comprehend_save_game(struct comprehend_game *game, const char *filename) {
fd = fopen(filename, "w");
if (!fd) {
printf("Error: Failed to open save file '%s': %s\n",
- filename, strerror(errno));
+ filename, strerror(errno));
return;
}
@@ -946,10 +1041,10 @@ void comprehend_save_game(struct comprehend_game *game, const char *filename) {
}
/*
- * Re-Comprehend doesn't need this since the number of items is
- * determined by the currently loaded game, but the original games
- * won't load the file properly without it.
- */
+ * Re-Comprehend doesn't need this since the number of items is
+ * determined by the currently loaded game, but the original games
+ * won't load the file properly without it.
+ */
file_buf_put_skip(fd, 0x12c - ftell(fd));
file_buf_put_u8(fd, nr_items);
@@ -960,19 +1055,19 @@ void comprehend_save_game(struct comprehend_game *game, const char *filename) {
/* Rooms */
file_buf_put_array_le16(fd, 1, game->info->rooms,
- string_desc, nr_rooms);
+ string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
file_buf_put_array_u8(fd, 1, game->info->rooms,
- direction[dir], nr_rooms);
+ direction[dir], nr_rooms);
file_buf_put_array_u8(fd, 1, game->info->rooms, flags, nr_rooms);
file_buf_put_array_u8(fd, 1, game->info->rooms, graphic, nr_rooms);
/*
- * Objects
- *
- * Layout differs depending on Comprehend version. Version 2 also
- * has long string descriptions for each object.
- */
+ * Objects
+ *
+ * Layout differs depending on Comprehend version. Version 2 also
+ * has long string descriptions for each object.
+ */
file_buf_put_array_le16(fd, 0, game->info->item, string_desc, nr_items);
if (game->info->comprehend_version == 1) {
file_buf_put_array_u8(fd, 0, game->info->item, room, nr_items);
@@ -993,7 +1088,7 @@ void comprehend_save_game(struct comprehend_game *game, const char *filename) {
#endif
}
-void comprehend_restore_game(struct comprehend_game *game, const char *filename) {
+void comprehend_restore_game(struct comprehend_game * game, const char *filename) {
#ifdef TODO
struct file_buf fb;
size_t nr_rooms, nr_items;
@@ -1002,7 +1097,7 @@ void comprehend_restore_game(struct comprehend_game *game, const char *filename)
err = file_buf_map_may_fail(filename, &fb);
if (err) {
printf("Error: Failed to open save file '%s': %s\n",
- filename, strerror(-err));
+ filename, strerror(-err));
return;
}
@@ -1026,19 +1121,19 @@ void comprehend_restore_game(struct comprehend_game *game, const char *filename)
/* Restore rooms */
file_buf_get_array_le16(&fb, 1, game->info->rooms,
- string_desc, nr_rooms);
+ string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
file_buf_get_array_u8(&fb, 1, game->info->rooms,
- direction[dir], nr_rooms);
+ direction[dir], nr_rooms);
file_buf_get_array_u8(&fb, 1, game->info->rooms, flags, nr_rooms);
file_buf_get_array_u8(&fb, 1, game->info->rooms, graphic, nr_rooms);
/*
- * Restore objects
- *
- * Layout differs depending on Comprehend version. Version 2 also
- * has long string descriptions for each object.
- */
+ * Restore objects
+ *
+ * Layout differs depending on Comprehend version. Version 2 also
+ * has long string descriptions for each object.
+ */
file_buf_get_array_le16(&fb, 0, game->info->item, string_desc, nr_items);
if (game->info->comprehend_version == 1) {
file_buf_get_array_u8(&fb, 0, game->info->item, room, nr_items);
@@ -1054,9 +1149,9 @@ void comprehend_restore_game(struct comprehend_game *game, const char *filename)
}
/*
- * FIXME - The save file has some string descriptors masked with 0x8000.
- * Not sure what this means, so just mask it out for now.
- */
+ * FIXME - The save file has some string descriptors masked with 0x8000.
+ * Not sure what this means, so just mask it out for now.
+ */
for (i = 1; i <= nr_rooms; i++)
patch_string_desc(&game->info->rooms[i].string_desc);
for (i = 0; i < nr_items; i++)
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index d48b6f68fe..74636f5319 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -50,6 +50,8 @@ struct function_state {
bool _and;
bool in_command;
bool executed;
+
+ function_state();
};
struct room {
@@ -57,6 +59,8 @@ struct room {
uint8 flags;
uint8 graphic;
uint16 string_desc;
+
+ room();
};
struct item {
@@ -66,23 +70,31 @@ struct item {
uint8 flags;
uint8 word;
uint8 graphic;
+
+ item();
};
struct word {
- char word[7];
- uint8 index;
- uint8 type;
+ char _word[7];
+ uint8 _index;
+ uint8 _type;
+
+ word();
};
struct word_index {
uint8 index;
uint8 type;
+
+ word_index() : index(0), type(0) {}
};
struct word_map {
/* <word[0]>, <word[1]> == <word[2]> */
- struct word_index word[3];
+ word_index word[3];
uint8 flags;
+
+ word_map() : flags(0) {}
};
struct action {
@@ -92,6 +104,8 @@ struct action {
uint8 word[4];
uint8 word_type[4];
uint16 function;
+
+ action();
};
struct instruction {
@@ -99,16 +113,22 @@ struct instruction {
size_t nr_operands;
uint8 operand[3];
bool is_command;
+
+ instruction();
};
struct function {
- struct instruction instructions[0x100];
+ instruction instructions[0x100];
size_t nr_instructions;
+
+ function() : nr_instructions(0) {}
};
struct string_table {
char *strings[0xffff];
size_t nr_strings;
+
+ string_table();
};
struct game_header {
@@ -142,16 +162,18 @@ struct game_header {
uint16 addr_actions_v;
uint16 addr_vm; // FIXME - functions
+
+ game_header();
};
struct game_info {
- struct game_header header;
+ game_header header;
unsigned comprehend_version;
uint8 start_room;
- struct room rooms[0x100];
+ room rooms[0x100];
size_t nr_rooms;
uint8 current_room;
@@ -183,6 +205,8 @@ struct game_info {
uint8 current_replace_word;
unsigned update_flags;
+
+ game_info();
};
struct string_file {
@@ -191,8 +215,7 @@ struct string_file {
uint32 end_offset;
string_file() : filename(nullptr), base_offset(0), end_offset(0) {}
- string_file(const char *fname, uint32 baseOfs, uint32 endO = 0) :
- filename(fname), base_offset(baseOfs), end_offset(endO) {
+ string_file(const char *fname, uint32 baseOfs, uint32 endO = 0) : filename(fname), base_offset(baseOfs), end_offset(endO) {
}
};
Commit: 16b1713afd6e39d75103de93e747c39e2006c0fa
https://github.com/scummvm/scummvm/commit/16b1713afd6e39d75103de93e747c39e2006c0fa
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Change comprehend_game to ComprehendGame
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/detection.cpp
engines/glk/comprehend/detection_tables.h
engines/glk/comprehend/dictionary.cpp
engines/glk/comprehend/dictionary.h
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/dump_game_data.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_cc.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_oo.h
engines/glk/comprehend/game_tm.cpp
engines/glk/comprehend/game_tm.h
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/game_tr.h
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
engines/glk/comprehend/opcode_map.cpp
engines/glk/comprehend/opcode_map.h
engines/glk/comprehend/recomprehend.cpp
engines/glk/comprehend/strings.cpp
engines/glk/comprehend/strings.h
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index cf1eb2933d..e2a0a09bbb 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -70,7 +70,7 @@ int main(int argc, char **argv) {
{NULL, 0, 0, 0},
};
const char *short_opts = "dD:pgfw:h:?";
- struct comprehend_game *game;
+ ComprehendGame *game;
const char *game_name, *game_dir;
unsigned dump_flags = 0;
int i, c, opt_index;
@@ -153,7 +153,7 @@ void Comprehend::runGame() {
initialize();
// Lookup game
- comprehend_game *game = createGame();
+ ComprehendGame *game = createGame();
comprehend_load_game(game);
comprehend_play_game(game);
@@ -173,7 +173,7 @@ void Comprehend::deinitialize() {
glk_window_close(_textBufferWindow);
}
-comprehend_game *Comprehend::createGame() {
+ComprehendGame *Comprehend::createGame() {
if (_gameDescription._gameId == "crimsoncrown")
return new CrimsonCrownGame();
if (_gameDescription._gameId == "ootopis")
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 49b80efdb6..6b83e8896c 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -27,6 +27,7 @@
#include "glk/glk_api.h"
#include "glk/window_graphics.h"
#include "glk/window_text_buffer.h"
+#include "glk/comprehend/game.h"
namespace Glk {
namespace Comprehend {
@@ -38,7 +39,6 @@ namespace Comprehend {
#define PATH_MAX 256
-struct comprehend_game;
struct game_info;
struct game_state;
@@ -68,7 +68,7 @@ private:
*/
void deinitialize();
- comprehend_game *createGame();
+ ComprehendGame *createGame();
public:
/**
diff --git a/engines/glk/comprehend/detection.cpp b/engines/glk/comprehend/detection.cpp
index ca5074a17c..8624a3b7b9 100644
--- a/engines/glk/comprehend/detection.cpp
+++ b/engines/glk/comprehend/detection.cpp
@@ -31,12 +31,12 @@ namespace Glk {
namespace Comprehend {
void ComprehendMetaEngine::getSupportedGames(PlainGameList &games) {
- for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd)
+ for (const PlainGameDescriptor *pd = ComprehendGame_LIST; pd->gameId; ++pd)
games.push_back(*pd);
}
GameDescriptor ComprehendMetaEngine::findGame(const char *gameId) {
- for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd) {
+ for (const PlainGameDescriptor *pd = ComprehendGame_LIST; pd->gameId; ++pd) {
if (!strcmp(gameId, pd->gameId))
return *pd;
}
@@ -64,7 +64,7 @@ bool ComprehendMetaEngine::detectGames(const Common::FSList &fslist, DetectedGam
gameFile.close();
// Iterate through the known games
- const ComprehendDetectionEntry *p = COMPREHEND_GAMES;
+ const ComprehendDetectionEntry *p = ComprehendGameS;
for (; p->_gameId; ++p) {
if (filename.equalsIgnoreCase(p->_filename)) {
// Check for an md5 match
@@ -81,7 +81,7 @@ bool ComprehendMetaEngine::detectGames(const Common::FSList &fslist, DetectedGam
}
void ComprehendMetaEngine::detectClashes(Common::StringMap &map) {
- for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd) {
+ for (const PlainGameDescriptor *pd = ComprehendGame_LIST; pd->gameId; ++pd) {
if (map.contains(pd->gameId))
error("Duplicate game Id found - %s", pd->gameId);
map[pd->gameId] = "";
diff --git a/engines/glk/comprehend/detection_tables.h b/engines/glk/comprehend/detection_tables.h
index cd884b90b7..5b744f86b2 100644
--- a/engines/glk/comprehend/detection_tables.h
+++ b/engines/glk/comprehend/detection_tables.h
@@ -27,7 +27,7 @@
namespace Glk {
namespace Comprehend {
-const PlainGameDescriptor COMPREHEND_GAME_LIST[] = {
+const PlainGameDescriptor ComprehendGame_LIST[] = {
{"crimsoncrown", "Crimson Crown"},
{"ootopis", "OO-Topos"},
{"transylvania", "Transylvania"},
@@ -41,7 +41,7 @@ struct ComprehendDetectionEntry {
const char *const _md5;
};
-const ComprehendDetectionEntry COMPREHEND_GAMES[] = {
+const ComprehendDetectionEntry ComprehendGameS[] = {
// DOS games
{"crimsoncrown", "cc1.gda", "f2abf019675ac5c9bcfd81032bc7787b"},
{"transylvania", "tr.gda", "22e08633eea02ceee49b909dfd982d22"},
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
index cbab1ff0c4..4899476f89 100644
--- a/engines/glk/comprehend/dictionary.cpp
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -37,7 +37,7 @@ static bool word_match(struct word *word, const char *string)
return strncmp(word->_word, string, strlen(word->_word)) == 0;
}
-word *dict_find_word_by_string(struct comprehend_game *game,
+word *dict_find_word_by_string(ComprehendGame *game,
const char *string)
{
uint i;
@@ -52,7 +52,7 @@ word *dict_find_word_by_string(struct comprehend_game *game,
return NULL;
}
-struct word *dict_find_word_by_index_type(struct comprehend_game *game,
+struct word *dict_find_word_by_index_type(ComprehendGame *game,
uint8 index, uint8 type)
{
uint i;
@@ -66,7 +66,7 @@ struct word *dict_find_word_by_index_type(struct comprehend_game *game,
return NULL;
}
-struct word *find_dict_word_by_index(struct comprehend_game *game,
+struct word *find_dict_word_by_index(ComprehendGame *game,
uint8 index, uint8 type_mask)
{
uint i;
@@ -80,7 +80,7 @@ struct word *find_dict_word_by_index(struct comprehend_game *game,
return NULL;
}
-bool dict_match_index_type(struct comprehend_game *game, const char *word,
+bool dict_match_index_type(ComprehendGame *game, const char *word,
uint8 index, uint8 type_mask)
{
uint i;
diff --git a/engines/glk/comprehend/dictionary.h b/engines/glk/comprehend/dictionary.h
index 8efa401473..cdf4add8a8 100644
--- a/engines/glk/comprehend/dictionary.h
+++ b/engines/glk/comprehend/dictionary.h
@@ -26,16 +26,16 @@
namespace Glk {
namespace Comprehend {
-struct comprehend_game;
+class ComprehendGame;
struct word;
-struct word *find_dict_word_by_index(struct comprehend_game *game,
+struct word *find_dict_word_by_index(ComprehendGame *game,
uint8 index, uint8 type_mask);
-struct word *dict_find_word_by_index_type(struct comprehend_game *game,
+struct word *dict_find_word_by_index_type(ComprehendGame *game,
uint8 index, uint8 type);
-struct word *dict_find_word_by_string(struct comprehend_game *game,
+struct word *dict_find_word_by_string(ComprehendGame *game,
const char *string);
-bool dict_match_index_type(struct comprehend_game *game, const char *word,
+bool dict_match_index_type(ComprehendGame *game, const char *word,
uint8 index, uint8 type_mask);
} // namespace Comprehend
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index 6ef5a66478..52dde56f89 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -113,7 +113,7 @@ static const char *opcode_names[] = {
#endif
};
-void dump_instruction(struct comprehend_game *game,
+void dump_instruction(ComprehendGame *game,
struct function_state *func_state,
struct instruction *instr)
{
@@ -167,7 +167,7 @@ void dump_instruction(struct comprehend_game *game,
debugN("\n");
}
-static void dump_functions(struct comprehend_game *game)
+static void dump_functions(ComprehendGame *game)
{
struct function *func;
uint i, j;
@@ -183,7 +183,7 @@ static void dump_functions(struct comprehend_game *game)
}
}
-static void dump_action_table(struct comprehend_game *game)
+static void dump_action_table(ComprehendGame *game)
{
struct action *action;
struct word *word;
@@ -240,7 +240,7 @@ static int word_index_compare(const void *a, const void *b)
return 0;
}
-static void dump_dictionary(struct comprehend_game *game)
+static void dump_dictionary(ComprehendGame *game)
{
word *dictionary;
word *words;
@@ -263,7 +263,7 @@ static void dump_dictionary(struct comprehend_game *game)
free(dictionary);
}
-static void dump_word_map(struct comprehend_game *game)
+static void dump_word_map(ComprehendGame *game)
{
struct word *word[3];
char str[3][6];
@@ -290,7 +290,7 @@ static void dump_word_map(struct comprehend_game *game)
}
}
-static void dump_rooms(struct comprehend_game *game)
+static void dump_rooms(ComprehendGame *game)
{
struct room *room;
uint i;
@@ -317,7 +317,7 @@ static void dump_rooms(struct comprehend_game *game)
}
}
-static void dump_items(struct comprehend_game *game)
+static void dump_items(ComprehendGame *game)
{
struct item *item;
uint i, j;
@@ -356,21 +356,21 @@ static void dump_string_table(struct string_table *table)
debugN("[%.4x] %s\n", i, table->strings[i]);
}
-static void dump_game_data_strings(struct comprehend_game *game)
+static void dump_game_data_strings(ComprehendGame *game)
{
debugN("Main string table (%zd entries)\n",
game->info->strings.nr_strings);
dump_string_table(&game->info->strings);
}
-static void dump_extra_strings(struct comprehend_game *game)
+static void dump_extra_strings(ComprehendGame *game)
{
debugN("Extra strings (%zd entries)\n",
game->info->strings2.nr_strings);
dump_string_table(&game->info->strings2);
}
-static void dump_replace_words(struct comprehend_game *game)
+static void dump_replace_words(ComprehendGame *game)
{
uint i;
@@ -380,7 +380,7 @@ static void dump_replace_words(struct comprehend_game *game)
debugN(" [%.2x] %s\n", i + 1, game->info->replace_words[i]);
}
-static void dump_header(struct comprehend_game *game)
+static void dump_header(ComprehendGame *game)
{
struct game_header *header = &game->info->header;
uint16 *dir_table = header->room_direction_table;
@@ -418,7 +418,7 @@ static void dump_header(struct comprehend_game *game)
debugN(" string table end: %.4x\n", header->addr_strings_end);
}
-typedef void (*dump_func_t)(struct comprehend_game *game);
+typedef void (*dump_func_t)(ComprehendGame *game);
struct dumper {
dump_func_t dump_func;
@@ -438,7 +438,7 @@ static struct dumper dumpers[] = {
{dump_replace_words, DUMP_REPLACE_WORDS},
};
-void dump_game_data(struct comprehend_game *game, unsigned flags)
+void dump_game_data(ComprehendGame *game, unsigned flags)
{
int i;
diff --git a/engines/glk/comprehend/dump_game_data.h b/engines/glk/comprehend/dump_game_data.h
index 361a47f969..bb91757d15 100644
--- a/engines/glk/comprehend/dump_game_data.h
+++ b/engines/glk/comprehend/dump_game_data.h
@@ -26,7 +26,7 @@
namespace Glk {
namespace Comprehend {
-struct comprehend_game;
+class ComprehendGame;
struct function_state;
struct instruction;
@@ -42,10 +42,10 @@ struct instruction;
#define DUMP_HEADER (1 << 9)
#define DUMP_ALL (~0U)
-void dump_instruction(struct comprehend_game *game,
+void dump_instruction(ComprehendGame *game,
struct function_state *func_state,
struct instruction *instr);
-void dump_game_data(struct comprehend_game *game, unsigned flags);
+void dump_game_data(ComprehendGame *game, unsigned flags);
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index c55145f7a2..862ebeaa03 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -43,7 +43,7 @@ struct winsize {
};
static struct winsize console_winsize;
-comprehend_game::comprehend_game() : game_name(nullptr),
+ComprehendGame::ComprehendGame() : game_name(nullptr),
short_name(nullptr),
game_data_file(nullptr),
save_game_file_fmt(nullptr),
@@ -52,7 +52,7 @@ comprehend_game::comprehend_game() : game_name(nullptr),
info = (game_info *)malloc(sizeof(*info));
}
-comprehend_game::~comprehend_game() {
+ComprehendGame::~ComprehendGame() {
free(info);
}
@@ -72,7 +72,7 @@ int console_get_key(void) {
return c;
}
-void console_println(comprehend_game *game, const char *text) {
+void console_println(ComprehendGame *game, const char *text) {
const char *replace, *word = nullptr, *p = text;
char bad_word[64];
size_t line_length = 0;
@@ -159,7 +159,7 @@ void console_println(comprehend_game *game, const char *text) {
printf("\n");
}
-static struct room *get_room(comprehend_game *game, uint16 index) {
+static struct room *get_room(ComprehendGame *game, uint16 index) {
/* Room zero is reserved for the players inventory */
if (index == 0)
fatal_error("Room index 0 (player inventory) is invalid");
@@ -170,14 +170,14 @@ static struct room *get_room(comprehend_game *game, uint16 index) {
return &game->info->rooms[index];
}
-struct item *get_item(comprehend_game *game, uint16 index) {
+struct item *get_item(ComprehendGame *game, uint16 index) {
if (index >= game->info->header.nr_items)
fatal_error("Bad item %d\n", index);
return &game->info->item[index];
}
-void game_save(comprehend_game *game) {
+void game_save(ComprehendGame *game) {
char filename[32];
int c;
@@ -197,7 +197,7 @@ void game_save(comprehend_game *game) {
comprehend_save_game(game, filename);
}
-void game_restore(comprehend_game *game) {
+void game_restore(ComprehendGame *game) {
char filename[32];
int c;
@@ -219,7 +219,7 @@ void game_restore(comprehend_game *game) {
game->info->update_flags = UPDATE_ALL;
}
-void game_restart(comprehend_game *game) {
+void game_restart(ComprehendGame *game) {
console_println(game, string_lookup(game, game->strings->game_restart));
console_get_key();
@@ -227,7 +227,7 @@ void game_restart(comprehend_game *game) {
game->info->update_flags = UPDATE_ALL;
}
-static struct word_index *is_word_pair(comprehend_game *game,
+static struct word_index *is_word_pair(ComprehendGame *game,
struct word *word1, struct word *word2) {
struct word_map *map;
uint i;
@@ -246,7 +246,7 @@ static struct word_index *is_word_pair(comprehend_game *game,
return NULL;
}
-static struct item *get_item_by_noun(comprehend_game *game,
+static struct item *get_item_by_noun(ComprehendGame *game,
struct word *noun) {
uint i;
@@ -265,7 +265,7 @@ static struct item *get_item_by_noun(comprehend_game *game,
return NULL;
}
-static void update_graphics(comprehend_game *game) {
+static void update_graphics(ComprehendGame *game) {
struct item *item;
struct room *room;
int type;
@@ -309,7 +309,7 @@ static void update_graphics(comprehend_game *game) {
}
}
-static void describe_objects_in_current_room(comprehend_game *game) {
+static void describe_objects_in_current_room(ComprehendGame *game) {
struct item *item;
size_t count = 0;
uint i;
@@ -335,7 +335,7 @@ static void describe_objects_in_current_room(comprehend_game *game) {
}
}
-static void update(comprehend_game *game) {
+static void update(ComprehendGame *game) {
struct room *room = get_room(game, game->info->current_room);
unsigned room_type, room_desc_string;
@@ -356,7 +356,7 @@ static void update(comprehend_game *game) {
game->info->update_flags = 0;
}
-static void move_to(comprehend_game *game, uint8 room) {
+static void move_to(ComprehendGame *game, uint8 room) {
if (room - 1 >= (int)game->info->nr_rooms)
fatal_error("Attempted to move to invalid room %.2x\n", room);
@@ -383,7 +383,7 @@ static void func_set_test_result(struct function_state *func_state, bool value)
}
}
-static size_t num_objects_in_room(comprehend_game *game, int room) {
+static size_t num_objects_in_room(ComprehendGame *game, int room) {
size_t count = 0, i;
for (i = 0; i < game->info->header.nr_items; i++)
@@ -393,7 +393,7 @@ static size_t num_objects_in_room(comprehend_game *game, int room) {
return count;
}
-void move_object(comprehend_game *game, struct item *item, int new_room) {
+void move_object(ComprehendGame *game, struct item *item, int new_room) {
unsigned obj_weight = item->flags & ITEMF_WEIGHT_MASK;
if (item->room == new_room)
@@ -424,7 +424,7 @@ void move_object(comprehend_game *game, struct item *item, int new_room) {
item->room = new_room;
}
-static void eval_instruction(comprehend_game *game,
+static void eval_instruction(ComprehendGame *game,
struct function_state *func_state,
struct instruction *instr,
struct word *verb, struct word *noun) {
@@ -983,7 +983,7 @@ static void eval_instruction(comprehend_game *game,
* is reached. Otherwise the commands instructions are skipped over and the
* next test sequence (if there is one) is tried.
*/
-void eval_function(comprehend_game *game, struct function *func,
+void eval_function(ComprehendGame *game, struct function *func,
struct word *verb, struct word *noun) {
struct function_state func_state;
uint i;
@@ -1016,7 +1016,7 @@ static void skip_non_whitespace(char **p) {
}
#ifdef TODO
-static void handle_debug_command(comprehend_game *game,
+static void handle_debug_command(ComprehendGame *game,
const char *line) {
int i;
@@ -1057,7 +1057,7 @@ static void handle_debug_command(comprehend_game *game,
}
#endif
-static bool handle_sentence(comprehend_game *game,
+static bool handle_sentence(ComprehendGame *game,
struct sentence *sentence) {
struct function *func;
struct action *action;
@@ -1103,7 +1103,7 @@ static bool handle_sentence(comprehend_game *game,
return false;
}
-static void read_sentence(comprehend_game *game, char **line,
+static void read_sentence(ComprehendGame *game, char **line,
struct sentence *sentence) {
bool sentence_end = false;
char *word_string, *p = *line;
@@ -1163,7 +1163,7 @@ static void read_sentence(comprehend_game *game, char **line,
*line = p;
}
-static void before_turn(comprehend_game *game) {
+static void before_turn(ComprehendGame *game) {
// Run the game specific before turn bits
game->before_turn();
@@ -1173,12 +1173,12 @@ static void before_turn(comprehend_game *game) {
update(game);
}
-static void after_turn(comprehend_game *game) {
+static void after_turn(ComprehendGame *game) {
// Do post turn game specific bits
game->after_turn();
}
-static void read_input(comprehend_game *game) {
+static void read_input(ComprehendGame *game) {
#ifdef TODO
struct sentence sentence;
char *line = NULL, buffer[1024];
@@ -1218,7 +1218,7 @@ static void read_input(comprehend_game *game) {
#endif
}
-void comprehend_play_game(comprehend_game *game) {
+void comprehend_play_game(ComprehendGame *game) {
console_init();
game->before_game();
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 6a3d80b607..1d0b8c02e3 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_COMPREHEND_GAME_H
-#define GLK_COMPREHEND_GAME_H
+#ifndef GLK_ComprehendGame_H
+#define GLK_ComprehendGame_H
#include "common/array.h"
#include "glk/comprehend/game_data.h"
@@ -33,7 +33,7 @@ namespace Comprehend {
#define ROOM_IS_DARK 1
#define ROOM_IS_TOO_BRIGHT 2
-struct comprehend_game {
+class ComprehendGame {
public:
const char *game_name;
const char *short_name;
@@ -49,8 +49,8 @@ public:
struct game_info *info;
public:
- comprehend_game();
- virtual ~comprehend_game();
+ ComprehendGame();
+ virtual ~ComprehendGame();
virtual void before_game() {}
virtual void before_prompt() {}
@@ -67,18 +67,18 @@ public:
virtual void handle_special_opcode(uint8 operand) {}
};
-void console_println(comprehend_game *game, const char *text);
+void console_println(ComprehendGame *game, const char *text);
int console_get_key(void);
-struct item *get_item(comprehend_game *game, uint16 index);
-void move_object(comprehend_game *game, struct item *item, int new_room);
-void eval_function(comprehend_game *game, struct function *func,
+struct item *get_item(ComprehendGame *game, uint16 index);
+void move_object(ComprehendGame *game, struct item *item, int new_room);
+void eval_function(ComprehendGame *game, struct function *func,
struct word *verb, struct word *noun);
-void comprehend_play_game(comprehend_game *game);
-void game_save(comprehend_game *game);
-void game_restore(comprehend_game *game);
-void game_restart(comprehend_game *game);
+void comprehend_play_game(ComprehendGame *game);
+void game_save(ComprehendGame *game);
+void game_restore(ComprehendGame *game);
+void game_restart(ComprehendGame *game);
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index 9bc6a3daa3..74e5cdfe1e 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -38,7 +38,7 @@ static struct game_ops cc2_ops = {
cc2_handle_special_opcode};
#endif
-CrimsonCrownGame::CrimsonCrownGame() : comprehend_game() {
+CrimsonCrownGame::CrimsonCrownGame() : ComprehendGame() {
game_name = "Crimson Crown";
short_name = "cc1";
game_data_file = "cc1.gda";
@@ -55,7 +55,7 @@ CrimsonCrownGame::CrimsonCrownGame() : comprehend_game() {
}
#ifdef TODO
-struct comprehend_game game_crimson_crown_2 = {
+ComprehendGame game_crimson_crown_2 = {
"Crimson Crown (Part 2/2)",
"cc2",
"CC2.GDA",
@@ -69,13 +69,13 @@ struct comprehend_game game_crimson_crown_2 = {
nullptr};
#endif
-static void cc_clear_companion_flags(struct comprehend_game *game) {
+static void cc_clear_companion_flags(ComprehendGame *game) {
/* Clear the Sabrina/Erik action flags */
game->info->flags[0xa] = 0;
game->info->flags[0xb] = 0;
}
-static bool cc_common_handle_special_opcode(struct comprehend_game *game,
+static bool cc_common_handle_special_opcode(ComprehendGame *game,
uint8 operand) {
switch (operand) {
case 0x03:
@@ -120,7 +120,7 @@ void CrimsonCrownGame::handle_special_opcode(uint8 operand) {
}
}
-static void cc2_handle_special_opcode(struct comprehend_game *game,
+static void cc2_handle_special_opcode(ComprehendGame *game,
uint8 operand) {
if (cc_common_handle_special_opcode(game, operand))
return;
@@ -142,7 +142,7 @@ static void cc2_handle_special_opcode(struct comprehend_game *game,
}
}
-static void cc2_before_prompt(struct comprehend_game *game) {
+static void cc2_before_prompt(ComprehendGame *game) {
cc_clear_companion_flags(game);
}
diff --git a/engines/glk/comprehend/game_cc.h b/engines/glk/comprehend/game_cc.h
index ccbbc147a9..a60d9f2317 100644
--- a/engines/glk/comprehend/game_cc.h
+++ b/engines/glk/comprehend/game_cc.h
@@ -20,15 +20,15 @@
*
*/
-#ifndef GLK_COMPREHEND_GAME_CC_H
-#define GLK_COMPREHEND_GAME_CC_H
+#ifndef GLK_ComprehendGame_CC_H
+#define GLK_ComprehendGame_CC_H
#include "glk/comprehend/game.h"
namespace Glk {
namespace Comprehend {
-class CrimsonCrownGame : public comprehend_game {
+class CrimsonCrownGame : public ComprehendGame {
public:
CrimsonCrownGame();
~CrimsonCrownGame() override {}
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 5c92182e2d..ea3d2eae07 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -187,7 +187,7 @@ static void parse_function(struct file_buf * fb, struct function * func) {
}
}
-static void parse_vm(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_vm(ComprehendGame * game, struct file_buf * fb) {
struct function *func;
file_buf_set_pos(fb, game->info->header.addr_vm);
@@ -202,7 +202,7 @@ static void parse_vm(struct comprehend_game * game, struct file_buf * fb) {
}
}
-static void parse_action_table_vvnn(struct comprehend_game * game,
+static void parse_action_table_vvnn(ComprehendGame * game,
struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
@@ -246,7 +246,7 @@ static void parse_action_table_vvnn(struct comprehend_game * game,
}
}
-static void parse_action_table_vnjn(struct comprehend_game * game,
+static void parse_action_table_vnjn(ComprehendGame * game,
struct file_buf * fb, size_t * index) {
struct action *action;
uint8 join, count;
@@ -291,7 +291,7 @@ static void parse_action_table_vnjn(struct comprehend_game * game,
}
}
-static void parse_action_table_vjn(struct comprehend_game * game,
+static void parse_action_table_vjn(ComprehendGame * game,
struct file_buf * fb, size_t * index) {
struct action *action;
uint8 join, count;
@@ -332,7 +332,7 @@ static void parse_action_table_vjn(struct comprehend_game * game,
}
}
-static void parse_action_table_vdn(struct comprehend_game * game,
+static void parse_action_table_vdn(ComprehendGame * game,
struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
@@ -373,7 +373,7 @@ static void parse_action_table_vdn(struct comprehend_game * game,
}
}
-static void parse_action_table_vnn(struct comprehend_game * game,
+static void parse_action_table_vnn(ComprehendGame * game,
struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
@@ -415,7 +415,7 @@ static void parse_action_table_vnn(struct comprehend_game * game,
}
}
-static void parse_action_table_vn(struct comprehend_game * game,
+static void parse_action_table_vn(ComprehendGame * game,
struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, count;
@@ -454,7 +454,7 @@ static void parse_action_table_vn(struct comprehend_game * game,
}
}
-static void parse_action_table_v(struct comprehend_game * game,
+static void parse_action_table_v(ComprehendGame * game,
struct file_buf * fb, size_t * index) {
struct action *action;
uint8 verb, nr_funcs;
@@ -497,7 +497,7 @@ static void parse_action_table_v(struct comprehend_game * game,
}
}
-static void parse_action_table(struct comprehend_game * game,
+static void parse_action_table(ComprehendGame * game,
struct file_buf * fb) {
game->info->nr_actions = 0;
@@ -515,7 +515,7 @@ static void parse_action_table(struct comprehend_game * game,
parse_action_table_v(game, fb, &game->info->nr_actions);
}
-static void parse_dictionary(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
word *words;
uint i, j;
@@ -538,7 +538,7 @@ static void parse_dictionary(struct comprehend_game * game, struct file_buf * fb
}
}
-static void parse_word_map(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
struct word_map *map;
uint8 index, type, dummy;
uint i;
@@ -586,7 +586,7 @@ static void parse_word_map(struct comprehend_game * game, struct file_buf * fb)
}
}
-static void parse_items(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_items(ComprehendGame * game, struct file_buf * fb) {
size_t nr_items = game->info->header.nr_items;
/* Item descriptions */
@@ -617,7 +617,7 @@ static void parse_items(struct comprehend_game * game, struct file_buf * fb) {
file_buf_get_array_u8(fb, 0, game->info->item, graphic, nr_items);
}
-static void parse_rooms(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_rooms(ComprehendGame * game, struct file_buf * fb) {
size_t nr_rooms = game->info->nr_rooms;
int i;
@@ -748,14 +748,14 @@ static void parse_string_table(struct file_buf * fb, unsigned start_addr,
}
}
-static void parse_variables(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_variables(ComprehendGame * game, struct file_buf * fb) {
int i;
for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
file_buf_get_le16(fb, &game->info->variable[i]);
}
-static void parse_flags(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_flags(ComprehendGame * game, struct file_buf * fb) {
int i, bit, flag_index = 0;
uint8 bitmask;
@@ -768,7 +768,7 @@ static void parse_flags(struct comprehend_game * game, struct file_buf * fb) {
}
}
-static void parse_replace_words(struct comprehend_game * game,
+static void parse_replace_words(ComprehendGame * game,
struct file_buf * fb) {
uint16 dummy;
size_t len;
@@ -798,7 +798,7 @@ static void parse_replace_words(struct comprehend_game * game,
* The main game data file header has the offsets for where each bit of
* game data is. The offsets have a magic constant value added to them.
*/
-static void parse_header(struct comprehend_game * game, struct file_buf * fb) {
+static void parse_header(ComprehendGame * game, struct file_buf * fb) {
struct game_header *header = &game->info->header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
@@ -916,7 +916,7 @@ static void parse_header(struct comprehend_game * game, struct file_buf * fb) {
8;
}
-static void load_extra_string_file(comprehend_game * game,
+static void load_extra_string_file(ComprehendGame * game,
string_file * string_file) {
struct file_buf fb;
unsigned end;
@@ -934,7 +934,7 @@ static void load_extra_string_file(comprehend_game * game,
file_buf_unmap(&fb);
}
-static void load_extra_string_files(comprehend_game * game) {
+static void load_extra_string_files(ComprehendGame * game) {
int i;
memset(&game->info->strings2, 0, sizeof(game->info->strings2));
@@ -952,7 +952,7 @@ static void load_extra_string_files(comprehend_game * game) {
}
}
-static void load_game_data(struct comprehend_game * game) {
+static void load_game_data(ComprehendGame * game) {
struct file_buf fb;
memset(game->info, 0, sizeof(*game->info));
@@ -975,7 +975,7 @@ static void load_game_data(struct comprehend_game * game) {
file_buf_unmap(&fb);
}
-void comprehend_load_game(struct comprehend_game * game) {
+void comprehend_load_game(ComprehendGame * game) {
/* Load the main game data file */
load_game_data(game);
@@ -1004,7 +1004,7 @@ static void patch_string_desc(uint16 * desc) {
}
#endif
-void comprehend_save_game(struct comprehend_game * game, const char *filename) {
+void comprehend_save_game(ComprehendGame * game, const char *filename) {
#ifdef TODO
FILE *fd;
uint8 bitmask;
@@ -1088,7 +1088,7 @@ void comprehend_save_game(struct comprehend_game * game, const char *filename) {
#endif
}
-void comprehend_restore_game(struct comprehend_game * game, const char *filename) {
+void comprehend_restore_game(ComprehendGame * game, const char *filename) {
#ifdef TODO
struct file_buf fb;
size_t nr_rooms, nr_items;
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 74636f5319..4146bf8ba5 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_COMPREHEND_GAME_DATA_H
-#define GLK_COMPREHEND_GAME_DATA_H
+#ifndef GLK_ComprehendGame_DATA_H
+#define GLK_ComprehendGame_DATA_H
#include "glk/comprehend/image_data.h"
@@ -341,10 +341,10 @@ enum {
#define WORD_TYPE_NOUN_MASK (WORD_TYPE_FEMALE | WORD_TYPE_MALE | \
WORD_TYPE_NOUN | WORD_TYPE_NOUN_PLURAL)
-void comprehend_load_game(struct comprehend_game *game);
-void comprehend_restore_game(struct comprehend_game *game,
+void comprehend_load_game(ComprehendGame *game);
+void comprehend_restore_game(ComprehendGame *game,
const char *filename);
-void comprehend_save_game(struct comprehend_game *game, const char *filename);
+void comprehend_save_game(ComprehendGame *game, const char *filename);
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index ab6a67c4bb..c53c6bf824 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -34,7 +34,7 @@ namespace Comprehend {
#define OO_FLAG_WEARING_GOGGLES 0x1b
#define OO_FLAG_FLASHLIGHT_ON 0x27
-OOToposGame::OOToposGame() : comprehend_game() {
+OOToposGame::OOToposGame() : ComprehendGame() {
game_name = "Oo-Topos";
short_name = "oo";
game_data_file = "g0";
diff --git a/engines/glk/comprehend/game_oo.h b/engines/glk/comprehend/game_oo.h
index c1b1f767e4..469a85e384 100644
--- a/engines/glk/comprehend/game_oo.h
+++ b/engines/glk/comprehend/game_oo.h
@@ -20,15 +20,15 @@
*
*/
-#ifndef GLK_COMPREHEND_GAME_OO_H
-#define GLK_COMPREHEND_GAME_OO_H
+#ifndef GLK_ComprehendGame_OO_H
+#define GLK_ComprehendGame_OO_H
#include "glk/comprehend/game.h"
namespace Glk {
namespace Comprehend {
-class OOToposGame : public comprehend_game {
+class OOToposGame : public ComprehendGame {
public:
OOToposGame();
~OOToposGame() override {}
diff --git a/engines/glk/comprehend/game_tm.cpp b/engines/glk/comprehend/game_tm.cpp
index 35b1f03a9e..ad714fb398 100644
--- a/engines/glk/comprehend/game_tm.cpp
+++ b/engines/glk/comprehend/game_tm.cpp
@@ -28,7 +28,7 @@ namespace Comprehend {
/* FIXME - This is broken */
-TalismanGame::TalismanGame() : comprehend_game() {
+TalismanGame::TalismanGame() : ComprehendGame() {
game_name = "Talisman, Challenging the Sands of Time (broken)";
short_name = "tm";
game_data_file = "G0";
diff --git a/engines/glk/comprehend/game_tm.h b/engines/glk/comprehend/game_tm.h
index 70f8537102..86c9cf20bb 100644
--- a/engines/glk/comprehend/game_tm.h
+++ b/engines/glk/comprehend/game_tm.h
@@ -20,15 +20,15 @@
*
*/
-#ifndef GLK_COMPREHEND_GAME_TM_H
-#define GLK_COMPREHEND_GAME_TM_H
+#ifndef GLK_ComprehendGame_TM_H
+#define GLK_ComprehendGame_TM_H
#include "glk/comprehend/game.h"
namespace Glk {
namespace Comprehend {
-class TalismanGame : public comprehend_game {
+class TalismanGame : public ComprehendGame {
public:
TalismanGame();
~TalismanGame() override {}
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 9596e48b42..f03fc29321 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -41,7 +41,7 @@ static struct game_strings tr_strings = {
};
-TransylvaniaGame::TransylvaniaGame() : comprehend_game() {
+TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
game_name = "Transylvania";
short_name = "tr";
game_data_file = "tr.gda";
diff --git a/engines/glk/comprehend/game_tr.h b/engines/glk/comprehend/game_tr.h
index 74dc09ba55..634588c58f 100644
--- a/engines/glk/comprehend/game_tr.h
+++ b/engines/glk/comprehend/game_tr.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_COMPREHEND_GAME_TR_H
-#define GLK_COMPREHEND_GAME_TR_H
+#ifndef GLK_ComprehendGame_TR_H
+#define GLK_ComprehendGame_TR_H
#include "glk/comprehend/game.h"
@@ -36,7 +36,7 @@ struct tr_monster {
unsigned randomness;
};
-class TransylvaniaGame : public comprehend_game {
+class TransylvaniaGame : public ComprehendGame {
private:
static const tr_monster WEREWOLF;
static const tr_monster VAMPIRE;
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index d5751d3038..7f783abe7c 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -348,7 +348,7 @@ void comprehend_load_image_file(const char *filename, struct image_data *info)
load_image_files(info, filenames);
}
-void comprehend_load_images(comprehend_game *game) {
+void comprehend_load_images(ComprehendGame *game) {
load_image_files(&game->info->room_images,
game->location_graphic_files);
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index 9a2c1882c1..ece82e98a4 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -28,7 +28,7 @@
namespace Glk {
namespace Comprehend {
-struct comprehend_game;
+class ComprehendGame;
struct file_buf;
struct image_data {
@@ -91,7 +91,7 @@ void draw_image(image_data *info, unsigned index);
void draw_location_image(image_data *info, unsigned index);
void comprehend_load_image_file(const char *filename, image_data *info);
-void comprehend_load_images(comprehend_game *game);
+void comprehend_load_images(ComprehendGame *game);
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/opcode_map.cpp b/engines/glk/comprehend/opcode_map.cpp
index 30d1932a70..61b0526b48 100644
--- a/engines/glk/comprehend/opcode_map.cpp
+++ b/engines/glk/comprehend/opcode_map.cpp
@@ -173,7 +173,7 @@ static uint8 opcode_map_v2[0x100] = {
#endif
};
-uint8 *get_opcode_map(comprehend_game *game)
+uint8 *get_opcode_map(ComprehendGame *game)
{
switch (game->info->comprehend_version) {
case 1:
diff --git a/engines/glk/comprehend/opcode_map.h b/engines/glk/comprehend/opcode_map.h
index 73eb5eb014..102a88dee6 100644
--- a/engines/glk/comprehend/opcode_map.h
+++ b/engines/glk/comprehend/opcode_map.h
@@ -28,7 +28,7 @@
namespace Glk {
namespace Comprehend {
-uint8 *get_opcode_map(comprehend_game *game);
+uint8 *get_opcode_map(ComprehendGame *game);
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/recomprehend.cpp b/engines/glk/comprehend/recomprehend.cpp
index a6646c0798..193bdad487 100644
--- a/engines/glk/comprehend/recomprehend.cpp
+++ b/engines/glk/comprehend/recomprehend.cpp
@@ -30,13 +30,13 @@
namespace Glk {
namespace Comprehend {
-extern struct comprehend_game game_transylvania;
-extern struct comprehend_game game_crimson_crown_1;
-extern struct comprehend_game game_crimson_crown_2;
-extern struct comprehend_game game_oo_topos;
-extern struct comprehend_game game_talisman;
+extern ComprehendGame game_transylvania;
+extern ComprehendGame game_crimson_crown_1;
+extern ComprehendGame game_crimson_crown_2;
+extern ComprehendGame game_oo_topos;
+extern ComprehendGame game_talisman;
-static struct comprehend_game *comprehend_games[] = {
+static ComprehendGame *ComprehendGames[] = {
&game_transylvania,
&game_crimson_crown_1,
&game_crimson_crown_2,
@@ -80,9 +80,9 @@ static void usage(const char *progname)
printf(" -h, --graphics-height=HEIGHT Graphics height\n");
printf("\nSupported games:\n");
- for (i = 0; i < ARRAY_SIZE(comprehend_games); i++)
- printf(" %-10s %s\n", comprehend_games[i]->short_name,
- comprehend_games[i]->game_name);
+ for (i = 0; i < ARRAY_SIZE(ComprehendGames); i++)
+ printf(" %-10s %s\n", ComprehendGames[i]->short_name,
+ ComprehendGames[i]->game_name);
exit(EXIT_FAILURE);
}
@@ -101,7 +101,7 @@ int main(int argc, char **argv)
{NULL, 0, 0, 0},
};
const char *short_opts = "dD:pgfw:h:?";
- struct comprehend_game *game;
+ ComprehendGame *game;
const char *game_name, *game_dir;
unsigned dump_flags = 0;
int i, c, opt_index;
@@ -171,9 +171,9 @@ int main(int argc, char **argv)
/* Lookup game */
game = NULL;
- for (i = 0; i < ARRAY_SIZE(comprehend_games); i++) {
- if (strcmp(game_name, comprehend_games[i]->short_name) == 0) {
- game = comprehend_games[i];
+ for (i = 0; i < ARRAY_SIZE(ComprehendGames); i++) {
+ if (strcmp(game_name, ComprehendGames[i]->short_name) == 0) {
+ game = ComprehendGames[i];
break;
}
}
diff --git a/engines/glk/comprehend/strings.cpp b/engines/glk/comprehend/strings.cpp
index 9bae241f97..784dfec506 100644
--- a/engines/glk/comprehend/strings.cpp
+++ b/engines/glk/comprehend/strings.cpp
@@ -30,7 +30,7 @@ namespace Comprehend {
static char bad_string[128];
-const char *string_lookup(comprehend_game *game, uint16 index)
+const char *string_lookup(ComprehendGame *game, uint16 index)
{
uint16 string;
uint8 table;
@@ -73,7 +73,7 @@ const char *string_lookup(comprehend_game *game, uint16 index)
return bad_string;
}
-const char *instr_lookup_string(struct comprehend_game *game, uint8 index,
+const char *instr_lookup_string(ComprehendGame *game, uint8 index,
uint8 table)
{
return string_lookup(game, table << 8 | index);
diff --git a/engines/glk/comprehend/strings.h b/engines/glk/comprehend/strings.h
index b3994cc257..4d5a40db11 100644
--- a/engines/glk/comprehend/strings.h
+++ b/engines/glk/comprehend/strings.h
@@ -26,10 +26,10 @@
namespace Glk {
namespace Comprehend {
-struct comprehend_game;
+class ComprehendGame;
-const char *string_lookup(struct comprehend_game *game, uint16 index);
-const char *instr_lookup_string(struct comprehend_game *game, uint8 index,
+const char *string_lookup(ComprehendGame *game, uint16 index);
+const char *instr_lookup_string(ComprehendGame *game, uint8 index,
uint8 table);
} // namespace Comprehend
Commit: 14cf02cc1b3d5aebcbb2370b36720fe222cf9ba0
https://github.com/scummvm/scummvm/commit/14cf02cc1b3d5aebcbb2370b36720fe222cf9ba0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Field renamings
Changed paths:
engines/glk/comprehend/dictionary.cpp
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tm.cpp
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/opcode_map.cpp
engines/glk/comprehend/strings.cpp
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
index 4899476f89..4ca9d545ac 100644
--- a/engines/glk/comprehend/dictionary.cpp
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -45,9 +45,9 @@ word *dict_find_word_by_string(ComprehendGame *game,
if (!string)
return NULL;
- for (i = 0; i < game->info->nr_words; i++)
- if (word_match(&game->info->words[i], string))
- return &game->info->words[i];
+ for (i = 0; i < game->info->_nr_words; i++)
+ if (word_match(&game->info->_words[i], string))
+ return &game->info->_words[i];
return NULL;
}
@@ -57,10 +57,10 @@ struct word *dict_find_word_by_index_type(ComprehendGame *game,
{
uint i;
- for (i = 0; i < game->info->nr_words; i++) {
- if (game->info->words[i]._index == index &&
- game->info->words[i]._type == type)
- return &game->info->words[i];
+ for (i = 0; i < game->info->_nr_words; i++) {
+ if (game->info->_words[i]._index == index &&
+ game->info->_words[i]._type == type)
+ return &game->info->_words[i];
}
return NULL;
@@ -71,10 +71,10 @@ struct word *find_dict_word_by_index(ComprehendGame *game,
{
uint i;
- for (i = 0; i < game->info->nr_words; i++) {
- if (game->info->words[i]._index == index &&
- (game->info->words[i]._type & type_mask) != 0)
- return &game->info->words[i];
+ for (i = 0; i < game->info->_nr_words; i++) {
+ if (game->info->_words[i]._index == index &&
+ (game->info->_words[i]._type & type_mask) != 0)
+ return &game->info->_words[i];
}
return NULL;
@@ -85,10 +85,10 @@ bool dict_match_index_type(ComprehendGame *game, const char *word,
{
uint i;
- for (i = 0; i < game->info->nr_words; i++)
- if (game->info->words[i]._index == index &&
- ((game->info->words[i]._type & type_mask) != 0) &&
- word_match(&game->info->words[i], word))
+ for (i = 0; i < game->info->_nr_words; i++)
+ if (game->info->_words[i]._index == index &&
+ ((game->info->_words[i]._type & type_mask) != 0) &&
+ word_match(&game->info->_words[i], word))
return true;
return false;
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index 52dde56f89..16ac91262b 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -160,7 +160,7 @@ void dump_instruction(ComprehendGame *game,
break;
case OPCODE_SET_STRING_REPLACEMENT:
- debugN(" %s", game->info->replace_words[instr->operand[0] - 1]);
+ debugN(" %s", game->info->_replaceWords[instr->operand[0] - 1]);
break;
}
@@ -172,9 +172,9 @@ static void dump_functions(ComprehendGame *game)
struct function *func;
uint i, j;
- debugN("Functions (%zd entries)\n", game->info->nr_functions);
- for (i = 0; i < game->info->nr_functions; i++) {
- func = &game->info->functions[i];
+ debugN("Functions (%zd entries)\n", game->info->_nr_functions);
+ for (i = 0; i < game->info->_nr_functions; i++) {
+ func = &game->info->_functions[i];
debugN("[%.4x] (%zd instructions)\n", i, func->nr_instructions);
for (j = 0; j < func->nr_instructions; j++)
@@ -189,9 +189,9 @@ static void dump_action_table(ComprehendGame *game)
struct word *word;
uint i, j;
- debugN("Action table (%zd entries)\n", game->info->nr_actions);
- for (i = 0; i < game->info->nr_actions; i++) {
- action = &game->info->action[i];
+ debugN("Action table (%zd entries)\n", game->info->_nr_actions);
+ for (i = 0; i < game->info->_nr_actions; i++) {
+ action = &game->info->_actions[i];
debugN("(");
for (j = 0; j < 4; j++) {
@@ -247,14 +247,14 @@ static void dump_dictionary(ComprehendGame *game)
uint i;
/* Sort the dictionary by index */
- dictionary = (word *)xmalloc(sizeof(*words) * game->info->nr_words);
- memcpy(dictionary, game->info->words,
- sizeof(*words) * game->info->nr_words);
- qsort(dictionary, game->info->nr_words, sizeof(*words),
+ dictionary = (word *)xmalloc(sizeof(*words) * game->info->_nr_words);
+ memcpy(dictionary, game->info->_words,
+ sizeof(*words) * game->info->_nr_words);
+ qsort(dictionary, game->info->_nr_words, sizeof(*words),
word_index_compare);
- debugN("Dictionary (%zd words)\n", game->info->nr_words);
- for (i = 0; i < game->info->nr_words; i++) {
+ debugN("Dictionary (%zd words)\n", game->info->_nr_words);
+ for (i = 0; i < game->info->_nr_words; i++) {
words = &dictionary[i];
debugN(" [%.2x] %.2x %s\n", words->_index, words->_type,
words->_word);
@@ -270,9 +270,9 @@ static void dump_word_map(ComprehendGame *game)
struct word_map *map;
uint i, j;
- debugN("Word pairs (%zd entries)\n", game->info->nr_word_maps);
- for (i = 0; i < game->info->nr_word_maps; i++) {
- map = &game->info->word_map[i];
+ debugN("Word pairs (%zd entries)\n", game->info->_nr_word_maps);
+ for (i = 0; i < game->info->_nr_word_maps; i++) {
+ map = &game->info->_wordMaps[i];
for (j = 0; j < 3; j++) {
word[j] = dict_find_word_by_index_type(
@@ -296,9 +296,9 @@ static void dump_rooms(ComprehendGame *game)
uint i;
/* Room zero acts as the players inventory */
- debugN("Rooms (%zd entries)\n", game->info->nr_rooms);
- for (i = 1; i <= game->info->nr_rooms; i++) {
- room = &game->info->rooms[i];
+ debugN("Rooms (%zd entries)\n", game->info->_nr_rooms);
+ for (i = 1; i <= game->info->_nr_rooms; i++) {
+ room = &game->info->_rooms[i];
debugN(" [%.2x] flags=%.2x, graphic=%.2x\n",
i, room->flags, room->graphic);
@@ -322,22 +322,22 @@ static void dump_items(ComprehendGame *game)
struct item *item;
uint i, j;
- debugN("Items (%zd entries)\n", game->info->header.nr_items);
- for (i = 0; i < game->info->header.nr_items; i++) {
- item = &game->info->item[i];
+ debugN("Items (%zd entries)\n", game->info->_header.nr_items);
+ for (i = 0; i < game->info->_header.nr_items; i++) {
+ item = &game->info->_item[i];
debugN(" [%.2x] %s\n", i + 1,
item->string_desc ?
string_lookup(game, item->string_desc) : "");
- if (game->info->comprehend_version == 2)
+ if (game->info->_comprehendVersion == 2)
debugN(" long desc: %s\n",
string_lookup(game, item->long_string));
debugN(" words: ");
- for (j = 0; j < game->info->nr_words; j++)
- if (game->info->words[j]._index == item->word &&
- (game->info->words[j]._type & WORD_TYPE_NOUN_MASK))
- debugN("%s ", game->info->words[j]._word);
+ for (j = 0; j < game->info->_nr_words; j++)
+ if (game->info->_words[j]._index == item->word &&
+ (game->info->_words[j]._type & WORD_TYPE_NOUN_MASK))
+ debugN("%s ", game->info->_words[j]._word);
debugN("\n");
debugN(" flags=%.2x (takeable=%d, weight=%d)\n",
item->flags, !!(item->flags & ITEMF_CAN_TAKE),
@@ -359,15 +359,15 @@ static void dump_string_table(struct string_table *table)
static void dump_game_data_strings(ComprehendGame *game)
{
debugN("Main string table (%zd entries)\n",
- game->info->strings.nr_strings);
- dump_string_table(&game->info->strings);
+ game->info->_strings.nr_strings);
+ dump_string_table(&game->info->_strings);
}
static void dump_extra_strings(ComprehendGame *game)
{
debugN("Extra strings (%zd entries)\n",
- game->info->strings2.nr_strings);
- dump_string_table(&game->info->strings2);
+ game->info->_strings2.nr_strings);
+ dump_string_table(&game->info->_strings2);
}
static void dump_replace_words(ComprehendGame *game)
@@ -375,14 +375,14 @@ static void dump_replace_words(ComprehendGame *game)
uint i;
debugN("Replacement words (%zd entries)\n",
- game->info->nr_replace_words);
- for (i = 0; i < game->info->nr_replace_words; i++)
- debugN(" [%.2x] %s\n", i + 1, game->info->replace_words[i]);
+ game->info->_nr_replace_words);
+ for (i = 0; i < game->info->_nr_replace_words; i++)
+ debugN(" [%.2x] %s\n", i + 1, game->info->_replaceWords[i]);
}
static void dump_header(ComprehendGame *game)
{
- struct game_header *header = &game->info->header;
+ struct game_header *header = &game->info->_header;
uint16 *dir_table = header->room_direction_table;
debugN("Game header:\n");
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 862ebeaa03..ff95370978 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -43,12 +43,12 @@ struct winsize {
};
static struct winsize console_winsize;
-ComprehendGame::ComprehendGame() : game_name(nullptr),
- short_name(nullptr),
- game_data_file(nullptr),
- save_game_file_fmt(nullptr),
- color_table(0),
- strings(nullptr) {
+ComprehendGame::ComprehendGame() : _gameName(nullptr),
+ _shortName(nullptr),
+ _gameDataFile(nullptr),
+ _savegameFileFormat(nullptr),
+ _colorTable(0),
+ _gameStrings(nullptr) {
info = (game_info *)malloc(sizeof(*info));
}
@@ -95,13 +95,13 @@ void console_println(ComprehendGame *game, const char *text) {
case '@':
/* Replace word */
- if (game->info->current_replace_word >= game->info->nr_replace_words) {
+ if (game->info->_currentReplaceWord >= game->info->_nr_replace_words) {
snprintf(bad_word, sizeof(bad_word),
"[BAD_REPLACE_WORD(%.2x)]",
- game->info->current_replace_word);
+ game->info->_currentReplaceWord);
word = bad_word;
} else {
- word = game->info->replace_words[game->info->current_replace_word];
+ word = game->info->_replaceWords[game->info->_currentReplaceWord];
}
word_len = strlen(word);
p++;
@@ -164,24 +164,24 @@ static struct room *get_room(ComprehendGame *game, uint16 index) {
if (index == 0)
fatal_error("Room index 0 (player inventory) is invalid");
- if (index - 1 >= (int)game->info->nr_rooms)
+ if (index - 1 >= (int)game->info->_nr_rooms)
fatal_error("Room index %d is invalid", index);
- return &game->info->rooms[index];
+ return &game->info->_rooms[index];
}
struct item *get_item(ComprehendGame *game, uint16 index) {
- if (index >= game->info->header.nr_items)
+ if (index >= game->info->_header.nr_items)
fatal_error("Bad item %d\n", index);
- return &game->info->item[index];
+ return &game->info->_item[index];
}
void game_save(ComprehendGame *game) {
char filename[32];
int c;
- console_println(game, game->info->strings.strings[STRING_SAVE_GAME]);
+ console_println(game, game->info->_strings.strings[STRING_SAVE_GAME]);
c = console_get_key();
if (c < '1' || c > '3') {
@@ -193,7 +193,7 @@ void game_save(ComprehendGame *game) {
return;
}
- snprintf(filename, sizeof(filename), game->save_game_file_fmt, c - '0');
+ snprintf(filename, sizeof(filename), game->_savegameFileFormat, c - '0');
comprehend_save_game(game, filename);
}
@@ -201,7 +201,7 @@ void game_restore(ComprehendGame *game) {
char filename[32];
int c;
- console_println(game, game->info->strings.strings[STRING_RESTORE_GAME]);
+ console_println(game, game->info->_strings.strings[STRING_RESTORE_GAME]);
c = console_get_key();
if (c < '1' || c > '3') {
@@ -213,18 +213,18 @@ void game_restore(ComprehendGame *game) {
return;
}
- snprintf(filename, sizeof(filename), game->save_game_file_fmt, c - '0');
+ snprintf(filename, sizeof(filename), game->_savegameFileFormat, c - '0');
comprehend_restore_game(game, filename);
- game->info->update_flags = UPDATE_ALL;
+ game->info->_updateFlags = UPDATE_ALL;
}
void game_restart(ComprehendGame *game) {
- console_println(game, string_lookup(game, game->strings->game_restart));
+ console_println(game, string_lookup(game, game->_gameStrings->game_restart));
console_get_key();
comprehend_load_game(game);
- game->info->update_flags = UPDATE_ALL;
+ game->info->_updateFlags = UPDATE_ALL;
}
static struct word_index *is_word_pair(ComprehendGame *game,
@@ -233,8 +233,8 @@ static struct word_index *is_word_pair(ComprehendGame *game,
uint i;
/* Check if this is a word pair */
- for (i = 0; i < game->info->nr_word_maps; i++) {
- map = &game->info->word_map[i];
+ for (i = 0; i < game->info->_nr_word_maps; i++) {
+ map = &game->info->_wordMaps[i];
if (map->word[0].index == word1->_index &&
map->word[0].type == word1->_type &&
@@ -258,9 +258,9 @@ static struct item *get_item_by_noun(ComprehendGame *game,
* (the box and the snarl-in-a-box). The player is unable
* to drop the latter because this will match the former.
*/
- for (i = 0; i < game->info->header.nr_items; i++)
- if (game->info->item[i].word == noun->_index)
- return &game->info->item[i];
+ for (i = 0; i < game->info->_header.nr_items; i++)
+ if (game->info->_item[i].word == noun->_index)
+ return &game->info->_item[i];
return NULL;
}
@@ -274,34 +274,34 @@ static void update_graphics(ComprehendGame *game) {
if (!g_enabled())
return;
- type = game->room_is_special(game->info->current_room, NULL);
+ type = game->room_is_special(game->info->_currentRoom, NULL);
switch (type) {
case ROOM_IS_DARK:
- if (game->info->update_flags & UPDATE_GRAPHICS)
+ if (game->info->_updateFlags & UPDATE_GRAPHICS)
draw_dark_room();
break;
case ROOM_IS_TOO_BRIGHT:
- if (game->info->update_flags & UPDATE_GRAPHICS)
+ if (game->info->_updateFlags & UPDATE_GRAPHICS)
draw_bright_room();
break;
default:
- if (game->info->update_flags & UPDATE_GRAPHICS) {
- room = get_room(game, game->info->current_room);
- draw_location_image(&game->info->room_images,
+ if (game->info->_updateFlags & UPDATE_GRAPHICS) {
+ room = get_room(game, game->info->_currentRoom);
+ draw_location_image(&game->info->_roomImages,
room->graphic - 1);
}
- if ((game->info->update_flags & UPDATE_GRAPHICS) ||
- (game->info->update_flags & UPDATE_GRAPHICS_ITEMS)) {
- for (i = 0; i < game->info->header.nr_items; i++) {
- item = &game->info->item[i];
+ if ((game->info->_updateFlags & UPDATE_GRAPHICS) ||
+ (game->info->_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
+ for (i = 0; i < game->info->_header.nr_items; i++) {
+ item = &game->info->_item[i];
- if (item->room == game->info->current_room &&
+ if (item->room == game->info->_currentRoom &&
item->graphic != 0)
- draw_image(&game->info->item_images,
+ draw_image(&game->info->_itemImages,
item->graphic - 1);
}
}
@@ -314,10 +314,10 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
size_t count = 0;
uint i;
- for (i = 0; i < game->info->header.nr_items; i++) {
- item = &game->info->item[i];
+ for (i = 0; i < game->info->_header.nr_items; i++) {
+ item = &game->info->_item[i];
- if (item->room == game->info->current_room &&
+ if (item->room == game->info->_currentRoom &&
item->string_desc != 0)
count++;
}
@@ -325,10 +325,10 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
if (count > 0) {
console_println(game, string_lookup(game, STRING_YOU_SEE));
- for (i = 0; i < game->info->header.nr_items; i++) {
- item = &game->info->item[i];
+ for (i = 0; i < game->info->_header.nr_items; i++) {
+ item = &game->info->_item[i];
- if (item->room == game->info->current_room &&
+ if (item->room == game->info->_currentRoom &&
item->string_desc != 0)
console_println(game, string_lookup(game, item->string_desc));
}
@@ -336,32 +336,32 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
}
static void update(ComprehendGame *game) {
- struct room *room = get_room(game, game->info->current_room);
+ struct room *room = get_room(game, game->info->_currentRoom);
unsigned room_type, room_desc_string;
update_graphics(game);
/* Check if the room is special (dark, too bright, etc) */
room_desc_string = room->string_desc;
- room_type = game->room_is_special(game->info->current_room,
+ room_type = game->room_is_special(game->info->_currentRoom,
&room_desc_string);
- if (game->info->update_flags & UPDATE_ROOM_DESC)
+ if (game->info->_updateFlags & UPDATE_ROOM_DESC)
console_println(game, string_lookup(game, room_desc_string));
- if ((game->info->update_flags & UPDATE_ITEM_LIST) &&
+ if ((game->info->_updateFlags & UPDATE_ITEM_LIST) &&
room_type == ROOM_IS_NORMAL)
describe_objects_in_current_room(game);
- game->info->update_flags = 0;
+ game->info->_updateFlags = 0;
}
static void move_to(ComprehendGame *game, uint8 room) {
- if (room - 1 >= (int)game->info->nr_rooms)
+ if (room - 1 >= (int)game->info->_nr_rooms)
fatal_error("Attempted to move to invalid room %.2x\n", room);
- game->info->current_room = room;
- game->info->update_flags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
+ game->info->_currentRoom = room;
+ game->info->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
UPDATE_ITEM_LIST);
}
@@ -386,8 +386,8 @@ static void func_set_test_result(struct function_state *func_state, bool value)
static size_t num_objects_in_room(ComprehendGame *game, int room) {
size_t count = 0, i;
- for (i = 0; i < game->info->header.nr_items; i++)
- if (game->info->item[i].room == room)
+ for (i = 0; i < game->info->_header.nr_items; i++)
+ if (game->info->_item[i].room == room)
count++;
return count;
@@ -401,23 +401,23 @@ void move_object(ComprehendGame *game, struct item *item, int new_room) {
if (item->room == ROOM_INVENTORY) {
/* Removed from player's inventory */
- game->info->variable[VAR_INVENTORY_WEIGHT] -= obj_weight;
+ game->info->_variables[VAR_INVENTORY_WEIGHT] -= obj_weight;
}
if (new_room == ROOM_INVENTORY) {
/* Moving to the player's inventory */
- game->info->variable[VAR_INVENTORY_WEIGHT] += obj_weight;
+ game->info->_variables[VAR_INVENTORY_WEIGHT] += obj_weight;
}
- if (item->room == game->info->current_room) {
+ if (item->room == game->info->_currentRoom) {
/* Item moved away from the current room */
- game->info->update_flags |= UPDATE_GRAPHICS;
+ game->info->_updateFlags |= UPDATE_GRAPHICS;
- } else if (new_room == game->info->current_room) {
+ } else if (new_room == game->info->_currentRoom) {
/*
* Item moved into the current room. Only the item needs a
* redraw, not the whole room.
*/
- game->info->update_flags |= (UPDATE_GRAPHICS_ITEMS |
+ game->info->_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
UPDATE_ITEM_LIST);
}
@@ -435,7 +435,7 @@ static void eval_instruction(ComprehendGame *game,
bool test;
uint i, count;
- room = get_room(game, game->info->current_room);
+ room = get_room(game, game->info->_currentRoom);
if (debugging_enabled()) {
if (!instr->is_command) {
@@ -482,31 +482,31 @@ static void eval_instruction(ComprehendGame *game,
opcode_map = get_opcode_map(game);
switch (opcode_map[instr->opcode]) {
case OPCODE_VAR_ADD:
- game->info->variable[instr->operand[0]] +=
- game->info->variable[instr->operand[1]];
+ game->info->_variables[instr->operand[0]] +=
+ game->info->_variables[instr->operand[1]];
break;
case OPCODE_VAR_SUB:
- game->info->variable[instr->operand[0]] -=
- game->info->variable[instr->operand[1]];
+ game->info->_variables[instr->operand[0]] -=
+ game->info->_variables[instr->operand[1]];
break;
case OPCODE_VAR_INC:
- game->info->variable[instr->operand[0]]++;
+ game->info->_variables[instr->operand[0]]++;
break;
case OPCODE_VAR_DEC:
- game->info->variable[instr->operand[0]]--;
+ game->info->_variables[instr->operand[0]]--;
break;
case OPCODE_VAR_EQ:
func_set_test_result(func_state,
- game->info->variable[instr->operand[0]] ==
- game->info->variable[instr->operand[1]]);
+ game->info->_variables[instr->operand[0]] ==
+ game->info->_variables[instr->operand[1]]);
break;
case OPCODE_TURN_TICK:
- game->info->variable[VAR_TURN_COUNT]++;
+ game->info->_variables[VAR_TURN_COUNT]++;
break;
case OPCODE_PRINT:
@@ -527,12 +527,12 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_NOT_IN_ROOM:
func_set_test_result(func_state,
- game->info->current_room != instr->operand[0]);
+ game->info->_currentRoom != instr->operand[0]);
break;
case OPCODE_IN_ROOM:
func_set_test_result(func_state,
- game->info->current_room == instr->operand[0]);
+ game->info->_currentRoom == instr->operand[0]);
break;
case OPCODE_MOVE_TO_ROOM:
@@ -574,7 +574,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM:
item = get_item(game, instr->operand[0] - 1);
- move_object(game, item, game->info->current_room);
+ move_object(game, item, game->info->_currentRoom);
break;
case OPCODE_OBJECT_IN_ROOM:
@@ -597,9 +597,9 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_INVENTORY_FULL:
item = get_item_by_noun(game, noun);
func_set_test_result(func_state,
- game->info->variable[VAR_INVENTORY_WEIGHT] +
+ game->info->_variables[VAR_INVENTORY_WEIGHT] +
(item->flags & ITEMF_WEIGHT_MASK) >
- game->info->variable[VAR_INVENTORY_LIMIT]);
+ game->info->_variables[VAR_INVENTORY_LIMIT]);
break;
case OPCODE_DESCRIBE_CURRENT_OBJECT:
@@ -616,8 +616,8 @@ static void eval_instruction(ComprehendGame *game,
test = false;
if (noun) {
- for (i = 0; i < game->info->header.nr_items; i++) {
- struct item *itemP = &game->info->item[i];
+ for (i = 0; i < game->info->_header.nr_items; i++) {
+ struct item *itemP = &game->info->_item[i];
if (itemP->word == noun->_index &&
itemP->room == instr->operand[0]) {
@@ -635,7 +635,7 @@ static void eval_instruction(ComprehendGame *game,
item = get_item_by_noun(game, noun);
if (item)
func_set_test_result(func_state,
- item->room != game->info->current_room);
+ item->room != game->info->_currentRoom);
else
func_set_test_result(func_state, true);
break;
@@ -644,7 +644,7 @@ static void eval_instruction(ComprehendGame *game,
item = get_item_by_noun(game, noun);
if (item)
func_set_test_result(func_state,
- item->room == game->info->current_room);
+ item->room == game->info->_currentRoom);
else
func_set_test_result(func_state, false);
break;
@@ -715,13 +715,13 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_OBJECT_NOT_PRESENT:
item = get_item(game, instr->operand[0] - 1);
func_set_test_result(func_state,
- item->room != game->info->current_room);
+ item->room != game->info->_currentRoom);
break;
case OPCODE_OBJECT_PRESENT:
item = get_item(game, instr->operand[0] - 1);
func_set_test_result(func_state,
- item->room == game->info->current_room);
+ item->room == game->info->_currentRoom);
break;
case OPCODE_OBJECT_NOT_VALID:
@@ -758,8 +758,8 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, string_lookup(game, STRING_INVENTORY));
- for (i = 0; i < game->info->header.nr_items; i++) {
- item = &game->info->item[i];
+ for (i = 0; i < game->info->_header.nr_items; i++) {
+ item = &game->info->_item[i];
if (item->room == ROOM_INVENTORY)
printf("%s\n",
string_lookup(game, item->string_desc));
@@ -774,8 +774,8 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, string_lookup(game, instr->operand[1]));
- for (i = 0; i < game->info->header.nr_items; i++) {
- item = &game->info->item[i];
+ for (i = 0; i < game->info->_header.nr_items; i++) {
+ item = &game->info->_item[i];
if (item->room == instr->operand[0])
printf("%s\n",
string_lookup(game, item->string_desc));
@@ -792,7 +792,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_DROP_OBJECT:
item = get_item(game, instr->operand[0] - 1);
- move_object(game, item, game->info->current_room);
+ move_object(game, item, game->info->_currentRoom);
break;
case OPCODE_DROP_CURRENT_OBJECT:
@@ -800,7 +800,7 @@ static void eval_instruction(ComprehendGame *game,
if (!item)
fatal_error("Attempt to take object failed\n");
- move_object(game, item, game->info->current_room);
+ move_object(game, item, game->info->_currentRoom);
break;
case OPCODE_TAKE_CURRENT_OBJECT:
@@ -818,20 +818,20 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_TEST_FLAG:
func_set_test_result(func_state,
- game->info->flags[instr->operand[0]]);
+ game->info->_flags[instr->operand[0]]);
break;
case OPCODE_TEST_NOT_FLAG:
func_set_test_result(func_state,
- !game->info->flags[instr->operand[0]]);
+ !game->info->_flags[instr->operand[0]]);
break;
case OPCODE_CLEAR_FLAG:
- game->info->flags[instr->operand[0]] = false;
+ game->info->_flags[instr->operand[0]] = false;
break;
case OPCODE_SET_FLAG:
- game->info->flags[instr->operand[0]] = true;
+ game->info->_flags[instr->operand[0]] = true;
break;
case OPCODE_OR:
@@ -875,28 +875,28 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_SET_OBJECT_GRAPHIC:
item = get_item(game, instr->operand[0] - 1);
item->graphic = instr->operand[1];
- if (item->room == game->info->current_room)
- game->info->update_flags |= UPDATE_GRAPHICS;
+ if (item->room == game->info->_currentRoom)
+ game->info->_updateFlags |= UPDATE_GRAPHICS;
break;
case OPCODE_SET_ROOM_GRAPHIC:
room = get_room(game, instr->operand[0]);
room->graphic = instr->operand[1];
- if (instr->operand[0] == game->info->current_room)
- game->info->update_flags |= UPDATE_GRAPHICS;
+ if (instr->operand[0] == game->info->_currentRoom)
+ game->info->_updateFlags |= UPDATE_GRAPHICS;
break;
case OPCODE_CALL_FUNC:
index = instr->operand[0];
if (instr->operand[1] == 0x81)
index += 256;
- if (index >= game->info->nr_functions)
+ if (index >= game->info->_nr_functions)
fatal_error("Bad function %.4x >= %.4x\n",
- index, game->info->nr_functions);
+ index, game->info->_nr_functions);
debug_printf(DEBUG_FUNCTIONS,
"Calling subfunction %.4x\n", index);
- eval_function(game, &game->info->functions[index], verb, noun);
+ eval_function(game, &game->info->_functions[index], verb, noun);
break;
case OPCODE_TEST_FALSE:
@@ -923,7 +923,7 @@ static void eval_instruction(ComprehendGame *game,
break;
case OPCODE_SET_STRING_REPLACEMENT:
- game->info->current_replace_word = instr->operand[0] - 1;
+ game->info->_currentReplaceWord = instr->operand[0] - 1;
break;
case OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT:
@@ -932,22 +932,22 @@ static void eval_instruction(ComprehendGame *game,
* maybe capitalisation?
*/
if (noun && (noun->_type & WORD_TYPE_NOUN_PLURAL))
- game->info->current_replace_word = 3;
+ game->info->_currentReplaceWord = 3;
else if (noun && (noun->_type & WORD_TYPE_FEMALE))
- game->info->current_replace_word = 0;
+ game->info->_currentReplaceWord = 0;
else if (noun && (noun->_type & WORD_TYPE_MALE))
- game->info->current_replace_word = 1;
+ game->info->_currentReplaceWord = 1;
else
- game->info->current_replace_word = 2;
+ game->info->_currentReplaceWord = 2;
break;
case OPCODE_DRAW_ROOM:
- draw_location_image(&game->info->room_images,
+ draw_location_image(&game->info->_roomImages,
instr->operand[0] - 1);
break;
case OPCODE_DRAW_OBJECT:
- draw_image(&game->info->item_images, instr->operand[0] - 1);
+ draw_image(&game->info->_itemImages, instr->operand[0] - 1);
break;
case OPCODE_WAIT_KEY:
@@ -1067,8 +1067,8 @@ static bool handle_sentence(ComprehendGame *game,
return false;
/* Find a matching action */
- for (i = 0; i < game->info->nr_actions; i++) {
- action = &game->info->action[i];
+ for (i = 0; i < game->info->_nr_actions; i++) {
+ action = &game->info->_actions[i];
if (action->type == ACTION_VERB_OPT_NOUN &&
sentence->nr_words > action->nr_words + 1)
@@ -1091,7 +1091,7 @@ static bool handle_sentence(ComprehendGame *game,
}
if (j == action->nr_words) {
/* Match */
- func = &game->info->functions[action->function];
+ func = &game->info->_functions[action->function];
eval_function(game, func,
&sentence->words[0], &sentence->words[1]);
return true;
@@ -1168,7 +1168,7 @@ static void before_turn(ComprehendGame *game) {
game->before_turn();
// Run the each turn functions
- eval_function(game, &game->info->functions[0], NULL, NULL);
+ eval_function(game, &game->info->_functions[0], NULL, NULL);
update(game);
}
@@ -1223,7 +1223,7 @@ void comprehend_play_game(ComprehendGame *game) {
game->before_game();
- game->info->update_flags = (uint)UPDATE_ALL;
+ game->info->_updateFlags = (uint)UPDATE_ALL;
while (!g_comprehend->shouldQuit())
read_input(game);
}
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 1d0b8c02e3..8f0bcf710e 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -35,17 +35,17 @@ namespace Comprehend {
class ComprehendGame {
public:
- const char *game_name;
- const char *short_name;
+ const char *_gameName;
+ const char *_shortName;
- const char *game_data_file;
- Common::Array<string_file> string_files;
- Common::Array<const char *> location_graphic_files;
- Common::Array<const char *> item_graphic_files;
- const char *save_game_file_fmt;
- unsigned color_table;
+ const char *_gameDataFile;
+ Common::Array<string_file> _stringFiles;
+ Common::Array<const char *> _locationGraphicFiles;
+ Common::Array<const char *> _itemGraphicFiles;
+ const char *_savegameFileFormat;
+ unsigned _colorTable;
- struct game_strings *strings;
+ struct game_strings *_gameStrings;
struct game_info *info;
public:
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index 74e5cdfe1e..e0a4dca5b6 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -39,19 +39,19 @@ static struct game_ops cc2_ops = {
#endif
CrimsonCrownGame::CrimsonCrownGame() : ComprehendGame() {
- game_name = "Crimson Crown";
- short_name = "cc1";
- game_data_file = "cc1.gda";
-
- string_files.push_back(string_file("ma.ms1", 0x89));
- location_graphic_files.push_back("RA.MS1");
- location_graphic_files.push_back("RB.MS1");
- location_graphic_files.push_back("RC.MS1");
- item_graphic_files.push_back("OA.MS1");
- item_graphic_files.push_back("OB.MS1");
-
- save_game_file_fmt = "G%d.MS0";
- strings = &cc1_strings;
+ _gameName = "Crimson Crown";
+ _shortName = "cc1";
+ _gameDataFile = "cc1.gda";
+
+ _stringFiles.push_back(string_file("ma.ms1", 0x89));
+ _locationGraphicFiles.push_back("RA.MS1");
+ _locationGraphicFiles.push_back("RB.MS1");
+ _locationGraphicFiles.push_back("RC.MS1");
+ _itemGraphicFiles.push_back("OA.MS1");
+ _itemGraphicFiles.push_back("OB.MS1");
+
+ _savegameFileFormat = "G%d.MS0";
+ _gameStrings = &cc1_strings;
}
#ifdef TODO
@@ -71,8 +71,8 @@ ComprehendGame game_crimson_crown_2 = {
static void cc_clear_companion_flags(ComprehendGame *game) {
/* Clear the Sabrina/Erik action flags */
- game->info->flags[0xa] = 0;
- game->info->flags[0xb] = 0;
+ game->info->_flags[0xa] = 0;
+ game->info->_flags[0xb] = 0;
}
static bool cc_common_handle_special_opcode(ComprehendGame *game,
@@ -128,7 +128,7 @@ static void cc2_handle_special_opcode(ComprehendGame *game,
switch (operand) {
case 0x01:
/* Enter the Vampire's throne room */
- eval_function(game, &game->info->functions[0xe], NULL, NULL);
+ eval_function(game, &game->info->_functions[0xe], NULL, NULL);
break;
case 0x05:
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index ea3d2eae07..7b7cf3efd7 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -119,18 +119,18 @@ game_header::game_header() : magic(0),
/*-------------------------------------------------------*/
-game_info::game_info() : comprehend_version(0),
- start_room(0),
- nr_rooms(0),
- current_room(0),
- words(nullptr),
- nr_words(0),
- nr_word_maps(0),
- nr_actions(0),
- nr_functions(0),
- nr_replace_words(0),
- current_replace_word(0),
- update_flags(0) {
+game_info::game_info() : _comprehendVersion(0),
+ _startRoom(0),
+ _nr_rooms(0),
+ _currentRoom(0),
+ _words(nullptr),
+ _nr_words(0),
+ _nr_word_maps(0),
+ _nr_actions(0),
+ _nr_functions(0),
+ _nr_replace_words(0),
+ _currentReplaceWord(0),
+ _updateFlags(0) {
}
static void parse_header_le16(struct file_buf * fb, uint16 * val) {
@@ -190,15 +190,15 @@ static void parse_function(struct file_buf * fb, struct function * func) {
static void parse_vm(ComprehendGame * game, struct file_buf * fb) {
struct function *func;
- file_buf_set_pos(fb, game->info->header.addr_vm);
+ file_buf_set_pos(fb, game->info->_header.addr_vm);
while (1) {
- func = &game->info->functions[game->info->nr_functions];
+ func = &game->info->_functions[game->info->_nr_functions];
parse_function(fb, func);
if (func->nr_instructions == 0)
break;
- game->info->nr_functions++;
+ game->info->_nr_functions++;
}
}
@@ -218,7 +218,7 @@ static void parse_action_table_vvnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->info->header.addr_actions_vvnn);
+ file_buf_set_pos(fb, game->info->_header.addr_actions_vvnn);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
@@ -226,7 +226,7 @@ static void parse_action_table_vvnn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->action[*index];
+ action = &game->info->_actions[*index];
action->type = ACTION_VERB_VERB_NOUN_NOUN;
action->nr_words = 4;
@@ -262,7 +262,7 @@ static void parse_action_table_vnjn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->info->header.addr_actions_vnjn);
+ file_buf_set_pos(fb, game->info->_header.addr_actions_vnjn);
while (1) {
file_buf_get_u8(fb, &join);
if (join == 0)
@@ -270,7 +270,7 @@ static void parse_action_table_vnjn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->action[*index];
+ action = &game->info->_actions[*index];
action->type = ACTION_VERB_NOUN_JOIN_NOUN;
action->nr_words = 4;
@@ -306,7 +306,7 @@ static void parse_action_table_vjn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->info->header.addr_actions_vjn);
+ file_buf_set_pos(fb, game->info->_header.addr_actions_vjn);
while (1) {
file_buf_get_u8(fb, &join);
if (join == 0)
@@ -314,7 +314,7 @@ static void parse_action_table_vjn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->action[*index];
+ action = &game->info->_actions[*index];
action->type = ACTION_VERB_JOIN_NOUN;
action->word[1] = join;
@@ -347,7 +347,7 @@ static void parse_action_table_vdn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->info->header.addr_actions_vdn);
+ file_buf_set_pos(fb, game->info->_header.addr_actions_vdn);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
@@ -355,7 +355,7 @@ static void parse_action_table_vdn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->action[*index];
+ action = &game->info->_actions[*index];
action->type = ACTION_VERB_JOIN_NOUN;
action->word[0] = verb;
@@ -388,7 +388,7 @@ static void parse_action_table_vnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->info->header.addr_actions_vnn);
+ file_buf_set_pos(fb, game->info->_header.addr_actions_vnn);
while (1) {
/* 2-byte header */
file_buf_get_u8(fb, &verb);
@@ -397,7 +397,7 @@ static void parse_action_table_vnn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->action[*index];
+ action = &game->info->_actions[*index];
action->type = ACTION_VERB_NOUN_NOUN;
action->word[0] = verb;
@@ -429,7 +429,7 @@ static void parse_action_table_vn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->info->header.addr_actions_vn);
+ file_buf_set_pos(fb, game->info->_header.addr_actions_vn);
while (1) {
/* 2-byte header */
file_buf_get_u8(fb, &verb);
@@ -438,7 +438,7 @@ static void parse_action_table_vn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->action[*index];
+ action = &game->info->_actions[*index];
action->type = ACTION_VERB_NOUN;
action->word[0] = verb;
@@ -468,13 +468,13 @@ static void parse_action_table_v(ComprehendGame * game,
* u8: count (num actions)
* le16: action
*/
- file_buf_set_pos(fb, game->info->header.addr_actions_v);
+ file_buf_set_pos(fb, game->info->_header.addr_actions_v);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
break;
- action = &game->info->action[*index];
+ action = &game->info->_actions[*index];
action->type = ACTION_VERB_OPT_NOUN;
action->word[0] = verb;
@@ -499,20 +499,20 @@ static void parse_action_table_v(ComprehendGame * game,
static void parse_action_table(ComprehendGame * game,
struct file_buf * fb) {
- game->info->nr_actions = 0;
+ game->info->_nr_actions = 0;
- if (game->info->comprehend_version == 1) {
- parse_action_table_vvnn(game, fb, &game->info->nr_actions);
- parse_action_table_vdn(game, fb, &game->info->nr_actions);
+ if (game->info->_comprehendVersion == 1) {
+ parse_action_table_vvnn(game, fb, &game->info->_nr_actions);
+ parse_action_table_vdn(game, fb, &game->info->_nr_actions);
}
- if (game->info->comprehend_version >= 2) {
- parse_action_table_vnn(game, fb, &game->info->nr_actions);
+ if (game->info->_comprehendVersion >= 2) {
+ parse_action_table_vnn(game, fb, &game->info->_nr_actions);
}
- parse_action_table_vnjn(game, fb, &game->info->nr_actions);
- parse_action_table_vjn(game, fb, &game->info->nr_actions);
- parse_action_table_vn(game, fb, &game->info->nr_actions);
- parse_action_table_v(game, fb, &game->info->nr_actions);
+ parse_action_table_vnjn(game, fb, &game->info->_nr_actions);
+ parse_action_table_vjn(game, fb, &game->info->_nr_actions);
+ parse_action_table_vn(game, fb, &game->info->_nr_actions);
+ parse_action_table_v(game, fb, &game->info->_nr_actions);
}
static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
@@ -520,11 +520,11 @@ static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
uint i, j;
// FIXME - fixed size 0xff array?
- game->info->words = (word *)xmalloc(game->info->nr_words * sizeof(words));
+ game->info->_words = (word *)xmalloc(game->info->_nr_words * sizeof(words));
- file_buf_set_pos(fb, game->info->header.addr_dictionary);
- for (i = 0; i < game->info->nr_words; i++) {
- words = &game->info->words[i];
+ file_buf_set_pos(fb, game->info->_header.addr_dictionary);
+ for (i = 0; i < game->info->_nr_words; i++) {
+ words = &game->info->_words[i];
file_buf_get_data(fb, words->_word, 6);
@@ -543,15 +543,15 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
uint8 index, type, dummy;
uint i;
- game->info->nr_word_maps = 0;
- file_buf_set_pos(fb, game->info->header.addr_word_map);
+ game->info->_nr_word_maps = 0;
+ file_buf_set_pos(fb, game->info->_header.addr_word_map);
/*
* Parse the word pair table. Each entry has a pair of dictionary
* index/type values for a first and second word.
*/
while (1) {
- map = &game->info->word_map[game->info->nr_word_maps];
+ map = &game->info->_wordMaps[game->info->_nr_word_maps];
file_buf_get_u8(fb, &index);
file_buf_get_u8(fb, &type);
@@ -566,7 +566,7 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
file_buf_get_u8(fb, &map->word[1].index);
file_buf_get_u8(fb, &map->word[1].type);
- game->info->nr_word_maps++;
+ game->info->_nr_word_maps++;
}
/* Consume two more null bytes (type and index were also null) */
@@ -578,8 +578,8 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
* index/type. The first and second words from above map to the
* target word here. E.g. 'go north' -> 'north'.
*/
- for (i = 0; i < game->info->nr_word_maps; i++) {
- map = &game->info->word_map[i];
+ for (i = 0; i < game->info->_nr_word_maps; i++) {
+ map = &game->info->_wordMaps[i];
file_buf_get_u8(fb, &map->word[2].index);
file_buf_get_u8(fb, &map->word[2].type);
@@ -587,58 +587,58 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
}
static void parse_items(ComprehendGame * game, struct file_buf * fb) {
- size_t nr_items = game->info->header.nr_items;
+ size_t nr_items = game->info->_header.nr_items;
/* Item descriptions */
- file_buf_set_pos(fb, game->info->header.addr_item_strings);
- file_buf_get_array_le16(fb, 0, game->info->item, string_desc, nr_items);
+ file_buf_set_pos(fb, game->info->_header.addr_item_strings);
+ file_buf_get_array_le16(fb, 0, game->info->_item, string_desc, nr_items);
- if (game->info->comprehend_version == 2) {
+ if (game->info->_comprehendVersion == 2) {
/* Comprehend version 2 adds long string descriptions */
- file_buf_set_pos(fb, game->info->header.addr_item_strings +
- (game->info->header.nr_items * sizeof(uint16)));
- file_buf_get_array_le16(fb, 0, game->info->item, long_string, nr_items);
+ file_buf_set_pos(fb, game->info->_header.addr_item_strings +
+ (game->info->_header.nr_items * sizeof(uint16)));
+ file_buf_get_array_le16(fb, 0, game->info->_item, long_string, nr_items);
}
/* Item flags */
- file_buf_set_pos(fb, game->info->header.addr_item_flags);
- file_buf_get_array_u8(fb, 0, game->info->item, flags, nr_items);
+ file_buf_set_pos(fb, game->info->_header.addr_item_flags);
+ file_buf_get_array_u8(fb, 0, game->info->_item, flags, nr_items);
/* Item word */
- file_buf_set_pos(fb, game->info->header.addr_item_word);
- file_buf_get_array_u8(fb, 0, game->info->item, word, nr_items);
+ file_buf_set_pos(fb, game->info->_header.addr_item_word);
+ file_buf_get_array_u8(fb, 0, game->info->_item, word, nr_items);
/* Item locations */
- file_buf_set_pos(fb, game->info->header.addr_item_locations);
- file_buf_get_array_u8(fb, 0, game->info->item, room, nr_items);
+ file_buf_set_pos(fb, game->info->_header.addr_item_locations);
+ file_buf_get_array_u8(fb, 0, game->info->_item, room, nr_items);
/* Item graphic */
- file_buf_set_pos(fb, game->info->header.addr_item_graphics);
- file_buf_get_array_u8(fb, 0, game->info->item, graphic, nr_items);
+ file_buf_set_pos(fb, game->info->_header.addr_item_graphics);
+ file_buf_get_array_u8(fb, 0, game->info->_item, graphic, nr_items);
}
static void parse_rooms(ComprehendGame * game, struct file_buf * fb) {
- size_t nr_rooms = game->info->nr_rooms;
+ size_t nr_rooms = game->info->_nr_rooms;
int i;
/* Room exit directions */
for (i = 0; i < NR_DIRECTIONS; i++) {
- file_buf_set_pos(fb, game->info->header.room_direction_table[i]);
- file_buf_get_array_u8(fb, 1, game->info->rooms,
+ file_buf_set_pos(fb, game->info->_header.room_direction_table[i]);
+ file_buf_get_array_u8(fb, 1, game->info->_rooms,
direction[i], nr_rooms);
}
/* Room string descriptions */
- file_buf_set_pos(fb, game->info->header.room_desc_table);
- file_buf_get_array_le16(fb, 1, game->info->rooms, string_desc, nr_rooms);
+ file_buf_set_pos(fb, game->info->_header.room_desc_table);
+ file_buf_get_array_le16(fb, 1, game->info->_rooms, string_desc, nr_rooms);
/* Room flags */
- file_buf_set_pos(fb, game->info->header.room_flags_table);
- file_buf_get_array_u8(fb, 1, game->info->rooms, flags, nr_rooms);
+ file_buf_set_pos(fb, game->info->_header.room_flags_table);
+ file_buf_get_array_u8(fb, 1, game->info->_rooms, flags, nr_rooms);
/* Room graphic */
- file_buf_set_pos(fb, game->info->header.room_graphics_table);
- file_buf_get_array_u8(fb, 1, game->info->rooms, graphic, nr_rooms);
+ file_buf_set_pos(fb, game->info->_header.room_graphics_table);
+ file_buf_get_array_u8(fb, 1, game->info->_rooms, graphic, nr_rooms);
}
static uint64 string_get_chunk(uint8 * string) {
@@ -751,18 +751,18 @@ static void parse_string_table(struct file_buf * fb, unsigned start_addr,
static void parse_variables(ComprehendGame * game, struct file_buf * fb) {
int i;
- for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
- file_buf_get_le16(fb, &game->info->variable[i]);
+ for (i = 0; i < ARRAY_SIZE(game->info->_variables); i++)
+ file_buf_get_le16(fb, &game->info->_variables[i]);
}
static void parse_flags(ComprehendGame * game, struct file_buf * fb) {
int i, bit, flag_index = 0;
uint8 bitmask;
- for (i = 0; i < ARRAY_SIZE(game->info->flags) / 8; i++) {
+ for (i = 0; i < ARRAY_SIZE(game->info->_flags) / 8; i++) {
file_buf_get_u8(fb, &bitmask);
for (bit = 7; bit >= 0; bit--) {
- game->info->flags[flag_index] = !!(bitmask & (1 << bit));
+ game->info->_flags[flag_index] = !!(bitmask & (1 << bit));
flag_index++;
}
}
@@ -776,7 +776,7 @@ static void parse_replace_words(ComprehendGame * game,
int i;
/* FIXME - Rename addr_strings_end */
- file_buf_set_pos(fb, game->info->header.addr_strings_end);
+ file_buf_set_pos(fb, game->info->_header.addr_strings_end);
/* FIXME - what is this for */
file_buf_get_le16(fb, &dummy);
@@ -786,12 +786,12 @@ static void parse_replace_words(ComprehendGame * game,
if (len == 0)
break;
- game->info->replace_words[i] = xstrndup((char *)fb->p, len);
+ game->info->_replaceWords[i] = xstrndup((char *)fb->p, len);
file_buf_get_data(fb, NULL, len + (eof ? 0 : 1));
if (eof)
break;
}
- game->info->nr_replace_words = i;
+ game->info->_nr_replace_words = i;
}
/*
@@ -799,7 +799,7 @@ static void parse_replace_words(ComprehendGame * game,
* game data is. The offsets have a magic constant value added to them.
*/
static void parse_header(ComprehendGame * game, struct file_buf * fb) {
- struct game_header *header = &game->info->header;
+ struct game_header *header = &game->info->_header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
@@ -808,17 +808,17 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
switch (header->magic) {
case 0x2000: /* Transylvania, Crimson Crown disk one */
case 0x4800: /* Crimson Crown disk two */
- game->info->comprehend_version = 1;
+ game->info->_comprehendVersion = 1;
magic_offset = (uint16)(-0x5a00 + 0x4);
break;
case 0x93f0: /* OO-Topos */
- game->info->comprehend_version = 2;
+ game->info->_comprehendVersion = 2;
magic_offset = (uint16)-0x5a00;
break;
case 0xa429: /* Talisman */
- game->info->comprehend_version = 2;
+ game->info->_comprehendVersion = 2;
magic_offset = (uint16)-0x5a00;
break;
@@ -835,14 +835,14 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
*
* Layout depends on the comprehend version.
*/
- if (game->info->comprehend_version == 1) {
+ if (game->info->_comprehendVersion == 1) {
parse_header_le16(fb, &header->addr_actions_vvnn);
parse_header_le16(fb, &header->addr_actions_unknown);
parse_header_le16(fb, &header->addr_actions_vnjn);
parse_header_le16(fb, &header->addr_actions_vjn);
parse_header_le16(fb, &header->addr_actions_vdn);
}
- if (game->info->comprehend_version >= 2) {
+ if (game->info->_comprehendVersion >= 2) {
parse_header_le16(fb, &header->addr_actions_vnjn);
parse_header_le16(fb, &header->addr_actions_vjn);
parse_header_le16(fb, &header->addr_actions_vnn);
@@ -876,7 +876,7 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
*
* Layout is dependent on comprehend version.
*/
- if (game->info->comprehend_version == 1) {
+ if (game->info->_comprehendVersion == 1) {
parse_header_le16(fb, &header->addr_item_locations);
parse_header_le16(fb, &header->addr_item_flags);
parse_header_le16(fb, &header->addr_item_word);
@@ -902,16 +902,16 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
parse_header_le16(fb, &header->addr_strings_end);
file_buf_get_u8(fb, &dummy8);
- file_buf_get_u8(fb, &game->info->start_room);
+ file_buf_get_u8(fb, &game->info->_startRoom);
file_buf_get_u8(fb, &dummy8);
parse_variables(game, fb);
parse_flags(game, fb);
- game->info->nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
+ game->info->_nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
header->room_direction_table[DIRECTION_NORTH];
- game->info->nr_words = (addr_dictionary_end -
+ game->info->_nr_words = (addr_dictionary_end -
header->addr_dictionary) /
8;
}
@@ -929,7 +929,7 @@ static void load_extra_string_file(ComprehendGame * game,
end = fb.size;
parse_string_table(&fb, string_file->base_offset,
- end, &game->info->strings2);
+ end, &game->info->_strings2);
file_buf_unmap(&fb);
}
@@ -937,18 +937,18 @@ static void load_extra_string_file(ComprehendGame * game,
static void load_extra_string_files(ComprehendGame * game) {
int i;
- memset(&game->info->strings2, 0, sizeof(game->info->strings2));
+ memset(&game->info->_strings2, 0, sizeof(game->info->_strings2));
- for (i = 0; i < ARRAY_SIZE(game->string_files); i++) {
- if (!game->string_files[i].filename)
+ for (i = 0; i < ARRAY_SIZE(game->_stringFiles); i++) {
+ if (!game->_stringFiles[i].filename)
break;
// HACK - get string offsets correct
- game->info->strings2.nr_strings = 0x40 * i;
- if (game->info->strings2.nr_strings == 0)
- game->info->strings2.nr_strings++;
+ game->info->_strings2.nr_strings = 0x40 * i;
+ if (game->info->_strings2.nr_strings == 0)
+ game->info->_strings2.nr_strings++;
- load_extra_string_file(game, &game->string_files[i]);
+ load_extra_string_file(game, &game->_stringFiles[i]);
}
}
@@ -956,17 +956,17 @@ static void load_game_data(ComprehendGame * game) {
struct file_buf fb;
memset(game->info, 0, sizeof(*game->info));
- file_buf_map(game->game_data_file, &fb);
+ file_buf_map(game->_gameDataFile, &fb);
parse_header(game, &fb);
parse_rooms(game, &fb);
parse_items(game, &fb);
parse_dictionary(game, &fb);
parse_word_map(game, &fb);
- memset(&game->info->strings, 0, sizeof(game->info->strings));
- parse_string_table(&fb, game->info->header.addr_strings,
- game->info->header.addr_strings_end,
- &game->info->strings);
+ memset(&game->info->_strings, 0, sizeof(game->info->_strings));
+ parse_string_table(&fb, game->info->_header.addr_strings,
+ game->info->_header.addr_strings_end,
+ &game->info->_strings);
load_extra_string_files(game);
parse_vm(game, &fb);
parse_action_table(game, &fb);
@@ -981,12 +981,12 @@ void comprehend_load_game(ComprehendGame * game) {
if (g_enabled()) {
comprehend_load_images(game);
- if (game->color_table)
- g_set_color_table(game->color_table);
+ if (game->_colorTable)
+ g_set_color_table(game->_colorTable);
}
/* FIXME - This can be merged, don't need to keep start room around */
- game->info->current_room = game->info->start_room;
+ game->info->_currentRoom = game->info->_startRoom;
}
#ifdef TODO
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 4146bf8ba5..6bc13f211a 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -167,44 +167,44 @@ struct game_header {
};
struct game_info {
- game_header header;
+ game_header _header;
- unsigned comprehend_version;
+ unsigned _comprehendVersion;
- uint8 start_room;
+ uint8 _startRoom;
- room rooms[0x100];
- size_t nr_rooms;
- uint8 current_room;
+ room _rooms[0x100];
+ size_t _nr_rooms;
+ uint8 _currentRoom;
- struct item item[0xff];
+ struct item _item[0xff];
- struct word *words;
- size_t nr_words;
+ struct word *_words;
+ size_t _nr_words;
- struct word_map word_map[0xff];
- size_t nr_word_maps;
+ struct word_map _wordMaps[0xff];
+ size_t _nr_word_maps;
- struct string_table strings;
- struct string_table strings2;
+ struct string_table _strings;
+ struct string_table _strings2;
- struct action action[0xffff];
- size_t nr_actions;
+ struct action _actions[0xffff];
+ size_t _nr_actions;
- struct function functions[0xffff];
- size_t nr_functions;
+ struct function _functions[0xffff];
+ size_t _nr_functions;
- struct image_data room_images;
- struct image_data item_images;
+ struct image_data _roomImages;
+ struct image_data _itemImages;
- bool flags[MAX_FLAGS];
- uint16 variable[MAX_VARIABLES];
+ bool _flags[MAX_FLAGS];
+ uint16 _variables[MAX_VARIABLES];
- char *replace_words[256];
- size_t nr_replace_words;
+ char *_replaceWords[256];
+ size_t _nr_replace_words;
- uint8 current_replace_word;
- unsigned update_flags;
+ uint8 _currentReplaceWord;
+ unsigned _updateFlags;
game_info();
};
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index c53c6bf824..42fb1a0aa3 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -35,37 +35,37 @@ namespace Comprehend {
#define OO_FLAG_FLASHLIGHT_ON 0x27
OOToposGame::OOToposGame() : ComprehendGame() {
- game_name = "Oo-Topos";
- short_name = "oo";
- game_data_file = "g0";
+ _gameName = "Oo-Topos";
+ _shortName = "oo";
+ _gameDataFile = "g0";
// Extra strings are (annoyingly) stored in the game binary
- string_files.push_back(string_file("NOVEL.EXE", 0x16564, 0x17640));
- string_files.push_back(string_file("NOVEL.EXE", 0x17702, 0x18600));
- string_files.push_back(string_file("NOVEL.EXE", 0x186b2, 0x19b80));
- string_files.push_back(string_file("NOVEL.EXE", 0x19c62, 0x1a590));
- string_files.push_back(string_file("NOVEL.EXE", 0x1a634, 0x1b080));
- location_graphic_files.push_back("RA");
- location_graphic_files.push_back("RB");
- location_graphic_files.push_back("RC");
- location_graphic_files.push_back("RD");
- location_graphic_files.push_back("RE");
- item_graphic_files.push_back("OA");
- item_graphic_files.push_back("OB");
- item_graphic_files.push_back("OC");
- item_graphic_files.push_back("OD");
-
- save_game_file_fmt = "G%d";
- color_table = 1;
+ _stringFiles.push_back(string_file("NOVEL.EXE", 0x16564, 0x17640));
+ _stringFiles.push_back(string_file("NOVEL.EXE", 0x17702, 0x18600));
+ _stringFiles.push_back(string_file("NOVEL.EXE", 0x186b2, 0x19b80));
+ _stringFiles.push_back(string_file("NOVEL.EXE", 0x19c62, 0x1a590));
+ _stringFiles.push_back(string_file("NOVEL.EXE", 0x1a634, 0x1b080));
+ _locationGraphicFiles.push_back("RA");
+ _locationGraphicFiles.push_back("RB");
+ _locationGraphicFiles.push_back("RC");
+ _locationGraphicFiles.push_back("RD");
+ _locationGraphicFiles.push_back("RE");
+ _itemGraphicFiles.push_back("OA");
+ _itemGraphicFiles.push_back("OB");
+ _itemGraphicFiles.push_back("OC");
+ _itemGraphicFiles.push_back("OD");
+
+ _savegameFileFormat = "G%d";
+ _colorTable = 1;
}
int OOToposGame::room_is_special(unsigned room_index,
unsigned *room_desc_string) {
- room *room = &info->rooms[room_index];
+ room *room = &info->_rooms[room_index];
/* Is the room dark */
if ((room->flags & OO_ROOM_FLAG_DARK) &&
- !(info->flags[OO_FLAG_FLASHLIGHT_ON])) {
+ !(info->_flags[OO_FLAG_FLASHLIGHT_ON])) {
if (room_desc_string)
*room_desc_string = 0xb3;
return ROOM_IS_DARK;
@@ -73,7 +73,7 @@ int OOToposGame::room_is_special(unsigned room_index,
/* Is the room too bright */
if (room_index == OO_BRIGHT_ROOM &&
- !info->flags[OO_FLAG_WEARING_GOGGLES]) {
+ !info->_flags[OO_FLAG_WEARING_GOGGLES]) {
if (room_desc_string)
*room_desc_string = 0x1c;
return ROOM_IS_TOO_BRIGHT;
@@ -85,26 +85,26 @@ int OOToposGame::room_is_special(unsigned room_index,
bool OOToposGame::before_turn() {
/* FIXME - probably doesn't work correctly with restored games */
static bool flashlight_was_on = false, googles_were_worn = false;
- struct room *room = &info->rooms[info->current_room];
+ struct room *room = &info->_rooms[info->_currentRoom];
/*
* Check if the room needs to be redrawn because the flashlight
* was switch off or on.
*/
- if (info->flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
+ if (info->_flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
(room->flags & OO_ROOM_FLAG_DARK)) {
- flashlight_was_on = info->flags[OO_FLAG_FLASHLIGHT_ON];
- info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ flashlight_was_on = info->_flags[OO_FLAG_FLASHLIGHT_ON];
+ info->_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
/*
* Check if the room needs to be redrawn because the goggles were
* put on or removed.
*/
- if (info->flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
- info->current_room == OO_BRIGHT_ROOM) {
- googles_were_worn = info->flags[OO_FLAG_WEARING_GOGGLES];
- info->update_flags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ if (info->_flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
+ info->_currentRoom == OO_BRIGHT_ROOM) {
+ googles_were_worn = info->_flags[OO_FLAG_WEARING_GOGGLES];
+ info->_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
return false;
diff --git a/engines/glk/comprehend/game_tm.cpp b/engines/glk/comprehend/game_tm.cpp
index ad714fb398..6ba9ff960a 100644
--- a/engines/glk/comprehend/game_tm.cpp
+++ b/engines/glk/comprehend/game_tm.cpp
@@ -29,21 +29,21 @@ namespace Comprehend {
/* FIXME - This is broken */
TalismanGame::TalismanGame() : ComprehendGame() {
- game_name = "Talisman, Challenging the Sands of Time (broken)";
- short_name = "tm";
- game_data_file = "G0";
+ _gameName = "Talisman, Challenging the Sands of Time (broken)";
+ _shortName = "tm";
+ _gameDataFile = "G0";
- location_graphic_files.push_back("RA");
- location_graphic_files.push_back("RB");
- location_graphic_files.push_back("RC");
- location_graphic_files.push_back("RD");
- location_graphic_files.push_back("RE");
- location_graphic_files.push_back("RF");
- location_graphic_files.push_back("RG");
- item_graphic_files.push_back("OA");
- item_graphic_files.push_back("OB");
- item_graphic_files.push_back("OE");
- item_graphic_files.push_back("OF");
+ _locationGraphicFiles.push_back("RA");
+ _locationGraphicFiles.push_back("RB");
+ _locationGraphicFiles.push_back("RC");
+ _locationGraphicFiles.push_back("RD");
+ _locationGraphicFiles.push_back("RE");
+ _locationGraphicFiles.push_back("RF");
+ _locationGraphicFiles.push_back("RG");
+ _itemGraphicFiles.push_back("OA");
+ _itemGraphicFiles.push_back("OB");
+ _itemGraphicFiles.push_back("OE");
+ _itemGraphicFiles.push_back("OF");
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index f03fc29321..e94814aa86 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -42,26 +42,26 @@ static struct game_strings tr_strings = {
TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
- game_name = "Transylvania";
- short_name = "tr";
- game_data_file = "tr.gda";
-
- string_files.push_back(string_file("MA.MS1", 0x88));
- string_files.push_back(string_file("MB.MS1", 0x88));
- string_files.push_back(string_file("MC.MS1", 0x88));
- string_files.push_back(string_file("MD.MS1", 0x88));
- string_files.push_back(string_file("ME.MS1", 0x88));
-
- location_graphic_files.push_back("RA.MS1");
- location_graphic_files.push_back("RB.MS1");
- location_graphic_files.push_back("RC.MS1");
-
- item_graphic_files.push_back("OA.MS1");
- item_graphic_files.push_back("OB.MS1");
- item_graphic_files.push_back("OC.MS1");
-
- save_game_file_fmt = "G%d.MS0";
- strings = &tr_strings;
+ _gameName = "Transylvania";
+ _shortName = "tr";
+ _gameDataFile = "tr.gda";
+
+ _stringFiles.push_back(string_file("MA.MS1", 0x88));
+ _stringFiles.push_back(string_file("MB.MS1", 0x88));
+ _stringFiles.push_back(string_file("MC.MS1", 0x88));
+ _stringFiles.push_back(string_file("MD.MS1", 0x88));
+ _stringFiles.push_back(string_file("ME.MS1", 0x88));
+
+ _locationGraphicFiles.push_back("RA.MS1");
+ _locationGraphicFiles.push_back("RB.MS1");
+ _locationGraphicFiles.push_back("RC.MS1");
+
+ _itemGraphicFiles.push_back("OA.MS1");
+ _itemGraphicFiles.push_back("OB.MS1");
+ _itemGraphicFiles.push_back("OC.MS1");
+
+ _savegameFileFormat = "G%d.MS0";
+ _gameStrings = &tr_strings;
};
void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
@@ -69,17 +69,17 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
struct room *room;
uint16 turn_count;
- room = &info->rooms[info->current_room];
- turn_count = info->variable[VAR_TURN_COUNT];
+ room = &info->_rooms[info->_currentRoom];
+ turn_count = info->_variables[VAR_TURN_COUNT];
monster = get_item(this, monster_info->object);
- if (monster->room == info->current_room) {
+ if (monster->room == info->_currentRoom) {
/* The monster is in the current room - leave it there */
return;
}
if ((room->flags & monster_info->room_allow_flag) &&
- !info->flags[monster_info->dead_flag] &&
+ !info->_flags[monster_info->dead_flag] &&
turn_count > monster_info->min_turns_before) {
/*
* The monster is alive and allowed to move to the current
@@ -87,8 +87,8 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
* it back to limbo.
*/
if ((g_comprehend->getRandomNumber(0x7fffffff) % monster_info->randomness) == 0) {
- move_object(this, monster, info->current_room);
- info->variable[0xf] = turn_count + 1;
+ move_object(this, monster, info->_currentRoom);
+ info->_variables[0xf] = turn_count + 1;
} else {
move_object(this, monster, ROOM_NOWHERE);
}
@@ -98,7 +98,7 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
int TransylvaniaGame::room_is_special(unsigned room_index,
unsigned *room_desc_string)
{
- struct room *room = &info->rooms[room_index];
+ struct room *room = &info->_rooms[room_index];
if (room_index == 0x28) {
if (room_desc_string)
@@ -151,9 +151,9 @@ void TransylvaniaGame::handle_special_opcode(uint8 operand)
* Show the Zin screen in reponse to doing 'sing some enchanted
* evening' in his cabin.
*/
- draw_location_image(&info->room_images, 41);
+ draw_location_image(&info->_roomImages, 41);
console_get_key();
- info->update_flags |= UPDATE_GRAPHICS;
+ info->_updateFlags |= UPDATE_GRAPHICS;
break;
}
}
@@ -179,7 +179,7 @@ void TransylvaniaGame::before_game() {
char buffer[128];
/* Welcome to Transylvania - sign your name */
- console_println(this, info->strings.strings[0x20]);
+ console_println(this, info->_strings.strings[0x20]);
read_string(buffer, sizeof(buffer));
/*
@@ -188,15 +188,15 @@ void TransylvaniaGame::before_game() {
* limited (the original game will break if you put a name in that
* is too long).
*/
- if (!info->replace_words[0])
- info->replace_words[0] = xstrndup(buffer, strlen(buffer));
+ if (!info->_replaceWords[0])
+ info->_replaceWords[0] = xstrndup(buffer, strlen(buffer));
else
- snprintf(info->replace_words[0],
- strlen(info->replace_words[0]),
+ snprintf(info->_replaceWords[0],
+ strlen(info->_replaceWords[0]),
"%s", buffer);
/* And your next of kin - This isn't store by the game */
- console_println(this, info->strings.strings[0x21]);
+ console_println(this, info->_strings.strings[0x21]);
read_string(buffer, sizeof(buffer));
}
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 7f783abe7c..77b85167ee 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -349,11 +349,11 @@ void comprehend_load_image_file(const char *filename, struct image_data *info)
}
void comprehend_load_images(ComprehendGame *game) {
- load_image_files(&game->info->room_images,
- game->location_graphic_files);
+ load_image_files(&game->info->_roomImages,
+ game->_locationGraphicFiles);
- load_image_files(&game->info->item_images,
- game->item_graphic_files);
+ load_image_files(&game->info->_itemImages,
+ game->_itemGraphicFiles);
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/opcode_map.cpp b/engines/glk/comprehend/opcode_map.cpp
index 61b0526b48..431ba0c065 100644
--- a/engines/glk/comprehend/opcode_map.cpp
+++ b/engines/glk/comprehend/opcode_map.cpp
@@ -175,7 +175,7 @@ static uint8 opcode_map_v2[0x100] = {
uint8 *get_opcode_map(ComprehendGame *game)
{
- switch (game->info->comprehend_version) {
+ switch (game->info->_comprehendVersion) {
case 1:
return opcode_map_v1;
break;
@@ -183,7 +183,7 @@ uint8 *get_opcode_map(ComprehendGame *game)
return opcode_map_v2;
default:
fatal_error("Unsupported Comprehend version %d\n",
- game->info->comprehend_version);
+ game->info->_comprehendVersion);
/* Not reached */
return NULL;
diff --git a/engines/glk/comprehend/strings.cpp b/engines/glk/comprehend/strings.cpp
index 784dfec506..7ddf1a5059 100644
--- a/engines/glk/comprehend/strings.cpp
+++ b/engines/glk/comprehend/strings.cpp
@@ -55,8 +55,8 @@ const char *string_lookup(ComprehendGame *game, uint16 index)
/* Fall-through */
case 0x00:
case 0x80:
- if (string < game->info->strings.nr_strings)
- return game->info->strings.strings[string];
+ if (string < game->info->_strings.nr_strings)
+ return game->info->_strings.strings[string];
break;
case 0x83:
@@ -64,8 +64,8 @@ const char *string_lookup(ComprehendGame *game, uint16 index)
/* Fall-through */
case 0x02:
case 0x82:
- if (string < game->info->strings2.nr_strings)
- return game->info->strings2.strings[string];
+ if (string < game->info->_strings2.nr_strings)
+ return game->info->_strings2.strings[string];
break;
}
Commit: b0fe096225cfc9630bd741f1260d303bafd42c4e
https://github.com/scummvm/scummvm/commit/b0fe096225cfc9630bd741f1260d303bafd42c4e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Making comprehend game derive from game info
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/dictionary.cpp
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
engines/glk/comprehend/opcode_map.cpp
engines/glk/comprehend/strings.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index e2a0a09bbb..2f0d317eef 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -158,6 +158,7 @@ void Comprehend::runGame() {
comprehend_load_game(game);
comprehend_play_game(game);
+ delete game;
deinitialize();
}
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 6b83e8896c..d77f549182 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -39,7 +39,7 @@ namespace Comprehend {
#define PATH_MAX 256
-struct game_info;
+struct GameInfo;
struct game_state;
#define EXTRA_STRING_TABLE(x) (0x8200 | (x))
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
index 4ca9d545ac..1421763198 100644
--- a/engines/glk/comprehend/dictionary.cpp
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -45,9 +45,9 @@ word *dict_find_word_by_string(ComprehendGame *game,
if (!string)
return NULL;
- for (i = 0; i < game->info->_nr_words; i++)
- if (word_match(&game->info->_words[i], string))
- return &game->info->_words[i];
+ for (i = 0; i < game->_nr_words; i++)
+ if (word_match(&game->_words[i], string))
+ return &game->_words[i];
return NULL;
}
@@ -57,10 +57,10 @@ struct word *dict_find_word_by_index_type(ComprehendGame *game,
{
uint i;
- for (i = 0; i < game->info->_nr_words; i++) {
- if (game->info->_words[i]._index == index &&
- game->info->_words[i]._type == type)
- return &game->info->_words[i];
+ for (i = 0; i < game->_nr_words; i++) {
+ if (game->_words[i]._index == index &&
+ game->_words[i]._type == type)
+ return &game->_words[i];
}
return NULL;
@@ -71,10 +71,10 @@ struct word *find_dict_word_by_index(ComprehendGame *game,
{
uint i;
- for (i = 0; i < game->info->_nr_words; i++) {
- if (game->info->_words[i]._index == index &&
- (game->info->_words[i]._type & type_mask) != 0)
- return &game->info->_words[i];
+ for (i = 0; i < game->_nr_words; i++) {
+ if (game->_words[i]._index == index &&
+ (game->_words[i]._type & type_mask) != 0)
+ return &game->_words[i];
}
return NULL;
@@ -85,10 +85,10 @@ bool dict_match_index_type(ComprehendGame *game, const char *word,
{
uint i;
- for (i = 0; i < game->info->_nr_words; i++)
- if (game->info->_words[i]._index == index &&
- ((game->info->_words[i]._type & type_mask) != 0) &&
- word_match(&game->info->_words[i], word))
+ for (i = 0; i < game->_nr_words; i++)
+ if (game->_words[i]._index == index &&
+ ((game->_words[i]._type & type_mask) != 0) &&
+ word_match(&game->_words[i], word))
return true;
return false;
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index 16ac91262b..d33f8cb62e 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -160,7 +160,7 @@ void dump_instruction(ComprehendGame *game,
break;
case OPCODE_SET_STRING_REPLACEMENT:
- debugN(" %s", game->info->_replaceWords[instr->operand[0] - 1]);
+ debugN(" %s", game->_replaceWords[instr->operand[0] - 1]);
break;
}
@@ -172,9 +172,9 @@ static void dump_functions(ComprehendGame *game)
struct function *func;
uint i, j;
- debugN("Functions (%zd entries)\n", game->info->_nr_functions);
- for (i = 0; i < game->info->_nr_functions; i++) {
- func = &game->info->_functions[i];
+ debugN("Functions (%zd entries)\n", game->_nr_functions);
+ for (i = 0; i < game->_nr_functions; i++) {
+ func = &game->_functions[i];
debugN("[%.4x] (%zd instructions)\n", i, func->nr_instructions);
for (j = 0; j < func->nr_instructions; j++)
@@ -189,9 +189,9 @@ static void dump_action_table(ComprehendGame *game)
struct word *word;
uint i, j;
- debugN("Action table (%zd entries)\n", game->info->_nr_actions);
- for (i = 0; i < game->info->_nr_actions; i++) {
- action = &game->info->_actions[i];
+ debugN("Action table (%zd entries)\n", game->_nr_actions);
+ for (i = 0; i < game->_nr_actions; i++) {
+ action = &game->_actions[i];
debugN("(");
for (j = 0; j < 4; j++) {
@@ -247,14 +247,14 @@ static void dump_dictionary(ComprehendGame *game)
uint i;
/* Sort the dictionary by index */
- dictionary = (word *)xmalloc(sizeof(*words) * game->info->_nr_words);
- memcpy(dictionary, game->info->_words,
- sizeof(*words) * game->info->_nr_words);
- qsort(dictionary, game->info->_nr_words, sizeof(*words),
+ dictionary = (word *)xmalloc(sizeof(*words) * game->_nr_words);
+ memcpy(dictionary, game->_words,
+ sizeof(*words) * game->_nr_words);
+ qsort(dictionary, game->_nr_words, sizeof(*words),
word_index_compare);
- debugN("Dictionary (%zd words)\n", game->info->_nr_words);
- for (i = 0; i < game->info->_nr_words; i++) {
+ debugN("Dictionary (%zd words)\n", game->_nr_words);
+ for (i = 0; i < game->_nr_words; i++) {
words = &dictionary[i];
debugN(" [%.2x] %.2x %s\n", words->_index, words->_type,
words->_word);
@@ -270,9 +270,9 @@ static void dump_word_map(ComprehendGame *game)
struct word_map *map;
uint i, j;
- debugN("Word pairs (%zd entries)\n", game->info->_nr_word_maps);
- for (i = 0; i < game->info->_nr_word_maps; i++) {
- map = &game->info->_wordMaps[i];
+ debugN("Word pairs (%zd entries)\n", game->_nr_word_maps);
+ for (i = 0; i < game->_nr_word_maps; i++) {
+ map = &game->_wordMaps[i];
for (j = 0; j < 3; j++) {
word[j] = dict_find_word_by_index_type(
@@ -296,9 +296,9 @@ static void dump_rooms(ComprehendGame *game)
uint i;
/* Room zero acts as the players inventory */
- debugN("Rooms (%zd entries)\n", game->info->_nr_rooms);
- for (i = 1; i <= game->info->_nr_rooms; i++) {
- room = &game->info->_rooms[i];
+ debugN("Rooms (%zd entries)\n", game->_nr_rooms);
+ for (i = 1; i <= game->_nr_rooms; i++) {
+ room = &game->_rooms[i];
debugN(" [%.2x] flags=%.2x, graphic=%.2x\n",
i, room->flags, room->graphic);
@@ -322,22 +322,22 @@ static void dump_items(ComprehendGame *game)
struct item *item;
uint i, j;
- debugN("Items (%zd entries)\n", game->info->_header.nr_items);
- for (i = 0; i < game->info->_header.nr_items; i++) {
- item = &game->info->_item[i];
+ debugN("Items (%zd entries)\n", game->_header.nr_items);
+ for (i = 0; i < game->_header.nr_items; i++) {
+ item = &game->_items[i];
debugN(" [%.2x] %s\n", i + 1,
item->string_desc ?
string_lookup(game, item->string_desc) : "");
- if (game->info->_comprehendVersion == 2)
+ if (game->_comprehendVersion == 2)
debugN(" long desc: %s\n",
string_lookup(game, item->long_string));
debugN(" words: ");
- for (j = 0; j < game->info->_nr_words; j++)
- if (game->info->_words[j]._index == item->word &&
- (game->info->_words[j]._type & WORD_TYPE_NOUN_MASK))
- debugN("%s ", game->info->_words[j]._word);
+ for (j = 0; j < game->_nr_words; j++)
+ if (game->_words[j]._index == item->word &&
+ (game->_words[j]._type & WORD_TYPE_NOUN_MASK))
+ debugN("%s ", game->_words[j]._word);
debugN("\n");
debugN(" flags=%.2x (takeable=%d, weight=%d)\n",
item->flags, !!(item->flags & ITEMF_CAN_TAKE),
@@ -359,15 +359,15 @@ static void dump_string_table(struct string_table *table)
static void dump_game_data_strings(ComprehendGame *game)
{
debugN("Main string table (%zd entries)\n",
- game->info->_strings.nr_strings);
- dump_string_table(&game->info->_strings);
+ game->_strings.nr_strings);
+ dump_string_table(&game->_strings);
}
static void dump_extra_strings(ComprehendGame *game)
{
debugN("Extra strings (%zd entries)\n",
- game->info->_strings2.nr_strings);
- dump_string_table(&game->info->_strings2);
+ game->_strings2.nr_strings);
+ dump_string_table(&game->_strings2);
}
static void dump_replace_words(ComprehendGame *game)
@@ -375,14 +375,14 @@ static void dump_replace_words(ComprehendGame *game)
uint i;
debugN("Replacement words (%zd entries)\n",
- game->info->_nr_replace_words);
- for (i = 0; i < game->info->_nr_replace_words; i++)
- debugN(" [%.2x] %s\n", i + 1, game->info->_replaceWords[i]);
+ game->_nr_replace_words);
+ for (i = 0; i < game->_nr_replace_words; i++)
+ debugN(" [%.2x] %s\n", i + 1, game->_replaceWords[i]);
}
static void dump_header(ComprehendGame *game)
{
- struct game_header *header = &game->info->_header;
+ struct game_header *header = &game->_header;
uint16 *dir_table = header->room_direction_table;
debugN("Game header:\n");
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index ff95370978..b1440c979c 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -49,11 +49,9 @@ ComprehendGame::ComprehendGame() : _gameName(nullptr),
_savegameFileFormat(nullptr),
_colorTable(0),
_gameStrings(nullptr) {
- info = (game_info *)malloc(sizeof(*info));
}
ComprehendGame::~ComprehendGame() {
- free(info);
}
static void console_init(void) {
@@ -95,13 +93,13 @@ void console_println(ComprehendGame *game, const char *text) {
case '@':
/* Replace word */
- if (game->info->_currentReplaceWord >= game->info->_nr_replace_words) {
+ if (game->_currentReplaceWord >= game->_nr_replace_words) {
snprintf(bad_word, sizeof(bad_word),
"[BAD_REPLACE_WORD(%.2x)]",
- game->info->_currentReplaceWord);
+ game->_currentReplaceWord);
word = bad_word;
} else {
- word = game->info->_replaceWords[game->info->_currentReplaceWord];
+ word = game->_replaceWords[game->_currentReplaceWord];
}
word_len = strlen(word);
p++;
@@ -164,24 +162,24 @@ static struct room *get_room(ComprehendGame *game, uint16 index) {
if (index == 0)
fatal_error("Room index 0 (player inventory) is invalid");
- if (index - 1 >= (int)game->info->_nr_rooms)
+ if (index - 1 >= (int)game->_nr_rooms)
fatal_error("Room index %d is invalid", index);
- return &game->info->_rooms[index];
+ return &game->_rooms[index];
}
struct item *get_item(ComprehendGame *game, uint16 index) {
- if (index >= game->info->_header.nr_items)
+ if (index >= game->_header.nr_items)
fatal_error("Bad item %d\n", index);
- return &game->info->_item[index];
+ return &game->_items[index];
}
void game_save(ComprehendGame *game) {
char filename[32];
int c;
- console_println(game, game->info->_strings.strings[STRING_SAVE_GAME]);
+ console_println(game, game->_strings.strings[STRING_SAVE_GAME]);
c = console_get_key();
if (c < '1' || c > '3') {
@@ -201,7 +199,7 @@ void game_restore(ComprehendGame *game) {
char filename[32];
int c;
- console_println(game, game->info->_strings.strings[STRING_RESTORE_GAME]);
+ console_println(game, game->_strings.strings[STRING_RESTORE_GAME]);
c = console_get_key();
if (c < '1' || c > '3') {
@@ -216,7 +214,7 @@ void game_restore(ComprehendGame *game) {
snprintf(filename, sizeof(filename), game->_savegameFileFormat, c - '0');
comprehend_restore_game(game, filename);
- game->info->_updateFlags = UPDATE_ALL;
+ game->_updateFlags = UPDATE_ALL;
}
void game_restart(ComprehendGame *game) {
@@ -224,7 +222,7 @@ void game_restart(ComprehendGame *game) {
console_get_key();
comprehend_load_game(game);
- game->info->_updateFlags = UPDATE_ALL;
+ game->_updateFlags = UPDATE_ALL;
}
static struct word_index *is_word_pair(ComprehendGame *game,
@@ -233,8 +231,8 @@ static struct word_index *is_word_pair(ComprehendGame *game,
uint i;
/* Check if this is a word pair */
- for (i = 0; i < game->info->_nr_word_maps; i++) {
- map = &game->info->_wordMaps[i];
+ for (i = 0; i < game->_nr_word_maps; i++) {
+ map = &game->_wordMaps[i];
if (map->word[0].index == word1->_index &&
map->word[0].type == word1->_type &&
@@ -258,9 +256,9 @@ static struct item *get_item_by_noun(ComprehendGame *game,
* (the box and the snarl-in-a-box). The player is unable
* to drop the latter because this will match the former.
*/
- for (i = 0; i < game->info->_header.nr_items; i++)
- if (game->info->_item[i].word == noun->_index)
- return &game->info->_item[i];
+ for (i = 0; i < game->_header.nr_items; i++)
+ if (game->_items[i].word == noun->_index)
+ return &game->_items[i];
return NULL;
}
@@ -274,34 +272,34 @@ static void update_graphics(ComprehendGame *game) {
if (!g_enabled())
return;
- type = game->room_is_special(game->info->_currentRoom, NULL);
+ type = game->room_is_special(game->_currentRoom, NULL);
switch (type) {
case ROOM_IS_DARK:
- if (game->info->_updateFlags & UPDATE_GRAPHICS)
+ if (game->_updateFlags & UPDATE_GRAPHICS)
draw_dark_room();
break;
case ROOM_IS_TOO_BRIGHT:
- if (game->info->_updateFlags & UPDATE_GRAPHICS)
+ if (game->_updateFlags & UPDATE_GRAPHICS)
draw_bright_room();
break;
default:
- if (game->info->_updateFlags & UPDATE_GRAPHICS) {
- room = get_room(game, game->info->_currentRoom);
- draw_location_image(&game->info->_roomImages,
+ if (game->_updateFlags & UPDATE_GRAPHICS) {
+ room = get_room(game, game->_currentRoom);
+ draw_location_image(&game->_roomImages,
room->graphic - 1);
}
- if ((game->info->_updateFlags & UPDATE_GRAPHICS) ||
- (game->info->_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
- for (i = 0; i < game->info->_header.nr_items; i++) {
- item = &game->info->_item[i];
+ if ((game->_updateFlags & UPDATE_GRAPHICS) ||
+ (game->_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
+ for (i = 0; i < game->_header.nr_items; i++) {
+ item = &game->_items[i];
- if (item->room == game->info->_currentRoom &&
+ if (item->room == game->_currentRoom &&
item->graphic != 0)
- draw_image(&game->info->_itemImages,
+ draw_image(&game->_itemImages,
item->graphic - 1);
}
}
@@ -314,10 +312,10 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
size_t count = 0;
uint i;
- for (i = 0; i < game->info->_header.nr_items; i++) {
- item = &game->info->_item[i];
+ for (i = 0; i < game->_header.nr_items; i++) {
+ item = &game->_items[i];
- if (item->room == game->info->_currentRoom &&
+ if (item->room == game->_currentRoom &&
item->string_desc != 0)
count++;
}
@@ -325,10 +323,10 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
if (count > 0) {
console_println(game, string_lookup(game, STRING_YOU_SEE));
- for (i = 0; i < game->info->_header.nr_items; i++) {
- item = &game->info->_item[i];
+ for (i = 0; i < game->_header.nr_items; i++) {
+ item = &game->_items[i];
- if (item->room == game->info->_currentRoom &&
+ if (item->room == game->_currentRoom &&
item->string_desc != 0)
console_println(game, string_lookup(game, item->string_desc));
}
@@ -336,32 +334,32 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
}
static void update(ComprehendGame *game) {
- struct room *room = get_room(game, game->info->_currentRoom);
+ struct room *room = get_room(game, game->_currentRoom);
unsigned room_type, room_desc_string;
update_graphics(game);
/* Check if the room is special (dark, too bright, etc) */
room_desc_string = room->string_desc;
- room_type = game->room_is_special(game->info->_currentRoom,
+ room_type = game->room_is_special(game->_currentRoom,
&room_desc_string);
- if (game->info->_updateFlags & UPDATE_ROOM_DESC)
+ if (game->_updateFlags & UPDATE_ROOM_DESC)
console_println(game, string_lookup(game, room_desc_string));
- if ((game->info->_updateFlags & UPDATE_ITEM_LIST) &&
+ if ((game->_updateFlags & UPDATE_ITEM_LIST) &&
room_type == ROOM_IS_NORMAL)
describe_objects_in_current_room(game);
- game->info->_updateFlags = 0;
+ game->_updateFlags = 0;
}
static void move_to(ComprehendGame *game, uint8 room) {
- if (room - 1 >= (int)game->info->_nr_rooms)
+ if (room - 1 >= (int)game->_nr_rooms)
fatal_error("Attempted to move to invalid room %.2x\n", room);
- game->info->_currentRoom = room;
- game->info->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
+ game->_currentRoom = room;
+ game->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
UPDATE_ITEM_LIST);
}
@@ -386,8 +384,8 @@ static void func_set_test_result(struct function_state *func_state, bool value)
static size_t num_objects_in_room(ComprehendGame *game, int room) {
size_t count = 0, i;
- for (i = 0; i < game->info->_header.nr_items; i++)
- if (game->info->_item[i].room == room)
+ for (i = 0; i < game->_header.nr_items; i++)
+ if (game->_items[i].room == room)
count++;
return count;
@@ -401,23 +399,23 @@ void move_object(ComprehendGame *game, struct item *item, int new_room) {
if (item->room == ROOM_INVENTORY) {
/* Removed from player's inventory */
- game->info->_variables[VAR_INVENTORY_WEIGHT] -= obj_weight;
+ game->_variables[VAR_INVENTORY_WEIGHT] -= obj_weight;
}
if (new_room == ROOM_INVENTORY) {
/* Moving to the player's inventory */
- game->info->_variables[VAR_INVENTORY_WEIGHT] += obj_weight;
+ game->_variables[VAR_INVENTORY_WEIGHT] += obj_weight;
}
- if (item->room == game->info->_currentRoom) {
+ if (item->room == game->_currentRoom) {
/* Item moved away from the current room */
- game->info->_updateFlags |= UPDATE_GRAPHICS;
+ game->_updateFlags |= UPDATE_GRAPHICS;
- } else if (new_room == game->info->_currentRoom) {
+ } else if (new_room == game->_currentRoom) {
/*
* Item moved into the current room. Only the item needs a
* redraw, not the whole room.
*/
- game->info->_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
+ game->_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
UPDATE_ITEM_LIST);
}
@@ -435,7 +433,7 @@ static void eval_instruction(ComprehendGame *game,
bool test;
uint i, count;
- room = get_room(game, game->info->_currentRoom);
+ room = get_room(game, game->_currentRoom);
if (debugging_enabled()) {
if (!instr->is_command) {
@@ -482,31 +480,31 @@ static void eval_instruction(ComprehendGame *game,
opcode_map = get_opcode_map(game);
switch (opcode_map[instr->opcode]) {
case OPCODE_VAR_ADD:
- game->info->_variables[instr->operand[0]] +=
- game->info->_variables[instr->operand[1]];
+ game->_variables[instr->operand[0]] +=
+ game->_variables[instr->operand[1]];
break;
case OPCODE_VAR_SUB:
- game->info->_variables[instr->operand[0]] -=
- game->info->_variables[instr->operand[1]];
+ game->_variables[instr->operand[0]] -=
+ game->_variables[instr->operand[1]];
break;
case OPCODE_VAR_INC:
- game->info->_variables[instr->operand[0]]++;
+ game->_variables[instr->operand[0]]++;
break;
case OPCODE_VAR_DEC:
- game->info->_variables[instr->operand[0]]--;
+ game->_variables[instr->operand[0]]--;
break;
case OPCODE_VAR_EQ:
func_set_test_result(func_state,
- game->info->_variables[instr->operand[0]] ==
- game->info->_variables[instr->operand[1]]);
+ game->_variables[instr->operand[0]] ==
+ game->_variables[instr->operand[1]]);
break;
case OPCODE_TURN_TICK:
- game->info->_variables[VAR_TURN_COUNT]++;
+ game->_variables[VAR_TURN_COUNT]++;
break;
case OPCODE_PRINT:
@@ -527,12 +525,12 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_NOT_IN_ROOM:
func_set_test_result(func_state,
- game->info->_currentRoom != instr->operand[0]);
+ game->_currentRoom != instr->operand[0]);
break;
case OPCODE_IN_ROOM:
func_set_test_result(func_state,
- game->info->_currentRoom == instr->operand[0]);
+ game->_currentRoom == instr->operand[0]);
break;
case OPCODE_MOVE_TO_ROOM:
@@ -574,7 +572,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM:
item = get_item(game, instr->operand[0] - 1);
- move_object(game, item, game->info->_currentRoom);
+ move_object(game, item, game->_currentRoom);
break;
case OPCODE_OBJECT_IN_ROOM:
@@ -597,9 +595,9 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_INVENTORY_FULL:
item = get_item_by_noun(game, noun);
func_set_test_result(func_state,
- game->info->_variables[VAR_INVENTORY_WEIGHT] +
+ game->_variables[VAR_INVENTORY_WEIGHT] +
(item->flags & ITEMF_WEIGHT_MASK) >
- game->info->_variables[VAR_INVENTORY_LIMIT]);
+ game->_variables[VAR_INVENTORY_LIMIT]);
break;
case OPCODE_DESCRIBE_CURRENT_OBJECT:
@@ -616,8 +614,8 @@ static void eval_instruction(ComprehendGame *game,
test = false;
if (noun) {
- for (i = 0; i < game->info->_header.nr_items; i++) {
- struct item *itemP = &game->info->_item[i];
+ for (i = 0; i < game->_header.nr_items; i++) {
+ struct item *itemP = &game->_items[i];
if (itemP->word == noun->_index &&
itemP->room == instr->operand[0]) {
@@ -635,7 +633,7 @@ static void eval_instruction(ComprehendGame *game,
item = get_item_by_noun(game, noun);
if (item)
func_set_test_result(func_state,
- item->room != game->info->_currentRoom);
+ item->room != game->_currentRoom);
else
func_set_test_result(func_state, true);
break;
@@ -644,7 +642,7 @@ static void eval_instruction(ComprehendGame *game,
item = get_item_by_noun(game, noun);
if (item)
func_set_test_result(func_state,
- item->room == game->info->_currentRoom);
+ item->room == game->_currentRoom);
else
func_set_test_result(func_state, false);
break;
@@ -715,13 +713,13 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_OBJECT_NOT_PRESENT:
item = get_item(game, instr->operand[0] - 1);
func_set_test_result(func_state,
- item->room != game->info->_currentRoom);
+ item->room != game->_currentRoom);
break;
case OPCODE_OBJECT_PRESENT:
item = get_item(game, instr->operand[0] - 1);
func_set_test_result(func_state,
- item->room == game->info->_currentRoom);
+ item->room == game->_currentRoom);
break;
case OPCODE_OBJECT_NOT_VALID:
@@ -758,8 +756,8 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, string_lookup(game, STRING_INVENTORY));
- for (i = 0; i < game->info->_header.nr_items; i++) {
- item = &game->info->_item[i];
+ for (i = 0; i < game->_header.nr_items; i++) {
+ item = &game->_items[i];
if (item->room == ROOM_INVENTORY)
printf("%s\n",
string_lookup(game, item->string_desc));
@@ -774,8 +772,8 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, string_lookup(game, instr->operand[1]));
- for (i = 0; i < game->info->_header.nr_items; i++) {
- item = &game->info->_item[i];
+ for (i = 0; i < game->_header.nr_items; i++) {
+ item = &game->_items[i];
if (item->room == instr->operand[0])
printf("%s\n",
string_lookup(game, item->string_desc));
@@ -792,7 +790,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_DROP_OBJECT:
item = get_item(game, instr->operand[0] - 1);
- move_object(game, item, game->info->_currentRoom);
+ move_object(game, item, game->_currentRoom);
break;
case OPCODE_DROP_CURRENT_OBJECT:
@@ -800,7 +798,7 @@ static void eval_instruction(ComprehendGame *game,
if (!item)
fatal_error("Attempt to take object failed\n");
- move_object(game, item, game->info->_currentRoom);
+ move_object(game, item, game->_currentRoom);
break;
case OPCODE_TAKE_CURRENT_OBJECT:
@@ -818,20 +816,20 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_TEST_FLAG:
func_set_test_result(func_state,
- game->info->_flags[instr->operand[0]]);
+ game->_flags[instr->operand[0]]);
break;
case OPCODE_TEST_NOT_FLAG:
func_set_test_result(func_state,
- !game->info->_flags[instr->operand[0]]);
+ !game->_flags[instr->operand[0]]);
break;
case OPCODE_CLEAR_FLAG:
- game->info->_flags[instr->operand[0]] = false;
+ game->_flags[instr->operand[0]] = false;
break;
case OPCODE_SET_FLAG:
- game->info->_flags[instr->operand[0]] = true;
+ game->_flags[instr->operand[0]] = true;
break;
case OPCODE_OR:
@@ -875,28 +873,28 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_SET_OBJECT_GRAPHIC:
item = get_item(game, instr->operand[0] - 1);
item->graphic = instr->operand[1];
- if (item->room == game->info->_currentRoom)
- game->info->_updateFlags |= UPDATE_GRAPHICS;
+ if (item->room == game->_currentRoom)
+ game->_updateFlags |= UPDATE_GRAPHICS;
break;
case OPCODE_SET_ROOM_GRAPHIC:
room = get_room(game, instr->operand[0]);
room->graphic = instr->operand[1];
- if (instr->operand[0] == game->info->_currentRoom)
- game->info->_updateFlags |= UPDATE_GRAPHICS;
+ if (instr->operand[0] == game->_currentRoom)
+ game->_updateFlags |= UPDATE_GRAPHICS;
break;
case OPCODE_CALL_FUNC:
index = instr->operand[0];
if (instr->operand[1] == 0x81)
index += 256;
- if (index >= game->info->_nr_functions)
+ if (index >= game->_nr_functions)
fatal_error("Bad function %.4x >= %.4x\n",
- index, game->info->_nr_functions);
+ index, game->_nr_functions);
debug_printf(DEBUG_FUNCTIONS,
"Calling subfunction %.4x\n", index);
- eval_function(game, &game->info->_functions[index], verb, noun);
+ eval_function(game, &game->_functions[index], verb, noun);
break;
case OPCODE_TEST_FALSE:
@@ -923,7 +921,7 @@ static void eval_instruction(ComprehendGame *game,
break;
case OPCODE_SET_STRING_REPLACEMENT:
- game->info->_currentReplaceWord = instr->operand[0] - 1;
+ game->_currentReplaceWord = instr->operand[0] - 1;
break;
case OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT:
@@ -932,22 +930,22 @@ static void eval_instruction(ComprehendGame *game,
* maybe capitalisation?
*/
if (noun && (noun->_type & WORD_TYPE_NOUN_PLURAL))
- game->info->_currentReplaceWord = 3;
+ game->_currentReplaceWord = 3;
else if (noun && (noun->_type & WORD_TYPE_FEMALE))
- game->info->_currentReplaceWord = 0;
+ game->_currentReplaceWord = 0;
else if (noun && (noun->_type & WORD_TYPE_MALE))
- game->info->_currentReplaceWord = 1;
+ game->_currentReplaceWord = 1;
else
- game->info->_currentReplaceWord = 2;
+ game->_currentReplaceWord = 2;
break;
case OPCODE_DRAW_ROOM:
- draw_location_image(&game->info->_roomImages,
+ draw_location_image(&game->_roomImages,
instr->operand[0] - 1);
break;
case OPCODE_DRAW_OBJECT:
- draw_image(&game->info->_itemImages, instr->operand[0] - 1);
+ draw_image(&game->_itemImages, instr->operand[0] - 1);
break;
case OPCODE_WAIT_KEY:
@@ -1037,21 +1035,21 @@ static void handle_debug_command(ComprehendGame *game,
dump_game_data(game, DUMP_ROOMS);
} else if (strncmp(line, "dump state", 10) == 0) {
- printf("Current room: %.2x\n", game->info->current_room);
+ printf("Current room: %.2x\n", game->current_room);
printf("Carry weight %d/%d\n\n",
- game->info->variable[VAR_INVENTORY_WEIGHT],
- game->info->variable[VAR_INVENTORY_LIMIT]);
+ game->variable[VAR_INVENTORY_WEIGHT],
+ game->variable[VAR_INVENTORY_LIMIT]);
printf("Flags:\n");
- for (i = 0; i < ARRAY_SIZE(game->info->flags); i++)
- printf(" [%.2x]: %d\n", i, game->info->flags[i]);
+ for (i = 0; i < ARRAY_SIZE(game->flags); i++)
+ printf(" [%.2x]: %d\n", i, game->flags[i]);
printf("\n");
printf("Variables:\n");
- for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
+ for (i = 0; i < ARRAY_SIZE(game->variable); i++)
printf(" [%.2x]: %5d (0x%.4x)\n",
- i, game->info->variable[i],
- game->info->variable[i]);
+ i, game->variable[i],
+ game->variable[i]);
printf("\n");
}
}
@@ -1067,8 +1065,8 @@ static bool handle_sentence(ComprehendGame *game,
return false;
/* Find a matching action */
- for (i = 0; i < game->info->_nr_actions; i++) {
- action = &game->info->_actions[i];
+ for (i = 0; i < game->_nr_actions; i++) {
+ action = &game->_actions[i];
if (action->type == ACTION_VERB_OPT_NOUN &&
sentence->nr_words > action->nr_words + 1)
@@ -1091,7 +1089,7 @@ static bool handle_sentence(ComprehendGame *game,
}
if (j == action->nr_words) {
/* Match */
- func = &game->info->_functions[action->function];
+ func = &game->_functions[action->function];
eval_function(game, func,
&sentence->words[0], &sentence->words[1]);
return true;
@@ -1168,7 +1166,7 @@ static void before_turn(ComprehendGame *game) {
game->before_turn();
// Run the each turn functions
- eval_function(game, &game->info->_functions[0], NULL, NULL);
+ eval_function(game, &game->_functions[0], NULL, NULL);
update(game);
}
@@ -1223,7 +1221,7 @@ void comprehend_play_game(ComprehendGame *game) {
game->before_game();
- game->info->_updateFlags = (uint)UPDATE_ALL;
+ game->_updateFlags = (uint)UPDATE_ALL;
while (!g_comprehend->shouldQuit())
read_input(game);
}
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 8f0bcf710e..86fde90347 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -33,7 +33,7 @@ namespace Comprehend {
#define ROOM_IS_DARK 1
#define ROOM_IS_TOO_BRIGHT 2
-class ComprehendGame {
+class ComprehendGame : public GameInfo {
public:
const char *_gameName;
const char *_shortName;
@@ -46,7 +46,6 @@ public:
unsigned _colorTable;
struct game_strings *_gameStrings;
- struct game_info *info;
public:
ComprehendGame();
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index e0a4dca5b6..8eb79938a3 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -71,8 +71,8 @@ ComprehendGame game_crimson_crown_2 = {
static void cc_clear_companion_flags(ComprehendGame *game) {
/* Clear the Sabrina/Erik action flags */
- game->info->_flags[0xa] = 0;
- game->info->_flags[0xb] = 0;
+ game->_flags[0xa] = 0;
+ game->_flags[0xb] = 0;
}
static bool cc_common_handle_special_opcode(ComprehendGame *game,
@@ -128,7 +128,7 @@ static void cc2_handle_special_opcode(ComprehendGame *game,
switch (operand) {
case 0x01:
/* Enter the Vampire's throne room */
- eval_function(game, &game->info->_functions[0xe], NULL, NULL);
+ eval_function(game, &game->_functions[0xe], NULL, NULL);
break;
case 0x05:
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 7b7cf3efd7..482023cd5d 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -38,99 +38,149 @@ static char special_charset[] = "[]\n!\"#$%&'(),-/0123456789:;?<>";
static uint16 magic_offset;
-function_state::function_state() : test_result(true),
- else_result(false),
- or_count(0),
- _and(false),
- in_command(false),
- executed(false) {
+void function_state::clear() {
+ test_result = true;
+ else_result = false;
+ or_count = 0;
+ _and = false;
+ in_command = false;
+ executed = false;
}
/*-------------------------------------------------------*/
-room::room() : flags(0),
- graphic(0),
- string_desc(0) {
+void room::clear() {
+ flags = 0;
+ graphic = 0;
+ string_desc = 0;
Common::fill(&direction[0], &direction[NR_DIRECTIONS], 0);
}
/*-------------------------------------------------------*/
-item::item() : string_desc(0),
- long_string(0),
- room(0),
- flags(0),
- word(0),
- graphic(0) {
+void item::clear() {
+ string_desc = 0;
+ long_string = 0;
+ room = 0;
+ flags = 0;
+ word = 0;
+ graphic = 0;
}
/*-------------------------------------------------------*/
-word::word() : _index(0), _type(0) {
+void word::clear() {
+ _index = 0;
+ _type = 0;
Common::fill(&_word[0], &_word[7], '\0');
}
/*-------------------------------------------------------*/
-action::action() : type(0), nr_words(0), function(0) {
+void word_map::clear() {
+ flags = 0;
+ for (int idx = 0; idx < 3; ++idx)
+ word[idx].clear();
+}
+
+/*-------------------------------------------------------*/
+
+void action::clear() {
+ type = 0;
+ nr_words = 0;
+ function = 0;
Common::fill(&word[0], &word[4], 0);
Common::fill(&word_type[0], &word_type[4], 0);
}
-instruction::instruction() : opcode(0), nr_operands(0),
- is_command(false) {
+/*-------------------------------------------------------*/
+
+void instruction::clear() {
+ opcode = 0;
+ nr_operands = 0;
+ is_command= false;
Common::fill(&operand[0], &operand[3], 0);
}
/*-------------------------------------------------------*/
-string_table::string_table() : nr_strings(0) {
+void function::clear() {
+ nr_instructions = 0;
+ for (int idx = 0; idx < 0x100; ++idx)
+ instructions[idx].clear();
+}
+
+/*-------------------------------------------------------*/
+
+void string_table::clear() {
+ nr_strings = 0;
Common::fill(&strings[0], &strings[0xffff], nullptr);
}
/*-------------------------------------------------------*/
-game_header::game_header() : magic(0),
- room_desc_table(0),
- room_flags_table(0),
- room_graphics_table(0),
- nr_items(0),
- addr_item_locations(0),
- addr_item_flags(0),
- addr_item_word(0),
- addr_item_strings(0),
- addr_item_graphics(0),
- addr_dictionary(0),
- addr_word_map(0),
- addr_strings(0),
- addr_strings_end(0),
- addr_actions_vvnn(0),
- addr_actions_unknown(0),
- addr_actions_vnjn(0),
- addr_actions_vjn(0),
- addr_actions_vdn(0),
- addr_actions_vnn(0),
- addr_actions_vn(0),
- addr_actions_v(0),
- addr_vm(0) // FIXME - functions
-{
+void game_header::clear() {
+ magic = 0;
+ room_desc_table = 0;
+ room_flags_table = 0;
+ room_graphics_table = 0;
+ nr_items = 0;
+ addr_item_locations = 0;
+ addr_item_flags = 0;
+ addr_item_word = 0;
+ addr_item_strings = 0;
+ addr_item_graphics = 0;
+ addr_dictionary = 0;
+ addr_word_map = 0;
+ addr_strings = 0;
+ addr_strings_end = 0;
+ addr_actions_vvnn = 0;
+ addr_actions_unknown = 0;
+ addr_actions_vnjn = 0;
+ addr_actions_vjn = 0;
+ addr_actions_vdn = 0;
+ addr_actions_vnn = 0;
+ addr_actions_vn = 0;
+ addr_actions_v = 0;
+ addr_vm = 0; // FIXME - functions
Common::fill(&room_direction_table[0], &room_direction_table[NR_DIRECTIONS], 0);
}
/*-------------------------------------------------------*/
-game_info::game_info() : _comprehendVersion(0),
- _startRoom(0),
- _nr_rooms(0),
- _currentRoom(0),
- _words(nullptr),
- _nr_words(0),
- _nr_word_maps(0),
- _nr_actions(0),
- _nr_functions(0),
- _nr_replace_words(0),
- _currentReplaceWord(0),
- _updateFlags(0) {
+void GameInfo::clearInfo() {
+ _header.clear();
+ _comprehendVersion = 0;
+ _startRoom = 0;
+ _nr_rooms = 0;
+ _currentRoom = 0;
+ _words = nullptr;
+ _nr_words = 0;
+ _nr_word_maps = 0;
+ _nr_actions = 0;
+ _nr_functions = 0;
+ _nr_replace_words = 0;
+ _currentReplaceWord = 0;
+ _updateFlags = 0;
+ _strings.clear();
+ _strings2.clear();
+ _roomImages.clear();
+ _itemImages.clear();
+
+ for (uint idx = 0; idx < 0x100; ++idx)
+ _rooms[idx].clear();
+ for (uint idx = 0; idx < 0xff; ++idx)
+ _items[idx].clear();
+ for (uint idx = 0; idx < 0xff; ++idx)
+ _wordMaps[idx].clear();
+ for (uint idx = 0; idx < 0xffff; ++idx)
+ _actions[idx].clear();
+ for (uint idx = 0; idx < 0xffff; ++idx)
+ _functions[idx].clear();
+
+ Common::fill(&_flags[0], &_flags[MAX_FLAGS], false);
+ Common::fill(&_variables[0], &_variables[MAX_VARIABLES], 0);
+ Common::fill(&_replaceWords[0], &_replaceWords[256], (char *)nullptr);
}
static void parse_header_le16(struct file_buf * fb, uint16 * val) {
@@ -190,15 +240,15 @@ static void parse_function(struct file_buf * fb, struct function * func) {
static void parse_vm(ComprehendGame * game, struct file_buf * fb) {
struct function *func;
- file_buf_set_pos(fb, game->info->_header.addr_vm);
+ file_buf_set_pos(fb, game->_header.addr_vm);
while (1) {
- func = &game->info->_functions[game->info->_nr_functions];
+ func = &game->_functions[game->_nr_functions];
parse_function(fb, func);
if (func->nr_instructions == 0)
break;
- game->info->_nr_functions++;
+ game->_nr_functions++;
}
}
@@ -218,7 +268,7 @@ static void parse_action_table_vvnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->info->_header.addr_actions_vvnn);
+ file_buf_set_pos(fb, game->_header.addr_actions_vvnn);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
@@ -226,7 +276,7 @@ static void parse_action_table_vvnn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->_actions[*index];
+ action = &game->_actions[*index];
action->type = ACTION_VERB_VERB_NOUN_NOUN;
action->nr_words = 4;
@@ -262,7 +312,7 @@ static void parse_action_table_vnjn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->info->_header.addr_actions_vnjn);
+ file_buf_set_pos(fb, game->_header.addr_actions_vnjn);
while (1) {
file_buf_get_u8(fb, &join);
if (join == 0)
@@ -270,7 +320,7 @@ static void parse_action_table_vnjn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->_actions[*index];
+ action = &game->_actions[*index];
action->type = ACTION_VERB_NOUN_JOIN_NOUN;
action->nr_words = 4;
@@ -306,7 +356,7 @@ static void parse_action_table_vjn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->info->_header.addr_actions_vjn);
+ file_buf_set_pos(fb, game->_header.addr_actions_vjn);
while (1) {
file_buf_get_u8(fb, &join);
if (join == 0)
@@ -314,7 +364,7 @@ static void parse_action_table_vjn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->_actions[*index];
+ action = &game->_actions[*index];
action->type = ACTION_VERB_JOIN_NOUN;
action->word[1] = join;
@@ -347,7 +397,7 @@ static void parse_action_table_vdn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->info->_header.addr_actions_vdn);
+ file_buf_set_pos(fb, game->_header.addr_actions_vdn);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
@@ -355,7 +405,7 @@ static void parse_action_table_vdn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->_actions[*index];
+ action = &game->_actions[*index];
action->type = ACTION_VERB_JOIN_NOUN;
action->word[0] = verb;
@@ -388,7 +438,7 @@ static void parse_action_table_vnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->info->_header.addr_actions_vnn);
+ file_buf_set_pos(fb, game->_header.addr_actions_vnn);
while (1) {
/* 2-byte header */
file_buf_get_u8(fb, &verb);
@@ -397,7 +447,7 @@ static void parse_action_table_vnn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->_actions[*index];
+ action = &game->_actions[*index];
action->type = ACTION_VERB_NOUN_NOUN;
action->word[0] = verb;
@@ -429,7 +479,7 @@ static void parse_action_table_vn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->info->_header.addr_actions_vn);
+ file_buf_set_pos(fb, game->_header.addr_actions_vn);
while (1) {
/* 2-byte header */
file_buf_get_u8(fb, &verb);
@@ -438,7 +488,7 @@ static void parse_action_table_vn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
- action = &game->info->_actions[*index];
+ action = &game->_actions[*index];
action->type = ACTION_VERB_NOUN;
action->word[0] = verb;
@@ -468,13 +518,13 @@ static void parse_action_table_v(ComprehendGame * game,
* u8: count (num actions)
* le16: action
*/
- file_buf_set_pos(fb, game->info->_header.addr_actions_v);
+ file_buf_set_pos(fb, game->_header.addr_actions_v);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
break;
- action = &game->info->_actions[*index];
+ action = &game->_actions[*index];
action->type = ACTION_VERB_OPT_NOUN;
action->word[0] = verb;
@@ -499,20 +549,20 @@ static void parse_action_table_v(ComprehendGame * game,
static void parse_action_table(ComprehendGame * game,
struct file_buf * fb) {
- game->info->_nr_actions = 0;
+ game->_nr_actions = 0;
- if (game->info->_comprehendVersion == 1) {
- parse_action_table_vvnn(game, fb, &game->info->_nr_actions);
- parse_action_table_vdn(game, fb, &game->info->_nr_actions);
+ if (game->_comprehendVersion == 1) {
+ parse_action_table_vvnn(game, fb, &game->_nr_actions);
+ parse_action_table_vdn(game, fb, &game->_nr_actions);
}
- if (game->info->_comprehendVersion >= 2) {
- parse_action_table_vnn(game, fb, &game->info->_nr_actions);
+ if (game->_comprehendVersion >= 2) {
+ parse_action_table_vnn(game, fb, &game->_nr_actions);
}
- parse_action_table_vnjn(game, fb, &game->info->_nr_actions);
- parse_action_table_vjn(game, fb, &game->info->_nr_actions);
- parse_action_table_vn(game, fb, &game->info->_nr_actions);
- parse_action_table_v(game, fb, &game->info->_nr_actions);
+ parse_action_table_vnjn(game, fb, &game->_nr_actions);
+ parse_action_table_vjn(game, fb, &game->_nr_actions);
+ parse_action_table_vn(game, fb, &game->_nr_actions);
+ parse_action_table_v(game, fb, &game->_nr_actions);
}
static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
@@ -520,11 +570,11 @@ static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
uint i, j;
// FIXME - fixed size 0xff array?
- game->info->_words = (word *)xmalloc(game->info->_nr_words * sizeof(words));
+ game->_words = (word *)xmalloc(game->_nr_words * sizeof(words));
- file_buf_set_pos(fb, game->info->_header.addr_dictionary);
- for (i = 0; i < game->info->_nr_words; i++) {
- words = &game->info->_words[i];
+ file_buf_set_pos(fb, game->_header.addr_dictionary);
+ for (i = 0; i < game->_nr_words; i++) {
+ words = &game->_words[i];
file_buf_get_data(fb, words->_word, 6);
@@ -543,15 +593,15 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
uint8 index, type, dummy;
uint i;
- game->info->_nr_word_maps = 0;
- file_buf_set_pos(fb, game->info->_header.addr_word_map);
+ game->_nr_word_maps = 0;
+ file_buf_set_pos(fb, game->_header.addr_word_map);
/*
* Parse the word pair table. Each entry has a pair of dictionary
* index/type values for a first and second word.
*/
while (1) {
- map = &game->info->_wordMaps[game->info->_nr_word_maps];
+ map = &game->_wordMaps[game->_nr_word_maps];
file_buf_get_u8(fb, &index);
file_buf_get_u8(fb, &type);
@@ -566,7 +616,7 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
file_buf_get_u8(fb, &map->word[1].index);
file_buf_get_u8(fb, &map->word[1].type);
- game->info->_nr_word_maps++;
+ game->_nr_word_maps++;
}
/* Consume two more null bytes (type and index were also null) */
@@ -578,8 +628,8 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
* index/type. The first and second words from above map to the
* target word here. E.g. 'go north' -> 'north'.
*/
- for (i = 0; i < game->info->_nr_word_maps; i++) {
- map = &game->info->_wordMaps[i];
+ for (i = 0; i < game->_nr_word_maps; i++) {
+ map = &game->_wordMaps[i];
file_buf_get_u8(fb, &map->word[2].index);
file_buf_get_u8(fb, &map->word[2].type);
@@ -587,58 +637,58 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
}
static void parse_items(ComprehendGame * game, struct file_buf * fb) {
- size_t nr_items = game->info->_header.nr_items;
+ size_t nr_items = game->_header.nr_items;
/* Item descriptions */
- file_buf_set_pos(fb, game->info->_header.addr_item_strings);
- file_buf_get_array_le16(fb, 0, game->info->_item, string_desc, nr_items);
+ file_buf_set_pos(fb, game->_header.addr_item_strings);
+ file_buf_get_array_le16(fb, 0, game->_items, string_desc, nr_items);
- if (game->info->_comprehendVersion == 2) {
+ if (game->_comprehendVersion == 2) {
/* Comprehend version 2 adds long string descriptions */
- file_buf_set_pos(fb, game->info->_header.addr_item_strings +
- (game->info->_header.nr_items * sizeof(uint16)));
- file_buf_get_array_le16(fb, 0, game->info->_item, long_string, nr_items);
+ file_buf_set_pos(fb, game->_header.addr_item_strings +
+ (game->_header.nr_items * sizeof(uint16)));
+ file_buf_get_array_le16(fb, 0, game->_items, long_string, nr_items);
}
/* Item flags */
- file_buf_set_pos(fb, game->info->_header.addr_item_flags);
- file_buf_get_array_u8(fb, 0, game->info->_item, flags, nr_items);
+ file_buf_set_pos(fb, game->_header.addr_item_flags);
+ file_buf_get_array_u8(fb, 0, game->_items, flags, nr_items);
/* Item word */
- file_buf_set_pos(fb, game->info->_header.addr_item_word);
- file_buf_get_array_u8(fb, 0, game->info->_item, word, nr_items);
+ file_buf_set_pos(fb, game->_header.addr_item_word);
+ file_buf_get_array_u8(fb, 0, game->_items, word, nr_items);
/* Item locations */
- file_buf_set_pos(fb, game->info->_header.addr_item_locations);
- file_buf_get_array_u8(fb, 0, game->info->_item, room, nr_items);
+ file_buf_set_pos(fb, game->_header.addr_item_locations);
+ file_buf_get_array_u8(fb, 0, game->_items, room, nr_items);
/* Item graphic */
- file_buf_set_pos(fb, game->info->_header.addr_item_graphics);
- file_buf_get_array_u8(fb, 0, game->info->_item, graphic, nr_items);
+ file_buf_set_pos(fb, game->_header.addr_item_graphics);
+ file_buf_get_array_u8(fb, 0, game->_items, graphic, nr_items);
}
static void parse_rooms(ComprehendGame * game, struct file_buf * fb) {
- size_t nr_rooms = game->info->_nr_rooms;
+ size_t nr_rooms = game->_nr_rooms;
int i;
/* Room exit directions */
for (i = 0; i < NR_DIRECTIONS; i++) {
- file_buf_set_pos(fb, game->info->_header.room_direction_table[i]);
- file_buf_get_array_u8(fb, 1, game->info->_rooms,
+ file_buf_set_pos(fb, game->_header.room_direction_table[i]);
+ file_buf_get_array_u8(fb, 1, game->_rooms,
direction[i], nr_rooms);
}
/* Room string descriptions */
- file_buf_set_pos(fb, game->info->_header.room_desc_table);
- file_buf_get_array_le16(fb, 1, game->info->_rooms, string_desc, nr_rooms);
+ file_buf_set_pos(fb, game->_header.room_desc_table);
+ file_buf_get_array_le16(fb, 1, game->_rooms, string_desc, nr_rooms);
/* Room flags */
- file_buf_set_pos(fb, game->info->_header.room_flags_table);
- file_buf_get_array_u8(fb, 1, game->info->_rooms, flags, nr_rooms);
+ file_buf_set_pos(fb, game->_header.room_flags_table);
+ file_buf_get_array_u8(fb, 1, game->_rooms, flags, nr_rooms);
/* Room graphic */
- file_buf_set_pos(fb, game->info->_header.room_graphics_table);
- file_buf_get_array_u8(fb, 1, game->info->_rooms, graphic, nr_rooms);
+ file_buf_set_pos(fb, game->_header.room_graphics_table);
+ file_buf_get_array_u8(fb, 1, game->_rooms, graphic, nr_rooms);
}
static uint64 string_get_chunk(uint8 * string) {
@@ -751,18 +801,18 @@ static void parse_string_table(struct file_buf * fb, unsigned start_addr,
static void parse_variables(ComprehendGame * game, struct file_buf * fb) {
int i;
- for (i = 0; i < ARRAY_SIZE(game->info->_variables); i++)
- file_buf_get_le16(fb, &game->info->_variables[i]);
+ for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
+ file_buf_get_le16(fb, &game->_variables[i]);
}
static void parse_flags(ComprehendGame * game, struct file_buf * fb) {
int i, bit, flag_index = 0;
uint8 bitmask;
- for (i = 0; i < ARRAY_SIZE(game->info->_flags) / 8; i++) {
+ for (i = 0; i < ARRAY_SIZE(game->_flags) / 8; i++) {
file_buf_get_u8(fb, &bitmask);
for (bit = 7; bit >= 0; bit--) {
- game->info->_flags[flag_index] = !!(bitmask & (1 << bit));
+ game->_flags[flag_index] = !!(bitmask & (1 << bit));
flag_index++;
}
}
@@ -776,7 +826,7 @@ static void parse_replace_words(ComprehendGame * game,
int i;
/* FIXME - Rename addr_strings_end */
- file_buf_set_pos(fb, game->info->_header.addr_strings_end);
+ file_buf_set_pos(fb, game->_header.addr_strings_end);
/* FIXME - what is this for */
file_buf_get_le16(fb, &dummy);
@@ -786,12 +836,12 @@ static void parse_replace_words(ComprehendGame * game,
if (len == 0)
break;
- game->info->_replaceWords[i] = xstrndup((char *)fb->p, len);
+ game->_replaceWords[i] = xstrndup((char *)fb->p, len);
file_buf_get_data(fb, NULL, len + (eof ? 0 : 1));
if (eof)
break;
}
- game->info->_nr_replace_words = i;
+ game->_nr_replace_words = i;
}
/*
@@ -799,7 +849,7 @@ static void parse_replace_words(ComprehendGame * game,
* game data is. The offsets have a magic constant value added to them.
*/
static void parse_header(ComprehendGame * game, struct file_buf * fb) {
- struct game_header *header = &game->info->_header;
+ struct game_header *header = &game->_header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
@@ -808,17 +858,17 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
switch (header->magic) {
case 0x2000: /* Transylvania, Crimson Crown disk one */
case 0x4800: /* Crimson Crown disk two */
- game->info->_comprehendVersion = 1;
+ game->_comprehendVersion = 1;
magic_offset = (uint16)(-0x5a00 + 0x4);
break;
case 0x93f0: /* OO-Topos */
- game->info->_comprehendVersion = 2;
+ game->_comprehendVersion = 2;
magic_offset = (uint16)-0x5a00;
break;
case 0xa429: /* Talisman */
- game->info->_comprehendVersion = 2;
+ game->_comprehendVersion = 2;
magic_offset = (uint16)-0x5a00;
break;
@@ -835,14 +885,14 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
*
* Layout depends on the comprehend version.
*/
- if (game->info->_comprehendVersion == 1) {
+ if (game->_comprehendVersion == 1) {
parse_header_le16(fb, &header->addr_actions_vvnn);
parse_header_le16(fb, &header->addr_actions_unknown);
parse_header_le16(fb, &header->addr_actions_vnjn);
parse_header_le16(fb, &header->addr_actions_vjn);
parse_header_le16(fb, &header->addr_actions_vdn);
}
- if (game->info->_comprehendVersion >= 2) {
+ if (game->_comprehendVersion >= 2) {
parse_header_le16(fb, &header->addr_actions_vnjn);
parse_header_le16(fb, &header->addr_actions_vjn);
parse_header_le16(fb, &header->addr_actions_vnn);
@@ -876,7 +926,7 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
*
* Layout is dependent on comprehend version.
*/
- if (game->info->_comprehendVersion == 1) {
+ if (game->_comprehendVersion == 1) {
parse_header_le16(fb, &header->addr_item_locations);
parse_header_le16(fb, &header->addr_item_flags);
parse_header_le16(fb, &header->addr_item_word);
@@ -902,16 +952,16 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
parse_header_le16(fb, &header->addr_strings_end);
file_buf_get_u8(fb, &dummy8);
- file_buf_get_u8(fb, &game->info->_startRoom);
+ file_buf_get_u8(fb, &game->_startRoom);
file_buf_get_u8(fb, &dummy8);
parse_variables(game, fb);
parse_flags(game, fb);
- game->info->_nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
+ game->_nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
header->room_direction_table[DIRECTION_NORTH];
- game->info->_nr_words = (addr_dictionary_end -
+ game->_nr_words = (addr_dictionary_end -
header->addr_dictionary) /
8;
}
@@ -929,7 +979,7 @@ static void load_extra_string_file(ComprehendGame * game,
end = fb.size;
parse_string_table(&fb, string_file->base_offset,
- end, &game->info->_strings2);
+ end, &game->_strings2);
file_buf_unmap(&fb);
}
@@ -937,16 +987,16 @@ static void load_extra_string_file(ComprehendGame * game,
static void load_extra_string_files(ComprehendGame * game) {
int i;
- memset(&game->info->_strings2, 0, sizeof(game->info->_strings2));
+ memset(&game->_strings2, 0, sizeof(game->_strings2));
for (i = 0; i < ARRAY_SIZE(game->_stringFiles); i++) {
if (!game->_stringFiles[i].filename)
break;
// HACK - get string offsets correct
- game->info->_strings2.nr_strings = 0x40 * i;
- if (game->info->_strings2.nr_strings == 0)
- game->info->_strings2.nr_strings++;
+ game->_strings2.nr_strings = 0x40 * i;
+ if (game->_strings2.nr_strings == 0)
+ game->_strings2.nr_strings++;
load_extra_string_file(game, &game->_stringFiles[i]);
}
@@ -955,7 +1005,7 @@ static void load_extra_string_files(ComprehendGame * game) {
static void load_game_data(ComprehendGame * game) {
struct file_buf fb;
- memset(game->info, 0, sizeof(*game->info));
+ game->clearInfo();
file_buf_map(game->_gameDataFile, &fb);
parse_header(game, &fb);
@@ -963,10 +1013,10 @@ static void load_game_data(ComprehendGame * game) {
parse_items(game, &fb);
parse_dictionary(game, &fb);
parse_word_map(game, &fb);
- memset(&game->info->_strings, 0, sizeof(game->info->_strings));
- parse_string_table(&fb, game->info->_header.addr_strings,
- game->info->_header.addr_strings_end,
- &game->info->_strings);
+ memset(&game->_strings, 0, sizeof(game->_strings));
+ parse_string_table(&fb, game->_header.addr_strings,
+ game->_header.addr_strings_end,
+ &game->_strings);
load_extra_string_files(game);
parse_vm(game, &fb);
parse_action_table(game, &fb);
@@ -986,7 +1036,7 @@ void comprehend_load_game(ComprehendGame * game) {
}
/* FIXME - This can be merged, don't need to keep start room around */
- game->info->_currentRoom = game->info->_startRoom;
+ game->_currentRoom = game->_startRoom;
}
#ifdef TODO
@@ -1018,22 +1068,22 @@ void comprehend_save_game(ComprehendGame * game, const char *filename) {
return;
}
- nr_rooms = game->info->nr_rooms;
- nr_items = game->info->header.nr_items;
+ nr_rooms = game->nr_rooms;
+ nr_items = game->header.nr_items;
file_buf_put_u8(fd, 0);
- file_buf_put_u8(fd, game->info->current_room);
+ file_buf_put_u8(fd, game->current_room);
file_buf_put_u8(fd, 0);
/* Variables */
- for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
- file_buf_put_le16(fd, game->info->variable[i]);
+ for (i = 0; i < ARRAY_SIZE(game->variable); i++)
+ file_buf_put_le16(fd, game->variable[i]);
/* Flags */
- for (flag_index = 0, i = 0; i < ARRAY_SIZE(game->info->flags) / 8; i++) {
+ for (flag_index = 0, i = 0; i < ARRAY_SIZE(game->flags) / 8; i++) {
bitmask = 0;
for (bit = 7; bit >= 0; bit--) {
- bitmask |= (!!game->info->flags[flag_index]) << bit;
+ bitmask |= (!!game->flags[flag_index]) << bit;
flag_index++;
}
@@ -1048,19 +1098,19 @@ void comprehend_save_game(ComprehendGame * game, const char *filename) {
file_buf_put_skip(fd, 0x12c - ftell(fd));
file_buf_put_u8(fd, nr_items);
- if (game->info->comprehend_version == 1)
+ if (game->comprehend_version == 1)
file_buf_put_skip(fd, 0x230 - ftell(fd));
else
file_buf_put_skip(fd, 0x130 - ftell(fd));
/* Rooms */
- file_buf_put_array_le16(fd, 1, game->info->rooms,
+ file_buf_put_array_le16(fd, 1, game->rooms,
string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
- file_buf_put_array_u8(fd, 1, game->info->rooms,
+ file_buf_put_array_u8(fd, 1, game->rooms,
direction[dir], nr_rooms);
- file_buf_put_array_u8(fd, 1, game->info->rooms, flags, nr_rooms);
- file_buf_put_array_u8(fd, 1, game->info->rooms, graphic, nr_rooms);
+ file_buf_put_array_u8(fd, 1, game->rooms, flags, nr_rooms);
+ file_buf_put_array_u8(fd, 1, game->rooms, graphic, nr_rooms);
/*
* Objects
@@ -1068,18 +1118,18 @@ void comprehend_save_game(ComprehendGame * game, const char *filename) {
* Layout differs depending on Comprehend version. Version 2 also
* has long string descriptions for each object.
*/
- file_buf_put_array_le16(fd, 0, game->info->item, string_desc, nr_items);
- if (game->info->comprehend_version == 1) {
- file_buf_put_array_u8(fd, 0, game->info->item, room, nr_items);
- file_buf_put_array_u8(fd, 0, game->info->item, flags, nr_items);
- file_buf_put_array_u8(fd, 0, game->info->item, word, nr_items);
- file_buf_put_array_u8(fd, 0, game->info->item, graphic, nr_items);
+ file_buf_put_array_le16(fd, 0, game->item, string_desc, nr_items);
+ if (game->comprehend_version == 1) {
+ file_buf_put_array_u8(fd, 0, game->item, room, nr_items);
+ file_buf_put_array_u8(fd, 0, game->item, flags, nr_items);
+ file_buf_put_array_u8(fd, 0, game->item, word, nr_items);
+ file_buf_put_array_u8(fd, 0, game->item, graphic, nr_items);
} else {
- file_buf_put_array_le16(fd, 0, game->info->item, long_string, nr_items);
- file_buf_put_array_u8(fd, 0, game->info->item, word, nr_items);
- file_buf_put_array_u8(fd, 0, game->info->item, room, nr_items);
- file_buf_put_array_u8(fd, 0, game->info->item, flags, nr_items);
- file_buf_put_array_u8(fd, 0, game->info->item, graphic, nr_items);
+ file_buf_put_array_le16(fd, 0, game->item, long_string, nr_items);
+ file_buf_put_array_u8(fd, 0, game->item, word, nr_items);
+ file_buf_put_array_u8(fd, 0, game->item, room, nr_items);
+ file_buf_put_array_u8(fd, 0, game->item, flags, nr_items);
+ file_buf_put_array_u8(fd, 0, game->item, graphic, nr_items);
}
fclose(fd);
@@ -1101,12 +1151,12 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
return;
}
- nr_rooms = game->info->nr_rooms;
- nr_items = game->info->header.nr_items;
+ nr_rooms = game->nr_rooms;
+ nr_items = game->header.nr_items;
/* Restore starting room */
file_buf_set_pos(&fb, 1);
- file_buf_get_u8(&fb, &game->info->current_room);
+ file_buf_get_u8(&fb, &game->current_room);
/* Restore flags and variables */
file_buf_set_pos(&fb, 3);
@@ -1114,19 +1164,19 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
parse_flags(game, &fb);
/* FIXME - unknown restore data, skip over it */
- if (game->info->comprehend_version == 1)
+ if (game->comprehend_version == 1)
file_buf_set_pos(&fb, 0x230);
else
file_buf_set_pos(&fb, 0x130);
/* Restore rooms */
- file_buf_get_array_le16(&fb, 1, game->info->rooms,
+ file_buf_get_array_le16(&fb, 1, game->rooms,
string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
- file_buf_get_array_u8(&fb, 1, game->info->rooms,
+ file_buf_get_array_u8(&fb, 1, game->rooms,
direction[dir], nr_rooms);
- file_buf_get_array_u8(&fb, 1, game->info->rooms, flags, nr_rooms);
- file_buf_get_array_u8(&fb, 1, game->info->rooms, graphic, nr_rooms);
+ file_buf_get_array_u8(&fb, 1, game->rooms, flags, nr_rooms);
+ file_buf_get_array_u8(&fb, 1, game->rooms, graphic, nr_rooms);
/*
* Restore objects
@@ -1134,18 +1184,18 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
* Layout differs depending on Comprehend version. Version 2 also
* has long string descriptions for each object.
*/
- file_buf_get_array_le16(&fb, 0, game->info->item, string_desc, nr_items);
- if (game->info->comprehend_version == 1) {
- file_buf_get_array_u8(&fb, 0, game->info->item, room, nr_items);
- file_buf_get_array_u8(&fb, 0, game->info->item, flags, nr_items);
- file_buf_get_array_u8(&fb, 0, game->info->item, word, nr_items);
- file_buf_get_array_u8(&fb, 0, game->info->item, graphic, nr_items);
+ file_buf_get_array_le16(&fb, 0, game->item, string_desc, nr_items);
+ if (game->comprehend_version == 1) {
+ file_buf_get_array_u8(&fb, 0, game->item, room, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->item, flags, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->item, word, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->item, graphic, nr_items);
} else {
- file_buf_get_array_le16(&fb, 0, game->info->item, long_string, nr_items);
- file_buf_get_array_u8(&fb, 0, game->info->item, word, nr_items);
- file_buf_get_array_u8(&fb, 0, game->info->item, room, nr_items);
- file_buf_get_array_u8(&fb, 0, game->info->item, flags, nr_items);
- file_buf_get_array_u8(&fb, 0, game->info->item, graphic, nr_items);
+ file_buf_get_array_le16(&fb, 0, game->item, long_string, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->item, word, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->item, room, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->item, flags, nr_items);
+ file_buf_get_array_u8(&fb, 0, game->item, graphic, nr_items);
}
/*
@@ -1153,9 +1203,9 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
* Not sure what this means, so just mask it out for now.
*/
for (i = 1; i <= nr_rooms; i++)
- patch_string_desc(&game->info->rooms[i].string_desc);
+ patch_string_desc(&game->rooms[i].string_desc);
for (i = 0; i < nr_items; i++)
- patch_string_desc(&game->info->item[i].string_desc);
+ patch_string_desc(&game->item[i].string_desc);
file_buf_unmap(&fb);
#else
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 6bc13f211a..2e243198f1 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -51,7 +51,11 @@ struct function_state {
bool in_command;
bool executed;
- function_state();
+ function_state() {
+ clear();
+ }
+
+ void clear();
};
struct room {
@@ -60,7 +64,11 @@ struct room {
uint8 graphic;
uint16 string_desc;
- room();
+ room() {
+ clear();
+ }
+
+ void clear();
};
struct item {
@@ -71,7 +79,11 @@ struct item {
uint8 word;
uint8 graphic;
- item();
+ item() {
+ clear();
+ }
+
+ void clear();
};
struct word {
@@ -79,14 +91,24 @@ struct word {
uint8 _index;
uint8 _type;
- word();
+ word() {
+ clear();
+ }
+
+ void clear();
};
struct word_index {
uint8 index;
uint8 type;
- word_index() : index(0), type(0) {}
+ word_index() {
+ clear();
+ }
+
+ void clear() {
+ index = type = 0;
+ }
};
struct word_map {
@@ -94,7 +116,11 @@ struct word_map {
word_index word[3];
uint8 flags;
- word_map() : flags(0) {}
+ word_map() {
+ clear();
+ }
+
+ void clear();
};
struct action {
@@ -105,7 +131,11 @@ struct action {
uint8 word_type[4];
uint16 function;
- action();
+ action() {
+ clear();
+ }
+
+ void clear();
};
struct instruction {
@@ -114,21 +144,33 @@ struct instruction {
uint8 operand[3];
bool is_command;
- instruction();
+ instruction() {
+ clear();
+ }
+
+ void clear();
};
struct function {
instruction instructions[0x100];
size_t nr_instructions;
- function() : nr_instructions(0) {}
+ function() {
+ clear();
+ }
+
+ void clear();
};
struct string_table {
char *strings[0xffff];
size_t nr_strings;
- string_table();
+ string_table() {
+ clear();
+ }
+
+ void clear();
};
struct game_header {
@@ -163,10 +205,14 @@ struct game_header {
uint16 addr_vm; // FIXME - functions
- game_header();
+ game_header() {
+ clear();
+ }
+
+ void clear();
};
-struct game_info {
+struct GameInfo {
game_header _header;
unsigned _comprehendVersion;
@@ -177,7 +223,7 @@ struct game_info {
size_t _nr_rooms;
uint8 _currentRoom;
- struct item _item[0xff];
+ struct item _items[0xff];
struct word *_words;
size_t _nr_words;
@@ -206,7 +252,11 @@ struct game_info {
uint8 _currentReplaceWord;
unsigned _updateFlags;
- game_info();
+ GameInfo() {
+ clearInfo();
+ }
+
+ void clearInfo();
};
struct string_file {
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 42fb1a0aa3..4e230db896 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -61,11 +61,11 @@ OOToposGame::OOToposGame() : ComprehendGame() {
int OOToposGame::room_is_special(unsigned room_index,
unsigned *room_desc_string) {
- room *room = &info->_rooms[room_index];
+ room *room = &_rooms[room_index];
/* Is the room dark */
if ((room->flags & OO_ROOM_FLAG_DARK) &&
- !(info->_flags[OO_FLAG_FLASHLIGHT_ON])) {
+ !(_flags[OO_FLAG_FLASHLIGHT_ON])) {
if (room_desc_string)
*room_desc_string = 0xb3;
return ROOM_IS_DARK;
@@ -73,7 +73,7 @@ int OOToposGame::room_is_special(unsigned room_index,
/* Is the room too bright */
if (room_index == OO_BRIGHT_ROOM &&
- !info->_flags[OO_FLAG_WEARING_GOGGLES]) {
+ !_flags[OO_FLAG_WEARING_GOGGLES]) {
if (room_desc_string)
*room_desc_string = 0x1c;
return ROOM_IS_TOO_BRIGHT;
@@ -85,26 +85,26 @@ int OOToposGame::room_is_special(unsigned room_index,
bool OOToposGame::before_turn() {
/* FIXME - probably doesn't work correctly with restored games */
static bool flashlight_was_on = false, googles_were_worn = false;
- struct room *room = &info->_rooms[info->_currentRoom];
+ struct room *room = &_rooms[_currentRoom];
/*
* Check if the room needs to be redrawn because the flashlight
* was switch off or on.
*/
- if (info->_flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
+ if (_flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
(room->flags & OO_ROOM_FLAG_DARK)) {
- flashlight_was_on = info->_flags[OO_FLAG_FLASHLIGHT_ON];
- info->_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ flashlight_was_on = _flags[OO_FLAG_FLASHLIGHT_ON];
+ _updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
/*
* Check if the room needs to be redrawn because the goggles were
* put on or removed.
*/
- if (info->_flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
- info->_currentRoom == OO_BRIGHT_ROOM) {
- googles_were_worn = info->_flags[OO_FLAG_WEARING_GOGGLES];
- info->_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
+ if (_flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
+ _currentRoom == OO_BRIGHT_ROOM) {
+ googles_were_worn = _flags[OO_FLAG_WEARING_GOGGLES];
+ _updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
return false;
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index e94814aa86..7be0262219 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -69,17 +69,17 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
struct room *room;
uint16 turn_count;
- room = &info->_rooms[info->_currentRoom];
- turn_count = info->_variables[VAR_TURN_COUNT];
+ room = &_rooms[_currentRoom];
+ turn_count = _variables[VAR_TURN_COUNT];
monster = get_item(this, monster_info->object);
- if (monster->room == info->_currentRoom) {
+ if (monster->room == _currentRoom) {
/* The monster is in the current room - leave it there */
return;
}
if ((room->flags & monster_info->room_allow_flag) &&
- !info->_flags[monster_info->dead_flag] &&
+ !_flags[monster_info->dead_flag] &&
turn_count > monster_info->min_turns_before) {
/*
* The monster is alive and allowed to move to the current
@@ -87,8 +87,8 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
* it back to limbo.
*/
if ((g_comprehend->getRandomNumber(0x7fffffff) % monster_info->randomness) == 0) {
- move_object(this, monster, info->_currentRoom);
- info->_variables[0xf] = turn_count + 1;
+ move_object(this, monster, _currentRoom);
+ _variables[0xf] = turn_count + 1;
} else {
move_object(this, monster, ROOM_NOWHERE);
}
@@ -98,7 +98,7 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
int TransylvaniaGame::room_is_special(unsigned room_index,
unsigned *room_desc_string)
{
- struct room *room = &info->_rooms[room_index];
+ struct room *room = &_rooms[room_index];
if (room_index == 0x28) {
if (room_desc_string)
@@ -151,9 +151,9 @@ void TransylvaniaGame::handle_special_opcode(uint8 operand)
* Show the Zin screen in reponse to doing 'sing some enchanted
* evening' in his cabin.
*/
- draw_location_image(&info->_roomImages, 41);
+ draw_location_image(&_roomImages, 41);
console_get_key();
- info->_updateFlags |= UPDATE_GRAPHICS;
+ _updateFlags |= UPDATE_GRAPHICS;
break;
}
}
@@ -179,7 +179,7 @@ void TransylvaniaGame::before_game() {
char buffer[128];
/* Welcome to Transylvania - sign your name */
- console_println(this, info->_strings.strings[0x20]);
+ console_println(this, _strings.strings[0x20]);
read_string(buffer, sizeof(buffer));
/*
@@ -188,15 +188,15 @@ void TransylvaniaGame::before_game() {
* limited (the original game will break if you put a name in that
* is too long).
*/
- if (!info->_replaceWords[0])
- info->_replaceWords[0] = xstrndup(buffer, strlen(buffer));
+ if (!_replaceWords[0])
+ _replaceWords[0] = xstrndup(buffer, strlen(buffer));
else
- snprintf(info->_replaceWords[0],
- strlen(info->_replaceWords[0]),
+ snprintf(_replaceWords[0],
+ strlen(_replaceWords[0]),
"%s", buffer);
/* And your next of kin - This isn't store by the game */
- console_println(this, info->_strings.strings[0x21]);
+ console_println(this, _strings.strings[0x21]);
read_string(buffer, sizeof(buffer));
}
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 77b85167ee..4204001110 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -46,6 +46,12 @@ struct image_context {
static unsigned draw_flags;
+void image_data::clear() {
+ fb = nullptr;
+ image_offsets = nullptr;
+ nr_images = 0;
+}
+
void image_set_draw_flags(unsigned flags)
{
draw_flags |= flags;
@@ -349,10 +355,10 @@ void comprehend_load_image_file(const char *filename, struct image_data *info)
}
void comprehend_load_images(ComprehendGame *game) {
- load_image_files(&game->info->_roomImages,
+ load_image_files(&game->_roomImages,
game->_locationGraphicFiles);
- load_image_files(&game->info->_itemImages,
+ load_image_files(&game->_itemImages,
game->_itemGraphicFiles);
}
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index ece82e98a4..382c90a166 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -35,6 +35,12 @@ struct image_data {
file_buf *fb;
uint16 *image_offsets;
size_t nr_images;
+
+ image_data() {
+ clear();
+ }
+
+ void clear();
};
#define IMAGEF_OP_WAIT_KEYPRESS (1 << 0)
diff --git a/engines/glk/comprehend/opcode_map.cpp b/engines/glk/comprehend/opcode_map.cpp
index 431ba0c065..03c59206fe 100644
--- a/engines/glk/comprehend/opcode_map.cpp
+++ b/engines/glk/comprehend/opcode_map.cpp
@@ -175,7 +175,7 @@ static uint8 opcode_map_v2[0x100] = {
uint8 *get_opcode_map(ComprehendGame *game)
{
- switch (game->info->_comprehendVersion) {
+ switch (game->_comprehendVersion) {
case 1:
return opcode_map_v1;
break;
@@ -183,7 +183,7 @@ uint8 *get_opcode_map(ComprehendGame *game)
return opcode_map_v2;
default:
fatal_error("Unsupported Comprehend version %d\n",
- game->info->_comprehendVersion);
+ game->_comprehendVersion);
/* Not reached */
return NULL;
diff --git a/engines/glk/comprehend/strings.cpp b/engines/glk/comprehend/strings.cpp
index 7ddf1a5059..4b6ddb7f99 100644
--- a/engines/glk/comprehend/strings.cpp
+++ b/engines/glk/comprehend/strings.cpp
@@ -55,8 +55,8 @@ const char *string_lookup(ComprehendGame *game, uint16 index)
/* Fall-through */
case 0x00:
case 0x80:
- if (string < game->info->_strings.nr_strings)
- return game->info->_strings.strings[string];
+ if (string < game->_strings.nr_strings)
+ return game->_strings.strings[string];
break;
case 0x83:
@@ -64,8 +64,8 @@ const char *string_lookup(ComprehendGame *game, uint16 index)
/* Fall-through */
case 0x02:
case 0x82:
- if (string < game->info->_strings2.nr_strings)
- return game->info->_strings2.strings[string];
+ if (string < game->_strings2.nr_strings)
+ return game->_strings2.strings[string];
break;
}
Commit: fff77194d711e66e64018ba469b76f6f1440661e
https://github.com/scummvm/scummvm/commit/fff77194d711e66e64018ba469b76f6f1440661e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Converting data loading to be endian safe
Changed paths:
engines/glk/comprehend/file_buf.cpp
engines/glk/comprehend/file_buf.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
diff --git a/engines/glk/comprehend/file_buf.cpp b/engines/glk/comprehend/file_buf.cpp
index 512d88c705..d246bd738f 100644
--- a/engines/glk/comprehend/file_buf.cpp
+++ b/engines/glk/comprehend/file_buf.cpp
@@ -21,119 +21,103 @@
*/
#include "glk/comprehend/file_buf.h"
-#include "glk/comprehend/util.h"
#include "common/algorithm.h"
#include "common/file.h"
+#include "glk/comprehend/util.h"
namespace Glk {
namespace Comprehend {
-int file_buf_map_may_fail(const char *filename, struct file_buf *fb)
-{
+FileBuffer::FileBuffer(const Common::String &filename) : _pos(0) {
+ // Open the file
Common::File f;
-
- memset(fb, 0, sizeof(*fb));
-
if (!f.open(filename))
- return -1;
-
- fb->data = (uint8 *)xmalloc(f.size());
- fb->size = f.size();
- f.read(fb->data, fb->size);
- f.close();
-
- fb->p = fb->data;
-
- // FIXME - remove
- fb->marked = (uint8 *)malloc(fb->size);
- memset(fb->marked, 0, fb->size);
+ error("Could not open - %s", filename.c_str());
- return 0;
+ _data.resize(f.size());
+ _readBytes.resize(f.size());
+ f.read(&_data[0], f.size());
}
-void file_buf_map(const char *filename, struct file_buf *fb)
-{
- int err;
-
- err = file_buf_map_may_fail(filename, fb);
- if (err)
- fatal_strerror(errno, "Cannot open file '%s'", filename);
+bool FileBuffer::exists(const Common::String &filename) {
+ return Common::File::exists(filename);
}
-void file_buf_unmap(struct file_buf *fb)
-{
- free(fb->marked);
- free(fb->data);
-}
-
-void file_buf_set_pos(struct file_buf *fb, unsigned pos)
-{
- if (pos > fb->size)
- error("Bad position set in file (%x > %x)",
- pos, fb->size);
+bool FileBuffer::seek(int32 offset, int whence) {
+ switch (whence) {
+ case SEEK_SET:
+ _pos = offset;
+ break;
+ case SEEK_CUR:
+ _pos += offset;
+ break;
+ case SEEK_END:
+ _pos = (int)_data.size() + offset;
+ break;
+ default:
+ break;
+ }
- fb->p = fb->data + pos;
+ return true;
}
-unsigned file_buf_get_pos(struct file_buf *fb)
-{
- return fb->p - fb->data;
-}
+uint32 FileBuffer::read(void *dataPtr, uint32 dataSize) {
+ int32 bytesRead = CLIP((int32)dataSize, 0, (int32)_data.size() - _pos);
+ if (bytesRead) {
+ Common::fill(&_readBytes[_pos], &_readBytes[_pos + bytesRead], true);
+ Common::copy((byte *)dataPtr, (byte *)dataPtr + bytesRead, (byte *)dataPtr);
+ _pos += bytesRead;
+ }
-void *file_buf_data_pointer(struct file_buf *fb)
-{
- return fb->p;
+ return bytesRead;
}
-size_t file_buf_strlen(struct file_buf *fb, bool *eof)
-{
+size_t FileBuffer::strlen(bool *eof) {
uint8 *end;
if (eof)
*eof = false;
- end = (uint8 *)memchr(fb->p, '\0', fb->size - file_buf_get_pos(fb));
+ end = (uint8 *)memchr(&_data[_pos], '\0', size() - _pos);
if (!end) {
- /* No null terminator - string is remaining length */
+ // No null terminator - string is remaining length
if (eof)
*eof = true;
- return fb->size - file_buf_get_pos(fb);
+ return size() - _pos;
}
- return end - fb->p;
+ return end - &_data[_pos];
+}
+
+
+#ifdef TODO
+void file_buf_unmap(struct FileBuffer *fb) {
+ free(fb->marked);
+ free(fb->data);
+}
+
+unsigned file_buf_get_pos(struct FileBuffer *fb) {
+ return fb->p - fb->data;
}
-void file_buf_get_data(struct file_buf *fb, void *data, size_t data_size)
-{
- if (file_buf_get_pos(fb) + data_size > fb->size)
+void file_buf_get_data(struct FileBuffer *fb, void *data, size_t data_size) {
+ if (fb->pos() + data_size > fb->size)
error("Not enough data in file (%x + %x > %x)",
- file_buf_get_pos(fb), data_size, fb->size);
+ fb->pos(), data_size, fb->size);
if (data)
memcpy(data, fb->p, data_size);
/* Mark this region of the file as read */
- memset(fb->marked + file_buf_get_pos(fb), '?', data_size);
+ memset(fb->marked + fb->pos(), '?', data_size);
fb->p += data_size;
}
-void file_buf_get_u8(struct file_buf *fb, uint8 *val)
-{
- file_buf_get_data(fb, val, sizeof(*val));
-}
-
-void file_buf_get_le16(struct file_buf *fb, uint16 *val)
-{
- file_buf_get_data(fb, val, sizeof(*val));
- *val = READ_LE_UINT16(val);
-}
-
/*
* Debugging function to show regions of a file that have not been read.
*/
-void file_buf_show_unmarked(struct file_buf *fb)
-{
+void file_buf_show_unmarked(struct FileBuffer *fb) {
int i, start = -1;
for (i = 0; i < (int)fb->size; i++) {
@@ -141,15 +125,14 @@ void file_buf_show_unmarked(struct file_buf *fb)
start = i;
if ((fb->marked[i] || i == (int)fb->size - 1) && start != -1) {
- warning("%.4x - %.4x unmarked (%d bytes)\n",
- start, i - 1, i - start);
+ warning("%.4x - %.4x unmarked (%d bytes)\n",
+ start, i - 1, i - start);
start = -1;
}
}
}
-void file_buf_put_u8(Common::WriteStream *fd, uint8 val)
-{
+void file_buf_put_u8(Common::WriteStream *fd, uint8 val) {
fd->writeByte(val);
}
@@ -161,6 +144,7 @@ void file_buf_put_skip(Common::WriteStream *fd, size_t skip) {
for (uint i = 0; i < skip; i++)
file_buf_put_u8(fd, 0);
}
+#endif
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/file_buf.h b/engines/glk/comprehend/file_buf.h
index 27d1371034..3f323e3ec2 100644
--- a/engines/glk/comprehend/file_buf.h
+++ b/engines/glk/comprehend/file_buf.h
@@ -23,47 +23,47 @@
#ifndef GLK_COMPREHEND_FILE_BUF_H
#define GLK_COMPREHEND_FILE_BUF_H
-#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/memstream.h"
#include "common/stream.h"
namespace Glk {
namespace Comprehend {
-struct file_buf {
- uint8 *data;
- size_t size;
- uint8 *p;
+struct FileBuffer : public Common::SeekableReadStream {
+private:
+ Common::Array<byte> _data;
+ Common::Array<bool> _readBytes;
+ int32 _pos;
- uint8 *marked;
-};
+public:
+ FileBuffer() : _pos(0) {}
+ FileBuffer(const Common::String &filename);
+ static bool exists(const Common::String &filename);
-void file_buf_map(const char *filename, struct file_buf *fb);
-int file_buf_map_may_fail(const char *filename, struct file_buf *fb);
-void file_buf_unmap(struct file_buf *fb);
-void file_buf_show_unmarked(struct file_buf *fb);
+ int32 pos() const override { return _pos; }
+ int32 size() const override { return _data.size(); }
+ bool seek(int32 offset, int whence = SEEK_SET) override;
-void *file_buf_data_pointer(struct file_buf *fb);
-void file_buf_set_pos(struct file_buf *fb, unsigned pos);
-unsigned file_buf_get_pos(struct file_buf *fb);
+ bool eos() const override {
+ return _pos >= (int)_data.size();
+ }
+ uint32 read(void *dataPtr, uint32 dataSize) override;
-size_t file_buf_strlen(struct file_buf *fb, bool *eof);
+ const byte *dataPtr() const { return &_data[_pos]; }
+ size_t strlen(bool *eof = nullptr);
-void file_buf_get_data(struct file_buf *fb, void *data, size_t data_size);
-void file_buf_get_u8(struct file_buf *fb, uint8 *val);
-void file_buf_get_le16(struct file_buf *fb, uint16 *val);
+};
-#define file_buf_get_array(fb, type, base, array, member, size) \
- do { \
- uint __i; \
- for (__i = (base); __i < (base) + (size); __i++) \
- file_buf_get_##type(fb, &((array)[__i]).member); \
- } while (0)
+#ifdef TODO
+void file_buf_unmap(struct FileBuffer *fb);
+void file_buf_show_unmarked(struct FileBuffer *fb);
-#define file_buf_get_array_u8(fb, base, array, member, size) \
- file_buf_get_array(fb, u8, base, array, member, size)
+unsigned file_buf_get_pos(struct FileBuffer *fb);
-#define file_buf_get_array_le16(fb, base, array, member, size) \
- file_buf_get_array(fb, le16, base, array, member, size)
+size_t file_buf_strlen(struct FileBuffer *fb, bool *eof);
+
+void file_buf_get_data(struct FileBuffer *fb, void *data, size_t data_size);
void file_buf_put_skip(Common::WriteStream *fd, size_t skip);
void file_buf_put_u8(Common::WriteStream *fd, uint8 val);
@@ -81,6 +81,21 @@ void file_buf_put_le16(Common::WriteStream *fd, uint16 val);
#define file_buf_put_array_u8(fd, base, array, member, size) \
file_buf_put_array(fd, u8, base, array, member, size)
+#endif
+
+#define file_buf_get_array(fb, type, base, array, member, size) \
+ do { \
+ uint __i; \
+ for (__i = (base); __i < (base) + (size); __i++) \
+ (array)[__i].member = fb->read##type(); \
+ } while (0)
+
+#define file_buf_get_array_u8(fb, base, array, member, size) \
+ file_buf_get_array(fb, Byte, base, array, member, size)
+
+#define file_buf_get_array_le16(fb, base, array, member, size) \
+ file_buf_get_array(fb, Uint16LE, base, array, member, size)
+
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 482023cd5d..d10414b4ee 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -183,8 +183,8 @@ void GameInfo::clearInfo() {
Common::fill(&_replaceWords[0], &_replaceWords[256], (char *)nullptr);
}
-static void parse_header_le16(struct file_buf * fb, uint16 * val) {
- file_buf_get_le16(fb, val);
+static void parse_header_le16(FileBuffer *fb, uint16 *val) {
+ *val = fb->readUint16LE();
*val += (uint16)magic_offset;
}
@@ -198,31 +198,30 @@ static bool opcode_is_command(uint8 opcode) {
return opcode & 0x80;
}
-static uint8 parse_vm_instruction(struct file_buf * fb,
- struct instruction * instr) {
+static uint8 parse_vm_instruction(FileBuffer *fb,
+ instruction *instr) {
uint i;
/* Get the opcode */
- file_buf_get_u8(fb, &instr->opcode);
+ instr->opcode = fb->readByte();
instr->nr_operands = opcode_nr_operands(instr->opcode);
/* Get the operands */
for (i = 0; i < instr->nr_operands; i++)
- file_buf_get_u8(fb, &instr->operand[i]);
+ instr->operand[i] = fb->readByte();
instr->is_command = opcode_is_command(instr->opcode);
return instr->opcode;
}
-static void parse_function(struct file_buf * fb, struct function * func) {
+static void parse_function(struct FileBuffer * fb, struct function * func) {
struct instruction *instruction;
uint8 *p, opcode;
- p = (uint8 *)memchr(file_buf_data_pointer(fb), 0x00,
- fb->size - file_buf_get_pos(fb));
+ p = (uint8 *)memchr(fb->dataPtr(), 0x00, fb->size() - fb->pos());
if (!p)
- fatal_error("bad function @ %.4x", file_buf_get_pos(fb));
+ fatal_error("bad function @ %.4x", fb->pos());
while (1) {
instruction = &func->instructions[func->nr_instructions];
@@ -237,10 +236,10 @@ static void parse_function(struct file_buf * fb, struct function * func) {
}
}
-static void parse_vm(ComprehendGame * game, struct file_buf * fb) {
- struct function *func;
+static void parse_vm(ComprehendGame *game, struct FileBuffer * fb) {
+ function *func;
- file_buf_set_pos(fb, game->_header.addr_vm);
+ fb->seek(game->_header.addr_vm);
while (1) {
func = &game->_functions[game->_nr_functions];
@@ -252,8 +251,8 @@ static void parse_vm(ComprehendGame * game, struct file_buf * fb) {
}
}
-static void parse_action_table_vvnn(ComprehendGame * game,
- struct file_buf * fb, size_t * index) {
+static void parse_action_table_vvnn(ComprehendGame *game,
+ struct FileBuffer * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i, j;
@@ -268,12 +267,12 @@ static void parse_action_table_vvnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->_header.addr_actions_vvnn);
+ fb->seek(game->_header.addr_actions_vvnn);
while (1) {
- file_buf_get_u8(fb, &verb);
+ verb = fb->readByte();
if (verb == 0)
break;
- file_buf_get_u8(fb, &count);
+ count = fb->readByte();
for (i = 0; i < count; i++) {
action = &game->_actions[*index];
@@ -288,16 +287,16 @@ static void parse_action_table_vvnn(ComprehendGame * game,
action->word[0] = verb;
for (j = 0; j < 3; j++)
- file_buf_get_u8(fb, &action->word[j + 1]);
- file_buf_get_le16(fb, &action->function);
+ action->word[j + 1] = fb->readByte();
+ action->function = fb->readUint16LE();
(*index)++;
}
}
}
-static void parse_action_table_vnjn(ComprehendGame * game,
- struct file_buf * fb, size_t * index) {
+static void parse_action_table_vnjn(ComprehendGame *game,
+ struct FileBuffer * fb, size_t * index) {
struct action *action;
uint8 join, count;
int i;
@@ -312,12 +311,12 @@ static void parse_action_table_vnjn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->_header.addr_actions_vnjn);
+ fb->seek(game->_header.addr_actions_vnjn);
while (1) {
- file_buf_get_u8(fb, &join);
+ join = fb->readByte();
if (join == 0)
break;
- file_buf_get_u8(fb, &count);
+ count = fb->readByte();
for (i = 0; i < count; i++) {
action = &game->_actions[*index];
@@ -331,18 +330,18 @@ static void parse_action_table_vnjn(ComprehendGame * game,
action->word[2] = join;
- file_buf_get_u8(fb, &action->word[0]);
- file_buf_get_u8(fb, &action->word[1]);
- file_buf_get_u8(fb, &action->word[3]);
- file_buf_get_le16(fb, &action->function);
+ action->word[0] = fb->readByte();
+ action->word[1] = fb->readByte();
+ action->word[3] = fb->readByte();
+ action->function = fb->readUint16LE();
(*index)++;
}
}
}
-static void parse_action_table_vjn(ComprehendGame * game,
- struct file_buf * fb, size_t * index) {
+static void parse_action_table_vjn(ComprehendGame *game,
+ struct FileBuffer * fb, size_t * index) {
struct action *action;
uint8 join, count;
int i;
@@ -356,12 +355,12 @@ static void parse_action_table_vjn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->_header.addr_actions_vjn);
+ fb->seek(game->_header.addr_actions_vjn);
while (1) {
- file_buf_get_u8(fb, &join);
+ join = fb->readByte();
if (join == 0)
break;
- file_buf_get_u8(fb, &count);
+ count = fb->readByte();
for (i = 0; i < count; i++) {
action = &game->_actions[*index];
@@ -373,17 +372,17 @@ static void parse_action_table_vjn(ComprehendGame * game,
action->word_type[1] = WORD_TYPE_JOIN;
action->word_type[2] = WORD_TYPE_NOUN_MASK;
- file_buf_get_u8(fb, &action->word[0]);
- file_buf_get_u8(fb, &action->word[2]);
- file_buf_get_le16(fb, &action->function);
+ action->word[0] = fb->readByte();
+ action->word[2] = fb->readByte();
+ action->function = fb->readUint16LE();
(*index)++;
}
}
}
-static void parse_action_table_vdn(ComprehendGame * game,
- struct file_buf * fb, size_t * index) {
+static void parse_action_table_vdn(ComprehendGame *game,
+ struct FileBuffer * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i;
@@ -397,12 +396,12 @@ static void parse_action_table_vdn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->_header.addr_actions_vdn);
+ fb->seek(game->_header.addr_actions_vdn);
while (1) {
- file_buf_get_u8(fb, &verb);
+ verb = fb->readByte();
if (verb == 0)
break;
- file_buf_get_u8(fb, &count);
+ count = fb->readByte();
for (i = 0; i < count; i++) {
action = &game->_actions[*index];
@@ -414,17 +413,17 @@ static void parse_action_table_vdn(ComprehendGame * game,
action->word_type[1] = WORD_TYPE_VERB;
action->word_type[2] = WORD_TYPE_NOUN_MASK;
- file_buf_get_u8(fb, &action->word[1]);
- file_buf_get_u8(fb, &action->word[2]);
- file_buf_get_le16(fb, &action->function);
+ action->word[1] = fb->readByte();
+ action->word[2] = fb->readByte();
+ action->function = fb->readUint16LE();
(*index)++;
}
}
}
-static void parse_action_table_vnn(ComprehendGame * game,
- struct file_buf * fb, size_t * index) {
+static void parse_action_table_vnn(ComprehendGame *game,
+ struct FileBuffer * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i;
@@ -438,13 +437,13 @@ static void parse_action_table_vnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
- file_buf_set_pos(fb, game->_header.addr_actions_vnn);
+ fb->seek(game->_header.addr_actions_vnn);
while (1) {
/* 2-byte header */
- file_buf_get_u8(fb, &verb);
+ verb = fb->readByte();
if (verb == 0)
break;
- file_buf_get_u8(fb, &count);
+ count = fb->readByte();
for (i = 0; i < count; i++) {
action = &game->_actions[*index];
@@ -456,17 +455,17 @@ static void parse_action_table_vnn(ComprehendGame * game,
action->word_type[1] = WORD_TYPE_NOUN_MASK;
action->word_type[2] = WORD_TYPE_NOUN_MASK;
- file_buf_get_u8(fb, &action->word[1]);
- file_buf_get_u8(fb, &action->word[2]);
- file_buf_get_le16(fb, &action->function);
+ action->word[1] = fb->readByte();
+ action->word[2] = fb->readByte();
+ action->function = fb->readUint16LE();
(*index)++;
}
}
}
-static void parse_action_table_vn(ComprehendGame * game,
- struct file_buf * fb, size_t * index) {
+static void parse_action_table_vn(ComprehendGame *game,
+ struct FileBuffer * fb, size_t * index) {
struct action *action;
uint8 verb, count;
int i;
@@ -479,13 +478,13 @@ static void parse_action_table_vn(ComprehendGame * game,
* u8: noun
* le16: action
*/
- file_buf_set_pos(fb, game->_header.addr_actions_vn);
+ fb->seek(game->_header.addr_actions_vn);
while (1) {
/* 2-byte header */
- file_buf_get_u8(fb, &verb);
+ verb = fb->readByte();
if (verb == 0)
break;
- file_buf_get_u8(fb, &count);
+ count = fb->readByte();
for (i = 0; i < count; i++) {
action = &game->_actions[*index];
@@ -496,16 +495,16 @@ static void parse_action_table_vn(ComprehendGame * game,
action->word_type[0] = WORD_TYPE_VERB;
action->word_type[1] = WORD_TYPE_NOUN_MASK;
- file_buf_get_u8(fb, &action->word[1]);
- file_buf_get_le16(fb, &action->function);
+ action->word[1] = fb->readByte();
+ action->function = fb->readUint16LE();
(*index)++;
}
}
}
-static void parse_action_table_v(ComprehendGame * game,
- struct file_buf * fb, size_t * index) {
+static void parse_action_table_v(ComprehendGame *game,
+ struct FileBuffer * fb, size_t * index) {
struct action *action;
uint8 verb, nr_funcs;
uint16 func;
@@ -518,9 +517,9 @@ static void parse_action_table_v(ComprehendGame * game,
* u8: count (num actions)
* le16: action
*/
- file_buf_set_pos(fb, game->_header.addr_actions_v);
+ fb->seek(game->_header.addr_actions_v);
while (1) {
- file_buf_get_u8(fb, &verb);
+ verb = fb->readByte();
if (verb == 0)
break;
@@ -536,9 +535,9 @@ static void parse_action_table_v(ComprehendGame * game,
* Default actions can have more than one function, but only
* the first one actually seems to be used?
*/
- file_buf_get_u8(fb, &nr_funcs);
+ nr_funcs = fb->readByte();
for (i = 0; i < nr_funcs; i++) {
- file_buf_get_le16(fb, &func);
+ func = fb->readUint16LE();
if (i == 0)
action->function = func;
}
@@ -547,8 +546,8 @@ static void parse_action_table_v(ComprehendGame * game,
}
}
-static void parse_action_table(ComprehendGame * game,
- struct file_buf * fb) {
+static void parse_action_table(ComprehendGame *game,
+ struct FileBuffer * fb) {
game->_nr_actions = 0;
if (game->_comprehendVersion == 1) {
@@ -565,36 +564,36 @@ static void parse_action_table(ComprehendGame * game,
parse_action_table_v(game, fb, &game->_nr_actions);
}
-static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
+static void parse_dictionary(ComprehendGame *game, struct FileBuffer * fb) {
word *words;
uint i, j;
// FIXME - fixed size 0xff array?
game->_words = (word *)xmalloc(game->_nr_words * sizeof(words));
- file_buf_set_pos(fb, game->_header.addr_dictionary);
+ fb->seek(game->_header.addr_dictionary);
for (i = 0; i < game->_nr_words; i++) {
words = &game->_words[i];
-
- file_buf_get_data(fb, words->_word, 6);
+
+ fb->read(words->_word, 6);
/* Decode */
for (j = 0; j < 6; j++)
words->_word[j] ^= 0x8a;
words->_word[6] = '\0';
- file_buf_get_u8(fb, &words->_index);
- file_buf_get_u8(fb, &words->_type);
+ words->_index = fb->readByte();
+ words->_type = fb->readByte();
}
}
-static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
+static void parse_word_map(ComprehendGame *game, struct FileBuffer * fb) {
struct word_map *map;
uint8 index, type, dummy;
uint i;
game->_nr_word_maps = 0;
- file_buf_set_pos(fb, game->_header.addr_word_map);
+ fb->seek(game->_header.addr_word_map);
/*
* Parse the word pair table. Each entry has a pair of dictionary
@@ -603,8 +602,8 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
while (1) {
map = &game->_wordMaps[game->_nr_word_maps];
- file_buf_get_u8(fb, &index);
- file_buf_get_u8(fb, &type);
+ index = fb->readByte();
+ type = fb->readByte();
if (type == 0 && index == 0) {
/* End of pairs */
break;
@@ -612,16 +611,16 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
map->word[0].index = index;
map->word[0].type = type;
- file_buf_get_u8(fb, &map->flags);
- file_buf_get_u8(fb, &map->word[1].index);
- file_buf_get_u8(fb, &map->word[1].type);
+ map->flags = fb->readByte();
+ map->word[1].index = fb->readByte();
+ map->word[1].type = fb->readByte();
game->_nr_word_maps++;
}
/* Consume two more null bytes (type and index were also null) */
- file_buf_get_u8(fb, &dummy);
- file_buf_get_u8(fb, &dummy);
+ dummy = fb->readByte();
+ dummy = fb->readByte();
/*
* Parse the target word table. Each entry has a dictionary
@@ -631,63 +630,63 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
for (i = 0; i < game->_nr_word_maps; i++) {
map = &game->_wordMaps[i];
- file_buf_get_u8(fb, &map->word[2].index);
- file_buf_get_u8(fb, &map->word[2].type);
+ map->word[2].index = fb->readByte();
+ map->word[2].type = fb->readByte();
}
}
-static void parse_items(ComprehendGame * game, struct file_buf * fb) {
+static void parse_items(ComprehendGame *game, struct FileBuffer * fb) {
size_t nr_items = game->_header.nr_items;
/* Item descriptions */
- file_buf_set_pos(fb, game->_header.addr_item_strings);
+ fb->seek(game->_header.addr_item_strings);
file_buf_get_array_le16(fb, 0, game->_items, string_desc, nr_items);
if (game->_comprehendVersion == 2) {
/* Comprehend version 2 adds long string descriptions */
- file_buf_set_pos(fb, game->_header.addr_item_strings +
+ fb->seek(game->_header.addr_item_strings +
(game->_header.nr_items * sizeof(uint16)));
file_buf_get_array_le16(fb, 0, game->_items, long_string, nr_items);
}
/* Item flags */
- file_buf_set_pos(fb, game->_header.addr_item_flags);
+ fb->seek(game->_header.addr_item_flags);
file_buf_get_array_u8(fb, 0, game->_items, flags, nr_items);
/* Item word */
- file_buf_set_pos(fb, game->_header.addr_item_word);
+ fb->seek(game->_header.addr_item_word);
file_buf_get_array_u8(fb, 0, game->_items, word, nr_items);
/* Item locations */
- file_buf_set_pos(fb, game->_header.addr_item_locations);
+ fb->seek(game->_header.addr_item_locations);
file_buf_get_array_u8(fb, 0, game->_items, room, nr_items);
/* Item graphic */
- file_buf_set_pos(fb, game->_header.addr_item_graphics);
+ fb->seek(game->_header.addr_item_graphics);
file_buf_get_array_u8(fb, 0, game->_items, graphic, nr_items);
}
-static void parse_rooms(ComprehendGame * game, struct file_buf * fb) {
+static void parse_rooms(ComprehendGame *game, struct FileBuffer * fb) {
size_t nr_rooms = game->_nr_rooms;
int i;
/* Room exit directions */
for (i = 0; i < NR_DIRECTIONS; i++) {
- file_buf_set_pos(fb, game->_header.room_direction_table[i]);
+ fb->seek(game->_header.room_direction_table[i]);
file_buf_get_array_u8(fb, 1, game->_rooms,
direction[i], nr_rooms);
}
/* Room string descriptions */
- file_buf_set_pos(fb, game->_header.room_desc_table);
+ fb->seek(game->_header.room_desc_table);
file_buf_get_array_le16(fb, 1, game->_rooms, string_desc, nr_rooms);
/* Room flags */
- file_buf_set_pos(fb, game->_header.room_flags_table);
+ fb->seek(game->_header.room_flags_table);
file_buf_get_array_u8(fb, 1, game->_rooms, flags, nr_rooms);
/* Room graphic */
- file_buf_set_pos(fb, game->_header.room_graphics_table);
+ fb->seek(game->_header.room_graphics_table);
file_buf_get_array_u8(fb, 1, game->_rooms, graphic, nr_rooms);
}
@@ -739,7 +738,7 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
* specifier). If a character has the value 0x1f then the next character is
* taken from the symbols table.
*/
-static char *parse_string(struct file_buf * fb) {
+static char *parse_string(struct FileBuffer * fb) {
bool capital_next = false, special_next = false;
unsigned i, j, k = 0;
uint64 chunk;
@@ -747,17 +746,17 @@ static char *parse_string(struct file_buf * fb) {
char *string, c;
size_t encoded_len;
- encoded_len = file_buf_strlen(fb, NULL);
+ encoded_len = fb->strlen();
string = (char *)xmalloc(encoded_len * 2);
/* Get the encoded string */
encoded = (uint8 *)xmalloc(encoded_len + 5);
memset(encoded, 0, encoded_len);
- file_buf_get_data(fb, encoded, encoded_len);
+ fb->read(encoded, encoded_len);
/* Skip over the zero byte */
- if (file_buf_get_pos(fb) < fb->size)
- file_buf_get_u8(fb, NULL);
+ if (fb->pos() < fb->size())
+ fb->skip(1);
for (i = 0; i < encoded_len; i += 5) {
chunk = string_get_chunk(&encoded[i]);
@@ -788,29 +787,29 @@ done:
return string;
}
-static void parse_string_table(struct file_buf * fb, unsigned start_addr,
+static void parse_string_table(struct FileBuffer * fb, unsigned start_addr,
uint32 end_addr, struct string_table *table) {
- file_buf_set_pos(fb, start_addr);
+ fb->seek(start_addr);
while (1) {
table->strings[table->nr_strings++] = parse_string(fb);
- if (file_buf_get_pos(fb) >= end_addr)
+ if (fb->pos() >= (int32)end_addr)
break;
}
}
-static void parse_variables(ComprehendGame * game, struct file_buf * fb) {
+static void parse_variables(ComprehendGame *game, struct FileBuffer * fb) {
int i;
for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
- file_buf_get_le16(fb, &game->_variables[i]);
+ game->_variables[i] = fb->readUint16LE();
}
-static void parse_flags(ComprehendGame * game, struct file_buf * fb) {
+static void parse_flags(ComprehendGame *game, struct FileBuffer * fb) {
int i, bit, flag_index = 0;
uint8 bitmask;
for (i = 0; i < ARRAY_SIZE(game->_flags) / 8; i++) {
- file_buf_get_u8(fb, &bitmask);
+ bitmask = fb->readByte();
for (bit = 7; bit >= 0; bit--) {
game->_flags[flag_index] = !!(bitmask & (1 << bit));
flag_index++;
@@ -818,26 +817,26 @@ static void parse_flags(ComprehendGame * game, struct file_buf * fb) {
}
}
-static void parse_replace_words(ComprehendGame * game,
- struct file_buf * fb) {
+static void parse_replace_words(ComprehendGame *game,
+ struct FileBuffer * fb) {
uint16 dummy;
size_t len;
bool eof;
int i;
/* FIXME - Rename addr_strings_end */
- file_buf_set_pos(fb, game->_header.addr_strings_end);
+ fb->seek(game->_header.addr_strings_end);
/* FIXME - what is this for */
- file_buf_get_le16(fb, &dummy);
+ dummy = fb->readUint16LE();
for (i = 0;; i++) {
- len = file_buf_strlen(fb, &eof);
+ len = fb->strlen(&eof);
if (len == 0)
break;
- game->_replaceWords[i] = xstrndup((char *)fb->p, len);
- file_buf_get_data(fb, NULL, len + (eof ? 0 : 1));
+ game->_replaceWords[i] = xstrndup((const char *)fb->dataPtr(), len);
+ fb->read(NULL, len + (eof ? 0 : 1));
if (eof)
break;
}
@@ -848,13 +847,13 @@ static void parse_replace_words(ComprehendGame * game,
* The main game data file header has the offsets for where each bit of
* game data is. The offsets have a magic constant value added to them.
*/
-static void parse_header(ComprehendGame * game, struct file_buf * fb) {
+static void parse_header(ComprehendGame *game, struct FileBuffer * fb) {
struct game_header *header = &game->_header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
- file_buf_set_pos(fb, 0);
- file_buf_get_le16(fb, &header->magic);
+ fb->seek(0);
+ header->magic = fb->readUint16LE();
switch (header->magic) {
case 0x2000: /* Transylvania, Crimson Crown disk one */
case 0x4800: /* Crimson Crown disk two */
@@ -951,9 +950,9 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
parse_header_le16(fb, &dummy);
parse_header_le16(fb, &header->addr_strings_end);
- file_buf_get_u8(fb, &dummy8);
- file_buf_get_u8(fb, &game->_startRoom);
- file_buf_get_u8(fb, &dummy8);
+ dummy8 = fb->readByte();
+ game->_startRoom = fb->readByte();
+ dummy8 = fb->readByte();
parse_variables(game, fb);
parse_flags(game, fb);
@@ -966,25 +965,21 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
8;
}
-static void load_extra_string_file(ComprehendGame * game,
+static void load_extra_string_file(ComprehendGame *game,
string_file * string_file) {
- struct file_buf fb;
+ FileBuffer fb(string_file->filename);
unsigned end;
- file_buf_map(string_file->filename, &fb);
-
if (string_file->end_offset)
end = string_file->end_offset;
else
- end = fb.size;
+ end = fb.size();
parse_string_table(&fb, string_file->base_offset,
end, &game->_strings2);
-
- file_buf_unmap(&fb);
}
-static void load_extra_string_files(ComprehendGame * game) {
+static void load_extra_string_files(ComprehendGame *game) {
int i;
memset(&game->_strings2, 0, sizeof(game->_strings2));
@@ -1002,11 +997,10 @@ static void load_extra_string_files(ComprehendGame * game) {
}
}
-static void load_game_data(ComprehendGame * game) {
- struct file_buf fb;
+static void load_game_data(ComprehendGame *game) {
+ FileBuffer fb(game->_gameDataFile);
game->clearInfo();
- file_buf_map(game->_gameDataFile, &fb);
parse_header(game, &fb);
parse_rooms(game, &fb);
@@ -1021,11 +1015,9 @@ static void load_game_data(ComprehendGame * game) {
parse_vm(game, &fb);
parse_action_table(game, &fb);
parse_replace_words(game, &fb);
-
- file_buf_unmap(&fb);
}
-void comprehend_load_game(ComprehendGame * game) {
+void comprehend_load_game(ComprehendGame *game) {
/* Load the main game data file */
load_game_data(game);
@@ -1054,7 +1046,7 @@ static void patch_string_desc(uint16 * desc) {
}
#endif
-void comprehend_save_game(ComprehendGame * game, const char *filename) {
+void comprehend_save_game(ComprehendGame *game, const char *filename) {
#ifdef TODO
FILE *fd;
uint8 bitmask;
@@ -1138,9 +1130,9 @@ void comprehend_save_game(ComprehendGame * game, const char *filename) {
#endif
}
-void comprehend_restore_game(ComprehendGame * game, const char *filename) {
+void comprehend_restore_game(ComprehendGame *game, const char *filename) {
#ifdef TODO
- struct file_buf fb;
+ struct FileBuffer fb;
size_t nr_rooms, nr_items;
uint err, dir, i;
@@ -1156,7 +1148,7 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
/* Restore starting room */
file_buf_set_pos(&fb, 1);
- file_buf_get_u8(&fb, &game->current_room);
+ game->current_room = fb->readByte();
/* Restore flags and variables */
file_buf_set_pos(&fb, 3);
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 4204001110..db2e6ffaae 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -57,22 +57,22 @@ void image_set_draw_flags(unsigned flags)
draw_flags |= flags;
}
-static uint16 image_get_operand(struct file_buf *fb)
+static uint16 image_get_operand(FileBuffer *fb)
{
uint8 val;
- file_buf_get_u8(fb, &val);
+ val = fb->readByte();
return val;
}
-static bool do_image_op(struct file_buf *fb, struct image_context *ctx)
+static bool do_image_op(struct FileBuffer *fb, struct image_context *ctx)
{
uint8 opcode;
uint16 a, b;
- file_buf_get_u8(fb, &opcode);
+ opcode = fb->readByte();
debug_printf(DEBUG_IMAGE_DRAW,
- " %.4x [%.2x]: ", file_buf_get_pos(fb) - 1, opcode);
+ " %.4x [%.2x]: ", fb->pos() - 1, opcode);
switch (opcode) {
case IMAGE_OP_SCENE_END:
@@ -257,7 +257,7 @@ static bool do_image_op(struct file_buf *fb, struct image_context *ctx)
void draw_image(struct image_data *info, unsigned index)
{
unsigned file_num;
- struct file_buf *fb;
+ struct FileBuffer *fb;
bool done = false;
image_context ctx = {
0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE
@@ -272,7 +272,7 @@ void draw_image(struct image_data *info, unsigned index)
return;
}
- file_buf_set_pos(fb, info->image_offsets[index]);
+ fb->seek(info->image_offsets[index]);
while (!done) {
done = do_image_op(fb, &ctx);
if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
@@ -304,30 +304,28 @@ static void load_image_file(struct image_data *info, const char *filename,
unsigned file_num)
{
unsigned base = file_num * IMAGES_PER_FILE;
- struct file_buf *fb;
+ struct FileBuffer *fb;
uint16 version;
int i;
- fb = &info->fb[file_num];
- file_buf_map(filename, fb);
+ info->fb[file_num] = FileBuffer(filename);
/*
* In earlier versions of Comprehend the first word is 0x1000 and
* the image offsets start four bytes in. In newer versions the
* image offsets start at the beginning of the image file.
*/
- file_buf_get_le16(fb, &version);
+ version = fb->readUint16LE();
if (version == 0x1000)
- file_buf_set_pos(fb, 4);
+ fb->seek(4);
else
- file_buf_set_pos(fb, 0);
+ fb->seek(0);
/* Get the image offsets in the file */
for (i = 0; i < IMAGES_PER_FILE; i++) {
- file_buf_get_le16(fb, &info->image_offsets[base + i]); {
- if (version == 0x1000)
- info->image_offsets[base + i] += 4;
- }
+ info->image_offsets[base + i] = fb->readUint16LE();
+ if (version == 0x1000)
+ info->image_offsets[base + i] += 4;
}
}
@@ -338,7 +336,7 @@ static void load_image_files(struct image_data *info,
memset(info, 0, sizeof(*info));
info->nr_images = filenames.size() * IMAGES_PER_FILE;
- info->fb = (file_buf *)xmalloc(info->nr_images * sizeof(*info->fb));
+ info->fb = (FileBuffer *)xmalloc(info->nr_images * sizeof(*info->fb));
info->image_offsets = (uint16 *)xmalloc(info->nr_images * sizeof(uint16));
for (i = 0; i < filenames.size(); i++) {
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index 382c90a166..cb165e9fdb 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -29,10 +29,10 @@ namespace Glk {
namespace Comprehend {
class ComprehendGame;
-struct file_buf;
+struct FileBuffer;
struct image_data {
- file_buf *fb;
+ FileBuffer *fb;
uint16 *image_offsets;
size_t nr_images;
Commit: 5023e261ed6aac0d32b8d72bb2df726cd89db76d
https://github.com/scummvm/scummvm/commit/5023e261ed6aac0d32b8d72bb2df726cd89db76d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Removal of redundant struct prefixes
Changed paths:
engines/glk/comprehend/game_data.cpp
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index d10414b4ee..c28813e19f 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -215,8 +215,8 @@ static uint8 parse_vm_instruction(FileBuffer *fb,
return instr->opcode;
}
-static void parse_function(struct FileBuffer * fb, struct function * func) {
- struct instruction *instruction;
+static void parse_function(FileBuffer *fb, function * func) {
+ instruction *instruction;
uint8 *p, opcode;
p = (uint8 *)memchr(fb->dataPtr(), 0x00, fb->size() - fb->pos());
@@ -236,7 +236,7 @@ static void parse_function(struct FileBuffer * fb, struct function * func) {
}
}
-static void parse_vm(ComprehendGame *game, struct FileBuffer * fb) {
+static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
function *func;
fb->seek(game->_header.addr_vm);
@@ -252,8 +252,8 @@ static void parse_vm(ComprehendGame *game, struct FileBuffer * fb) {
}
static void parse_action_table_vvnn(ComprehendGame *game,
- struct FileBuffer * fb, size_t * index) {
- struct action *action;
+ FileBuffer *fb, size_t * index) {
+ action *action;
uint8 verb, count;
int i, j;
@@ -296,8 +296,8 @@ static void parse_action_table_vvnn(ComprehendGame *game,
}
static void parse_action_table_vnjn(ComprehendGame *game,
- struct FileBuffer * fb, size_t * index) {
- struct action *action;
+ FileBuffer *fb, size_t * index) {
+ action *action;
uint8 join, count;
int i;
@@ -341,8 +341,8 @@ static void parse_action_table_vnjn(ComprehendGame *game,
}
static void parse_action_table_vjn(ComprehendGame *game,
- struct FileBuffer * fb, size_t * index) {
- struct action *action;
+ FileBuffer *fb, size_t * index) {
+ action *action;
uint8 join, count;
int i;
@@ -382,8 +382,8 @@ static void parse_action_table_vjn(ComprehendGame *game,
}
static void parse_action_table_vdn(ComprehendGame *game,
- struct FileBuffer * fb, size_t * index) {
- struct action *action;
+ FileBuffer *fb, size_t * index) {
+ action *action;
uint8 verb, count;
int i;
@@ -423,8 +423,8 @@ static void parse_action_table_vdn(ComprehendGame *game,
}
static void parse_action_table_vnn(ComprehendGame *game,
- struct FileBuffer * fb, size_t * index) {
- struct action *action;
+ FileBuffer *fb, size_t * index) {
+ action *action;
uint8 verb, count;
int i;
@@ -465,8 +465,8 @@ static void parse_action_table_vnn(ComprehendGame *game,
}
static void parse_action_table_vn(ComprehendGame *game,
- struct FileBuffer * fb, size_t * index) {
- struct action *action;
+ FileBuffer *fb, size_t * index) {
+ action *action;
uint8 verb, count;
int i;
@@ -504,8 +504,8 @@ static void parse_action_table_vn(ComprehendGame *game,
}
static void parse_action_table_v(ComprehendGame *game,
- struct FileBuffer * fb, size_t * index) {
- struct action *action;
+ FileBuffer *fb, size_t * index) {
+ action *action;
uint8 verb, nr_funcs;
uint16 func;
int i;
@@ -547,7 +547,7 @@ static void parse_action_table_v(ComprehendGame *game,
}
static void parse_action_table(ComprehendGame *game,
- struct FileBuffer * fb) {
+ FileBuffer *fb) {
game->_nr_actions = 0;
if (game->_comprehendVersion == 1) {
@@ -564,7 +564,7 @@ static void parse_action_table(ComprehendGame *game,
parse_action_table_v(game, fb, &game->_nr_actions);
}
-static void parse_dictionary(ComprehendGame *game, struct FileBuffer * fb) {
+static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
word *words;
uint i, j;
@@ -587,8 +587,8 @@ static void parse_dictionary(ComprehendGame *game, struct FileBuffer * fb) {
}
}
-static void parse_word_map(ComprehendGame *game, struct FileBuffer * fb) {
- struct word_map *map;
+static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
+ word_map *map;
uint8 index, type, dummy;
uint i;
@@ -635,7 +635,7 @@ static void parse_word_map(ComprehendGame *game, struct FileBuffer * fb) {
}
}
-static void parse_items(ComprehendGame *game, struct FileBuffer * fb) {
+static void parse_items(ComprehendGame *game, FileBuffer *fb) {
size_t nr_items = game->_header.nr_items;
/* Item descriptions */
@@ -666,7 +666,7 @@ static void parse_items(ComprehendGame *game, struct FileBuffer * fb) {
file_buf_get_array_u8(fb, 0, game->_items, graphic, nr_items);
}
-static void parse_rooms(ComprehendGame *game, struct FileBuffer * fb) {
+static void parse_rooms(ComprehendGame *game, FileBuffer *fb) {
size_t nr_rooms = game->_nr_rooms;
int i;
@@ -738,7 +738,7 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
* specifier). If a character has the value 0x1f then the next character is
* taken from the symbols table.
*/
-static char *parse_string(struct FileBuffer * fb) {
+static char *parse_string(FileBuffer *fb) {
bool capital_next = false, special_next = false;
unsigned i, j, k = 0;
uint64 chunk;
@@ -787,8 +787,8 @@ done:
return string;
}
-static void parse_string_table(struct FileBuffer * fb, unsigned start_addr,
- uint32 end_addr, struct string_table *table) {
+static void parse_string_table(FileBuffer *fb, unsigned start_addr,
+ uint32 end_addr, string_table *table) {
fb->seek(start_addr);
while (1) {
table->strings[table->nr_strings++] = parse_string(fb);
@@ -797,14 +797,14 @@ static void parse_string_table(struct FileBuffer * fb, unsigned start_addr,
}
}
-static void parse_variables(ComprehendGame *game, struct FileBuffer * fb) {
+static void parse_variables(ComprehendGame *game, FileBuffer *fb) {
int i;
for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
game->_variables[i] = fb->readUint16LE();
}
-static void parse_flags(ComprehendGame *game, struct FileBuffer * fb) {
+static void parse_flags(ComprehendGame *game, FileBuffer *fb) {
int i, bit, flag_index = 0;
uint8 bitmask;
@@ -818,7 +818,7 @@ static void parse_flags(ComprehendGame *game, struct FileBuffer * fb) {
}
static void parse_replace_words(ComprehendGame *game,
- struct FileBuffer * fb) {
+ FileBuffer *fb) {
uint16 dummy;
size_t len;
bool eof;
@@ -847,8 +847,8 @@ static void parse_replace_words(ComprehendGame *game,
* The main game data file header has the offsets for where each bit of
* game data is. The offsets have a magic constant value added to them.
*/
-static void parse_header(ComprehendGame *game, struct FileBuffer * fb) {
- struct game_header *header = &game->_header;
+static void parse_header(ComprehendGame *game, FileBuffer *fb) {
+ game_header *header = &game->_header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
@@ -1132,7 +1132,7 @@ void comprehend_save_game(ComprehendGame *game, const char *filename) {
void comprehend_restore_game(ComprehendGame *game, const char *filename) {
#ifdef TODO
- struct FileBuffer fb;
+ FileBuffer fb;
size_t nr_rooms, nr_items;
uint err, dir, i;
Commit: 269b83f31ee17ecedc771aa9e6ef3ce04f3d06bc
https://github.com/scummvm/scummvm/commit/269b83f31ee17ecedc771aa9e6ef3ce04f3d06bc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Removal of redundant struct prefixes
Changed paths:
R engines/glk/comprehend/recomprehend.cpp
R engines/glk/comprehend/recomprehend.h
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/dictionary.cpp
engines/glk/comprehend/dictionary.h
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/dump_game_data.h
engines/glk/comprehend/file_buf.cpp
engines/glk/comprehend/file_buf.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/graphics.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_view.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 2f0d317eef..3ca90b7b28 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -58,7 +58,7 @@ static const dump_option dump_options[] = {
#ifdef TODO
int main(int argc, char **argv) {
- struct option long_opts[] = {
+ option long_opts[] = {
{"debug", no_argument, 0, 'd'},
{"dump", required_argument, 0, 'D'},
{"no-play", no_argument, 0, 'p'},
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
index 1421763198..2f6e4cf025 100644
--- a/engines/glk/comprehend/dictionary.cpp
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -28,7 +28,7 @@
namespace Glk {
namespace Comprehend {
-static bool word_match(struct word *word, const char *string)
+static bool word_match(word *word, const char *string)
{
/* Words less than 6 characters must match exactly */
if (strlen(word->_word) < 6 && strlen(string) != strlen(word->_word))
@@ -52,7 +52,7 @@ word *dict_find_word_by_string(ComprehendGame *game,
return NULL;
}
-struct word *dict_find_word_by_index_type(ComprehendGame *game,
+word *dict_find_word_by_index_type(ComprehendGame *game,
uint8 index, uint8 type)
{
uint i;
@@ -66,7 +66,7 @@ struct word *dict_find_word_by_index_type(ComprehendGame *game,
return NULL;
}
-struct word *find_dict_word_by_index(ComprehendGame *game,
+word *find_dict_word_by_index(ComprehendGame *game,
uint8 index, uint8 type_mask)
{
uint i;
diff --git a/engines/glk/comprehend/dictionary.h b/engines/glk/comprehend/dictionary.h
index cdf4add8a8..f685513811 100644
--- a/engines/glk/comprehend/dictionary.h
+++ b/engines/glk/comprehend/dictionary.h
@@ -29,11 +29,11 @@ namespace Comprehend {
class ComprehendGame;
struct word;
-struct word *find_dict_word_by_index(ComprehendGame *game,
+word *find_dict_word_by_index(ComprehendGame *game,
uint8 index, uint8 type_mask);
-struct word *dict_find_word_by_index_type(ComprehendGame *game,
+word *dict_find_word_by_index_type(ComprehendGame *game,
uint8 index, uint8 type);
-struct word *dict_find_word_by_string(ComprehendGame *game,
+word *dict_find_word_by_string(ComprehendGame *game,
const char *string);
bool dict_match_index_type(ComprehendGame *game, const char *word,
uint8 index, uint8 type_mask);
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index d33f8cb62e..bd99a5d4f3 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -114,8 +114,8 @@ static const char *opcode_names[] = {
};
void dump_instruction(ComprehendGame *game,
- struct function_state *func_state,
- struct instruction *instr)
+ function_state *func_state,
+ instruction *instr)
{
uint i;
int str_index, str_table;
@@ -169,7 +169,7 @@ void dump_instruction(ComprehendGame *game,
static void dump_functions(ComprehendGame *game)
{
- struct function *func;
+ function *func;
uint i, j;
debugN("Functions (%zd entries)\n", game->_nr_functions);
@@ -185,8 +185,8 @@ static void dump_functions(ComprehendGame *game)
static void dump_action_table(ComprehendGame *game)
{
- struct action *action;
- struct word *word;
+ action *action;
+ word *word;
uint i, j;
debugN("Action table (%zd entries)\n", game->_nr_actions);
@@ -265,9 +265,9 @@ static void dump_dictionary(ComprehendGame *game)
static void dump_word_map(ComprehendGame *game)
{
- struct word *word[3];
+ word *word[3];
char str[3][6];
- struct word_map *map;
+ word_map *map;
uint i, j;
debugN("Word pairs (%zd entries)\n", game->_nr_word_maps);
@@ -292,7 +292,7 @@ static void dump_word_map(ComprehendGame *game)
static void dump_rooms(ComprehendGame *game)
{
- struct room *room;
+ room *room;
uint i;
/* Room zero acts as the players inventory */
@@ -319,7 +319,7 @@ static void dump_rooms(ComprehendGame *game)
static void dump_items(ComprehendGame *game)
{
- struct item *item;
+ item *item;
uint i, j;
debugN("Items (%zd entries)\n", game->_header.nr_items);
@@ -348,7 +348,7 @@ static void dump_items(ComprehendGame *game)
}
}
-static void dump_string_table(struct string_table *table)
+static void dump_string_table(string_table *table)
{
uint i;
@@ -382,7 +382,7 @@ static void dump_replace_words(ComprehendGame *game)
static void dump_header(ComprehendGame *game)
{
- struct game_header *header = &game->_header;
+ game_header *header = &game->_header;
uint16 *dir_table = header->room_direction_table;
debugN("Game header:\n");
@@ -425,7 +425,7 @@ struct dumper {
unsigned flag;
};
-static struct dumper dumpers[] = {
+static dumper dumpers[] = {
{dump_header, DUMP_HEADER},
{dump_game_data_strings, DUMP_STRINGS},
{dump_extra_strings, DUMP_EXTRA_STRINGS},
diff --git a/engines/glk/comprehend/dump_game_data.h b/engines/glk/comprehend/dump_game_data.h
index bb91757d15..06c6609e6c 100644
--- a/engines/glk/comprehend/dump_game_data.h
+++ b/engines/glk/comprehend/dump_game_data.h
@@ -43,8 +43,8 @@ struct instruction;
#define DUMP_ALL (~0U)
void dump_instruction(ComprehendGame *game,
- struct function_state *func_state,
- struct instruction *instr);
+ function_state *func_state,
+ instruction *instr);
void dump_game_data(ComprehendGame *game, unsigned flags);
} // namespace Comprehend
diff --git a/engines/glk/comprehend/file_buf.cpp b/engines/glk/comprehend/file_buf.cpp
index d246bd738f..76b70cc82d 100644
--- a/engines/glk/comprehend/file_buf.cpp
+++ b/engines/glk/comprehend/file_buf.cpp
@@ -89,42 +89,14 @@ size_t FileBuffer::strlen(bool *eof) {
return end - &_data[_pos];
}
-
-#ifdef TODO
-void file_buf_unmap(struct FileBuffer *fb) {
- free(fb->marked);
- free(fb->data);
-}
-
-unsigned file_buf_get_pos(struct FileBuffer *fb) {
- return fb->p - fb->data;
-}
-
-void file_buf_get_data(struct FileBuffer *fb, void *data, size_t data_size) {
- if (fb->pos() + data_size > fb->size)
- error("Not enough data in file (%x + %x > %x)",
- fb->pos(), data_size, fb->size);
-
- if (data)
- memcpy(data, fb->p, data_size);
-
- /* Mark this region of the file as read */
- memset(fb->marked + fb->pos(), '?', data_size);
-
- fb->p += data_size;
-}
-
-/*
- * Debugging function to show regions of a file that have not been read.
- */
-void file_buf_show_unmarked(struct FileBuffer *fb) {
+void FileBuffer::showUnmarked() {
int i, start = -1;
- for (i = 0; i < (int)fb->size; i++) {
- if (!fb->marked[i] && start == -1)
+ for (i = 0; i < (int)_data.size(); i++) {
+ if (!_readBytes[i] && start == -1)
start = i;
- if ((fb->marked[i] || i == (int)fb->size - 1) && start != -1) {
+ if ((_readBytes[i] || i == (int)_data.size() - 1) && start != -1) {
warning("%.4x - %.4x unmarked (%d bytes)\n",
start, i - 1, i - start);
start = -1;
@@ -132,19 +104,5 @@ void file_buf_show_unmarked(struct FileBuffer *fb) {
}
}
-void file_buf_put_u8(Common::WriteStream *fd, uint8 val) {
- fd->writeByte(val);
-}
-
-void file_buf_put_le16(Common::WriteStream *fd, uint16 val) {
- fd->writeUint16LE(val);
-}
-
-void file_buf_put_skip(Common::WriteStream *fd, size_t skip) {
- for (uint i = 0; i < skip; i++)
- file_buf_put_u8(fd, 0);
-}
-#endif
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/file_buf.h b/engines/glk/comprehend/file_buf.h
index 3f323e3ec2..0805842809 100644
--- a/engines/glk/comprehend/file_buf.h
+++ b/engines/glk/comprehend/file_buf.h
@@ -53,36 +53,12 @@ public:
const byte *dataPtr() const { return &_data[_pos]; }
size_t strlen(bool *eof = nullptr);
+ /*
+ * Debugging function to show regions of a file that have not been read.
+ */
+ void showUnmarked();
};
-#ifdef TODO
-void file_buf_unmap(struct FileBuffer *fb);
-void file_buf_show_unmarked(struct FileBuffer *fb);
-
-unsigned file_buf_get_pos(struct FileBuffer *fb);
-
-size_t file_buf_strlen(struct FileBuffer *fb, bool *eof);
-
-void file_buf_get_data(struct FileBuffer *fb, void *data, size_t data_size);
-
-void file_buf_put_skip(Common::WriteStream *fd, size_t skip);
-void file_buf_put_u8(Common::WriteStream *fd, uint8 val);
-void file_buf_put_le16(Common::WriteStream *fd, uint16 val);
-
-#define file_buf_put_array(fd, type, base, array, member, size) \
- do { \
- int __i; \
- for (__i = (base); __i < (base) + (size); __i++) \
- file_buf_put_##type(fd, (array)[__i].member); \
- } while (0)
-
-#define file_buf_put_array_le16(fd, base, array, member, size) \
- file_buf_put_array(fd, le16, base, array, member, size)
-
-#define file_buf_put_array_u8(fd, base, array, member, size) \
- file_buf_put_array(fd, u8, base, array, member, size)
-#endif
-
#define file_buf_get_array(fb, type, base, array, member, size) \
do { \
uint __i; \
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index b1440c979c..a41842497e 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -34,14 +34,14 @@ namespace Glk {
namespace Comprehend {
struct sentence {
- struct word words[4];
+ word words[4];
size_t nr_words;
};
struct winsize {
uint ws_col;
};
-static struct winsize console_winsize;
+static winsize console_winsize;
ComprehendGame::ComprehendGame() : _gameName(nullptr),
_shortName(nullptr),
@@ -157,7 +157,7 @@ void console_println(ComprehendGame *game, const char *text) {
printf("\n");
}
-static struct room *get_room(ComprehendGame *game, uint16 index) {
+static room *get_room(ComprehendGame *game, uint16 index) {
/* Room zero is reserved for the players inventory */
if (index == 0)
fatal_error("Room index 0 (player inventory) is invalid");
@@ -168,7 +168,7 @@ static struct room *get_room(ComprehendGame *game, uint16 index) {
return &game->_rooms[index];
}
-struct item *get_item(ComprehendGame *game, uint16 index) {
+item *get_item(ComprehendGame *game, uint16 index) {
if (index >= game->_header.nr_items)
fatal_error("Bad item %d\n", index);
@@ -225,9 +225,9 @@ void game_restart(ComprehendGame *game) {
game->_updateFlags = UPDATE_ALL;
}
-static struct word_index *is_word_pair(ComprehendGame *game,
- struct word *word1, struct word *word2) {
- struct word_map *map;
+static word_index *is_word_pair(ComprehendGame *game,
+ word *word1, word *word2) {
+ word_map *map;
uint i;
/* Check if this is a word pair */
@@ -244,8 +244,8 @@ static struct word_index *is_word_pair(ComprehendGame *game,
return NULL;
}
-static struct item *get_item_by_noun(ComprehendGame *game,
- struct word *noun) {
+static item *get_item_by_noun(ComprehendGame *game,
+ word *noun) {
uint i;
if (!noun || !(noun->_type & WORD_TYPE_NOUN_MASK))
@@ -264,8 +264,8 @@ static struct item *get_item_by_noun(ComprehendGame *game,
}
static void update_graphics(ComprehendGame *game) {
- struct item *item;
- struct room *room;
+ item *item;
+ room *room;
int type;
uint i;
@@ -308,7 +308,7 @@ static void update_graphics(ComprehendGame *game) {
}
static void describe_objects_in_current_room(ComprehendGame *game) {
- struct item *item;
+ item *item;
size_t count = 0;
uint i;
@@ -334,7 +334,7 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
}
static void update(ComprehendGame *game) {
- struct room *room = get_room(game, game->_currentRoom);
+ room *room = get_room(game, game->_currentRoom);
unsigned room_type, room_desc_string;
update_graphics(game);
@@ -363,7 +363,7 @@ static void move_to(ComprehendGame *game, uint8 room) {
UPDATE_ITEM_LIST);
}
-static void func_set_test_result(struct function_state *func_state, bool value) {
+static void func_set_test_result(function_state *func_state, bool value) {
if (func_state->or_count == 0) {
/* And */
if (func_state->_and) {
@@ -391,7 +391,7 @@ static size_t num_objects_in_room(ComprehendGame *game, int room) {
return count;
}
-void move_object(ComprehendGame *game, struct item *item, int new_room) {
+void move_object(ComprehendGame *game, item *item, int new_room) {
unsigned obj_weight = item->flags & ITEMF_WEIGHT_MASK;
if (item->room == new_room)
@@ -423,12 +423,12 @@ void move_object(ComprehendGame *game, struct item *item, int new_room) {
}
static void eval_instruction(ComprehendGame *game,
- struct function_state *func_state,
- struct instruction *instr,
- struct word *verb, struct word *noun) {
+ function_state *func_state,
+ instruction *instr,
+ word *verb, word *noun) {
uint8 *opcode_map;
- struct room *room;
- struct item *item;
+ room *room;
+ item *item;
uint16 index;
bool test;
uint i, count;
@@ -981,9 +981,9 @@ static void eval_instruction(ComprehendGame *game,
* is reached. Otherwise the commands instructions are skipped over and the
* next test sequence (if there is one) is tried.
*/
-void eval_function(ComprehendGame *game, struct function *func,
- struct word *verb, struct word *noun) {
- struct function_state func_state;
+void eval_function(ComprehendGame *game, function *func,
+ word *verb, word *noun) {
+ function_state func_state;
uint i;
func_state.else_result = true;
@@ -1056,9 +1056,9 @@ static void handle_debug_command(ComprehendGame *game,
#endif
static bool handle_sentence(ComprehendGame *game,
- struct sentence *sentence) {
- struct function *func;
- struct action *action;
+ sentence *sentence) {
+ function *func;
+ action *action;
uint i, j;
if (sentence->nr_words == 0)
@@ -1102,11 +1102,11 @@ static bool handle_sentence(ComprehendGame *game,
}
static void read_sentence(ComprehendGame *game, char **line,
- struct sentence *sentence) {
+ sentence *sentence) {
bool sentence_end = false;
char *word_string, *p = *line;
- struct word_index *pair;
- struct word *word;
+ word_index *pair;
+ word *word;
int index;
memset(sentence, 0, sizeof(*sentence));
@@ -1178,7 +1178,7 @@ static void after_turn(ComprehendGame *game) {
static void read_input(ComprehendGame *game) {
#ifdef TODO
- struct sentence sentence;
+ sentence sentence;
char *line = NULL, buffer[1024];
bool handled;
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 86fde90347..583f333f53 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -69,10 +69,10 @@ public:
void console_println(ComprehendGame *game, const char *text);
int console_get_key(void);
-struct item *get_item(ComprehendGame *game, uint16 index);
-void move_object(ComprehendGame *game, struct item *item, int new_room);
-void eval_function(ComprehendGame *game, struct function *func,
- struct word *verb, struct word *noun);
+item *get_item(ComprehendGame *game, uint16 index);
+void move_object(ComprehendGame *game, item *item, int new_room);
+void eval_function(ComprehendGame *game, function *func,
+ word *verb, word *noun);
void comprehend_play_game(ComprehendGame *game);
void game_save(ComprehendGame *game);
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index 8eb79938a3..4b1a5feab7 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -26,10 +26,10 @@
namespace Glk {
namespace Comprehend {
-static struct game_strings cc1_strings = {0x9};
+static game_strings cc1_strings = {0x9};
#ifdef TODO
-static struct game_ops cc2_ops = {
+static game_ops cc2_ops = {
nullptr,
cc2_before_prompt,
nullptr,
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 4e230db896..b1faa9c705 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -85,7 +85,7 @@ int OOToposGame::room_is_special(unsigned room_index,
bool OOToposGame::before_turn() {
/* FIXME - probably doesn't work correctly with restored games */
static bool flashlight_was_on = false, googles_were_worn = false;
- struct room *room = &_rooms[_currentRoom];
+ room *room = &_rooms[_currentRoom];
/*
* Check if the room needs to be redrawn because the flashlight
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 7be0262219..041b4dfef0 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -36,7 +36,7 @@ const tr_monster TransylvaniaGame::VAMPIRE = {
0x26, 5, (1 << 7), 0, 5
};
-static struct game_strings tr_strings = {
+static game_strings tr_strings = {
EXTRA_STRING_TABLE(0x8a)
};
@@ -65,8 +65,8 @@ TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
};
void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
- struct item *monster;
- struct room *room;
+ item *monster;
+ room *room;
uint16 turn_count;
room = &_rooms[_currentRoom];
@@ -98,7 +98,7 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
int TransylvaniaGame::room_is_special(unsigned room_index,
unsigned *room_desc_string)
{
- struct room *room = &_rooms[room_index];
+ room *room = &_rooms[room_index];
if (room_index == 0x28) {
if (room_desc_string)
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/graphics.cpp
index b62df4d2fc..cb37182dc2 100644
--- a/engines/glk/comprehend/graphics.cpp
+++ b/engines/glk/comprehend/graphics.cpp
@@ -63,7 +63,7 @@ struct graphics_context {
// SDL_Surface *surface;
};
-static struct graphics_context ctx;
+static graphics_context ctx;
unsigned g_set_pen_color(uint8 opcode) {
return pen_colors[opcode - IMAGE_OP_PEN_COLOR_A];
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index db2e6ffaae..1a5be26d62 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -65,7 +65,7 @@ static uint16 image_get_operand(FileBuffer *fb)
return val;
}
-static bool do_image_op(struct FileBuffer *fb, struct image_context *ctx)
+static bool do_image_op(FileBuffer *fb, image_context *ctx)
{
uint8 opcode;
uint16 a, b;
@@ -254,10 +254,10 @@ static bool do_image_op(struct FileBuffer *fb, struct image_context *ctx)
return false;
}
-void draw_image(struct image_data *info, unsigned index)
+void draw_image(image_data *info, unsigned index)
{
unsigned file_num;
- struct FileBuffer *fb;
+ FileBuffer *fb;
bool done = false;
image_context ctx = {
0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE
@@ -294,17 +294,17 @@ void draw_bright_room(void)
g_clear_screen(G_COLOR_WHITE);
}
-void draw_location_image(struct image_data *info, unsigned index)
+void draw_location_image(image_data *info, unsigned index)
{
g_clear_screen(G_COLOR_WHITE);
draw_image(info, index);
}
-static void load_image_file(struct image_data *info, const char *filename,
+static void load_image_file(image_data *info, const char *filename,
unsigned file_num)
{
unsigned base = file_num * IMAGES_PER_FILE;
- struct FileBuffer *fb;
+ FileBuffer *fb;
uint16 version;
int i;
@@ -329,7 +329,7 @@ static void load_image_file(struct image_data *info, const char *filename,
}
}
-static void load_image_files(struct image_data *info,
+static void load_image_files(image_data *info,
const Common::Array<const char *> filenames) {
uint i;
@@ -344,7 +344,7 @@ static void load_image_files(struct image_data *info,
}
}
-void comprehend_load_image_file(const char *filename, struct image_data *info)
+void comprehend_load_image_file(const char *filename, image_data *info)
{
Common::Array<const char *> filenames;
filenames.push_back(filename);
diff --git a/engines/glk/comprehend/image_view.cpp b/engines/glk/comprehend/image_view.cpp
index c056e4b27d..c059316e80 100644
--- a/engines/glk/comprehend/image_view.cpp
+++ b/engines/glk/comprehend/image_view.cpp
@@ -59,7 +59,7 @@ int main(int argc, char **argv)
{NULL, 0, 0, 0},
};
const char *short_opts = "w:h:c:t:spfd?";
- struct image_data info;
+ image_data info;
const char *filename;
unsigned index, clear_color = G_COLOR_WHITE,
graphics_width = G_RENDER_WIDTH,
diff --git a/engines/glk/comprehend/recomprehend.cpp b/engines/glk/comprehend/recomprehend.cpp
deleted file mode 100644
index 193bdad487..0000000000
--- a/engines/glk/comprehend/recomprehend.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/* 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/comprehend/comprehend.h"
-#include "glk/comprehend/dump_game_data.h"
-#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/graphics.h"
-#include "glk/comprehend/game.h"
-#include "glk/comprehend/util.h"
-
-namespace Glk {
-namespace Comprehend {
-
-extern ComprehendGame game_transylvania;
-extern ComprehendGame game_crimson_crown_1;
-extern ComprehendGame game_crimson_crown_2;
-extern ComprehendGame game_oo_topos;
-extern ComprehendGame game_talisman;
-
-static ComprehendGame *ComprehendGames[] = {
- &game_transylvania,
- &game_crimson_crown_1,
- &game_crimson_crown_2,
- &game_oo_topos,
- &game_talisman,
-};
-
-struct dump_option {
- const char *option;
- unsigned flag;
-};
-
-static struct dump_option dump_options[] = {
- {"strings", DUMP_STRINGS},
- {"extra-strings", DUMP_EXTRA_STRINGS},
- {"rooms", DUMP_ROOMS},
- {"items", DUMP_ITEMS},
- {"dictionary", DUMP_DICTIONARY},
- {"word-pairs", DUMP_WORD_PAIRS},
- {"actions", DUMP_ACTIONS},
- {"functions", DUMP_FUNCTIONS},
- {"replace-words", DUMP_REPLACE_WORDS},
- {"header", DUMP_HEADER},
- {"all", DUMP_ALL},
-};
-
-static void usage(const char *progname)
-{
- int i;
-
- printf("Usage %s [OPTION]... GAME_NAME GAME_DIR\n", progname);
- printf("\nOptions:\n");
- printf(" -d, --debug Enable debugging\n");
- printf(" -D, --dump=OPTION Dump game data\n");
- for (i = 0; i < ARRAY_SIZE(dump_options); i++)
- printf(" %s\n", dump_options[i].option);
- printf(" -p, --no-play Don't run the interpreter\n");
- printf(" -g, --no-graphics Disable graphics\n");
- printf(" -f, --no-floodfill Disable floodfill\n");
- printf(" -w, --graphics-width=WIDTH Graphics width\n");
- printf(" -h, --graphics-height=HEIGHT Graphics height\n");
-
- printf("\nSupported games:\n");
- for (i = 0; i < ARRAY_SIZE(ComprehendGames); i++)
- printf(" %-10s %s\n", ComprehendGames[i]->short_name,
- ComprehendGames[i]->game_name);
-
- exit(EXIT_FAILURE);
-}
-
-int main(int argc, char **argv)
-{
- struct option long_opts[] = {
- {"debug", no_argument, 0, 'd'},
- {"dump", required_argument, 0, 'D'},
- {"no-play", no_argument, 0, 'p'},
- {"no-graphics", no_argument, 0, 'g'},
- {"no-floodfill", no_argument, 0, 'f'},
- {"graphics-width", required_argument, 0, 'w'},
- {"graphics-height", required_argument, 0, 'h'},
- {"help", no_argument, 0, '?'},
- {NULL, 0, 0, 0},
- };
- const char *short_opts = "dD:pgfw:h:?";
- ComprehendGame *game;
- const char *game_name, *game_dir;
- unsigned dump_flags = 0;
- int i, c, opt_index;
- unsigned graphics_width = G_RENDER_WIDTH,
- graphics_height = G_RENDER_HEIGHT;
- bool play_game = true, graphics_enabled = true;
-
- while (1) {
- c = getopt_long(argc, argv, short_opts, long_opts, &opt_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 'd':
- // FIXME
- debug_enable(DEBUG_FUNCTIONS);
- break;
-
- case 'D':
- for (i = 0; i < ARRAY_SIZE(dump_options); i++)
- if (strcmp(optarg, dump_options[i].option) == 0)
- break;
- if (i == ARRAY_SIZE(dump_options)) {
- printf("Invalid dump option '%s'\n", optarg);
- usage(argv[0]);
- }
-
- dump_flags |= dump_options[i].flag;
- break;
-
- case 'p':
- play_game = false;
- break;
-
- case 'g':
- graphics_enabled = false;
- break;
-
- case 'f':
- image_set_draw_flags(IMAGEF_NO_FLOODFILL);
- break;
-
- case 'w':
- graphics_width = strtoul(optarg, NULL, 0);
- break;
-
- case 'h':
- graphics_height = strtoul(optarg, NULL, 0);
- break;
-
- case '?':
- usage(argv[0]);
- break;
-
- default:
- printf("Invalid option\n");
- usage(argv[0]);
- break;
- }
- }
-
- if (optind >= argc || argc - optind != 2)
- usage(argv[0]);
-
- game_name = argv[optind++];
- game_dir = argv[optind++];
-
- /* Lookup game */
- game = NULL;
- for (i = 0; i < ARRAY_SIZE(ComprehendGames); i++) {
- if (strcmp(game_name, ComprehendGames[i]->short_name) == 0) {
- game = ComprehendGames[i];
- break;
- }
- }
- if (!game) {
- printf("Unknown game '%s'\n", game_name);
- usage(argv[0]);
- }
-
- if (graphics_enabled)
- g_init(graphics_width, graphics_height);
-
- game->info = xmalloc(sizeof(*game->info));
- comprehend_load_game(game, game_dir);
-
- if (dump_flags)
- dump_game_data(game, dump_flags);
-
- if (play_game)
- comprehend_play_game(game);
-
- exit(EXIT_SUCCESS);
-}
-
-} // namespace Comprehend
-} // namespace Glk
diff --git a/engines/glk/comprehend/recomprehend.h b/engines/glk/comprehend/recomprehend.h
deleted file mode 100644
index fd0fe31f80..0000000000
--- a/engines/glk/comprehend/recomprehend.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* 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_COMPREHEND_RECOMPREHEND_H
-#define GLK_COMPREHEND_RECOMPREHEND_H
-
-namespace Glk {
-namespace Comprehend {
-
-} // namespace Comprehend
-} // namespace Glk
-
-#endif
Commit: ec99b086fcc5e04e51f0c0536b0e67cb08786ad1
https://github.com/scummvm/scummvm/commit/ec99b086fcc5e04e51f0c0536b0e67cb08786ad1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Capitalizing class names
Changed paths:
engines/glk/adrift/scobjcts.cpp
engines/glk/adrift/scprotos.h
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/dictionary.cpp
engines/glk/comprehend/dictionary.h
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/dump_game_data.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/game_tr.h
engines/glk/comprehend/graphics.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
diff --git a/engines/glk/adrift/scobjcts.cpp b/engines/glk/adrift/scobjcts.cpp
index 1c94874f60..66c2e1e4ed 100644
--- a/engines/glk/adrift/scobjcts.cpp
+++ b/engines/glk/adrift/scobjcts.cpp
@@ -757,15 +757,15 @@ static sc_bool obj_indirectly_in_room_internal(sc_gameref_t game, sc_int object,
}
}
-sc_bool obj_indirectly_in_room(sc_gameref_t game, sc_int object, sc_int room) {
+sc_bool obj_indirectly_in_room(sc_gameref_t game, sc_int object, sc_int Room) {
sc_bool result;
/* Check, trace result, and return. */
- result = obj_indirectly_in_room_internal(game, object, room);
+ result = obj_indirectly_in_room_internal(game, object, Room);
if (obj_trace) {
sc_trace("Object: checking for object %ld indirectly in room %ld, %s\n",
- object, room, result ? "true" : "false");
+ object, Room, result ? "true" : "false");
}
return result;
diff --git a/engines/glk/adrift/scprotos.h b/engines/glk/adrift/scprotos.h
index 6b8a6f3845..efd7bb2ed3 100644
--- a/engines/glk/adrift/scprotos.h
+++ b/engines/glk/adrift/scprotos.h
@@ -91,7 +91,7 @@ extern sc_bool sc_strempty(const sc_char *string);
extern sc_char *sc_trim_string(sc_char *string);
extern sc_char *sc_normalize_string(sc_char *string);
extern sc_bool sc_compare_word(const sc_char *string,
- const sc_char *word, sc_int length);
+ const sc_char *Word, sc_int length);
extern sc_uint sc_hash(const sc_char *string);
/* TAF file reader/decompressor enumerations, opaque typedef and functions. */
@@ -281,7 +281,7 @@ extern void gs_copy(sc_gameref_t to, sc_gameref_t from);
extern void gs_destroy(sc_gameref_t game);
/* Game state accessors and mutators. */
-extern void gs_move_player_to_room(sc_gameref_t game, sc_int room);
+extern void gs_move_player_to_room(sc_gameref_t game, sc_int Room);
extern sc_bool gs_player_in_room(sc_gameref_t game, sc_int room);
extern sc_var_setref_t gs_get_vars(sc_gameref_t gs);
extern sc_prop_setref_t gs_get_bundle(sc_gameref_t gs);
@@ -300,8 +300,8 @@ extern sc_int gs_event_state(sc_gameref_t gs, sc_int event);
extern sc_int gs_event_time(sc_gameref_t gs, sc_int event);
extern void gs_decrement_event_time(sc_gameref_t gs, sc_int event);
extern sc_int gs_room_count(sc_gameref_t gs);
-extern void gs_set_room_seen(sc_gameref_t gs, sc_int room, sc_bool seen);
-extern sc_bool gs_room_seen(sc_gameref_t gs, sc_int room);
+extern void gs_set_room_seen(sc_gameref_t gs, sc_int Room, sc_bool seen);
+extern sc_bool gs_room_seen(sc_gameref_t gs, sc_int Room);
extern sc_int gs_task_count(sc_gameref_t gs);
extern void gs_set_task_done(sc_gameref_t gs, sc_int task, sc_bool done);
extern void gs_set_task_scored(sc_gameref_t gs, sc_int task, sc_bool scored);
@@ -367,9 +367,9 @@ enum {
extern void lib_warn_battle_system(void);
extern sc_int lib_random_roomgroup_member(sc_gameref_t game, sc_int roomgroup);
-extern const sc_char *lib_get_room_name(sc_gameref_t game, sc_int room);
-extern void lib_print_room_name(sc_gameref_t game, sc_int room);
-extern void lib_print_room_description(sc_gameref_t game, sc_int room);
+extern const sc_char *lib_get_room_name(sc_gameref_t game, sc_int Room);
+extern void lib_print_room_name(sc_gameref_t game, sc_int Room);
+extern void lib_print_room_description(sc_gameref_t game, sc_int Room);
extern sc_bool lib_cmd_go_north(sc_gameref_t game);
extern sc_bool lib_cmd_go_east(sc_gameref_t game);
extern sc_bool lib_cmd_go_south(sc_gameref_t game);
@@ -690,8 +690,8 @@ enum {
NPC_NEUTER = 2
};
-extern sc_bool npc_in_room(sc_gameref_t game, sc_int npc, sc_int room);
-extern sc_int npc_count_in_room(sc_gameref_t game, sc_int room);
+extern sc_bool npc_in_room(sc_gameref_t game, sc_int npc, sc_int Room);
+extern sc_int npc_count_in_room(sc_gameref_t game, sc_int Room);
extern void npc_setup_initial(sc_gameref_t game);
extern void npc_start_npc_walk(sc_gameref_t game, sc_int npc, sc_int walk);
extern void npc_tick_npcs(sc_gameref_t game);
@@ -712,10 +712,10 @@ extern sc_bool obj_is_surface(sc_gameref_t game, sc_int object);
extern sc_int obj_container_object(sc_gameref_t game, sc_int n);
extern sc_int obj_surface_object(sc_gameref_t game, sc_int n);
extern sc_bool obj_indirectly_in_room(sc_gameref_t game,
- sc_int object, sc_int room);
+ sc_int object, sc_int Room);
extern sc_bool obj_indirectly_held_by_player(sc_gameref_t game, sc_int object);
extern sc_bool obj_directly_in_room(sc_gameref_t game,
- sc_int object, sc_int room);
+ sc_int object, sc_int Room);
extern sc_int obj_stateful_object(sc_gameref_t game, sc_int n);
extern sc_int obj_dynamic_object(sc_gameref_t game, sc_int n);
extern sc_int obj_wearable_object(sc_gameref_t game, sc_int n);
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 3ca90b7b28..6b0c68507b 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -37,12 +37,12 @@ namespace Comprehend {
Comprehend *g_comprehend;
-struct dump_option {
+struct DumpOption {
const char *const option;
unsigned flag;
};
-static const dump_option dump_options[] = {
+static const DumpOption dump_options[] = {
{"strings", DUMP_STRINGS},
{"extra-strings", DUMP_EXTRA_STRINGS},
{"rooms", DUMP_ROOMS},
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index d77f549182..c961438d72 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -40,11 +40,11 @@ namespace Comprehend {
#define PATH_MAX 256
struct GameInfo;
-struct game_state;
+struct gameState;
#define EXTRA_STRING_TABLE(x) (0x8200 | (x))
-struct game_strings {
+struct GameStrings {
uint16 game_restart;
};
diff --git a/engines/glk/comprehend/dictionary.cpp b/engines/glk/comprehend/dictionary.cpp
index 2f6e4cf025..70959a889e 100644
--- a/engines/glk/comprehend/dictionary.cpp
+++ b/engines/glk/comprehend/dictionary.cpp
@@ -28,7 +28,7 @@
namespace Glk {
namespace Comprehend {
-static bool word_match(word *word, const char *string)
+static bool word_match(Word *word, const char *string)
{
/* Words less than 6 characters must match exactly */
if (strlen(word->_word) < 6 && strlen(string) != strlen(word->_word))
@@ -37,7 +37,7 @@ static bool word_match(word *word, const char *string)
return strncmp(word->_word, string, strlen(word->_word)) == 0;
}
-word *dict_find_word_by_string(ComprehendGame *game,
+Word *dict_find_word_by_string(ComprehendGame *game,
const char *string)
{
uint i;
@@ -52,7 +52,7 @@ word *dict_find_word_by_string(ComprehendGame *game,
return NULL;
}
-word *dict_find_word_by_index_type(ComprehendGame *game,
+Word *dict_find_word_by_index_type(ComprehendGame *game,
uint8 index, uint8 type)
{
uint i;
@@ -66,7 +66,7 @@ word *dict_find_word_by_index_type(ComprehendGame *game,
return NULL;
}
-word *find_dict_word_by_index(ComprehendGame *game,
+Word *find_dict_word_by_index(ComprehendGame *game,
uint8 index, uint8 type_mask)
{
uint i;
diff --git a/engines/glk/comprehend/dictionary.h b/engines/glk/comprehend/dictionary.h
index f685513811..ed8fb56908 100644
--- a/engines/glk/comprehend/dictionary.h
+++ b/engines/glk/comprehend/dictionary.h
@@ -27,13 +27,13 @@ namespace Glk {
namespace Comprehend {
class ComprehendGame;
-struct word;
+struct Word;
-word *find_dict_word_by_index(ComprehendGame *game,
+Word *find_dict_word_by_index(ComprehendGame *game,
uint8 index, uint8 type_mask);
-word *dict_find_word_by_index_type(ComprehendGame *game,
+Word *dict_find_word_by_index_type(ComprehendGame *game,
uint8 index, uint8 type);
-word *dict_find_word_by_string(ComprehendGame *game,
+Word *dict_find_word_by_string(ComprehendGame *game,
const char *string);
bool dict_match_index_type(ComprehendGame *game, const char *word,
uint8 index, uint8 type_mask);
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index bd99a5d4f3..bef4f9ef0a 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -114,8 +114,8 @@ static const char *opcode_names[] = {
};
void dump_instruction(ComprehendGame *game,
- function_state *func_state,
- instruction *instr)
+ FunctionState *func_state,
+ Instruction *instr)
{
uint i;
int str_index, str_table;
@@ -169,7 +169,7 @@ void dump_instruction(ComprehendGame *game,
static void dump_functions(ComprehendGame *game)
{
- function *func;
+ Function *func;
uint i, j;
debugN("Functions (%zd entries)\n", game->_nr_functions);
@@ -185,8 +185,8 @@ static void dump_functions(ComprehendGame *game)
static void dump_action_table(ComprehendGame *game)
{
- action *action;
- word *word;
+ Action *action;
+ Word *word;
uint i, j;
debugN("Action table (%zd entries)\n", game->_nr_actions);
@@ -231,7 +231,7 @@ static void dump_action_table(ComprehendGame *game)
static int word_index_compare(const void *a, const void *b)
{
- const word *word_a = (const word *)a, *word_b = (const word *)b;
+ const Word *word_a = (const Word *)a, *word_b = (const Word *)b;
if (word_a->_index > word_b->_index)
return 1;
@@ -242,12 +242,12 @@ static int word_index_compare(const void *a, const void *b)
static void dump_dictionary(ComprehendGame *game)
{
- word *dictionary;
- word *words;
+ Word *dictionary;
+ Word *words;
uint i;
/* Sort the dictionary by index */
- dictionary = (word *)xmalloc(sizeof(*words) * game->_nr_words);
+ dictionary = (Word *)xmalloc(sizeof(*words) * game->_nr_words);
memcpy(dictionary, game->_words,
sizeof(*words) * game->_nr_words);
qsort(dictionary, game->_nr_words, sizeof(*words),
@@ -265,9 +265,9 @@ static void dump_dictionary(ComprehendGame *game)
static void dump_word_map(ComprehendGame *game)
{
- word *word[3];
+ Word *word[3];
char str[3][6];
- word_map *map;
+ WordMap *map;
uint i, j;
debugN("Word pairs (%zd entries)\n", game->_nr_word_maps);
@@ -292,7 +292,7 @@ static void dump_word_map(ComprehendGame *game)
static void dump_rooms(ComprehendGame *game)
{
- room *room;
+ Room *room;
uint i;
/* Room zero acts as the players inventory */
@@ -319,7 +319,7 @@ static void dump_rooms(ComprehendGame *game)
static void dump_items(ComprehendGame *game)
{
- item *item;
+ Item *item;
uint i, j;
debugN("Items (%zd entries)\n", game->_header.nr_items);
@@ -348,7 +348,7 @@ static void dump_items(ComprehendGame *game)
}
}
-static void dump_string_table(string_table *table)
+static void dump_string_table(StringTable *table)
{
uint i;
@@ -382,7 +382,7 @@ static void dump_replace_words(ComprehendGame *game)
static void dump_header(ComprehendGame *game)
{
- game_header *header = &game->_header;
+ GameHeader *header = &game->_header;
uint16 *dir_table = header->room_direction_table;
debugN("Game header:\n");
@@ -420,12 +420,12 @@ static void dump_header(ComprehendGame *game)
typedef void (*dump_func_t)(ComprehendGame *game);
-struct dumper {
+struct Dumper {
dump_func_t dump_func;
unsigned flag;
};
-static dumper dumpers[] = {
+static Dumper dumpers[] = {
{dump_header, DUMP_HEADER},
{dump_game_data_strings, DUMP_STRINGS},
{dump_extra_strings, DUMP_EXTRA_STRINGS},
diff --git a/engines/glk/comprehend/dump_game_data.h b/engines/glk/comprehend/dump_game_data.h
index 06c6609e6c..311ff2b139 100644
--- a/engines/glk/comprehend/dump_game_data.h
+++ b/engines/glk/comprehend/dump_game_data.h
@@ -27,8 +27,8 @@ namespace Glk {
namespace Comprehend {
class ComprehendGame;
-struct function_state;
-struct instruction;
+struct FunctionState;
+struct Instruction;
#define DUMP_STRINGS (1 << 0)
#define DUMP_EXTRA_STRINGS (1 << 1)
@@ -43,8 +43,8 @@ struct instruction;
#define DUMP_ALL (~0U)
void dump_instruction(ComprehendGame *game,
- function_state *func_state,
- instruction *instr);
+ FunctionState *func_state,
+ Instruction *instr);
void dump_game_data(ComprehendGame *game, unsigned flags);
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index a41842497e..2022656364 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -33,15 +33,15 @@
namespace Glk {
namespace Comprehend {
-struct sentence {
- word words[4];
+struct Sentence {
+ Word words[4];
size_t nr_words;
};
-struct winsize {
+struct WinSize {
uint ws_col;
};
-static winsize console_winsize;
+static WinSize console_winsize;
ComprehendGame::ComprehendGame() : _gameName(nullptr),
_shortName(nullptr),
@@ -157,7 +157,7 @@ void console_println(ComprehendGame *game, const char *text) {
printf("\n");
}
-static room *get_room(ComprehendGame *game, uint16 index) {
+static Room *get_room(ComprehendGame *game, uint16 index) {
/* Room zero is reserved for the players inventory */
if (index == 0)
fatal_error("Room index 0 (player inventory) is invalid");
@@ -168,7 +168,7 @@ static room *get_room(ComprehendGame *game, uint16 index) {
return &game->_rooms[index];
}
-item *get_item(ComprehendGame *game, uint16 index) {
+Item *get_item(ComprehendGame *game, uint16 index) {
if (index >= game->_header.nr_items)
fatal_error("Bad item %d\n", index);
@@ -225,9 +225,9 @@ void game_restart(ComprehendGame *game) {
game->_updateFlags = UPDATE_ALL;
}
-static word_index *is_word_pair(ComprehendGame *game,
- word *word1, word *word2) {
- word_map *map;
+static WordIndex *is_word_pair(ComprehendGame *game,
+ Word *word1, Word *word2) {
+ WordMap *map;
uint i;
/* Check if this is a word pair */
@@ -244,8 +244,8 @@ static word_index *is_word_pair(ComprehendGame *game,
return NULL;
}
-static item *get_item_by_noun(ComprehendGame *game,
- word *noun) {
+static Item *get_item_by_noun(ComprehendGame *game,
+ Word *noun) {
uint i;
if (!noun || !(noun->_type & WORD_TYPE_NOUN_MASK))
@@ -264,8 +264,8 @@ static item *get_item_by_noun(ComprehendGame *game,
}
static void update_graphics(ComprehendGame *game) {
- item *item;
- room *room;
+ Item *item;
+ Room *room;
int type;
uint i;
@@ -308,7 +308,7 @@ static void update_graphics(ComprehendGame *game) {
}
static void describe_objects_in_current_room(ComprehendGame *game) {
- item *item;
+ Item *item;
size_t count = 0;
uint i;
@@ -334,7 +334,7 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
}
static void update(ComprehendGame *game) {
- room *room = get_room(game, game->_currentRoom);
+ Room *room = get_room(game, game->_currentRoom);
unsigned room_type, room_desc_string;
update_graphics(game);
@@ -363,7 +363,7 @@ static void move_to(ComprehendGame *game, uint8 room) {
UPDATE_ITEM_LIST);
}
-static void func_set_test_result(function_state *func_state, bool value) {
+static void func_set_test_result(FunctionState *func_state, bool value) {
if (func_state->or_count == 0) {
/* And */
if (func_state->_and) {
@@ -391,7 +391,7 @@ static size_t num_objects_in_room(ComprehendGame *game, int room) {
return count;
}
-void move_object(ComprehendGame *game, item *item, int new_room) {
+void move_object(ComprehendGame *game, Item *item, int new_room) {
unsigned obj_weight = item->flags & ITEMF_WEIGHT_MASK;
if (item->room == new_room)
@@ -423,12 +423,12 @@ void move_object(ComprehendGame *game, item *item, int new_room) {
}
static void eval_instruction(ComprehendGame *game,
- function_state *func_state,
- instruction *instr,
- word *verb, word *noun) {
+ FunctionState *func_state,
+ Instruction *instr,
+ Word *verb, Word *noun) {
uint8 *opcode_map;
- room *room;
- item *item;
+ Room *room;
+ Item *item;
uint16 index;
bool test;
uint i, count;
@@ -615,7 +615,7 @@ static void eval_instruction(ComprehendGame *game,
if (noun) {
for (i = 0; i < game->_header.nr_items; i++) {
- struct item *itemP = &game->_items[i];
+ Item *itemP = &game->_items[i];
if (itemP->word == noun->_index &&
itemP->room == instr->operand[0]) {
@@ -981,9 +981,9 @@ static void eval_instruction(ComprehendGame *game,
* is reached. Otherwise the commands instructions are skipped over and the
* next test sequence (if there is one) is tried.
*/
-void eval_function(ComprehendGame *game, function *func,
- word *verb, word *noun) {
- function_state func_state;
+void eval_function(ComprehendGame *game, Function *func,
+ Word *verb, Word *noun) {
+ FunctionState func_state;
uint i;
func_state.else_result = true;
@@ -1056,9 +1056,9 @@ static void handle_debug_command(ComprehendGame *game,
#endif
static bool handle_sentence(ComprehendGame *game,
- sentence *sentence) {
- function *func;
- action *action;
+ Sentence *sentence) {
+ Function *func;
+ Action *action;
uint i, j;
if (sentence->nr_words == 0)
@@ -1102,11 +1102,11 @@ static bool handle_sentence(ComprehendGame *game,
}
static void read_sentence(ComprehendGame *game, char **line,
- sentence *sentence) {
+ Sentence *sentence) {
bool sentence_end = false;
char *word_string, *p = *line;
- word_index *pair;
- word *word;
+ WordIndex *pair;
+ Word *word;
int index;
memset(sentence, 0, sizeof(*sentence));
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 583f333f53..ce4689a32a 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -39,13 +39,13 @@ public:
const char *_shortName;
const char *_gameDataFile;
- Common::Array<string_file> _stringFiles;
+ Common::Array<StringFile> _stringFiles;
Common::Array<const char *> _locationGraphicFiles;
Common::Array<const char *> _itemGraphicFiles;
const char *_savegameFileFormat;
unsigned _colorTable;
- struct game_strings *_gameStrings;
+ struct GameStrings *_gameStrings;
public:
ComprehendGame();
@@ -69,10 +69,10 @@ public:
void console_println(ComprehendGame *game, const char *text);
int console_get_key(void);
-item *get_item(ComprehendGame *game, uint16 index);
-void move_object(ComprehendGame *game, item *item, int new_room);
-void eval_function(ComprehendGame *game, function *func,
- word *verb, word *noun);
+Item *get_item(ComprehendGame *game, uint16 index);
+void move_object(ComprehendGame *game, Item *item, int new_room);
+void eval_function(ComprehendGame *game, Function *func,
+ Word *verb, Word *noun);
void comprehend_play_game(ComprehendGame *game);
void game_save(ComprehendGame *game);
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index 4b1a5feab7..da416aa32d 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -26,7 +26,7 @@
namespace Glk {
namespace Comprehend {
-static game_strings cc1_strings = {0x9};
+static GameStrings cc1_strings = {0x9};
#ifdef TODO
static game_ops cc2_ops = {
@@ -43,7 +43,7 @@ CrimsonCrownGame::CrimsonCrownGame() : ComprehendGame() {
_shortName = "cc1";
_gameDataFile = "cc1.gda";
- _stringFiles.push_back(string_file("ma.ms1", 0x89));
+ _stringFiles.push_back(StringFile("ma.ms1", 0x89));
_locationGraphicFiles.push_back("RA.MS1");
_locationGraphicFiles.push_back("RB.MS1");
_locationGraphicFiles.push_back("RC.MS1");
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index c28813e19f..db9d1d6eec 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -38,7 +38,7 @@ static char special_charset[] = "[]\n!\"#$%&'(),-/0123456789:;?<>";
static uint16 magic_offset;
-void function_state::clear() {
+void FunctionState::clear() {
test_result = true;
else_result = false;
or_count = 0;
@@ -49,7 +49,7 @@ void function_state::clear() {
/*-------------------------------------------------------*/
-void room::clear() {
+void Room::clear() {
flags = 0;
graphic = 0;
string_desc = 0;
@@ -58,7 +58,7 @@ void room::clear() {
/*-------------------------------------------------------*/
-void item::clear() {
+void Item::clear() {
string_desc = 0;
long_string = 0;
room = 0;
@@ -69,7 +69,7 @@ void item::clear() {
/*-------------------------------------------------------*/
-void word::clear() {
+void Word::clear() {
_index = 0;
_type = 0;
Common::fill(&_word[0], &_word[7], '\0');
@@ -77,7 +77,7 @@ void word::clear() {
/*-------------------------------------------------------*/
-void word_map::clear() {
+void WordMap::clear() {
flags = 0;
for (int idx = 0; idx < 3; ++idx)
word[idx].clear();
@@ -85,7 +85,7 @@ void word_map::clear() {
/*-------------------------------------------------------*/
-void action::clear() {
+void Action::clear() {
type = 0;
nr_words = 0;
function = 0;
@@ -95,7 +95,7 @@ void action::clear() {
/*-------------------------------------------------------*/
-void instruction::clear() {
+void Instruction::clear() {
opcode = 0;
nr_operands = 0;
is_command= false;
@@ -104,7 +104,7 @@ void instruction::clear() {
/*-------------------------------------------------------*/
-void function::clear() {
+void Function::clear() {
nr_instructions = 0;
for (int idx = 0; idx < 0x100; ++idx)
instructions[idx].clear();
@@ -112,14 +112,14 @@ void function::clear() {
/*-------------------------------------------------------*/
-void string_table::clear() {
+void StringTable::clear() {
nr_strings = 0;
Common::fill(&strings[0], &strings[0xffff], nullptr);
}
/*-------------------------------------------------------*/
-void game_header::clear() {
+void GameHeader::clear() {
magic = 0;
room_desc_table = 0;
room_flags_table = 0;
@@ -199,7 +199,7 @@ static bool opcode_is_command(uint8 opcode) {
}
static uint8 parse_vm_instruction(FileBuffer *fb,
- instruction *instr) {
+ Instruction *instr) {
uint i;
/* Get the opcode */
@@ -215,8 +215,8 @@ static uint8 parse_vm_instruction(FileBuffer *fb,
return instr->opcode;
}
-static void parse_function(FileBuffer *fb, function * func) {
- instruction *instruction;
+static void parse_function(FileBuffer *fb, Function * func) {
+ Instruction *instruction;
uint8 *p, opcode;
p = (uint8 *)memchr(fb->dataPtr(), 0x00, fb->size() - fb->pos());
@@ -237,7 +237,7 @@ static void parse_function(FileBuffer *fb, function * func) {
}
static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
- function *func;
+ Function *func;
fb->seek(game->_header.addr_vm);
while (1) {
@@ -253,7 +253,7 @@ static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
static void parse_action_table_vvnn(ComprehendGame *game,
FileBuffer *fb, size_t * index) {
- action *action;
+ Action *action;
uint8 verb, count;
int i, j;
@@ -297,7 +297,7 @@ static void parse_action_table_vvnn(ComprehendGame *game,
static void parse_action_table_vnjn(ComprehendGame *game,
FileBuffer *fb, size_t * index) {
- action *action;
+ Action *action;
uint8 join, count;
int i;
@@ -342,7 +342,7 @@ static void parse_action_table_vnjn(ComprehendGame *game,
static void parse_action_table_vjn(ComprehendGame *game,
FileBuffer *fb, size_t * index) {
- action *action;
+ Action *action;
uint8 join, count;
int i;
@@ -383,7 +383,7 @@ static void parse_action_table_vjn(ComprehendGame *game,
static void parse_action_table_vdn(ComprehendGame *game,
FileBuffer *fb, size_t * index) {
- action *action;
+ Action *action;
uint8 verb, count;
int i;
@@ -424,7 +424,7 @@ static void parse_action_table_vdn(ComprehendGame *game,
static void parse_action_table_vnn(ComprehendGame *game,
FileBuffer *fb, size_t * index) {
- action *action;
+ Action *action;
uint8 verb, count;
int i;
@@ -466,7 +466,7 @@ static void parse_action_table_vnn(ComprehendGame *game,
static void parse_action_table_vn(ComprehendGame *game,
FileBuffer *fb, size_t * index) {
- action *action;
+ Action *action;
uint8 verb, count;
int i;
@@ -505,7 +505,7 @@ static void parse_action_table_vn(ComprehendGame *game,
static void parse_action_table_v(ComprehendGame *game,
FileBuffer *fb, size_t * index) {
- action *action;
+ Action *action;
uint8 verb, nr_funcs;
uint16 func;
int i;
@@ -565,11 +565,11 @@ static void parse_action_table(ComprehendGame *game,
}
static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
- word *words;
+ Word *words;
uint i, j;
// FIXME - fixed size 0xff array?
- game->_words = (word *)xmalloc(game->_nr_words * sizeof(words));
+ game->_words = (Word *)xmalloc(game->_nr_words * sizeof(words));
fb->seek(game->_header.addr_dictionary);
for (i = 0; i < game->_nr_words; i++) {
@@ -588,7 +588,7 @@ static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
}
static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
- word_map *map;
+ WordMap *map;
uint8 index, type, dummy;
uint i;
@@ -788,7 +788,7 @@ done:
}
static void parse_string_table(FileBuffer *fb, unsigned start_addr,
- uint32 end_addr, string_table *table) {
+ uint32 end_addr, StringTable *table) {
fb->seek(start_addr);
while (1) {
table->strings[table->nr_strings++] = parse_string(fb);
@@ -848,7 +848,7 @@ static void parse_replace_words(ComprehendGame *game,
* game data is. The offsets have a magic constant value added to them.
*/
static void parse_header(ComprehendGame *game, FileBuffer *fb) {
- game_header *header = &game->_header;
+ GameHeader *header = &game->_header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
@@ -966,7 +966,7 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
}
static void load_extra_string_file(ComprehendGame *game,
- string_file * string_file) {
+ StringFile * string_file) {
FileBuffer fb(string_file->filename);
unsigned end;
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 2e243198f1..95c4c6a028 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -43,7 +43,7 @@ enum {
NR_DIRECTIONS,
};
-struct function_state {
+struct FunctionState {
bool test_result;
bool else_result;
unsigned or_count;
@@ -51,27 +51,27 @@ struct function_state {
bool in_command;
bool executed;
- function_state() {
+ FunctionState() {
clear();
}
void clear();
};
-struct room {
+struct Room {
uint8 direction[NR_DIRECTIONS];
uint8 flags;
uint8 graphic;
uint16 string_desc;
- room() {
+ Room() {
clear();
}
void clear();
};
-struct item {
+struct Item {
uint16 string_desc;
uint16 long_string; /* Only used by version 2 */
uint8 room;
@@ -79,30 +79,30 @@ struct item {
uint8 word;
uint8 graphic;
- item() {
+ Item() {
clear();
}
void clear();
};
-struct word {
+struct Word {
char _word[7];
uint8 _index;
uint8 _type;
- word() {
+ Word() {
clear();
}
void clear();
};
-struct word_index {
+struct WordIndex {
uint8 index;
uint8 type;
- word_index() {
+ WordIndex() {
clear();
}
@@ -111,19 +111,19 @@ struct word_index {
}
};
-struct word_map {
+struct WordMap {
/* <word[0]>, <word[1]> == <word[2]> */
- word_index word[3];
+ WordIndex word[3];
uint8 flags;
- word_map() {
+ WordMap() {
clear();
}
void clear();
};
-struct action {
+struct Action {
int type;
size_t nr_words;
// FIXME - use struct word_index here.
@@ -131,49 +131,49 @@ struct action {
uint8 word_type[4];
uint16 function;
- action() {
+ Action() {
clear();
}
void clear();
};
-struct instruction {
+struct Instruction {
uint8 opcode;
size_t nr_operands;
uint8 operand[3];
bool is_command;
- instruction() {
+ Instruction() {
clear();
}
void clear();
};
-struct function {
- instruction instructions[0x100];
+struct Function {
+ Instruction instructions[0x100];
size_t nr_instructions;
- function() {
+ Function() {
clear();
}
void clear();
};
-struct string_table {
+struct StringTable {
char *strings[0xffff];
size_t nr_strings;
- string_table() {
+ StringTable() {
clear();
}
void clear();
};
-struct game_header {
+struct GameHeader {
uint16 magic;
uint16 room_desc_table;
@@ -205,7 +205,7 @@ struct game_header {
uint16 addr_vm; // FIXME - functions
- game_header() {
+ GameHeader() {
clear();
}
@@ -213,35 +213,35 @@ struct game_header {
};
struct GameInfo {
- game_header _header;
+ GameHeader _header;
unsigned _comprehendVersion;
uint8 _startRoom;
- room _rooms[0x100];
+ Room _rooms[0x100];
size_t _nr_rooms;
uint8 _currentRoom;
- struct item _items[0xff];
+ struct Item _items[0xff];
- struct word *_words;
+ struct Word *_words;
size_t _nr_words;
- struct word_map _wordMaps[0xff];
+ struct WordMap _wordMaps[0xff];
size_t _nr_word_maps;
- struct string_table _strings;
- struct string_table _strings2;
+ struct StringTable _strings;
+ struct StringTable _strings2;
- struct action _actions[0xffff];
+ struct Action _actions[0xffff];
size_t _nr_actions;
- struct function _functions[0xffff];
+ struct Function _functions[0xffff];
size_t _nr_functions;
- struct image_data _roomImages;
- struct image_data _itemImages;
+ struct ImageData _roomImages;
+ struct ImageData _itemImages;
bool _flags[MAX_FLAGS];
uint16 _variables[MAX_VARIABLES];
@@ -259,13 +259,13 @@ struct GameInfo {
void clearInfo();
};
-struct string_file {
+struct StringFile {
const char *filename;
uint32 base_offset;
uint32 end_offset;
- string_file() : filename(nullptr), base_offset(0), end_offset(0) {}
- string_file(const char *fname, uint32 baseOfs, uint32 endO = 0) : filename(fname), base_offset(baseOfs), end_offset(endO) {
+ StringFile() : filename(nullptr), base_offset(0), end_offset(0) {}
+ StringFile(const char *fname, uint32 baseOfs, uint32 endO = 0) : filename(fname), base_offset(baseOfs), end_offset(endO) {
}
};
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index b1faa9c705..124f8d6e08 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -40,11 +40,11 @@ OOToposGame::OOToposGame() : ComprehendGame() {
_gameDataFile = "g0";
// Extra strings are (annoyingly) stored in the game binary
- _stringFiles.push_back(string_file("NOVEL.EXE", 0x16564, 0x17640));
- _stringFiles.push_back(string_file("NOVEL.EXE", 0x17702, 0x18600));
- _stringFiles.push_back(string_file("NOVEL.EXE", 0x186b2, 0x19b80));
- _stringFiles.push_back(string_file("NOVEL.EXE", 0x19c62, 0x1a590));
- _stringFiles.push_back(string_file("NOVEL.EXE", 0x1a634, 0x1b080));
+ _stringFiles.push_back(StringFile("NOVEL.EXE", 0x16564, 0x17640));
+ _stringFiles.push_back(StringFile("NOVEL.EXE", 0x17702, 0x18600));
+ _stringFiles.push_back(StringFile("NOVEL.EXE", 0x186b2, 0x19b80));
+ _stringFiles.push_back(StringFile("NOVEL.EXE", 0x19c62, 0x1a590));
+ _stringFiles.push_back(StringFile("NOVEL.EXE", 0x1a634, 0x1b080));
_locationGraphicFiles.push_back("RA");
_locationGraphicFiles.push_back("RB");
_locationGraphicFiles.push_back("RC");
@@ -61,7 +61,7 @@ OOToposGame::OOToposGame() : ComprehendGame() {
int OOToposGame::room_is_special(unsigned room_index,
unsigned *room_desc_string) {
- room *room = &_rooms[room_index];
+ Room *room = &_rooms[room_index];
/* Is the room dark */
if ((room->flags & OO_ROOM_FLAG_DARK) &&
@@ -85,7 +85,7 @@ int OOToposGame::room_is_special(unsigned room_index,
bool OOToposGame::before_turn() {
/* FIXME - probably doesn't work correctly with restored games */
static bool flashlight_was_on = false, googles_were_worn = false;
- room *room = &_rooms[_currentRoom];
+ Room *room = &_rooms[_currentRoom];
/*
* Check if the room needs to be redrawn because the flashlight
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 041b4dfef0..66a9a890b3 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -28,15 +28,15 @@
namespace Glk {
namespace Comprehend {
-const tr_monster TransylvaniaGame::WEREWOLF = {
+const TransylvaniaMonster TransylvaniaGame::WEREWOLF = {
0x21, 7, (1 << 6), 5, 5
};
-const tr_monster TransylvaniaGame::VAMPIRE = {
+const TransylvaniaMonster TransylvaniaGame::VAMPIRE = {
0x26, 5, (1 << 7), 0, 5
};
-static game_strings tr_strings = {
+static GameStrings tr_strings = {
EXTRA_STRING_TABLE(0x8a)
};
@@ -46,11 +46,11 @@ TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
_shortName = "tr";
_gameDataFile = "tr.gda";
- _stringFiles.push_back(string_file("MA.MS1", 0x88));
- _stringFiles.push_back(string_file("MB.MS1", 0x88));
- _stringFiles.push_back(string_file("MC.MS1", 0x88));
- _stringFiles.push_back(string_file("MD.MS1", 0x88));
- _stringFiles.push_back(string_file("ME.MS1", 0x88));
+ _stringFiles.push_back(StringFile("MA.MS1", 0x88));
+ _stringFiles.push_back(StringFile("MB.MS1", 0x88));
+ _stringFiles.push_back(StringFile("MC.MS1", 0x88));
+ _stringFiles.push_back(StringFile("MD.MS1", 0x88));
+ _stringFiles.push_back(StringFile("ME.MS1", 0x88));
_locationGraphicFiles.push_back("RA.MS1");
_locationGraphicFiles.push_back("RB.MS1");
@@ -64,9 +64,9 @@ TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
_gameStrings = &tr_strings;
};
-void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
- item *monster;
- room *room;
+void TransylvaniaGame::update_monster(const TransylvaniaMonster *monster_info) {
+ Item *monster;
+ Room *room;
uint16 turn_count;
room = &_rooms[_currentRoom];
@@ -98,7 +98,7 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
int TransylvaniaGame::room_is_special(unsigned room_index,
unsigned *room_desc_string)
{
- room *room = &_rooms[room_index];
+ Room *room = &_rooms[room_index];
if (room_index == 0x28) {
if (room_desc_string)
diff --git a/engines/glk/comprehend/game_tr.h b/engines/glk/comprehend/game_tr.h
index 634588c58f..c9d4fdddb7 100644
--- a/engines/glk/comprehend/game_tr.h
+++ b/engines/glk/comprehend/game_tr.h
@@ -28,7 +28,7 @@
namespace Glk {
namespace Comprehend {
-struct tr_monster {
+struct TransylvaniaMonster {
uint8 object;
uint8 dead_flag;
unsigned min_turns_before;
@@ -38,10 +38,10 @@ struct tr_monster {
class TransylvaniaGame : public ComprehendGame {
private:
- static const tr_monster WEREWOLF;
- static const tr_monster VAMPIRE;
+ static const TransylvaniaMonster WEREWOLF;
+ static const TransylvaniaMonster VAMPIRE;
- void update_monster(const tr_monster *monster_info);
+ void update_monster(const TransylvaniaMonster *monster_info);
public:
TransylvaniaGame();
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/graphics.cpp
index cb37182dc2..b053aceb5b 100644
--- a/engines/glk/comprehend/graphics.cpp
+++ b/engines/glk/comprehend/graphics.cpp
@@ -48,7 +48,7 @@ static unsigned pen_colors[] = {
RGB(0xff, 0x00, 0x00),
};
-struct graphics_context {
+struct GraphicsContext {
Window *screen;
/*
@@ -63,7 +63,7 @@ struct graphics_context {
// SDL_Surface *surface;
};
-static graphics_context ctx;
+static GraphicsContext ctx;
unsigned g_set_pen_color(uint8 opcode) {
return pen_colors[opcode - IMAGE_OP_PEN_COLOR_A];
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 1a5be26d62..9a44b21e8d 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -33,7 +33,7 @@ namespace Comprehend {
#define IMAGES_PER_FILE 16
-struct image_context {
+struct ImageContext {
unsigned x;
unsigned y;
unsigned pen_color;
@@ -46,7 +46,7 @@ struct image_context {
static unsigned draw_flags;
-void image_data::clear() {
+void ImageData::clear() {
fb = nullptr;
image_offsets = nullptr;
nr_images = 0;
@@ -65,7 +65,7 @@ static uint16 image_get_operand(FileBuffer *fb)
return val;
}
-static bool do_image_op(FileBuffer *fb, image_context *ctx)
+static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
{
uint8 opcode;
uint16 a, b;
@@ -254,12 +254,12 @@ static bool do_image_op(FileBuffer *fb, image_context *ctx)
return false;
}
-void draw_image(image_data *info, unsigned index)
+void draw_image(ImageData *info, unsigned index)
{
unsigned file_num;
FileBuffer *fb;
bool done = false;
- image_context ctx = {
+ ImageContext ctx = {
0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE
};
@@ -294,13 +294,13 @@ void draw_bright_room(void)
g_clear_screen(G_COLOR_WHITE);
}
-void draw_location_image(image_data *info, unsigned index)
+void draw_location_image(ImageData *info, unsigned index)
{
g_clear_screen(G_COLOR_WHITE);
draw_image(info, index);
}
-static void load_image_file(image_data *info, const char *filename,
+static void load_image_file(ImageData *info, const char *filename,
unsigned file_num)
{
unsigned base = file_num * IMAGES_PER_FILE;
@@ -329,7 +329,7 @@ static void load_image_file(image_data *info, const char *filename,
}
}
-static void load_image_files(image_data *info,
+static void load_image_files(ImageData *info,
const Common::Array<const char *> filenames) {
uint i;
@@ -344,7 +344,7 @@ static void load_image_files(image_data *info,
}
}
-void comprehend_load_image_file(const char *filename, image_data *info)
+void comprehend_load_image_file(const char *filename, ImageData *info)
{
Common::Array<const char *> filenames;
filenames.push_back(filename);
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index cb165e9fdb..718b57c9aa 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -31,12 +31,12 @@ namespace Comprehend {
class ComprehendGame;
struct FileBuffer;
-struct image_data {
+struct ImageData {
FileBuffer *fb;
uint16 *image_offsets;
size_t nr_images;
- image_data() {
+ ImageData() {
clear();
}
@@ -93,10 +93,10 @@ void image_set_draw_flags(unsigned flags);
void draw_dark_room(void);
void draw_bright_room(void);
-void draw_image(image_data *info, unsigned index);
-void draw_location_image(image_data *info, unsigned index);
+void draw_image(ImageData *info, unsigned index);
+void draw_location_image(ImageData *info, unsigned index);
-void comprehend_load_image_file(const char *filename, image_data *info);
+void comprehend_load_image_file(const char *filename, ImageData *info);
void comprehend_load_images(ComprehendGame *game);
} // namespace Comprehend
Commit: eca27789b1f019ccf443cb81716ba9b9d8fcf938
https://github.com/scummvm/scummvm/commit/eca27789b1f019ccf443cb81716ba9b9d8fcf938
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Data loading fixes
Changed paths:
engines/glk/comprehend/file_buf.cpp
engines/glk/comprehend/game_data.cpp
diff --git a/engines/glk/comprehend/file_buf.cpp b/engines/glk/comprehend/file_buf.cpp
index 76b70cc82d..28b20b69c4 100644
--- a/engines/glk/comprehend/file_buf.cpp
+++ b/engines/glk/comprehend/file_buf.cpp
@@ -65,7 +65,7 @@ uint32 FileBuffer::read(void *dataPtr, uint32 dataSize) {
int32 bytesRead = CLIP((int32)dataSize, 0, (int32)_data.size() - _pos);
if (bytesRead) {
Common::fill(&_readBytes[_pos], &_readBytes[_pos + bytesRead], true);
- Common::copy((byte *)dataPtr, (byte *)dataPtr + bytesRead, (byte *)dataPtr);
+ Common::copy(&_data[_pos], &_data[_pos + bytesRead], (byte *)dataPtr);
_pos += bytesRead;
}
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index db9d1d6eec..8b0ea5936b 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -982,8 +982,6 @@ static void load_extra_string_file(ComprehendGame *game,
static void load_extra_string_files(ComprehendGame *game) {
int i;
- memset(&game->_strings2, 0, sizeof(game->_strings2));
-
for (i = 0; i < ARRAY_SIZE(game->_stringFiles); i++) {
if (!game->_stringFiles[i].filename)
break;
@@ -1007,7 +1005,6 @@ static void load_game_data(ComprehendGame *game) {
parse_items(game, &fb);
parse_dictionary(game, &fb);
parse_word_map(game, &fb);
- memset(&game->_strings, 0, sizeof(game->_strings));
parse_string_table(&fb, game->_header.addr_strings,
game->_header.addr_strings_end,
&game->_strings);
Commit: 16c36841aa0020bde71e690b9e00ed8ae7bc9e01
https://github.com/scummvm/scummvm/commit/16c36841aa0020bde71e690b9e00ed8ae7bc9e01
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: gcc compilation fixes
Changed paths:
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/file_buf.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/graphics.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/util.cpp
engines/glk/comprehend/util.h
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index bef4f9ef0a..04b59c4d5b 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -172,11 +172,11 @@ static void dump_functions(ComprehendGame *game)
Function *func;
uint i, j;
- debugN("Functions (%zd entries)\n", game->_nr_functions);
+ debugN("Functions (%u entries)\n", (uint)game->_nr_functions);
for (i = 0; i < game->_nr_functions; i++) {
func = &game->_functions[i];
- debugN("[%.4x] (%zd instructions)\n", i, func->nr_instructions);
+ debugN("[%.4x] (%u instructions)\n", i, (uint)func->nr_instructions);
for (j = 0; j < func->nr_instructions; j++)
dump_instruction(game, NULL, &func->instructions[j]);
debugN("\n");
@@ -189,7 +189,7 @@ static void dump_action_table(ComprehendGame *game)
Word *word;
uint i, j;
- debugN("Action table (%zd entries)\n", game->_nr_actions);
+ debugN("Action table (%u entries)\n", (uint)game->_nr_actions);
for (i = 0; i < game->_nr_actions; i++) {
action = &game->_actions[i];
@@ -253,7 +253,7 @@ static void dump_dictionary(ComprehendGame *game)
qsort(dictionary, game->_nr_words, sizeof(*words),
word_index_compare);
- debugN("Dictionary (%zd words)\n", game->_nr_words);
+ debugN("Dictionary (%u words)\n", (uint)game->_nr_words);
for (i = 0; i < game->_nr_words; i++) {
words = &dictionary[i];
debugN(" [%.2x] %.2x %s\n", words->_index, words->_type,
@@ -270,7 +270,7 @@ static void dump_word_map(ComprehendGame *game)
WordMap *map;
uint i, j;
- debugN("Word pairs (%zd entries)\n", game->_nr_word_maps);
+ debugN("Word pairs (%u entries)\n", (uint)game->_nr_word_maps);
for (i = 0; i < game->_nr_word_maps; i++) {
map = &game->_wordMaps[i];
@@ -296,7 +296,7 @@ static void dump_rooms(ComprehendGame *game)
uint i;
/* Room zero acts as the players inventory */
- debugN("Rooms (%zd entries)\n", game->_nr_rooms);
+ debugN("Rooms (%u entries)\n", (uint)game->_nr_rooms);
for (i = 1; i <= game->_nr_rooms; i++) {
room = &game->_rooms[i];
@@ -322,7 +322,7 @@ static void dump_items(ComprehendGame *game)
Item *item;
uint i, j;
- debugN("Items (%zd entries)\n", game->_header.nr_items);
+ debugN("Items (%u entries)\n", (uint)game->_header.nr_items);
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
@@ -358,15 +358,15 @@ static void dump_string_table(StringTable *table)
static void dump_game_data_strings(ComprehendGame *game)
{
- debugN("Main string table (%zd entries)\n",
- game->_strings.nr_strings);
+ debugN("Main string table (%u entries)\n",
+ (uint)game->_strings.nr_strings);
dump_string_table(&game->_strings);
}
static void dump_extra_strings(ComprehendGame *game)
{
- debugN("Extra strings (%zd entries)\n",
- game->_strings2.nr_strings);
+ debugN("Extra strings (%u entries)\n",
+ (uint)game->_strings2.nr_strings);
dump_string_table(&game->_strings2);
}
@@ -374,8 +374,8 @@ static void dump_replace_words(ComprehendGame *game)
{
uint i;
- debugN("Replacement words (%zd entries)\n",
- game->_nr_replace_words);
+ debugN("Replacement words (%u entries)\n",
+ (uint)game->_nr_replace_words);
for (i = 0; i < game->_nr_replace_words; i++)
debugN(" [%.2x] %s\n", i + 1, game->_replaceWords[i]);
}
@@ -440,7 +440,7 @@ static Dumper dumpers[] = {
void dump_game_data(ComprehendGame *game, unsigned flags)
{
- int i;
+ uint i;
for (i = 0; i < ARRAY_SIZE(dumpers); i++)
if (flags & dumpers[i].flag) {
diff --git a/engines/glk/comprehend/file_buf.cpp b/engines/glk/comprehend/file_buf.cpp
index 28b20b69c4..d22fd2495d 100644
--- a/engines/glk/comprehend/file_buf.cpp
+++ b/engines/glk/comprehend/file_buf.cpp
@@ -64,8 +64,8 @@ bool FileBuffer::seek(int32 offset, int whence) {
uint32 FileBuffer::read(void *dataPtr, uint32 dataSize) {
int32 bytesRead = CLIP((int32)dataSize, 0, (int32)_data.size() - _pos);
if (bytesRead) {
- Common::fill(&_readBytes[_pos], &_readBytes[_pos + bytesRead], true);
- Common::copy(&_data[_pos], &_data[_pos + bytesRead], (byte *)dataPtr);
+ Common::fill(&_readBytes[_pos], &_readBytes[_pos] + bytesRead, true);
+ Common::copy(&_data[_pos], &_data[_pos] + bytesRead, (byte *)dataPtr);
_pos += bytesRead;
}
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 2022656364..8fed83a1f0 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -890,7 +890,7 @@ static void eval_instruction(ComprehendGame *game,
index += 256;
if (index >= game->_nr_functions)
fatal_error("Bad function %.4x >= %.4x\n",
- index, game->_nr_functions);
+ index, (uint)game->_nr_functions);
debug_printf(DEBUG_FUNCTIONS,
"Calling subfunction %.4x\n", index);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 8b0ea5936b..fee2c9b46d 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -51,7 +51,7 @@ void FunctionState::clear() {
void Room::clear() {
flags = 0;
- graphic = 0;
+ graphic = 0;
string_desc = 0;
Common::fill(&direction[0], &direction[NR_DIRECTIONS], 0);
}
@@ -60,11 +60,11 @@ void Room::clear() {
void Item::clear() {
string_desc = 0;
- long_string = 0;
- room = 0;
- flags = 0;
- word = 0;
- graphic = 0;
+ long_string = 0;
+ room = 0;
+ flags = 0;
+ word = 0;
+ graphic = 0;
}
/*-------------------------------------------------------*/
@@ -75,6 +75,18 @@ void Word::clear() {
Common::fill(&_word[0], &_word[7], '\0');
}
+void Word::load(FileBuffer *fb) {
+ fb->read(_word, 6);
+
+ // Decode
+ for (int j = 0; j < 6; j++)
+ _word[j] ^= 0x8a;
+ _word[6] = '\0';
+
+ _index = fb->readByte();
+ _type = fb->readByte();
+}
+
/*-------------------------------------------------------*/
void WordMap::clear() {
@@ -98,7 +110,7 @@ void Action::clear() {
void Instruction::clear() {
opcode = 0;
nr_operands = 0;
- is_command= false;
+ is_command = false;
Common::fill(&operand[0], &operand[3], 0);
}
@@ -113,8 +125,8 @@ void Function::clear() {
/*-------------------------------------------------------*/
void StringTable::clear() {
- nr_strings = 0;
- Common::fill(&strings[0], &strings[0xffff], nullptr);
+ nr_strings = 0;
+ Common::fill(&strings[0], &strings[0xffff], (char *)nullptr);
}
/*-------------------------------------------------------*/
@@ -199,7 +211,7 @@ static bool opcode_is_command(uint8 opcode) {
}
static uint8 parse_vm_instruction(FileBuffer *fb,
- Instruction *instr) {
+ Instruction *instr) {
uint i;
/* Get the opcode */
@@ -215,11 +227,12 @@ static uint8 parse_vm_instruction(FileBuffer *fb,
return instr->opcode;
}
-static void parse_function(FileBuffer *fb, Function * func) {
+static void parse_function(FileBuffer *fb, Function *func) {
Instruction *instruction;
- uint8 *p, opcode;
+ const uint8 *p;
+ uint8 opcode;
- p = (uint8 *)memchr(fb->dataPtr(), 0x00, fb->size() - fb->pos());
+ p = (const uint8 *)memchr(fb->dataPtr(), 0x00, fb->size() - fb->pos());
if (!p)
fatal_error("bad function @ %.4x", fb->pos());
@@ -252,7 +265,7 @@ static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
}
static void parse_action_table_vvnn(ComprehendGame *game,
- FileBuffer *fb, size_t * index) {
+ FileBuffer *fb, size_t *index) {
Action *action;
uint8 verb, count;
int i, j;
@@ -296,7 +309,7 @@ static void parse_action_table_vvnn(ComprehendGame *game,
}
static void parse_action_table_vnjn(ComprehendGame *game,
- FileBuffer *fb, size_t * index) {
+ FileBuffer *fb, size_t *index) {
Action *action;
uint8 join, count;
int i;
@@ -341,7 +354,7 @@ static void parse_action_table_vnjn(ComprehendGame *game,
}
static void parse_action_table_vjn(ComprehendGame *game,
- FileBuffer *fb, size_t * index) {
+ FileBuffer *fb, size_t *index) {
Action *action;
uint8 join, count;
int i;
@@ -382,7 +395,7 @@ static void parse_action_table_vjn(ComprehendGame *game,
}
static void parse_action_table_vdn(ComprehendGame *game,
- FileBuffer *fb, size_t * index) {
+ FileBuffer *fb, size_t *index) {
Action *action;
uint8 verb, count;
int i;
@@ -423,7 +436,7 @@ static void parse_action_table_vdn(ComprehendGame *game,
}
static void parse_action_table_vnn(ComprehendGame *game,
- FileBuffer *fb, size_t * index) {
+ FileBuffer *fb, size_t *index) {
Action *action;
uint8 verb, count;
int i;
@@ -465,7 +478,7 @@ static void parse_action_table_vnn(ComprehendGame *game,
}
static void parse_action_table_vn(ComprehendGame *game,
- FileBuffer *fb, size_t * index) {
+ FileBuffer *fb, size_t *index) {
Action *action;
uint8 verb, count;
int i;
@@ -504,7 +517,7 @@ static void parse_action_table_vn(ComprehendGame *game,
}
static void parse_action_table_v(ComprehendGame *game,
- FileBuffer *fb, size_t * index) {
+ FileBuffer *fb, size_t *index) {
Action *action;
uint8 verb, nr_funcs;
uint16 func;
@@ -547,7 +560,7 @@ static void parse_action_table_v(ComprehendGame *game,
}
static void parse_action_table(ComprehendGame *game,
- FileBuffer *fb) {
+ FileBuffer *fb) {
game->_nr_actions = 0;
if (game->_comprehendVersion == 1) {
@@ -565,31 +578,19 @@ static void parse_action_table(ComprehendGame *game,
}
static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
- Word *words;
- uint i, j;
+ uint i;
// FIXME - fixed size 0xff array?
- game->_words = (Word *)xmalloc(game->_nr_words * sizeof(words));
+ game->_words = (Word *)xmalloc(game->_nr_words * sizeof(Word));
fb->seek(game->_header.addr_dictionary);
- for (i = 0; i < game->_nr_words; i++) {
- words = &game->_words[i];
-
- fb->read(words->_word, 6);
-
- /* Decode */
- for (j = 0; j < 6; j++)
- words->_word[j] ^= 0x8a;
- words->_word[6] = '\0';
-
- words->_index = fb->readByte();
- words->_type = fb->readByte();
- }
+ for (i = 0; i < game->_nr_words; i++)
+ game->_words[i].load(fb);
}
static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
WordMap *map;
- uint8 index, type, dummy;
+ uint8 index, type;
uint i;
game->_nr_word_maps = 0;
@@ -619,8 +620,7 @@ static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
}
/* Consume two more null bytes (type and index were also null) */
- dummy = fb->readByte();
- dummy = fb->readByte();
+ fb->skip(2);
/*
* Parse the target word table. Each entry has a dictionary
@@ -645,7 +645,7 @@ static void parse_items(ComprehendGame *game, FileBuffer *fb) {
if (game->_comprehendVersion == 2) {
/* Comprehend version 2 adds long string descriptions */
fb->seek(game->_header.addr_item_strings +
- (game->_header.nr_items * sizeof(uint16)));
+ (game->_header.nr_items * sizeof(uint16)));
file_buf_get_array_le16(fb, 0, game->_items, long_string, nr_items);
}
@@ -674,7 +674,7 @@ static void parse_rooms(ComprehendGame *game, FileBuffer *fb) {
for (i = 0; i < NR_DIRECTIONS; i++) {
fb->seek(game->_header.room_direction_table[i]);
file_buf_get_array_u8(fb, 1, game->_rooms,
- direction[i], nr_rooms);
+ direction[i], nr_rooms);
}
/* Room string descriptions */
@@ -690,7 +690,7 @@ static void parse_rooms(ComprehendGame *game, FileBuffer *fb) {
file_buf_get_array_u8(fb, 1, game->_rooms, graphic, nr_rooms);
}
-static uint64 string_get_chunk(uint8 * string) {
+static uint64 string_get_chunk(uint8 *string) {
uint64 c, val = 0;
int i;
@@ -772,7 +772,7 @@ static char *parse_string(FileBuffer *fb) {
special_next = true;
} else {
c = decode_string_elem(elem, capital_next,
- special_next);
+ special_next);
special_next = false;
capital_next = false;
string[k++] = c;
@@ -788,7 +788,7 @@ done:
}
static void parse_string_table(FileBuffer *fb, unsigned start_addr,
- uint32 end_addr, StringTable *table) {
+ uint32 end_addr, StringTable *table) {
fb->seek(start_addr);
while (1) {
table->strings[table->nr_strings++] = parse_string(fb);
@@ -798,14 +798,15 @@ static void parse_string_table(FileBuffer *fb, unsigned start_addr,
}
static void parse_variables(ComprehendGame *game, FileBuffer *fb) {
- int i;
+ uint i;
for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
game->_variables[i] = fb->readUint16LE();
}
static void parse_flags(ComprehendGame *game, FileBuffer *fb) {
- int i, bit, flag_index = 0;
+ uint i, flag_index = 0;
+ int bit;
uint8 bitmask;
for (i = 0; i < ARRAY_SIZE(game->_flags) / 8; i++) {
@@ -818,8 +819,7 @@ static void parse_flags(ComprehendGame *game, FileBuffer *fb) {
}
static void parse_replace_words(ComprehendGame *game,
- FileBuffer *fb) {
- uint16 dummy;
+ FileBuffer *fb) {
size_t len;
bool eof;
int i;
@@ -828,7 +828,7 @@ static void parse_replace_words(ComprehendGame *game,
fb->seek(game->_header.addr_strings_end);
/* FIXME - what is this for */
- dummy = fb->readUint16LE();
+ fb->skip(2);
for (i = 0;; i++) {
len = fb->strlen(&eof);
@@ -836,7 +836,7 @@ static void parse_replace_words(ComprehendGame *game,
break;
game->_replaceWords[i] = xstrndup((const char *)fb->dataPtr(), len);
- fb->read(NULL, len + (eof ? 0 : 1));
+ fb->skip(len + (eof ? 0 : 1));
if (eof)
break;
}
@@ -850,7 +850,6 @@ static void parse_replace_words(ComprehendGame *game,
static void parse_header(ComprehendGame *game, FileBuffer *fb) {
GameHeader *header = &game->_header;
uint16 dummy, addr_dictionary_end;
- uint8 dummy8;
fb->seek(0);
header->magic = fb->readUint16LE();
@@ -933,7 +932,7 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
parse_header_le16(fb, &header->addr_item_graphics);
header->nr_items = (header->addr_item_word -
- header->addr_item_flags);
+ header->addr_item_flags);
} else {
parse_header_le16(fb, &header->addr_item_strings);
@@ -943,30 +942,30 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
parse_header_le16(fb, &header->addr_item_graphics);
header->nr_items = (header->addr_item_flags -
- header->addr_item_locations);
+ header->addr_item_locations);
}
parse_header_le16(fb, &header->addr_strings);
parse_header_le16(fb, &dummy);
parse_header_le16(fb, &header->addr_strings_end);
- dummy8 = fb->readByte();
+ fb->skip(1);
game->_startRoom = fb->readByte();
- dummy8 = fb->readByte();
+ fb->skip(1);
parse_variables(game, fb);
parse_flags(game, fb);
game->_nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
- header->room_direction_table[DIRECTION_NORTH];
+ header->room_direction_table[DIRECTION_NORTH];
game->_nr_words = (addr_dictionary_end -
- header->addr_dictionary) /
- 8;
+ header->addr_dictionary) /
+ 8;
}
static void load_extra_string_file(ComprehendGame *game,
- StringFile * string_file) {
+ StringFile *string_file) {
FileBuffer fb(string_file->filename);
unsigned end;
@@ -976,11 +975,11 @@ static void load_extra_string_file(ComprehendGame *game,
end = fb.size();
parse_string_table(&fb, string_file->base_offset,
- end, &game->_strings2);
+ end, &game->_strings2);
}
static void load_extra_string_files(ComprehendGame *game) {
- int i;
+ uint i;
for (i = 0; i < ARRAY_SIZE(game->_stringFiles); i++) {
if (!game->_stringFiles[i].filename)
@@ -1006,8 +1005,8 @@ static void load_game_data(ComprehendGame *game) {
parse_dictionary(game, &fb);
parse_word_map(game, &fb);
parse_string_table(&fb, game->_header.addr_strings,
- game->_header.addr_strings_end,
- &game->_strings);
+ game->_header.addr_strings_end,
+ &game->_strings);
load_extra_string_files(game);
parse_vm(game, &fb);
parse_action_table(game, &fb);
@@ -1029,7 +1028,7 @@ void comprehend_load_game(ComprehendGame *game) {
}
#ifdef TODO
-static void patch_string_desc(uint16 * desc) {
+static void patch_string_desc(uint16 *desc) {
/*
* String descriptors in the save file sometimes are encoded as a
* table/index value like the instruction opcodes used, and other
@@ -1053,7 +1052,7 @@ void comprehend_save_game(ComprehendGame *game, const char *filename) {
fd = fopen(filename, "w");
if (!fd) {
printf("Error: Failed to open save file '%s': %s\n",
- filename, strerror(errno));
+ filename, strerror(errno));
return;
}
@@ -1094,10 +1093,10 @@ void comprehend_save_game(ComprehendGame *game, const char *filename) {
/* Rooms */
file_buf_put_array_le16(fd, 1, game->rooms,
- string_desc, nr_rooms);
+ string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
file_buf_put_array_u8(fd, 1, game->rooms,
- direction[dir], nr_rooms);
+ direction[dir], nr_rooms);
file_buf_put_array_u8(fd, 1, game->rooms, flags, nr_rooms);
file_buf_put_array_u8(fd, 1, game->rooms, graphic, nr_rooms);
@@ -1136,7 +1135,7 @@ void comprehend_restore_game(ComprehendGame *game, const char *filename) {
err = file_buf_map_may_fail(filename, &fb);
if (err) {
printf("Error: Failed to open save file '%s': %s\n",
- filename, strerror(-err));
+ filename, strerror(-err));
return;
}
@@ -1160,10 +1159,10 @@ void comprehend_restore_game(ComprehendGame *game, const char *filename) {
/* Restore rooms */
file_buf_get_array_le16(&fb, 1, game->rooms,
- string_desc, nr_rooms);
+ string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
file_buf_get_array_u8(&fb, 1, game->rooms,
- direction[dir], nr_rooms);
+ direction[dir], nr_rooms);
file_buf_get_array_u8(&fb, 1, game->rooms, flags, nr_rooms);
file_buf_get_array_u8(&fb, 1, game->rooms, graphic, nr_rooms);
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 95c4c6a028..f8a6e6f0fe 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -40,7 +40,7 @@ enum {
DIRECTION_DOWN,
DIRECTION_IN,
DIRECTION_OUT,
- NR_DIRECTIONS,
+ NR_DIRECTIONS
};
struct FunctionState {
@@ -96,6 +96,8 @@ struct Word {
}
void clear();
+
+ void load(FileBuffer *fb);
};
struct WordIndex {
@@ -225,7 +227,7 @@ struct GameInfo {
struct Item _items[0xff];
- struct Word *_words;
+ Word *_words;
size_t _nr_words;
struct WordMap _wordMaps[0xff];
@@ -337,7 +339,7 @@ enum {
OPCODE_CURRENT_IS_OBJECT,
OPCODE_DRAW_ROOM,
OPCODE_DRAW_OBJECT,
- OPCODE_WAIT_KEY,
+ OPCODE_WAIT_KEY
};
/* Game state update flags */
@@ -355,7 +357,7 @@ enum {
ACTION_VERB_DIR_NOUN,
ACTION_VERB_NOUN_NOUN,
ACTION_VERB_NOUN,
- ACTION_VERB_OPT_NOUN,
+ ACTION_VERB_OPT_NOUN
};
/* Standard strings (main string table) */
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 66a9a890b3..fe2c0fb880 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -62,7 +62,7 @@ TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
_savegameFileFormat = "G%d.MS0";
_gameStrings = &tr_strings;
-};
+}
void TransylvaniaGame::update_monster(const TransylvaniaMonster *monster_info) {
Item *monster;
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/graphics.cpp
index b053aceb5b..7d8937423d 100644
--- a/engines/glk/comprehend/graphics.cpp
+++ b/engines/glk/comprehend/graphics.cpp
@@ -63,7 +63,9 @@ struct GraphicsContext {
// SDL_Surface *surface;
};
+#ifdef TODO
static GraphicsContext ctx;
+#endif
unsigned g_set_pen_color(uint8 opcode) {
return pen_colors[opcode - IMAGE_OP_PEN_COLOR_A];
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 9a44b21e8d..a256f33ccd 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -260,15 +260,15 @@ void draw_image(ImageData *info, unsigned index)
FileBuffer *fb;
bool done = false;
ImageContext ctx = {
- 0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE
+ 0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE, 0, 0
};
file_num = index / IMAGES_PER_FILE;
fb = &info->fb[file_num];
if (index >= info->nr_images) {
- printf("WARNING: Bad image index %.8x (max=%.8zx)\n", index,
- info->nr_images);
+ warning("Bad image index %.8x (max=%.8x)\n", index,
+ (uint)info->nr_images);
return;
}
@@ -309,6 +309,7 @@ static void load_image_file(ImageData *info, const char *filename,
int i;
info->fb[file_num] = FileBuffer(filename);
+ fb = &info->fb[file_num];
/*
* In earlier versions of Comprehend the first word is 0x1000 and
diff --git a/engines/glk/comprehend/util.cpp b/engines/glk/comprehend/util.cpp
index 5740b69215..2a64d1d0c2 100644
--- a/engines/glk/comprehend/util.cpp
+++ b/engines/glk/comprehend/util.cpp
@@ -64,7 +64,7 @@ void debug_printf(unsigned flags, const char *fmt, ...) {
if (debug_flags & flags) {
va_start(args, fmt);
- Common::String msg = Common::String(fmt, args);
+ Common::String msg = Common::String::vformat(fmt, args);
va_end(args);
debug(1, "%s", msg.c_str());
diff --git a/engines/glk/comprehend/util.h b/engines/glk/comprehend/util.h
index 947317aa71..335b7b5132 100644
--- a/engines/glk/comprehend/util.h
+++ b/engines/glk/comprehend/util.h
@@ -23,6 +23,8 @@
#ifndef GLK_COMPREHEND_UTIL_H
#define GLK_COMPREHEND_UTIL_H
+#include "common/scummsys.h"
+
namespace Glk {
namespace Comprehend {
Commit: fbf8e0a23b15cbb01dcae76ada6609e2a1c1422c
https://github.com/scummvm/scummvm/commit/fbf8e0a23b15cbb01dcae76ada6609e2a1c1422c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Fix opcode map definition
Changed paths:
engines/glk/comprehend/dump_game_data.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/opcode_map.cpp
engines/glk/comprehend/opcode_map.h
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
index 04b59c4d5b..93ef85fe8f 100644
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ b/engines/glk/comprehend/dump_game_data.cpp
@@ -126,7 +126,7 @@ void dump_instruction(ComprehendGame *game,
func_state->or_count, func_state->_and,
func_state->test_result, func_state->else_result);
- opcode_map = get_opcode_map(game);
+ opcode_map = game->_opcodeMap;
opcode = opcode_map[instr->opcode];
debugN(" [%.2x] ", instr->opcode);
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 8fed83a1f0..ef21951c9b 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -44,11 +44,11 @@ struct WinSize {
static WinSize console_winsize;
ComprehendGame::ComprehendGame() : _gameName(nullptr),
- _shortName(nullptr),
- _gameDataFile(nullptr),
- _savegameFileFormat(nullptr),
- _colorTable(0),
- _gameStrings(nullptr) {
+ _shortName(nullptr),
+ _gameDataFile(nullptr),
+ _savegameFileFormat(nullptr),
+ _colorTable(0),
+ _gameStrings(nullptr) {
}
ComprehendGame::~ComprehendGame() {
@@ -426,7 +426,7 @@ static void eval_instruction(ComprehendGame *game,
FunctionState *func_state,
Instruction *instr,
Word *verb, Word *noun) {
- uint8 *opcode_map;
+ const byte *opcode_map = game->_opcodeMap;
Room *room;
Item *item;
uint16 index;
@@ -477,7 +477,6 @@ static void eval_instruction(ComprehendGame *game,
}
}
- opcode_map = get_opcode_map(game);
switch (opcode_map[instr->opcode]) {
case OPCODE_VAR_ADD:
game->_variables[instr->operand[0]] +=
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index ce4689a32a..30d906ccf7 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -25,6 +25,7 @@
#include "common/array.h"
#include "glk/comprehend/game_data.h"
+#include "glk/comprehend/opcode_map.h"
namespace Glk {
namespace Comprehend {
@@ -33,7 +34,7 @@ namespace Comprehend {
#define ROOM_IS_DARK 1
#define ROOM_IS_TOO_BRIGHT 2
-class ComprehendGame : public GameInfo {
+class ComprehendGame : public GameInfo, public OpcodeMap {
public:
const char *_gameName;
const char *_shortName;
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index fee2c9b46d..4bc7b42a02 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -875,6 +875,8 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
break;
}
+ game->loadOpcodes(game->_comprehendVersion);
+
/* FIXME - Second word in header has unknown usage */
parse_header_le16(fb, &dummy);
diff --git a/engines/glk/comprehend/opcode_map.cpp b/engines/glk/comprehend/opcode_map.cpp
index 03c59206fe..c327ef63fe 100644
--- a/engines/glk/comprehend/opcode_map.cpp
+++ b/engines/glk/comprehend/opcode_map.cpp
@@ -1,193 +1,169 @@
/* ScummVM - Graphic Adventure Engine
*
- * ScummVM is the legal property of its developers, whose names
+ * 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.
+ * of the License; or (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
+ * 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.
+ * 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/comprehend/comprehend.h"
-#include "glk/comprehend/game.h"
+#include "glk/comprehend/opcode_map.h"
#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/util.h"
+#include "common/algorithm.h"
+#include "common/textconsole.h"
namespace Glk {
namespace Comprehend {
-/*
- * Version 2 of the Comprehend engine (OO-Topos) changes some of the opcode
- * numbers and adds new opcodes. Use tables to translate the opcodes used
- * in the original games into a generic version used by Re-Comprehend.
- *
- * FIXME - unimplemented/unknown ocpodes:
- *
- * d5(obj): Make object visible. This will print a "you see: object" when the
- * object is in the room.
- */
-static uint8 opcode_map_v1[0x100] = {
-#ifdef TODO
- [0x01] = OPCODE_HAVE_OBJECT,
- [0x04] = OPCODE_OR,
- [0x05] = OPCODE_IN_ROOM,
- [0x06] = OPCODE_VAR_EQ,
- [0x08] = OPCODE_CURRENT_OBJECT_TAKEABLE,
- [0x09] = OPCODE_OBJECT_PRESENT,
- [0x0c] = OPCODE_ELSE,
- [0x0e] = OPCODE_OBJECT_IN_ROOM,
- [0x14] = OPCODE_OBJECT_NOT_VALID,
- [0x18] = OPCODE_INVENTORY_FULL,
- [0x19] = OPCODE_TEST_FLAG,
- [0x1d] = OPCODE_CURRENT_OBJECT_IN_ROOM,
- [0x20] = OPCODE_HAVE_CURRENT_OBJECT,
- [0x21] = OPCODE_OBJECT_IS_NOT_NOWHERE,
- [0x24] = OPCODE_CURRENT_OBJECT_PRESENT,
- [0x31] = OPCODE_TEST_ROOM_FLAG,
- [0x41] = OPCODE_NOT_HAVE_OBJECT,
- [0x45] = OPCODE_NOT_IN_ROOM,
- [0x48] = OPCODE_CURRENT_OBJECT_IS_NOWHERE,
- [0x49] = OPCODE_OBJECT_NOT_PRESENT,
- [0x43] = OPCODE_OBJECT_NOT_IN_ROOM,
- [0x50] = OPCODE_TEST_FALSE,
- [0x59] = OPCODE_TEST_NOT_FLAG,
- [0x60] = OPCODE_NOT_HAVE_CURRENT_OBJECT,
- [0x61] = OPCODE_OBJECT_IS_NOWHERE,
- [0x64] = OPCODE_CURRENT_OBJECT_NOT_PRESENT,
- [0x68] = OPCODE_CURRENT_OBJECT_NOT_TAKEABLE,
- [0x71] = OPCODE_TEST_NOT_ROOM_FLAG,
- [0x80] = OPCODE_INVENTORY,
- [0x81] = OPCODE_TAKE_OBJECT,
- [0x82] = OPCODE_MOVE_OBJECT_TO_ROOM,
- [0x84] = OPCODE_SAVE_ACTION,
- [0x85] = OPCODE_MOVE_TO_ROOM,
- [0x86] = OPCODE_VAR_ADD,
- [0x87] = OPCODE_SET_ROOM_DESCRIPTION,
- [0x89] = OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM,
- [0x8a] = OPCODE_VAR_SUB,
- [0x8b] = OPCODE_SET_OBJECT_DESCRIPTION,
- [0x8c] = OPCODE_MOVE,
- [0x8e] = OPCODE_PRINT,
- [0x95] = OPCODE_REMOVE_OBJECT,
- [0x99] = OPCODE_SET_FLAG,
- [0x92] = OPCODE_CALL_FUNC,
- [0x98] = OPCODE_TURN_TICK,
- [0x9d] = OPCODE_CLEAR_FLAG,
- [0x9e] = OPCODE_INVENTORY_ROOM,
- [0xa0] = OPCODE_TAKE_CURRENT_OBJECT,
- [0xa1] = OPCODE_SPECIAL,
- [0xa4] = OPCODE_DROP_CURRENT_OBJECT,
- [0xa2] = OPCODE_SET_ROOM_GRAPHIC,
- [0xb0] = OPCODE_REMOVE_CURRENT_OBJECT,
- [0xb1] = OPCODE_DO_VERB,
- [0xb9] = OPCODE_SET_STRING_REPLACEMENT,
- [0xbd] = OPCODE_VAR_INC,
- [0xc1] = OPCODE_VAR_DEC,
- [0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM
-#else
- 0
- #endif
-};
+void OpcodeMap::loadOpcodes(int version) {
+ Common::fill(&_opcodeMap[0], &_opcodeMap[0x100], 0);
-static uint8 opcode_map_v2[0x100] = {
-#ifdef TODO
- [0x01] = OPCODE_HAVE_OBJECT,
- [0x04] = OPCODE_OR,
- [0x05] = OPCODE_IN_ROOM,
- [0x06] = OPCODE_VAR_EQ,
- [0x08] = OPCODE_CURRENT_IS_OBJECT,
- [0x09] = OPCODE_OBJECT_PRESENT,
- [0x0c] = OPCODE_ELSE,
- [0x11] = OPCODE_OBJECT_IS_NOWHERE,
- [0x14] = OPCODE_OBJECT_NOT_VALID,
- [0x19] = OPCODE_TEST_FLAG,
- [0x1d] = OPCODE_TEST_ROOM_FLAG,
- [0x20] = OPCODE_HAVE_CURRENT_OBJECT,
- [0x21] = OPCODE_OBJECT_PRESENT,
- [0x22] = OPCODE_OBJECT_IN_ROOM,
- [0x30] = OPCODE_CURRENT_OBJECT_PRESENT,
- [0x31] = OPCODE_TEST_ROOM_FLAG,
- [0x38] = OPCODE_INVENTORY_FULL,
- [0x41] = OPCODE_NOT_HAVE_OBJECT,
- [0x45] = OPCODE_NOT_IN_ROOM,
- [0x48] = OPCODE_CURRENT_OBJECT_IS_NOWHERE,
- [0x43] = OPCODE_OBJECT_NOT_IN_ROOM,
- [0x59] = OPCODE_TEST_NOT_FLAG,
- [0x5d] = OPCODE_TEST_NOT_ROOM_FLAG,
- [0x60] = OPCODE_NOT_HAVE_CURRENT_OBJECT,
- [0x61] = OPCODE_OBJECT_NOT_PRESENT,
- [0x70] = OPCODE_CURRENT_OBJECT_NOT_PRESENT,
- [0x74] = OPCODE_CURRENT_NOT_OBJECT,
- [0x80] = OPCODE_INVENTORY,
- [0x81] = OPCODE_TAKE_OBJECT,
- [0x82] = OPCODE_MOVE_OBJECT_TO_ROOM,
- [0x84] = OPCODE_SAVE_ACTION,
- [0x85] = OPCODE_MOVE_TO_ROOM,
- [0x86] = OPCODE_VAR_ADD,
- [0x87] = OPCODE_SET_ROOM_DESCRIPTION,
- [0x89] = OPCODE_SPECIAL,
- [0x8a] = OPCODE_VAR_SUB,
- [0x8b] = OPCODE_SET_OBJECT_DESCRIPTION,
- [0x8c] = OPCODE_MOVE,
- [0x8e] = OPCODE_PRINT,
- [0x8f] = OPCODE_SET_OBJECT_LONG_DESCRIPTION,
- [0x90] = OPCODE_WAIT_KEY,
- [0x92] = OPCODE_CALL_FUNC,
- [0x95] = OPCODE_REMOVE_OBJECT,
- [0x98] = OPCODE_TURN_TICK,
- [0x99] = OPCODE_SET_FLAG,
- [0x9d] = OPCODE_CLEAR_FLAG,
- [0x9e] = OPCODE_INVENTORY_ROOM,
- [0xa0] = OPCODE_TAKE_CURRENT_OBJECT,
- [0xa2] = OPCODE_SET_OBJECT_GRAPHIC,
- [0xb1] = OPCODE_DO_VERB,
- [0xb5] = OPCODE_DESCRIBE_CURRENT_OBJECT,
- [0xc1] = OPCODE_VAR_DEC,
- [0xc2] = OPCODE_SET_ROOM_GRAPHIC,
- [0xc5] = OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT,
- [0xc6] = OPCODE_SET_OBJECT_GRAPHIC,
- [0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM,
- [0xcd] = OPCODE_SET_STRING_REPLACEMENT,
- [0xd1] = OPCODE_MOVE_DIRECTION,
- [0xd5] = OPCODE_DRAW_ROOM,
- [0xd9] = OPCODE_DRAW_OBJECT,
- [0xdd] = OPCODE_VAR_INC,
- [0xe1] = OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM,
- [0xed] = OPCODE_REMOVE_OBJECT,
- [0xf0] = OPCODE_DROP_CURRENT_OBJECT,
- [0xfc] = OPCODE_REMOVE_CURRENT_OBJECT
-#else
- 0
- #endif
-};
+ if (version == 1)
+ loadVersion1();
+ else if (version == 2)
+ loadVersion2();
+ else
+ error("Invalid version");
+}
-uint8 *get_opcode_map(ComprehendGame *game)
-{
- switch (game->_comprehendVersion) {
- case 1:
- return opcode_map_v1;
- break;
- case 2:
- return opcode_map_v2;
- default:
- fatal_error("Unsupported Comprehend version %d\n",
- game->_comprehendVersion);
+void OpcodeMap::loadVersion1() {
+ _opcodeMap[0x01] = OPCODE_HAVE_OBJECT;
+ _opcodeMap[0x04] = OPCODE_OR;
+ _opcodeMap[0x05] = OPCODE_IN_ROOM;
+ _opcodeMap[0x06] = OPCODE_VAR_EQ;
+ _opcodeMap[0x08] = OPCODE_CURRENT_OBJECT_TAKEABLE;
+ _opcodeMap[0x09] = OPCODE_OBJECT_PRESENT;
+ _opcodeMap[0x0c] = OPCODE_ELSE;
+ _opcodeMap[0x0e] = OPCODE_OBJECT_IN_ROOM;
+ _opcodeMap[0x14] = OPCODE_OBJECT_NOT_VALID;
+ _opcodeMap[0x18] = OPCODE_INVENTORY_FULL;
+ _opcodeMap[0x19] = OPCODE_TEST_FLAG;
+ _opcodeMap[0x1d] = OPCODE_CURRENT_OBJECT_IN_ROOM;
+ _opcodeMap[0x20] = OPCODE_HAVE_CURRENT_OBJECT;
+ _opcodeMap[0x21] = OPCODE_OBJECT_IS_NOT_NOWHERE;
+ _opcodeMap[0x24] = OPCODE_CURRENT_OBJECT_PRESENT;
+ _opcodeMap[0x31] = OPCODE_TEST_ROOM_FLAG;
+ _opcodeMap[0x41] = OPCODE_NOT_HAVE_OBJECT;
+ _opcodeMap[0x45] = OPCODE_NOT_IN_ROOM;
+ _opcodeMap[0x48] = OPCODE_CURRENT_OBJECT_IS_NOWHERE;
+ _opcodeMap[0x49] = OPCODE_OBJECT_NOT_PRESENT;
+ _opcodeMap[0x43] = OPCODE_OBJECT_NOT_IN_ROOM;
+ _opcodeMap[0x50] = OPCODE_TEST_FALSE;
+ _opcodeMap[0x59] = OPCODE_TEST_NOT_FLAG;
+ _opcodeMap[0x60] = OPCODE_NOT_HAVE_CURRENT_OBJECT;
+ _opcodeMap[0x61] = OPCODE_OBJECT_IS_NOWHERE;
+ _opcodeMap[0x64] = OPCODE_CURRENT_OBJECT_NOT_PRESENT;
+ _opcodeMap[0x68] = OPCODE_CURRENT_OBJECT_NOT_TAKEABLE;
+ _opcodeMap[0x71] = OPCODE_TEST_NOT_ROOM_FLAG;
+ _opcodeMap[0x80] = OPCODE_INVENTORY;
+ _opcodeMap[0x81] = OPCODE_TAKE_OBJECT;
+ _opcodeMap[0x82] = OPCODE_MOVE_OBJECT_TO_ROOM;
+ _opcodeMap[0x84] = OPCODE_SAVE_ACTION;
+ _opcodeMap[0x85] = OPCODE_MOVE_TO_ROOM;
+ _opcodeMap[0x86] = OPCODE_VAR_ADD;
+ _opcodeMap[0x87] = OPCODE_SET_ROOM_DESCRIPTION;
+ _opcodeMap[0x89] = OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM;
+ _opcodeMap[0x8a] = OPCODE_VAR_SUB;
+ _opcodeMap[0x8b] = OPCODE_SET_OBJECT_DESCRIPTION;
+ _opcodeMap[0x8c] = OPCODE_MOVE;
+ _opcodeMap[0x8e] = OPCODE_PRINT;
+ _opcodeMap[0x95] = OPCODE_REMOVE_OBJECT;
+ _opcodeMap[0x99] = OPCODE_SET_FLAG;
+ _opcodeMap[0x92] = OPCODE_CALL_FUNC;
+ _opcodeMap[0x98] = OPCODE_TURN_TICK;
+ _opcodeMap[0x9d] = OPCODE_CLEAR_FLAG;
+ _opcodeMap[0x9e] = OPCODE_INVENTORY_ROOM;
+ _opcodeMap[0xa0] = OPCODE_TAKE_CURRENT_OBJECT;
+ _opcodeMap[0xa1] = OPCODE_SPECIAL;
+ _opcodeMap[0xa4] = OPCODE_DROP_CURRENT_OBJECT;
+ _opcodeMap[0xa2] = OPCODE_SET_ROOM_GRAPHIC;
+ _opcodeMap[0xb0] = OPCODE_REMOVE_CURRENT_OBJECT;
+ _opcodeMap[0xb1] = OPCODE_DO_VERB;
+ _opcodeMap[0xb9] = OPCODE_SET_STRING_REPLACEMENT;
+ _opcodeMap[0xbd] = OPCODE_VAR_INC;
+ _opcodeMap[0xc1] = OPCODE_VAR_DEC;
+ _opcodeMap[0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM;
+}
- /* Not reached */
- return NULL;
- }
+void OpcodeMap::loadVersion2() {
+ _opcodeMap[0x01] = OPCODE_HAVE_OBJECT;
+ _opcodeMap[0x04] = OPCODE_OR;
+ _opcodeMap[0x05] = OPCODE_IN_ROOM;
+ _opcodeMap[0x06] = OPCODE_VAR_EQ;
+ _opcodeMap[0x08] = OPCODE_CURRENT_IS_OBJECT;
+ _opcodeMap[0x09] = OPCODE_OBJECT_PRESENT;
+ _opcodeMap[0x0c] = OPCODE_ELSE;
+ _opcodeMap[0x11] = OPCODE_OBJECT_IS_NOWHERE;
+ _opcodeMap[0x14] = OPCODE_OBJECT_NOT_VALID;
+ _opcodeMap[0x19] = OPCODE_TEST_FLAG;
+ _opcodeMap[0x1d] = OPCODE_TEST_ROOM_FLAG;
+ _opcodeMap[0x20] = OPCODE_HAVE_CURRENT_OBJECT;
+ _opcodeMap[0x21] = OPCODE_OBJECT_PRESENT;
+ _opcodeMap[0x22] = OPCODE_OBJECT_IN_ROOM;
+ _opcodeMap[0x30] = OPCODE_CURRENT_OBJECT_PRESENT;
+ _opcodeMap[0x31] = OPCODE_TEST_ROOM_FLAG;
+ _opcodeMap[0x38] = OPCODE_INVENTORY_FULL;
+ _opcodeMap[0x41] = OPCODE_NOT_HAVE_OBJECT;
+ _opcodeMap[0x45] = OPCODE_NOT_IN_ROOM;
+ _opcodeMap[0x48] = OPCODE_CURRENT_OBJECT_IS_NOWHERE;
+ _opcodeMap[0x43] = OPCODE_OBJECT_NOT_IN_ROOM;
+ _opcodeMap[0x59] = OPCODE_TEST_NOT_FLAG;
+ _opcodeMap[0x5d] = OPCODE_TEST_NOT_ROOM_FLAG;
+ _opcodeMap[0x60] = OPCODE_NOT_HAVE_CURRENT_OBJECT;
+ _opcodeMap[0x61] = OPCODE_OBJECT_NOT_PRESENT;
+ _opcodeMap[0x70] = OPCODE_CURRENT_OBJECT_NOT_PRESENT;
+ _opcodeMap[0x74] = OPCODE_CURRENT_NOT_OBJECT;
+ _opcodeMap[0x80] = OPCODE_INVENTORY;
+ _opcodeMap[0x81] = OPCODE_TAKE_OBJECT;
+ _opcodeMap[0x82] = OPCODE_MOVE_OBJECT_TO_ROOM;
+ _opcodeMap[0x84] = OPCODE_SAVE_ACTION;
+ _opcodeMap[0x85] = OPCODE_MOVE_TO_ROOM;
+ _opcodeMap[0x86] = OPCODE_VAR_ADD;
+ _opcodeMap[0x87] = OPCODE_SET_ROOM_DESCRIPTION;
+ _opcodeMap[0x89] = OPCODE_SPECIAL;
+ _opcodeMap[0x8a] = OPCODE_VAR_SUB;
+ _opcodeMap[0x8b] = OPCODE_SET_OBJECT_DESCRIPTION;
+ _opcodeMap[0x8c] = OPCODE_MOVE;
+ _opcodeMap[0x8e] = OPCODE_PRINT;
+ _opcodeMap[0x8f] = OPCODE_SET_OBJECT_LONG_DESCRIPTION;
+ _opcodeMap[0x90] = OPCODE_WAIT_KEY;
+ _opcodeMap[0x92] = OPCODE_CALL_FUNC;
+ _opcodeMap[0x95] = OPCODE_REMOVE_OBJECT;
+ _opcodeMap[0x98] = OPCODE_TURN_TICK;
+ _opcodeMap[0x99] = OPCODE_SET_FLAG;
+ _opcodeMap[0x9d] = OPCODE_CLEAR_FLAG;
+ _opcodeMap[0x9e] = OPCODE_INVENTORY_ROOM;
+ _opcodeMap[0xa0] = OPCODE_TAKE_CURRENT_OBJECT;
+ _opcodeMap[0xa2] = OPCODE_SET_OBJECT_GRAPHIC;
+ _opcodeMap[0xb1] = OPCODE_DO_VERB;
+ _opcodeMap[0xb5] = OPCODE_DESCRIBE_CURRENT_OBJECT;
+ _opcodeMap[0xc1] = OPCODE_VAR_DEC;
+ _opcodeMap[0xc2] = OPCODE_SET_ROOM_GRAPHIC;
+ _opcodeMap[0xc5] = OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT;
+ _opcodeMap[0xc6] = OPCODE_SET_OBJECT_GRAPHIC;
+ _opcodeMap[0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM;
+ _opcodeMap[0xcd] = OPCODE_SET_STRING_REPLACEMENT;
+ _opcodeMap[0xd1] = OPCODE_MOVE_DIRECTION;
+ _opcodeMap[0xd5] = OPCODE_DRAW_ROOM;
+ _opcodeMap[0xd9] = OPCODE_DRAW_OBJECT;
+ _opcodeMap[0xdd] = OPCODE_VAR_INC;
+ _opcodeMap[0xe1] = OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM;
+ _opcodeMap[0xed] = OPCODE_REMOVE_OBJECT;
+ _opcodeMap[0xf0] = OPCODE_DROP_CURRENT_OBJECT;
+ _opcodeMap[0xfc] = OPCODE_REMOVE_CURRENT_OBJECT;
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/opcode_map.h b/engines/glk/comprehend/opcode_map.h
index 102a88dee6..909183ddb6 100644
--- a/engines/glk/comprehend/opcode_map.h
+++ b/engines/glk/comprehend/opcode_map.h
@@ -23,12 +23,32 @@
#ifndef GLK_COMPREHEND_OPCODE_MAP_H
#define GLK_COMPREHEND_OPCODE_MAP_H
-#include "glk/comprehend/game.h"
+#include "common/scummsys.h"
namespace Glk {
namespace Comprehend {
-uint8 *get_opcode_map(ComprehendGame *game);
+/*
+ * Version 2 of the Comprehend engine (OO-Topos) changes some of the opcode
+ * numbers and adds new opcodes. This class encapsulates a table to translate
+ * the opcodes used in the original games into a generic version used by the engine
+ *
+ * FIXME - unimplemented/unknown ocpodes:
+ *
+ * d5(obj): Make object visible. This will print a "you see: object" when the
+ * object is in the room.
+ */
+class OpcodeMap {
+public:
+ byte _opcodeMap[0x100];
+
+private:
+ void loadVersion1();
+ void loadVersion2();
+
+public:
+ void loadOpcodes(int version);
+};
} // namespace Comprehend
} // namespace Glk
Commit: e55aaa91da4a17d64801b30e604ac809dc598959
https://github.com/scummvm/scummvm/commit/e55aaa91da4a17d64801b30e604ac809dc598959
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Adding method to print text to text buffer
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 6b0c68507b..0ca0a020f1 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -167,6 +167,7 @@ void Comprehend::initialize() {
_graphicsWindow = (GraphicsWindow *)glk_window_open(
_textBufferWindow, winmethod_Above | winmethod_Proportional,
160, wintype_Graphics, 0);
+ glk_set_window(_textBufferWindow);
}
void Comprehend::deinitialize() {
@@ -187,5 +188,15 @@ ComprehendGame *Comprehend::createGame() {
error("Unknown game");
}
+void Comprehend::print(const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ Common::String msg = Common::String::vformat(fmt, argp);
+ va_end(argp);
+
+ glk_put_string_stream(glk_window_get_stream(_textBufferWindow),
+ msg.c_str());
+}
+
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index c961438d72..607d80d634 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -102,6 +102,8 @@ public:
Common::Error writeGameData(Common::WriteStream *ws) override {
return Common::kWritingFailed;
}
+
+ void print(const char *fmt, ...);
};
extern Comprehend *g_comprehend;
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index ef21951c9b..7b75567d01 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -38,11 +38,6 @@ struct Sentence {
size_t nr_words;
};
-struct WinSize {
- uint ws_col;
-};
-static WinSize console_winsize;
-
ComprehendGame::ComprehendGame() : _gameName(nullptr),
_shortName(nullptr),
_gameDataFile(nullptr),
@@ -73,7 +68,6 @@ int console_get_key(void) {
void console_println(ComprehendGame *game, const char *text) {
const char *replace, *word = nullptr, *p = text;
char bad_word[64];
- size_t line_length = 0;
int word_len = 0;
if (!text) {
@@ -86,7 +80,6 @@ void console_println(ComprehendGame *game, const char *text) {
case '\n':
word = NULL;
word_len = 0;
- line_length = 0;
printf("\n");
p++;
break;
@@ -126,26 +119,19 @@ void console_println(ComprehendGame *game, const char *text) {
if (!word || !word_len)
continue;
-
+#ifdef DEPRECATED
/* Print this word */
if (line_length + word_len > console_winsize.ws_col) {
/* Too long - insert a line break */
printf("\n");
line_length = 0;
}
-
- printf("%.*s", word_len, word);
- line_length += word_len;
+#endif
+ Common::String wordStr(word, word_len);
+ g_comprehend->print("%s", wordStr.c_str());
if (*p == ' ') {
- if (line_length >= console_winsize.ws_col) {
- /* Newline, don't print the space */
- printf("\n");
- line_length = 0;
- } else {
- printf(" ");
- line_length++;
- }
+ g_comprehend->print(" ");
p++;
/* Skip any double spaces */
@@ -154,7 +140,7 @@ void console_println(ComprehendGame *game, const char *text) {
}
}
- printf("\n");
+ g_comprehend->print("\n");
}
static Room *get_room(ComprehendGame *game, uint16 index) {
Commit: 51ff674d99df013a4891ce9d733d7605c240331d
https://github.com/scummvm/scummvm/commit/51ff674d99df013a4891ce9d733d7605c240331d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Adding method for reading text
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game_tr.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 0ca0a020f1..dccfc5a969 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -163,16 +163,16 @@ void Comprehend::runGame() {
}
void Comprehend::initialize() {
- _textBufferWindow = (TextBufferWindow *)glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
- _graphicsWindow = (GraphicsWindow *)glk_window_open(
- _textBufferWindow, winmethod_Above | winmethod_Proportional,
- 160, wintype_Graphics, 0);
- glk_set_window(_textBufferWindow);
+ _topWindow = (GraphicsWindow *)glk_window_open(0, 0, 0, wintype_Graphics, 1);
+ _bottomWindow = (TextBufferWindow *)glk_window_open(
+ _topWindow, winmethod_Below | winmethod_Fixed,
+ 80, wintype_TextBuffer, 0);
+ glk_set_window(_bottomWindow);
}
void Comprehend::deinitialize() {
- glk_window_close(_graphicsWindow);
- glk_window_close(_textBufferWindow);
+ glk_window_close(_topWindow);
+ glk_window_close(_bottomWindow);
}
ComprehendGame *Comprehend::createGame() {
@@ -194,9 +194,27 @@ void Comprehend::print(const char *fmt, ...) {
Common::String msg = Common::String::vformat(fmt, argp);
va_end(argp);
- glk_put_string_stream(glk_window_get_stream(_textBufferWindow),
+ glk_put_string_stream(glk_window_get_stream(_bottomWindow),
msg.c_str());
}
+void Comprehend::readLine(char *buffer, size_t maxLen) {
+ event_t ev;
+
+ glk_request_line_event(_bottomWindow, buffer, maxLen - 1, 0);
+
+ for (;;) {
+ glk_select(&ev);
+ if (ev.type == evtype_Quit) {
+ glk_cancel_line_event(_bottomWindow, &ev);
+ return;
+ } else if (ev.type == evtype_LineInput)
+ break;
+ }
+
+ buffer[ev.val1] = 0;
+}
+
+
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 607d80d634..3e76f07bc8 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -55,8 +55,8 @@ class Comprehend : public GlkAPI {
private:
int _saveSlot; ///< Save slot when loading savegame from launcher
public:
- GraphicsWindow *_graphicsWindow;
- TextBufferWindow *_textBufferWindow;
+ GraphicsWindow *_topWindow;
+ TextBufferWindow *_bottomWindow;
private:
/**
* Initialization code
@@ -103,7 +103,15 @@ public:
return Common::kWritingFailed;
}
+ /**
+ * Print string to the buffer window
+ */
void print(const char *fmt, ...);
+
+ /**
+ * Read an input line
+ */
+ void readLine(char *buffer, size_t maxLen);
};
extern Comprehend *g_comprehend;
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index fe2c0fb880..b014d9dec6 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -158,29 +158,12 @@ void TransylvaniaGame::handle_special_opcode(uint8 operand)
}
}
-static void read_string(char *buffer, size_t size)
-{
-#ifdef TODO
- char *p;
-
- printf("> ");
- fgets(buffer, size, stdin);
-
- /* Remove trailing newline */
- p = strchr(buffer, '\n');
- if (p)
- *p = '\0';
-#else
- error("TODO");
-#endif
-}
-
void TransylvaniaGame::before_game() {
char buffer[128];
- /* Welcome to Transylvania - sign your name */
+ // Welcome to Transylvania - sign your name
console_println(this, _strings.strings[0x20]);
- read_string(buffer, sizeof(buffer));
+ g_comprehend->readLine(buffer, sizeof(buffer));
/*
* Transylvania uses replace word 0 as the player's name, the game
@@ -195,9 +178,9 @@ void TransylvaniaGame::before_game() {
strlen(_replaceWords[0]),
"%s", buffer);
- /* And your next of kin - This isn't store by the game */
+ // And your next of kin - This isn't stored by the game
console_println(this, _strings.strings[0x21]);
- read_string(buffer, sizeof(buffer));
+ g_comprehend->readLine(buffer, sizeof(buffer));
}
} // namespace Comprehend
Commit: 7a88a18d472d38b3e52d3892e17ded8cbf4bcf72
https://github.com/scummvm/scummvm/commit/7a88a18d472d38b3e52d3892e17ded8cbf4bcf72
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Implement action line input
Changed paths:
engines/glk/comprehend/game.cpp
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 7b75567d01..14b1e42d5e 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -998,13 +998,12 @@ static void skip_non_whitespace(char **p) {
(*p)++;
}
-#ifdef TODO
static void handle_debug_command(ComprehendGame *game,
const char *line) {
int i;
if (strncmp(line, "quit", 4) == 0) {
- error("Quit");
+ g_comprehend->quitGame();
} else if (strncmp(line, "debug", 5) == 0) {
if (debugging_enabled())
@@ -1020,25 +1019,24 @@ static void handle_debug_command(ComprehendGame *game,
dump_game_data(game, DUMP_ROOMS);
} else if (strncmp(line, "dump state", 10) == 0) {
- printf("Current room: %.2x\n", game->current_room);
+ printf("Current room: %.2x\n", game->_currentRoom);
printf("Carry weight %d/%d\n\n",
- game->variable[VAR_INVENTORY_WEIGHT],
- game->variable[VAR_INVENTORY_LIMIT]);
+ game->_variables[VAR_INVENTORY_WEIGHT],
+ game->_variables[VAR_INVENTORY_LIMIT]);
printf("Flags:\n");
- for (i = 0; i < ARRAY_SIZE(game->flags); i++)
- printf(" [%.2x]: %d\n", i, game->flags[i]);
+ for (i = 0; i < ARRAY_SIZE(game->_flags); i++)
+ printf(" [%.2x]: %d\n", i, game->_flags[i]);
printf("\n");
printf("Variables:\n");
- for (i = 0; i < ARRAY_SIZE(game->variable); i++)
+ for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
printf(" [%.2x]: %5d (0x%.4x)\n",
- i, game->variable[i],
- game->variable[i]);
+ i, game->_variables[i],
+ game->_variables[i]);
printf("\n");
}
}
-#endif
static bool handle_sentence(ComprehendGame *game,
Sentence *sentence) {
@@ -1162,21 +1160,20 @@ static void after_turn(ComprehendGame *game) {
}
static void read_input(ComprehendGame *game) {
-#ifdef TODO
- sentence sentence;
+ Sentence sentence;
char *line = NULL, buffer[1024];
bool handled;
- if (game->ops->before_prompt)
- game->ops->before_prompt(game);
+ game->before_prompt();
before_turn(game);
- while (!line) {
- printf("> ");
- line = fgets(buffer, sizeof(buffer), stdin);
- }
+ g_comprehend->print("> ");
+ g_comprehend->readLine(buffer, sizeof(buffer));
+ if (g_comprehend->shouldQuit())
+ return;
// Re-comprehend special commands start with '!'
+ line = &buffer[0];
if (*line == '!') {
handle_debug_command(game, &line[1]);
return;
@@ -1196,9 +1193,6 @@ static void read_input(ComprehendGame *game) {
if (handled)
before_turn(game);
}
-#else
- error("TODO: read_input");
-#endif
}
void comprehend_play_game(ComprehendGame *game) {
Commit: 21462c57f67fbcb2ea47e5f8784d88e1e5be7f07
https://github.com/scummvm/scummvm/commit/21462c57f67fbcb2ea47e5f8784d88e1e5be7f07
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:09-07:00
Commit Message:
GLK: COMPREHEND: Creating debugger to hold dumping methods
Changed paths:
A engines/glk/comprehend/debugger.cpp
A engines/glk/comprehend/debugger.h
A engines/glk/comprehend/debugger_dumper.cpp
A engines/glk/comprehend/debugger_dumper.h
R engines/glk/comprehend/dump_game_data.cpp
R engines/glk/comprehend/dump_game_data.h
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/util.cpp
engines/glk/comprehend/util.h
engines/glk/glk.cpp
engines/glk/glk.h
engines/glk/module.mk
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index dccfc5a969..0ead807108 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -23,7 +23,7 @@
#include "glk/comprehend/comprehend.h"
#include "common/config-manager.h"
#include "common/translation.h"
-#include "glk/comprehend/dump_game_data.h"
+#include "glk/comprehend/debugger.h"
#include "glk/comprehend/game.h"
#include "glk/comprehend/game_cc.h"
#include "glk/comprehend/game_data.h"
@@ -37,25 +37,6 @@ namespace Comprehend {
Comprehend *g_comprehend;
-struct DumpOption {
- const char *const option;
- unsigned flag;
-};
-
-static const DumpOption dump_options[] = {
- {"strings", DUMP_STRINGS},
- {"extra-strings", DUMP_EXTRA_STRINGS},
- {"rooms", DUMP_ROOMS},
- {"items", DUMP_ITEMS},
- {"dictionary", DUMP_DICTIONARY},
- {"word-pairs", DUMP_WORD_PAIRS},
- {"actions", DUMP_ACTIONS},
- {"functions", DUMP_FUNCTIONS},
- {"replace-words", DUMP_REPLACE_WORDS},
- {"header", DUMP_HEADER},
- {"all", DUMP_ALL},
-};
-
#ifdef TODO
int main(int argc, char **argv) {
option long_opts[] = {
@@ -140,12 +121,14 @@ int main(int argc, char **argv) {
}
#endif
-Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
- _saveSlot(-1) {
+Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) :
+ GlkAPI(syst, gameDesc), _saveSlot(-1), _game(nullptr) {
g_comprehend = this;
}
Comprehend::~Comprehend() {
+ delete _game;
+
g_comprehend = nullptr;
}
@@ -153,12 +136,11 @@ void Comprehend::runGame() {
initialize();
// Lookup game
- ComprehendGame *game = createGame();
+ createGame();
- comprehend_load_game(game);
- comprehend_play_game(game);
+ comprehend_load_game(_game);
+ comprehend_play_game(_game);
- delete game;
deinitialize();
}
@@ -175,17 +157,21 @@ void Comprehend::deinitialize() {
glk_window_close(_bottomWindow);
}
-ComprehendGame *Comprehend::createGame() {
+void Comprehend::createDebugger() {
+ setDebugger(new Debugger());
+}
+
+void Comprehend::createGame() {
if (_gameDescription._gameId == "crimsoncrown")
- return new CrimsonCrownGame();
+ _game = new CrimsonCrownGame();
if (_gameDescription._gameId == "ootopis")
- return new OOToposGame();
+ _game = new OOToposGame();
if (_gameDescription._gameId == "talisman")
- return new OOToposGame();
+ _game = new OOToposGame();
if (_gameDescription._gameId == "transylvania")
- return new TransylvaniaGame();
-
- error("Unknown game");
+ _game = new TransylvaniaGame();
+ else
+ error("Unknown game");
}
void Comprehend::print(const char *fmt, ...) {
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 3e76f07bc8..3f1bee6eb6 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -57,6 +57,8 @@ private:
public:
GraphicsWindow *_topWindow;
TextBufferWindow *_bottomWindow;
+ ComprehendGame *_game;
+
private:
/**
* Initialization code
@@ -68,7 +70,15 @@ private:
*/
void deinitialize();
- ComprehendGame *createGame();
+ /**
+ * Create the debugger
+ */
+ void createDebugger() override;
+
+ /**
+ * Creates the appropriate game class
+ */
+ void createGame();
public:
/**
diff --git a/engines/glk/comprehend/dump_game_data.h b/engines/glk/comprehend/debugger.cpp
similarity index 59%
rename from engines/glk/comprehend/dump_game_data.h
rename to engines/glk/comprehend/debugger.cpp
index 311ff2b139..63d3e9f8d8 100644
--- a/engines/glk/comprehend/dump_game_data.h
+++ b/engines/glk/comprehend/debugger.cpp
@@ -20,34 +20,41 @@
*
*/
-#ifndef GLK_COMPREHEND_DUMP_GAME_DATA_H
-#define GLK_COMPREHEND_DUMP_GAME_DATA_H
+#include "glk/comprehend/debugger.h"
+#include "glk/comprehend/comprehend.h"
namespace Glk {
namespace Comprehend {
-class ComprehendGame;
-struct FunctionState;
-struct Instruction;
-
-#define DUMP_STRINGS (1 << 0)
-#define DUMP_EXTRA_STRINGS (1 << 1)
-#define DUMP_ROOMS (1 << 2)
-#define DUMP_ITEMS (1 << 3)
-#define DUMP_DICTIONARY (1 << 4)
-#define DUMP_WORD_PAIRS (1 << 5)
-#define DUMP_ACTIONS (1 << 6)
-#define DUMP_FUNCTIONS (1 << 7)
-#define DUMP_REPLACE_WORDS (1 << 8)
-#define DUMP_HEADER (1 << 9)
-#define DUMP_ALL (~0U)
-
-void dump_instruction(ComprehendGame *game,
- FunctionState *func_state,
- Instruction *instr);
-void dump_game_data(ComprehendGame *game, unsigned flags);
+Debugger *g_debugger;
+
+Debugger::Debugger() : Glk::Debugger() {
+ g_debugger = this;
+ registerCmd("dump", WRAP_METHOD(Debugger, cmdDump));
+}
+
+Debugger::~Debugger() {
+ g_debugger = nullptr;
+}
+
+void Debugger::print(const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ Common::String msg = Common::String::vformat(fmt, argp);
+ va_end(argp);
+
+ debugPrintf("%s", msg.c_str());
+}
+
+bool Debugger::cmdDump(int argc, const char **argv) {
+ Common::String param = (argc == 2) ? argv[1] : "";
+ ComprehendGame *game = g_comprehend->_game;
+
+ if (!dumpGameData(game, param))
+ debugPrintf("Unknown dump option\n");
+
+ return true;
+}
} // namespace Comprehend
} // namespace Glk
-
-#endif
diff --git a/engines/glk/comprehend/debugger.h b/engines/glk/comprehend/debugger.h
new file mode 100644
index 0000000000..d42a953d78
--- /dev/null
+++ b/engines/glk/comprehend/debugger.h
@@ -0,0 +1,52 @@
+/* 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_COMPREHEND_DEBUGGER_H
+#define GLK_COMPREHEND_DEBUGGER_H
+
+#include "glk/debugger.h"
+#include "glk/comprehend/debugger_dumper.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class Debugger : public Glk::Debugger, public DebuggerDumper {
+private:
+ /**
+ * Dump data
+ */
+ bool cmdDump(int argc, const char **argv);
+
+protected:
+ void print(const char *fmt, ...) override;
+
+public:
+ Debugger();
+ ~Debugger();
+};
+
+extern Debugger *g_debugger;
+
+} // End of namespace Comprehend
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
new file mode 100644
index 0000000000..362031efc6
--- /dev/null
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -0,0 +1,461 @@
+/* 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/comprehend/debugger_dumper.h"
+#include "glk/comprehend/dictionary.h"
+#include "glk/comprehend/game.h"
+#include "glk/comprehend/strings.h"
+#include "glk/comprehend/util.h"
+
+namespace Glk {
+namespace Comprehend {
+
+DebuggerDumper::DebuggerDumper() : _game(nullptr) {
+ _opcodes[OPCODE_UNKNOWN] = "unknown";
+
+ _opcodes[OPCODE_HAVE_OBJECT] = "have_object";
+ _opcodes[OPCODE_NOT_HAVE_OBJECT] = "not_have_object";
+ _opcodes[OPCODE_HAVE_CURRENT_OBJECT] = "have_current_object";
+ _opcodes[OPCODE_NOT_HAVE_CURRENT_OBJECT] = "not_have_current_object";
+
+ _opcodes[OPCODE_OBJECT_IS_NOT_NOWHERE] = "object_is_not_nowhere";
+
+ _opcodes[OPCODE_CURRENT_OBJECT_TAKEABLE] = "current_object_takeable";
+ _opcodes[OPCODE_CURRENT_OBJECT_NOT_TAKEABLE] = "current_object_not_takeable";
+
+ _opcodes[OPCODE_CURRENT_OBJECT_IS_NOWHERE] = "current_object_is_nowhere";
+
+ _opcodes[OPCODE_CURRENT_OBJECT_NOT_PRESENT] = "current_object_not_present";
+
+ _opcodes[OPCODE_TAKE_OBJECT] = "take_object";
+ _opcodes[OPCODE_TAKE_CURRENT_OBJECT] = "take_current_object";
+ _opcodes[OPCODE_DROP_OBJECT] = "drop_object";
+ _opcodes[OPCODE_DROP_CURRENT_OBJECT] = "drop_current_object";
+
+ _opcodes[OPCODE_OR] = "or";
+ _opcodes[OPCODE_IN_ROOM] = "in_room";
+ _opcodes[OPCODE_VAR_EQ] = "var_eq";
+ _opcodes[OPCODE_OBJECT_NOT_VALID] = "object_not_valid";
+ _opcodes[OPCODE_INVENTORY_FULL] = "inventory_full";
+ _opcodes[OPCODE_OBJECT_PRESENT] = "object_present";
+ _opcodes[OPCODE_ELSE] = "else";
+ _opcodes[OPCODE_OBJECT_IN_ROOM] = "object_in_room";
+ _opcodes[OPCODE_TEST_FLAG] = "test_flag";
+ _opcodes[OPCODE_CURRENT_OBJECT_IN_ROOM] = "current_object_in_room";
+ _opcodes[OPCODE_CURRENT_OBJECT_PRESENT] = "current_object_present";
+ _opcodes[OPCODE_TEST_ROOM_FLAG] = "test_room_flag";
+ _opcodes[OPCODE_NOT_IN_ROOM] = "not_in_room";
+ _opcodes[OPCODE_OBJECT_NOT_PRESENT] = "object_not_present";
+ _opcodes[OPCODE_OBJECT_NOT_IN_ROOM] = "object_not_in_room";
+ _opcodes[OPCODE_TEST_NOT_FLAG] = "test_not_flag";
+ _opcodes[OPCODE_OBJECT_IS_NOWHERE] = "object_is_nowhere";
+ _opcodes[OPCODE_TEST_NOT_ROOM_FLAG] = "test_not_room_flag";
+ _opcodes[OPCODE_INVENTORY] = "inventory";
+ _opcodes[OPCODE_MOVE_OBJECT_TO_ROOM] = "move_object_to_room";
+ _opcodes[OPCODE_SAVE_ACTION] = "save_action";
+ _opcodes[OPCODE_MOVE_TO_ROOM] = "move_to_room";
+ _opcodes[OPCODE_VAR_ADD] = "var_add";
+ _opcodes[OPCODE_SET_ROOM_DESCRIPTION] = "set_room_description";
+ _opcodes[OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM] = "move_object_to_current_room";
+ _opcodes[OPCODE_VAR_SUB] = "var_sub";
+ _opcodes[OPCODE_SET_OBJECT_DESCRIPTION] = "set_object_description";
+ _opcodes[OPCODE_SET_OBJECT_LONG_DESCRIPTION] = "set_object_long_description";
+ _opcodes[OPCODE_MOVE] = "move";
+ _opcodes[OPCODE_PRINT] = "print";
+ _opcodes[OPCODE_REMOVE_OBJECT] = "remove_object";
+ _opcodes[OPCODE_SET_FLAG] = "set_flag";
+ _opcodes[OPCODE_CALL_FUNC] = "call_func";
+ _opcodes[OPCODE_TURN_TICK] = "turn_tick";
+ _opcodes[OPCODE_CLEAR_FLAG] = "clear_flag";
+ _opcodes[OPCODE_INVENTORY_ROOM] = "inventory_room";
+ _opcodes[OPCODE_SPECIAL] = "special";
+ _opcodes[OPCODE_SET_ROOM_GRAPHIC] = "set_room_graphic";
+ _opcodes[OPCODE_SET_OBJECT_GRAPHIC] = "set_object_graphic";
+ _opcodes[OPCODE_REMOVE_CURRENT_OBJECT] = "remove_current_object";
+ _opcodes[OPCODE_DO_VERB] = "do_verb";
+ _opcodes[OPCODE_VAR_INC] = "var_inc";
+ _opcodes[OPCODE_VAR_DEC] = "var_dec";
+ _opcodes[OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM] = "move_current_object_to_room";
+ _opcodes[OPCODE_DESCRIBE_CURRENT_OBJECT] = "describe_current_object";
+ _opcodes[OPCODE_SET_STRING_REPLACEMENT] = "set_string_replacement";
+ _opcodes[OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT] = "set_current_noun_string_replacement";
+ _opcodes[OPCODE_CURRENT_NOT_OBJECT] = "current_not_object";
+ _opcodes[OPCODE_CURRENT_IS_OBJECT] = "current_is_object";
+ _opcodes[OPCODE_DRAW_ROOM] = "draw_room";
+ _opcodes[OPCODE_DRAW_OBJECT] = "draw_object";
+ _opcodes[OPCODE_WAIT_KEY] = "wait_key";
+}
+
+Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
+ FunctionState *func_state, Instruction *instr) {
+ uint i;
+ int str_index, str_table;
+ uint8 *opcode_map, opcode;
+ Common::String line;
+
+ if (func_state)
+ line = Common::String::format("[or=%d,and=%d,test=%d,else=%d]",
+ func_state->or_count, func_state->_and,
+ func_state->test_result, func_state->else_result);
+
+ opcode_map = game->_opcodeMap;
+ opcode = opcode_map[instr->opcode];
+
+ line += " [%.2x] ", instr->opcode;
+ if (_opcodes.contains(opcode))
+ line += _opcodes[opcode];
+ else
+ line += "unknown";
+
+ if (instr->nr_operands) {
+ line += "(";
+ for (i = 0; i < instr->nr_operands; i++)
+ line += "%.2x%s", instr->operand[i],
+ i == instr->nr_operands - 1 ? ")" : ", ";
+ }
+
+ switch (opcode) {
+ case OPCODE_PRINT:
+ case OPCODE_SET_ROOM_DESCRIPTION:
+ case OPCODE_SET_OBJECT_DESCRIPTION:
+ case OPCODE_SET_OBJECT_LONG_DESCRIPTION:
+
+ if (opcode == OPCODE_PRINT) {
+ str_index = instr->operand[0];
+ str_table = instr->operand[1];
+ } else {
+ str_index = instr->operand[1];
+ str_table = instr->operand[2];
+ }
+
+ line += " %s", instr_lookup_string(game, str_index, str_table);
+ break;
+
+ case OPCODE_SET_STRING_REPLACEMENT:
+ line += " %s", game->_replaceWords[instr->operand[0] - 1];
+ break;
+ }
+
+ line += "\n";
+ return line;
+}
+
+void DebuggerDumper::dumpFunctions() {
+ Function *func;
+ uint i, j;
+
+ print("Functions (%u entries)\n", (uint)_game->_nr_functions);
+ for (i = 0; i < _game->_nr_functions; i++) {
+ func = &_game->_functions[i];
+
+ print("[%.4x] (%u instructions)\n", i, (uint)func->nr_instructions);
+ for (j = 0; j < func->nr_instructions; j++) {
+ Common::String line = dumpInstruction(_game, NULL, &func->instructions[j]);
+ print("%s", line.c_str());
+ }
+ print("\n");
+ }
+}
+
+void DebuggerDumper::dumpActionTable() {
+ Action *action;
+ Word *word;
+ uint i, j;
+
+ print("Action table (%u entries)\n", (uint)_game->_nr_actions);
+ for (i = 0; i < _game->_nr_actions; i++) {
+ action = &_game->_actions[i];
+
+ print("(");
+ for (j = 0; j < 4; j++) {
+ if (j < action->nr_words) {
+ switch (action->word_type[j]) {
+ case WORD_TYPE_VERB:
+ print("v");
+ break;
+ case WORD_TYPE_JOIN:
+ print("j");
+ break;
+ case WORD_TYPE_NOUN_MASK:
+ print("n");
+ break;
+ default:
+ print("?");
+ break;
+ }
+ } else {
+ print(" ");
+ }
+ }
+
+ print(") [%.4x] ", i);
+
+ for (j = 0; j < action->nr_words; j++)
+ print("%.2x:%.2x ",
+ action->word[j], action->word_type[j]);
+
+ print("| ");
+
+ for (j = 0; j < action->nr_words; j++) {
+ word = find_dict_word_by_index(_game, action->word[j],
+ action->word_type[j]);
+ if (word)
+ print("%-6s ", word->_word);
+ else
+ print("%.2x:%.2x ", action->word[j],
+ action->word_type[j]);
+ }
+
+ print("-> %.4x\n", action->function);
+ }
+}
+
+int DebuggerDumper::wordIndexCompare(const void *a, const void *b) {
+ const Word *word_a = (const Word *)a, *word_b = (const Word *)b;
+
+ if (word_a->_index > word_b->_index)
+ return 1;
+ if (word_a->_index < word_b->_index)
+ return -1;
+ return 0;
+}
+
+void DebuggerDumper::dumpDictionary() {
+ Word *dictionary;
+ Word *words;
+ uint i;
+
+ /* Sort the dictionary by index */
+ dictionary = (Word *)xmalloc(sizeof(*words) * _game->_nr_words);
+ memcpy(dictionary, _game->_words,
+ sizeof(*words) * _game->_nr_words);
+ qsort(dictionary, _game->_nr_words, sizeof(*words),
+ wordIndexCompare);
+
+ print("Dictionary (%u words)\n", (uint)_game->_nr_words);
+ for (i = 0; i < _game->_nr_words; i++) {
+ words = &dictionary[i];
+ print(" [%.2x] %.2x %s\n", words->_index, words->_type,
+ words->_word);
+ }
+
+ free(dictionary);
+}
+
+void DebuggerDumper::dumpWordMap() {
+ Word *word[3];
+ char str[3][6];
+ WordMap *map;
+ uint i, j;
+
+ print("Word pairs (%u entries)\n", (uint)_game->_nr_word_maps);
+ for (i = 0; i < _game->_nr_word_maps; i++) {
+ map = &_game->_wordMaps[i];
+
+ for (j = 0; j < 3; j++) {
+ word[j] = dict_find_word_by_index_type(
+ _game, map->word[j].index, map->word[j].type);
+ if (word[j])
+ snprintf(str[j], sizeof(str[j]),
+ "%s", word[j]->_word);
+ else
+ snprintf(str[j], sizeof(str[j]), "%.2x:%.2x ",
+ map->word[j].index, map->word[j].type);
+ }
+
+ print(" [%.2x] %-6s %-6s -> %-6s\n",
+ i, str[0], str[1], str[2]);
+ }
+}
+
+void DebuggerDumper::dumpRooms() {
+ Room *room;
+ uint i;
+
+ /* Room zero acts as the players inventory */
+ print("Rooms (%u entries)\n", (uint)_game->_nr_rooms);
+ for (i = 1; i <= _game->_nr_rooms; i++) {
+ room = &_game->_rooms[i];
+
+ print(" [%.2x] flags=%.2x, graphic=%.2x\n",
+ i, room->flags, room->graphic);
+ print(" %s\n", string_lookup(_game, room->string_desc));
+ print(" n: %.2x s: %.2x e: %.2x w: %.2x\n",
+ room->direction[DIRECTION_NORTH],
+ room->direction[DIRECTION_SOUTH],
+ room->direction[DIRECTION_EAST],
+ room->direction[DIRECTION_WEST]);
+ print(" u: %.2x d: %.2x i: %.2x o: %.2x\n",
+ room->direction[DIRECTION_UP],
+ room->direction[DIRECTION_DOWN],
+ room->direction[DIRECTION_IN],
+ room->direction[DIRECTION_OUT]);
+ print("\n");
+ }
+}
+
+void DebuggerDumper::dumpItems() {
+ Item *item;
+ uint i, j;
+
+ print("Items (%u entries)\n", (uint)_game->_header.nr_items);
+ for (i = 0; i < _game->_header.nr_items; i++) {
+ item = &_game->_items[i];
+
+ print(" [%.2x] %s\n", i + 1,
+ item->string_desc ? string_lookup(_game, item->string_desc) : "");
+ if (_game->_comprehendVersion == 2)
+ print(" long desc: %s\n",
+ string_lookup(_game, item->long_string));
+
+ print(" words: ");
+ for (j = 0; j < _game->_nr_words; j++)
+ if (_game->_words[j]._index == item->word &&
+ (_game->_words[j]._type & WORD_TYPE_NOUN_MASK))
+ print("%s ", _game->_words[j]._word);
+ print("\n");
+ print(" flags=%.2x (takeable=%d, weight=%d)\n",
+ item->flags, !!(item->flags & ITEMF_CAN_TAKE),
+ (item->flags & ITEMF_WEIGHT_MASK));
+ print(" room=%.2x, graphic=%.2x\n",
+ item->room, item->graphic);
+ print("\n");
+ }
+}
+
+void DebuggerDumper::dumpStringTable(StringTable *table) {
+ uint i;
+
+ for (i = 0; i < table->nr_strings; i++)
+ print("[%.4x] %s\n", i, table->strings[i]);
+}
+
+void DebuggerDumper::dumpGameDataStrings() {
+ print("Main string table (%u entries)\n",
+ (uint)_game->_strings.nr_strings);
+ dumpStringTable(&_game->_strings);
+}
+
+void DebuggerDumper::dumpExtraStrings() {
+ print("Extra strings (%u entries)\n",
+ (uint)_game->_strings2.nr_strings);
+ dumpStringTable(&_game->_strings2);
+}
+
+void DebuggerDumper::dumpReplaceWords() {
+ uint i;
+
+ print("Replacement words (%u entries)\n",
+ (uint)_game->_nr_replace_words);
+ for (i = 0; i < _game->_nr_replace_words; i++)
+ print(" [%.2x] %s\n", i + 1, _game->_replaceWords[i]);
+}
+
+void DebuggerDumper::dumpHeader() {
+ GameHeader *header = &_game->_header;
+ uint16 *dir_table = header->room_direction_table;
+
+ print("Game header:\n");
+ print(" magic: %.4x\n", header->magic);
+ print(" action(vvnn): %.4x\n", header->addr_actions_vvnn);
+ print(" actions(?):\n");
+ print(" actions(vnjn): %.4x\n", header->addr_actions_vnjn);
+ print(" actions(vjn): %.4x\n", header->addr_actions_vjn);
+ print(" actions(vdn): %.4x\n", header->addr_actions_vdn);
+ print(" actions(vnn): %.4x\n", header->addr_actions_vnn);
+ print(" actions(vn): %.4x\n", header->addr_actions_vn);
+ print(" actions(v): %.4x\n", header->addr_actions_v);
+ print(" functions: %.4x\n", header->addr_vm);
+ print(" dictionary: %.4x\n", header->addr_dictionary);
+ print(" word map pairs: %.4x\n", header->addr_word_map);
+ print(" room desc strings: %.4x\n", header->room_desc_table);
+ print(" room north: %.4x\n", dir_table[DIRECTION_NORTH]);
+ print(" room south: %.4x\n", dir_table[DIRECTION_SOUTH]);
+ print(" room east: %.4x\n", dir_table[DIRECTION_EAST]);
+ print(" room west: %.4x\n", dir_table[DIRECTION_WEST]);
+ print(" room up: %.4x\n", dir_table[DIRECTION_UP]);
+ print(" room down: %.4x\n", dir_table[DIRECTION_DOWN]);
+ print(" room in: %.4x\n", dir_table[DIRECTION_IN]);
+ print(" room out: %.4x\n", dir_table[DIRECTION_OUT]);
+ print(" room flags: %.4x\n", header->room_flags_table);
+ print(" room images: %.4x\n", header->room_graphics_table);
+ print(" item locations: %.4x\n", header->addr_item_locations);
+ print(" item flags: %.4x\n", header->addr_item_flags);
+ print(" item words: %.4x\n", header->addr_item_word);
+ print(" item desc strings: %.4x\n", header->addr_item_strings);
+ print(" item images: %.4x\n", header->addr_item_graphics);
+ print(" string table: %.4x\n", header->addr_strings);
+ print(" string table end: %.4x\n", header->addr_strings_end);
+}
+
+void DebuggerDumper::dumpState() {
+ print("Current room: %.2x\n", _game->_currentRoom);
+ print("Carry weight %d/%d\n\n",
+ _game->_variables[VAR_INVENTORY_WEIGHT],
+ _game->_variables[VAR_INVENTORY_LIMIT]);
+
+ print("Flags:\n");
+ for (uint i = 0; i < ARRAY_SIZE(_game->_flags); i++)
+ print(" [%.2x]: %d\n", i, _game->_flags[i]);
+ print("\n");
+
+ print("Variables:\n");
+ for (uint i = 0; i < ARRAY_SIZE(_game->_variables); i++)
+ print(" [%.2x]: %5d (0x%.4x)\n",
+ i, _game->_variables[i],
+ _game->_variables[i]);
+ print("\n");
+}
+
+bool DebuggerDumper::dumpGameData(ComprehendGame *game, const Common::String &type) {
+ _game = game;
+
+ if (type == "header")
+ dumpHeader();
+ else if (type == "strings")
+ dumpGameDataStrings();
+ else if (type == "extra_strings")
+ dumpExtraStrings();
+ else if (type == "rooms")
+ dumpRooms();
+ else if (type == "items")
+ dumpItems();
+ else if (type == "dictionary")
+ dumpDictionary();
+ else if (type == "word_map")
+ dumpWordMap();
+ else if (type == "actions")
+ dumpActionTable();
+ else if (type == "functions")
+ dumpFunctions();
+ else if (type == "replace_words")
+ dumpReplaceWords();
+ else if (type == "state")
+ dumpState();
+ else
+ return false;
+
+ return true;
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/debugger_dumper.h b/engines/glk/comprehend/debugger_dumper.h
new file mode 100644
index 0000000000..add248e94d
--- /dev/null
+++ b/engines/glk/comprehend/debugger_dumper.h
@@ -0,0 +1,74 @@
+/* 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_COMPREHEND_DEBUGGER_DUMPER_H
+#define GLK_COMPREHEND_DEBUGGER_DUMPER_H
+
+#include "common/hashmap.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class ComprehendGame;
+struct FunctionState;
+struct Instruction;
+struct StringTable;
+
+class DebuggerDumper {
+private:
+ Common::HashMap<byte, Common::String> _opcodes;
+ ComprehendGame *_game;
+
+private:
+ void dumpFunctions();
+ void dumpActionTable();
+ static int wordIndexCompare(const void *a, const void *b);
+ void dumpDictionary();
+ void dumpWordMap();
+ void dumpRooms();
+ void dumpItems();
+ void dumpStringTable(StringTable *table);
+ void dumpGameDataStrings();
+ void dumpExtraStrings();
+ void dumpReplaceWords();
+ void dumpHeader();
+ void dumpState();
+
+protected:
+ /**
+ * Prints out dumped text
+ */
+ virtual void print(const char *fmt, ...) = 0;
+
+public:
+ DebuggerDumper();
+
+ Common::String dumpInstruction(ComprehendGame *game,
+ FunctionState *func_state, Instruction *instr);
+
+ bool dumpGameData(ComprehendGame *game, const Common::String &type);
+};
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/dump_game_data.cpp b/engines/glk/comprehend/dump_game_data.cpp
deleted file mode 100644
index 93ef85fe8f..0000000000
--- a/engines/glk/comprehend/dump_game_data.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/* 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/comprehend/comprehend.h"
-#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/dump_game_data.h"
-#include "glk/comprehend/dictionary.h"
-#include "glk/comprehend/file_buf.h"
-#include "glk/comprehend/strings.h"
-#include "glk/comprehend/game.h"
-#include "glk/comprehend/util.h"
-#include "glk/comprehend/opcode_map.h"
-
-namespace Glk {
-namespace Comprehend {
-
-static const char *opcode_names[] = {
-#ifdef TODO
- [OPCODE_UNKNOWN] = "unknown",
-
- [OPCODE_HAVE_OBJECT] = "have_object",
- [OPCODE_NOT_HAVE_OBJECT] = "not_have_object",
- [OPCODE_HAVE_CURRENT_OBJECT] = "have_current_object",
- [OPCODE_NOT_HAVE_CURRENT_OBJECT] = "not_have_current_object",
-
- [OPCODE_OBJECT_IS_NOT_NOWHERE] = "object_is_not_nowhere",
-
- [OPCODE_CURRENT_OBJECT_TAKEABLE] = "current_object_takeable",
- [OPCODE_CURRENT_OBJECT_NOT_TAKEABLE] = "current_object_not_takeable",
-
- [OPCODE_CURRENT_OBJECT_IS_NOWHERE] = "current_object_is_nowhere",
-
- [OPCODE_CURRENT_OBJECT_NOT_PRESENT] = "current_object_not_present",
-
- [OPCODE_TAKE_OBJECT] = "take_object",
- [OPCODE_TAKE_CURRENT_OBJECT] = "take_current_object",
- [OPCODE_DROP_OBJECT] = "drop_object",
- [OPCODE_DROP_CURRENT_OBJECT] = "drop_current_object",
-
- [OPCODE_OR] = "or",
- [OPCODE_IN_ROOM] = "in_room",
- [OPCODE_VAR_EQ] = "var_eq",
- [OPCODE_OBJECT_NOT_VALID] = "object_not_valid",
- [OPCODE_INVENTORY_FULL] = "inventory_full",
- [OPCODE_OBJECT_PRESENT] = "object_present",
- [OPCODE_ELSE] = "else",
- [OPCODE_OBJECT_IN_ROOM] = "object_in_room",
- [OPCODE_TEST_FLAG] = "test_flag",
- [OPCODE_CURRENT_OBJECT_IN_ROOM] = "current_object_in_room",
- [OPCODE_CURRENT_OBJECT_PRESENT] = "current_object_present",
- [OPCODE_TEST_ROOM_FLAG] = "test_room_flag",
- [OPCODE_NOT_IN_ROOM] = "not_in_room",
- [OPCODE_OBJECT_NOT_PRESENT] = "object_not_present",
- [OPCODE_OBJECT_NOT_IN_ROOM] = "object_not_in_room",
- [OPCODE_TEST_NOT_FLAG] = "test_not_flag",
- [OPCODE_OBJECT_IS_NOWHERE] = "object_is_nowhere",
- [OPCODE_TEST_NOT_ROOM_FLAG] = "test_not_room_flag",
- [OPCODE_INVENTORY] = "inventory",
- [OPCODE_MOVE_OBJECT_TO_ROOM] = "move_object_to_room",
- [OPCODE_SAVE_ACTION] = "save_action",
- [OPCODE_MOVE_TO_ROOM] = "move_to_room",
- [OPCODE_VAR_ADD] = "var_add",
- [OPCODE_SET_ROOM_DESCRIPTION] = "set_room_description",
- [OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM] = "move_object_to_current_room",
- [OPCODE_VAR_SUB] = "var_sub",
- [OPCODE_SET_OBJECT_DESCRIPTION] = "set_object_description",
- [OPCODE_SET_OBJECT_LONG_DESCRIPTION] = "set_object_long_description",
- [OPCODE_MOVE] = "move",
- [OPCODE_PRINT] = "print",
- [OPCODE_REMOVE_OBJECT] = "remove_object",
- [OPCODE_SET_FLAG] = "set_flag",
- [OPCODE_CALL_FUNC] = "call_func",
- [OPCODE_TURN_TICK] = "turn_tick",
- [OPCODE_CLEAR_FLAG] = "clear_flag",
- [OPCODE_INVENTORY_ROOM] = "inventory_room",
- [OPCODE_SPECIAL] = "special",
- [OPCODE_SET_ROOM_GRAPHIC] = "set_room_graphic",
- [OPCODE_SET_OBJECT_GRAPHIC] = "set_object_graphic",
- [OPCODE_REMOVE_CURRENT_OBJECT] = "remove_current_object",
- [OPCODE_DO_VERB] = "do_verb",
- [OPCODE_VAR_INC] = "var_inc",
- [OPCODE_VAR_DEC] = "var_dec",
- [OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM] = "move_current_object_to_room",
- [OPCODE_DESCRIBE_CURRENT_OBJECT] = "describe_current_object",
- [OPCODE_SET_STRING_REPLACEMENT] = "set_string_replacement",
- [OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT] = "set_current_noun_string_replacement",
- [OPCODE_CURRENT_NOT_OBJECT] = "current_not_object",
- [OPCODE_CURRENT_IS_OBJECT] = "current_is_object",
- [OPCODE_DRAW_ROOM] = "draw_room",
- [OPCODE_DRAW_OBJECT] = "draw_object",
- [OPCODE_WAIT_KEY] = "wait_key",
-#else
- "TODO"
-#endif
-};
-
-void dump_instruction(ComprehendGame *game,
- FunctionState *func_state,
- Instruction *instr)
-{
- uint i;
- int str_index, str_table;
- uint8 *opcode_map, opcode;
-
- if (func_state)
- debugN("[or=%d,and=%d,test=%d,else=%d]",
- func_state->or_count, func_state->_and,
- func_state->test_result, func_state->else_result);
-
- opcode_map = game->_opcodeMap;
- opcode = opcode_map[instr->opcode];
-
- debugN(" [%.2x] ", instr->opcode);
- if (opcode < ARRAY_SIZE(opcode_names) && opcode_names[opcode])
- debugN("%s", opcode_names[opcode]);
- else
- debugN("unknown");
-
- if (instr->nr_operands) {
- debugN("(");
- for (i = 0; i < instr->nr_operands; i++)
- debugN("%.2x%s", instr->operand[i],
- i == instr->nr_operands - 1 ? ")" : ", ");
- }
-
- switch (opcode) {
- case OPCODE_PRINT:
- case OPCODE_SET_ROOM_DESCRIPTION:
- case OPCODE_SET_OBJECT_DESCRIPTION:
- case OPCODE_SET_OBJECT_LONG_DESCRIPTION:
-
- if (opcode == OPCODE_PRINT) {
- str_index = instr->operand[0];
- str_table = instr->operand[1];
- } else {
- str_index = instr->operand[1];
- str_table = instr->operand[2];
- }
-
- debugN(" %s", instr_lookup_string(game, str_index, str_table));
- break;
-
- case OPCODE_SET_STRING_REPLACEMENT:
- debugN(" %s", game->_replaceWords[instr->operand[0] - 1]);
- break;
- }
-
- debugN("\n");
-}
-
-static void dump_functions(ComprehendGame *game)
-{
- Function *func;
- uint i, j;
-
- debugN("Functions (%u entries)\n", (uint)game->_nr_functions);
- for (i = 0; i < game->_nr_functions; i++) {
- func = &game->_functions[i];
-
- debugN("[%.4x] (%u instructions)\n", i, (uint)func->nr_instructions);
- for (j = 0; j < func->nr_instructions; j++)
- dump_instruction(game, NULL, &func->instructions[j]);
- debugN("\n");
- }
-}
-
-static void dump_action_table(ComprehendGame *game)
-{
- Action *action;
- Word *word;
- uint i, j;
-
- debugN("Action table (%u entries)\n", (uint)game->_nr_actions);
- for (i = 0; i < game->_nr_actions; i++) {
- action = &game->_actions[i];
-
- debugN("(");
- for (j = 0; j < 4; j++) {
- if (j < action->nr_words) {
- switch (action->word_type[j]) {
- case WORD_TYPE_VERB: debugN("v"); break;
- case WORD_TYPE_JOIN: debugN("j"); break;
- case WORD_TYPE_NOUN_MASK: debugN("n"); break;
- default: debugN("?"); break;
- }
- } else {
- debugN(" ");
- }
- }
-
- debugN(") [%.4x] ", i );
-
- for (j = 0; j < action->nr_words; j++)
- debugN("%.2x:%.2x ",
- action->word[j], action->word_type[j]);
-
- debugN("| ");
-
- for (j = 0; j < action->nr_words; j++) {
- word = find_dict_word_by_index(game, action->word[j],
- action->word_type[j]);
- if (word)
- debugN("%-6s ", word->_word);
- else
- debugN("%.2x:%.2x ", action->word[j],
- action->word_type[j]);
- }
-
- debugN("-> %.4x\n", action->function);
- }
-}
-
-static int word_index_compare(const void *a, const void *b)
-{
- const Word *word_a = (const Word *)a, *word_b = (const Word *)b;
-
- if (word_a->_index > word_b->_index)
- return 1;
- if (word_a->_index < word_b->_index)
- return -1;
- return 0;
-}
-
-static void dump_dictionary(ComprehendGame *game)
-{
- Word *dictionary;
- Word *words;
- uint i;
-
- /* Sort the dictionary by index */
- dictionary = (Word *)xmalloc(sizeof(*words) * game->_nr_words);
- memcpy(dictionary, game->_words,
- sizeof(*words) * game->_nr_words);
- qsort(dictionary, game->_nr_words, sizeof(*words),
- word_index_compare);
-
- debugN("Dictionary (%u words)\n", (uint)game->_nr_words);
- for (i = 0; i < game->_nr_words; i++) {
- words = &dictionary[i];
- debugN(" [%.2x] %.2x %s\n", words->_index, words->_type,
- words->_word);
- }
-
- free(dictionary);
-}
-
-static void dump_word_map(ComprehendGame *game)
-{
- Word *word[3];
- char str[3][6];
- WordMap *map;
- uint i, j;
-
- debugN("Word pairs (%u entries)\n", (uint)game->_nr_word_maps);
- for (i = 0; i < game->_nr_word_maps; i++) {
- map = &game->_wordMaps[i];
-
- for (j = 0; j < 3; j++) {
- word[j] = dict_find_word_by_index_type(
- game, map->word[j].index, map->word[j].type);
- if (word[j])
- snprintf(str[j], sizeof(str[j]),
- "%s", word[j]->_word);
- else
- snprintf(str[j], sizeof(str[j]), "%.2x:%.2x ",
- map->word[j].index, map->word[j].type);
- }
-
- debugN(" [%.2x] %-6s %-6s -> %-6s\n",
- i, str[0], str[1], str[2]);
- }
-}
-
-static void dump_rooms(ComprehendGame *game)
-{
- Room *room;
- uint i;
-
- /* Room zero acts as the players inventory */
- debugN("Rooms (%u entries)\n", (uint)game->_nr_rooms);
- for (i = 1; i <= game->_nr_rooms; i++) {
- room = &game->_rooms[i];
-
- debugN(" [%.2x] flags=%.2x, graphic=%.2x\n",
- i, room->flags, room->graphic);
- debugN(" %s\n", string_lookup(game, room->string_desc));
- debugN(" n: %.2x s: %.2x e: %.2x w: %.2x\n",
- room->direction[DIRECTION_NORTH],
- room->direction[DIRECTION_SOUTH],
- room->direction[DIRECTION_EAST],
- room->direction[DIRECTION_WEST]);
- debugN(" u: %.2x d: %.2x i: %.2x o: %.2x\n",
- room->direction[DIRECTION_UP],
- room->direction[DIRECTION_DOWN],
- room->direction[DIRECTION_IN],
- room->direction[DIRECTION_OUT]);
- debugN("\n");
- }
-}
-
-static void dump_items(ComprehendGame *game)
-{
- Item *item;
- uint i, j;
-
- debugN("Items (%u entries)\n", (uint)game->_header.nr_items);
- for (i = 0; i < game->_header.nr_items; i++) {
- item = &game->_items[i];
-
- debugN(" [%.2x] %s\n", i + 1,
- item->string_desc ?
- string_lookup(game, item->string_desc) : "");
- if (game->_comprehendVersion == 2)
- debugN(" long desc: %s\n",
- string_lookup(game, item->long_string));
-
- debugN(" words: ");
- for (j = 0; j < game->_nr_words; j++)
- if (game->_words[j]._index == item->word &&
- (game->_words[j]._type & WORD_TYPE_NOUN_MASK))
- debugN("%s ", game->_words[j]._word);
- debugN("\n");
- debugN(" flags=%.2x (takeable=%d, weight=%d)\n",
- item->flags, !!(item->flags & ITEMF_CAN_TAKE),
- (item->flags & ITEMF_WEIGHT_MASK));
- debugN(" room=%.2x, graphic=%.2x\n",
- item->room, item->graphic);
- debugN("\n");
- }
-}
-
-static void dump_string_table(StringTable *table)
-{
- uint i;
-
- for (i = 0; i < table->nr_strings; i++)
- debugN("[%.4x] %s\n", i, table->strings[i]);
-}
-
-static void dump_game_data_strings(ComprehendGame *game)
-{
- debugN("Main string table (%u entries)\n",
- (uint)game->_strings.nr_strings);
- dump_string_table(&game->_strings);
-}
-
-static void dump_extra_strings(ComprehendGame *game)
-{
- debugN("Extra strings (%u entries)\n",
- (uint)game->_strings2.nr_strings);
- dump_string_table(&game->_strings2);
-}
-
-static void dump_replace_words(ComprehendGame *game)
-{
- uint i;
-
- debugN("Replacement words (%u entries)\n",
- (uint)game->_nr_replace_words);
- for (i = 0; i < game->_nr_replace_words; i++)
- debugN(" [%.2x] %s\n", i + 1, game->_replaceWords[i]);
-}
-
-static void dump_header(ComprehendGame *game)
-{
- GameHeader *header = &game->_header;
- uint16 *dir_table = header->room_direction_table;
-
- debugN("Game header:\n");
- debugN(" magic: %.4x\n", header->magic);
- debugN(" action(vvnn): %.4x\n", header->addr_actions_vvnn);
- debugN(" actions(?):\n");
- debugN(" actions(vnjn): %.4x\n", header->addr_actions_vnjn);
- debugN(" actions(vjn): %.4x\n", header->addr_actions_vjn);
- debugN(" actions(vdn): %.4x\n", header->addr_actions_vdn);
- debugN(" actions(vnn): %.4x\n", header->addr_actions_vnn);
- debugN(" actions(vn): %.4x\n", header->addr_actions_vn);
- debugN(" actions(v): %.4x\n", header->addr_actions_v);
- debugN(" functions: %.4x\n", header->addr_vm);
- debugN(" dictionary: %.4x\n", header->addr_dictionary);
- debugN(" word map pairs: %.4x\n", header->addr_word_map);
- debugN(" room desc strings: %.4x\n", header->room_desc_table);
- debugN(" room north: %.4x\n", dir_table[DIRECTION_NORTH]);
- debugN(" room south: %.4x\n", dir_table[DIRECTION_SOUTH]);
- debugN(" room east: %.4x\n", dir_table[DIRECTION_EAST]);
- debugN(" room west: %.4x\n", dir_table[DIRECTION_WEST]);
- debugN(" room up: %.4x\n", dir_table[DIRECTION_UP]);
- debugN(" room down: %.4x\n", dir_table[DIRECTION_DOWN]);
- debugN(" room in: %.4x\n", dir_table[DIRECTION_IN]);
- debugN(" room out: %.4x\n", dir_table[DIRECTION_OUT]);
- debugN(" room flags: %.4x\n", header->room_flags_table);
- debugN(" room images: %.4x\n", header->room_graphics_table);
- debugN(" item locations: %.4x\n", header->addr_item_locations);
- debugN(" item flags: %.4x\n", header->addr_item_flags);
- debugN(" item words: %.4x\n", header->addr_item_word);
- debugN(" item desc strings: %.4x\n", header->addr_item_strings);
- debugN(" item images: %.4x\n", header->addr_item_graphics);
- debugN(" string table: %.4x\n", header->addr_strings);
- debugN(" string table end: %.4x\n", header->addr_strings_end);
-}
-
-typedef void (*dump_func_t)(ComprehendGame *game);
-
-struct Dumper {
- dump_func_t dump_func;
- unsigned flag;
-};
-
-static Dumper dumpers[] = {
- {dump_header, DUMP_HEADER},
- {dump_game_data_strings, DUMP_STRINGS},
- {dump_extra_strings, DUMP_EXTRA_STRINGS},
- {dump_rooms, DUMP_ROOMS},
- {dump_items, DUMP_ITEMS},
- {dump_dictionary, DUMP_DICTIONARY},
- {dump_word_map, DUMP_WORD_PAIRS},
- {dump_action_table, DUMP_ACTIONS},
- {dump_functions, DUMP_FUNCTIONS},
- {dump_replace_words, DUMP_REPLACE_WORDS},
-};
-
-void dump_game_data(ComprehendGame *game, unsigned flags)
-{
- uint i;
-
- for (i = 0; i < ARRAY_SIZE(dumpers); i++)
- if (flags & dumpers[i].flag) {
- dumpers[i].dump_func(game);
- debugN("\n\n");
- }
-}
-
-} // namespace Comprehend
-} // namespace Glk
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 14b1e42d5e..60c9384cf0 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -22,8 +22,8 @@
#include "glk/comprehend/game.h"
#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/debugger.h"
#include "glk/comprehend/dictionary.h"
-#include "glk/comprehend/dump_game_data.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/graphics.h"
#include "glk/comprehend/opcode_map.h"
@@ -421,17 +421,19 @@ static void eval_instruction(ComprehendGame *game,
room = get_room(game, game->_currentRoom);
- if (debugging_enabled()) {
+ if (gDebugLevel > 0) {
+ Common::String line;
if (!instr->is_command) {
- printf("? ");
+ line += "? ";
} else {
if (func_state->test_result)
- printf("+ ");
+ line += "+ ";
else
- printf("- ");
+ line += "- ";
}
- dump_instruction(game, func_state, instr);
+ line += g_debugger->dumpInstruction(game, func_state, instr);
+ debug("%s", line.c_str());
}
if (func_state->or_count)
@@ -998,46 +1000,6 @@ static void skip_non_whitespace(char **p) {
(*p)++;
}
-static void handle_debug_command(ComprehendGame *game,
- const char *line) {
- int i;
-
- if (strncmp(line, "quit", 4) == 0) {
- g_comprehend->quitGame();
-
- } else if (strncmp(line, "debug", 5) == 0) {
- if (debugging_enabled())
- debug_disable(DEBUG_ALL);
- else
- debug_enable(DEBUG_FUNCTIONS);
- printf("Debugging %s\n", debugging_enabled() ? "on" : "off");
-
- } else if (strncmp(line, "dump objects", 12) == 0) {
- dump_game_data(game, DUMP_ITEMS);
-
- } else if (strncmp(line, "dump rooms", 10) == 0) {
- dump_game_data(game, DUMP_ROOMS);
-
- } else if (strncmp(line, "dump state", 10) == 0) {
- printf("Current room: %.2x\n", game->_currentRoom);
- printf("Carry weight %d/%d\n\n",
- game->_variables[VAR_INVENTORY_WEIGHT],
- game->_variables[VAR_INVENTORY_LIMIT]);
-
- printf("Flags:\n");
- for (i = 0; i < ARRAY_SIZE(game->_flags); i++)
- printf(" [%.2x]: %d\n", i, game->_flags[i]);
- printf("\n");
-
- printf("Variables:\n");
- for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
- printf(" [%.2x]: %5d (0x%.4x)\n",
- i, game->_variables[i],
- game->_variables[i]);
- printf("\n");
- }
-}
-
static bool handle_sentence(ComprehendGame *game,
Sentence *sentence) {
Function *func;
@@ -1167,17 +1129,15 @@ static void read_input(ComprehendGame *game) {
game->before_prompt();
before_turn(game);
- g_comprehend->print("> ");
- g_comprehend->readLine(buffer, sizeof(buffer));
- if (g_comprehend->shouldQuit())
- return;
+ do {
+ g_comprehend->print("> ");
+ g_comprehend->readLine(buffer, sizeof(buffer));
+ if (g_comprehend->shouldQuit())
+ return;
+ } while (strlen(buffer) == 0);
// Re-comprehend special commands start with '!'
line = &buffer[0];
- if (*line == '!') {
- handle_debug_command(game, &line[1]);
- return;
- }
while (1) {
read_sentence(game, &line, &sentence);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 4bc7b42a02..0914a777b4 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -23,7 +23,6 @@
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/dictionary.h"
-#include "glk/comprehend/dump_game_data.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
#include "glk/comprehend/graphics.h"
diff --git a/engines/glk/comprehend/util.cpp b/engines/glk/comprehend/util.cpp
index 2a64d1d0c2..62abe26163 100644
--- a/engines/glk/comprehend/util.cpp
+++ b/engines/glk/comprehend/util.cpp
@@ -28,8 +28,6 @@
namespace Glk {
namespace Comprehend {
-static unsigned debug_flags;
-
void __fatal_error(const char *func, unsigned line, const char *fmt, ...) {
error("TODO");
}
@@ -60,6 +58,7 @@ char *xstrndup(const char *str, size_t len) {
}
void debug_printf(unsigned flags, const char *fmt, ...) {
+#ifdef TODO
va_list args;
if (debug_flags & flags) {
@@ -69,19 +68,7 @@ void debug_printf(unsigned flags, const char *fmt, ...) {
debug(1, "%s", msg.c_str());
}
-}
-
-void debug_enable(unsigned flags) {
- debug_flags |= flags;
-}
-
-void debug_disable(unsigned flags) {
- debug_flags &= ~flags;
-}
-
-bool debugging_enabled(void) {
- // FIXME
- return debug_flags;
+ #endif
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/util.h b/engines/glk/comprehend/util.h
index 335b7b5132..f979d17937 100644
--- a/engines/glk/comprehend/util.h
+++ b/engines/glk/comprehend/util.h
@@ -43,9 +43,6 @@ void *xmalloc(size_t size);
char *xstrndup(const char *str, size_t size);
void debug_printf(unsigned flags, const char *fmt, ...);
-void debug_enable(unsigned flags);
-void debug_disable(unsigned flags);
-bool debugging_enabled(void);
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/glk.cpp b/engines/glk/glk.cpp
index 3f092e3232..6441f44421 100644
--- a/engines/glk/glk.cpp
+++ b/engines/glk/glk.cpp
@@ -78,7 +78,7 @@ GlkEngine::~GlkEngine() {
void GlkEngine::initialize() {
initGraphicsMode();
- setDebugger(new Debugger());
+ createDebugger();
_conf = new Conf(getInterpreterType());
_screen = createScreen();
@@ -116,6 +116,10 @@ void GlkEngine::initGraphicsMode() {
initGraphics(width, height, &format);
}
+void GlkEngine::createDebugger() {
+ setDebugger(new Debugger());
+}
+
Common::Error GlkEngine::run() {
// Open up the game file
Common::String filename = getFilename();
diff --git a/engines/glk/glk.h b/engines/glk/glk.h
index fe4d6b8411..0593565914 100644
--- a/engines/glk/glk.h
+++ b/engines/glk/glk.h
@@ -94,6 +94,11 @@ protected:
*/
virtual void initGraphicsMode();
+ /**
+ * Create the debugger
+ */
+ virtual void createDebugger();
+
/**
* Create the screen
*/
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index d4fb6f873d..5bce6774f5 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -167,9 +167,10 @@ MODULE_OBJS := \
archetype/timestamp.o \
archetype/token.o \
comprehend/comprehend.o \
+ comprehend/debugger.o \
+ comprehend/debugger_dumper.o \
comprehend/detection.o \
comprehend/dictionary.o \
- comprehend/dump_game_data.o \
comprehend/file_buf.o \
comprehend/game.o \
comprehend/game_cc.o \
Commit: 0f411b62dddefa83e72f367e0a7c45189601ea68
https://github.com/scummvm/scummvm/commit/0f411b62dddefa83e72f367e0a7c45189601ea68
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Improved graphic vs text area setup
Changed paths:
engines/glk/comprehend/comprehend.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 0ead807108..c32a0f0875 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -121,8 +121,7 @@ int main(int argc, char **argv) {
}
#endif
-Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) :
- GlkAPI(syst, gameDesc), _saveSlot(-1), _game(nullptr) {
+Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc), _saveSlot(-1), _game(nullptr) {
g_comprehend = this;
}
@@ -143,13 +142,17 @@ void Comprehend::runGame() {
deinitialize();
}
-
void Comprehend::initialize() {
- _topWindow = (GraphicsWindow *)glk_window_open(0, 0, 0, wintype_Graphics, 1);
- _bottomWindow = (TextBufferWindow *)glk_window_open(
- _topWindow, winmethod_Below | winmethod_Fixed,
- 80, wintype_TextBuffer, 0);
+ g_conf->_wMarginX = 0;
+ g_conf->_wMarginY = 0;
+
+ _bottomWindow = (TextBufferWindow *)glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
+ _topWindow = (GraphicsWindow *)glk_window_open(_bottomWindow,
+ winmethod_Above | winmethod_Fixed,
+ 400, wintype_Graphics, 2);
+
glk_set_window(_bottomWindow);
+ _topWindow->fillRect(0, Rect(0, 0, _topWindow->_w, _topWindow->_h));
}
void Comprehend::deinitialize() {
@@ -181,7 +184,7 @@ void Comprehend::print(const char *fmt, ...) {
va_end(argp);
glk_put_string_stream(glk_window_get_stream(_bottomWindow),
- msg.c_str());
+ msg.c_str());
}
void Comprehend::readLine(char *buffer, size_t maxLen) {
@@ -201,6 +204,5 @@ void Comprehend::readLine(char *buffer, size_t maxLen) {
buffer[ev.val1] = 0;
}
-
} // namespace Comprehend
} // namespace Glk
Commit: 0944b7aa6a60feadf2eed7f1095bf142796e5c7b
https://github.com/scummvm/scummvm/commit/0944b7aa6a60feadf2eed7f1095bf142796e5c7b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Implementing some graphic primitives
Changed paths:
engines/glk/comprehend/graphics.cpp
engines/glk/window_graphics.cpp
engines/glk/window_graphics.h
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/graphics.cpp
index 7d8937423d..bb5441c15e 100644
--- a/engines/glk/comprehend/graphics.cpp
+++ b/engines/glk/comprehend/graphics.cpp
@@ -424,36 +424,14 @@ static void set_color(unsigned color) {
void g_draw_box(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
unsigned color) {
-#ifdef TODO
- SDL_Rect rect;
- int i;
-
- rect.x = x1;
- rect.y = y1;
- rect.w = x2 - x1;
- rect.h = y2 - y1;
-
- set_color(color);
- for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
- SDL_RenderDrawRect(ctx.renderer[i], &rect);
-#endif
+ Rect r(x1, y1, x2, y2);
+ g_comprehend->_topWindow->frameRect(color, r);
}
static void g_draw_filled_box(unsigned x1, unsigned y1,
unsigned x2, unsigned y2, unsigned color) {
-#ifdef TODO
- SDL_Rect rect;
- int i;
-
- rect.x = x1;
- rect.y = y1;
- rect.w = x2 - x1;
- rect.h = y2 - y1;
-
- set_color(color);
- for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
- SDL_RenderFillRect(ctx.renderer[i], &rect);
-#endif
+ Rect r(x1, y1, x2, y2);
+ g_comprehend->_topWindow->fillRect(color, r);
}
unsigned g_get_pixel_color(int x, int y) {
@@ -481,15 +459,8 @@ void g_draw_pixel(unsigned x, unsigned y, unsigned color) {
}
void g_draw_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
- unsigned color)
-{
-#ifdef TODO
- int i;
-
- set_color(color);
- for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
- SDL_RenderDrawLine(ctx.renderer[i], x1, y1, x2, y2);
-#endif
+ unsigned color) {
+ g_comprehend->_topWindow->drawLine(color, Point(x1, y1), Point(x2, y2));
}
void g_draw_shape(int x, int y, int shape_type, unsigned fill_color)
@@ -630,27 +601,18 @@ void g_floodfill(int x, int y, unsigned fill_color,
}
-void g_flip_buffers(void)
-{
+void g_flip_buffers(void) {
#ifdef TODO
SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
#endif
}
void g_clear_screen(unsigned color) {
- #ifdef TODO
- int i;
-
- set_color(color);
- for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
- SDL_RenderClear(ctx.renderer[i]);
-
- SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
-#endif
+ GraphicsWindow *win = g_comprehend->_topWindow;
+ win->fillRect(color, Rect(0, 0, win->_w, win->_h));
}
-void g_init(unsigned width, unsigned height)
-{
+void g_init(unsigned width, unsigned height) {
#ifdef TODO
int err;
diff --git a/engines/glk/window_graphics.cpp b/engines/glk/window_graphics.cpp
index f9fd43a878..2090165441 100644
--- a/engines/glk/window_graphics.cpp
+++ b/engines/glk/window_graphics.cpp
@@ -177,6 +177,16 @@ void GraphicsWindow::fillRect(uint color, const Rect &box) {
touch();
}
+void GraphicsWindow::frameRect(uint color, const Rect &box) {
+ _surface->frameRect(box, color);
+ touch();
+}
+
+void GraphicsWindow::drawLine(uint color, const Point &from, const Point &to) {
+ _surface->drawLine(from.x, from.y, to.x, to.y, color);
+ touch();
+}
+
void GraphicsWindow::drawPicture(Picture *src, int x0, int y0, int width, int height, uint linkval) {
if (width != src->w || height != src->h) {
src = g_vm->_pictures->scale(src, width, height);
diff --git a/engines/glk/window_graphics.h b/engines/glk/window_graphics.h
index 6fdc74ea62..7a3eb9bc48 100644
--- a/engines/glk/window_graphics.h
+++ b/engines/glk/window_graphics.h
@@ -103,8 +103,21 @@ public:
void eraseRect(bool whole, const Rect &box) override;
+ /**
+ * Fill an area of the window
+ */
void fillRect(uint color, const Rect &box) override;
+ /**
+ * Draw a rectangle in the given area
+ */
+ void frameRect(uint color, const Rect &box);
+
+ /**
+ * Draws a line between two points
+ */
+ void drawLine(uint color, const Point &from, const Point &to);
+
void getSize(uint *width, uint *height) const override;
void setBackgroundColor(uint color) override;
Commit: 687ed8be0408aaf8f943b88928e9c408c342a7ae
https://github.com/scummvm/scummvm/commit/687ed8be0408aaf8f943b88928e9c408c342a7ae
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Objectifying image file methods
Changed paths:
R engines/glk/comprehend/image_view.cpp
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/file_buf.cpp
engines/glk/comprehend/file_buf.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/graphics.cpp
engines/glk/comprehend/graphics.h
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
engines/glk/module.mk
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index c32a0f0875..e9e54ad241 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -30,6 +30,7 @@
#include "glk/comprehend/game_oo.h"
#include "glk/comprehend/game_tm.h"
#include "glk/comprehend/game_tr.h"
+#include "glk/comprehend/graphics.h"
#include "glk/quetzal.h"
namespace Glk {
@@ -153,6 +154,8 @@ void Comprehend::initialize() {
glk_set_window(_bottomWindow);
_topWindow->fillRect(0, Rect(0, 0, _topWindow->_w, _topWindow->_h));
+
+ g_init();
}
void Comprehend::deinitialize() {
diff --git a/engines/glk/comprehend/file_buf.cpp b/engines/glk/comprehend/file_buf.cpp
index d22fd2495d..426cbf4672 100644
--- a/engines/glk/comprehend/file_buf.cpp
+++ b/engines/glk/comprehend/file_buf.cpp
@@ -43,6 +43,12 @@ bool FileBuffer::exists(const Common::String &filename) {
return Common::File::exists(filename);
}
+void FileBuffer::close() {
+ _data.clear();
+ _readBytes.clear();
+ _pos = 0;
+}
+
bool FileBuffer::seek(int32 offset, int whence) {
switch (whence) {
case SEEK_SET:
diff --git a/engines/glk/comprehend/file_buf.h b/engines/glk/comprehend/file_buf.h
index 0805842809..ed66911a36 100644
--- a/engines/glk/comprehend/file_buf.h
+++ b/engines/glk/comprehend/file_buf.h
@@ -40,6 +40,7 @@ public:
FileBuffer() : _pos(0) {}
FileBuffer(const Common::String &filename);
static bool exists(const Common::String &filename);
+ void close();
int32 pos() const override { return _pos; }
int32 size() const override { return _data.size(); }
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 0914a777b4..a5c60bd699 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -1019,7 +1019,10 @@ void comprehend_load_game(ComprehendGame *game) {
load_game_data(game);
if (g_enabled()) {
- comprehend_load_images(game);
+ // Set up image files
+ game->_roomImages.load(game->_locationGraphicFiles);
+ game->_itemImages.load(game->_itemGraphicFiles);
+
if (game->_colorTable)
g_set_color_table(game->_colorTable);
}
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/graphics.cpp
index bb5441c15e..13d215d10d 100644
--- a/engines/glk/comprehend/graphics.cpp
+++ b/engines/glk/comprehend/graphics.cpp
@@ -612,32 +612,7 @@ void g_clear_screen(unsigned color) {
win->fillRect(color, Rect(0, 0, win->_w, win->_h));
}
-void g_init(unsigned width, unsigned height) {
- #ifdef TODO
- int err;
-
- err = SDL_Init(SDL_INIT_VIDEO);
- if (err == -1)
- fatal_error("Failed to initialize graphics\n");
-
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
-
- ctx.screen = SDL_CreateWindow("Re-Comprehend",
- SDL_WINDOWPOS_CENTERED,
- SDL_WINDOWPOS_CENTERED,
- width, height, 0);
-
- ctx.renderer[RENDERER_SCREEN] =
- SDL_CreateRenderer(ctx.screen, -1, SDL_RENDERER_ACCELERATED);
- SDL_RenderSetLogicalSize(ctx.renderer[RENDERER_SCREEN],
- G_RENDER_WIDTH, G_RENDER_HEIGHT);
-
- ctx.surface = SDL_CreateRGBSurface(0, G_RENDER_WIDTH, G_RENDER_HEIGHT,
- 32, 0x000000ff, 0x0000ff00,
- 0x00ff0000, 0xff000000);
- ctx.renderer[RENDERER_PIXEL_DATA] =
- SDL_CreateSoftwareRenderer(ctx.surface);
-#endif
+void g_init() {
graphics_enabled = true;
}
diff --git a/engines/glk/comprehend/graphics.h b/engines/glk/comprehend/graphics.h
index 414850cbc1..99815b6b56 100644
--- a/engines/glk/comprehend/graphics.h
+++ b/engines/glk/comprehend/graphics.h
@@ -79,7 +79,7 @@ void g_floodfill(int x, int y, unsigned fill_color, unsigned old_color);
void g_clear_screen(unsigned color);
void g_flip_buffers(void);
-void g_init(unsigned width, unsigned height);
+void g_init();
bool g_enabled(void);
} // namespace Comprehend
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index a256f33ccd..50893e6c37 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -46,33 +46,53 @@ struct ImageContext {
static unsigned draw_flags;
-void ImageData::clear() {
- fb = nullptr;
- image_offsets = nullptr;
- nr_images = 0;
-}
+/*-------------------------------------------------------*/
-void image_set_draw_flags(unsigned flags)
-{
- draw_flags |= flags;
+void ImageFileData::load(const char *filename) {
+ uint16 version;
+ int i;
+
+ _fb = FileBuffer(filename);
+
+ /*
+ * In earlier versions of Comprehend the first word is 0x1000 and
+ * the image offsets start four bytes in. In newer versions the
+ * image offsets start at the beginning of the image file.
+ */
+ version = _fb.readUint16LE();
+ if (version == 0x1000)
+ _fb.seek(4);
+ else
+ _fb.seek(0);
+
+ // Get the image offsets in the file
+ _imageOffsets.resize(IMAGES_PER_FILE);
+ for (i = 0; i < IMAGES_PER_FILE; i++) {
+ _imageOffsets[i] = _fb.readUint16LE();
+ if (version == 0x1000)
+ _imageOffsets[i] += 4;
+ }
}
-static uint16 image_get_operand(FileBuffer *fb)
-{
- uint8 val;
+void ImageFileData::draw(uint index, ImageContext *ctx) {
+ _fb.seek(_imageOffsets[index]);
- val = fb->readByte();
- return val;
+ for (bool done = false; !done;) {
+ done = doImageOp(ctx);
+ if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
+ getchar();
+ g_flip_buffers();
+ }
+ }
}
-static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
-{
+bool ImageFileData::doImageOp(ImageContext *ctx) {
uint8 opcode;
uint16 a, b;
- opcode = fb->readByte();
+ opcode = _fb.readByte();
debug_printf(DEBUG_IMAGE_DRAW,
- " %.4x [%.2x]: ", fb->pos() - 1, opcode);
+ " %.4x [%.2x]: ", _fb.pos() - 1, opcode);
switch (opcode) {
case IMAGE_OP_SCENE_END:
@@ -94,15 +114,15 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
case IMAGE_OP_DRAW_LINE:
case IMAGE_OP_DRAW_LINE_FAR:
- a = image_get_operand(fb);
- b = image_get_operand(fb);
+ a = imageGetOperand();
+ b = imageGetOperand();
if (opcode & 0x1)
a += 255;
debug_printf(DEBUG_IMAGE_DRAW,
- "draw_line (%d, %d) - (%d, %d)\n", opcode,
- ctx->x, ctx->y, a, b);
+ "draw_line (%d, %d) - (%d, %d)\n", opcode,
+ ctx->x, ctx->y, a, b);
g_draw_line(ctx->x, ctx->y, a, b, ctx->pen_color);
ctx->x = a;
@@ -111,15 +131,15 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
case IMAGE_OP_DRAW_BOX:
case IMAGE_OP_DRAW_BOX_FAR:
- a = image_get_operand(fb);
- b = image_get_operand(fb);
+ a = imageGetOperand();
+ b = imageGetOperand();
if (opcode & 0x1)
a += 255;
debug_printf(DEBUG_IMAGE_DRAW,
- "draw_box (%d, %d) - (%d, %d)\n", opcode,
- ctx->x, ctx->y, a, b);
+ "draw_box (%d, %d) - (%d, %d)\n", opcode,
+ ctx->x, ctx->y, a, b);
g_draw_box(ctx->x, ctx->y, a, b, ctx->pen_color);
break;
@@ -127,8 +147,8 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
case IMAGE_OP_MOVE_TO:
case IMAGE_OP_MOVE_TO_FAR:
/* Move to */
- a = image_get_operand(fb);
- b = image_get_operand(fb);
+ a = imageGetOperand();
+ b = imageGetOperand();
if (opcode & 0x1)
a += 255;
@@ -147,7 +167,7 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
case IMAGE_OP_SHAPE_A:
case IMAGE_OP_SHAPE_SPRAY:
debug_printf(DEBUG_IMAGE_DRAW,
- "set_shape_type(%.2x)\n", opcode - 0x40);
+ "set_shape_type(%.2x)\n", opcode - 0x40);
ctx->shape = opcode;
break;
@@ -162,15 +182,15 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
case IMAGE_OP_DRAW_SHAPE:
case IMAGE_OP_DRAW_SHAPE_FAR:
- a = image_get_operand(fb);
- b = image_get_operand(fb);
+ a = imageGetOperand();
+ b = imageGetOperand();
if (opcode & 0x1)
a += 255;
debug_printf(DEBUG_IMAGE_DRAW,
- "draw_shape(%d, %d), style=%.2x, fill=%.2x\n",
- a, b, ctx->shape, ctx->fill_color);
+ "draw_shape(%d, %d), style=%.2x, fill=%.2x\n",
+ a, b, ctx->shape, ctx->fill_color);
g_draw_shape(a, b, ctx->shape, ctx->fill_color);
break;
@@ -178,8 +198,8 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
case IMAGE_OP_PAINT:
case IMAGE_OP_PAINT_FAR:
/* Paint */
- a = image_get_operand(fb);
- b = image_get_operand(fb);
+ a = imageGetOperand();
+ b = imageGetOperand();
if (opcode & 0x1)
a += 255;
@@ -187,18 +207,18 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
debug_printf(DEBUG_IMAGE_DRAW, "paint(%d, %d)\n", a, b);
if (!(draw_flags & IMAGEF_NO_FLOODFILL))
g_floodfill(a, b, ctx->fill_color,
- g_get_pixel_color(a, b));
+ g_get_pixel_color(a, b));
break;
case IMAGE_OP_FILL_COLOR:
- a = image_get_operand(fb);
+ a = imageGetOperand();
debug_printf(DEBUG_IMAGE_DRAW, "set_fill_color(%.2x)\n", a);
ctx->fill_color = g_set_fill_color(a);
break;
case IMAGE_OP_SET_TEXT_POS:
- a = image_get_operand(fb);
- b = image_get_operand(fb);
+ a = imageGetOperand();
+ b = imageGetOperand();
debug_printf(DEBUG_IMAGE_DRAW, "set_text_pos(%d, %d)\n", a, b);
ctx->text_x = a;
@@ -206,12 +226,12 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
break;
case IMAGE_OP_DRAW_CHAR:
- a = image_get_operand(fb);
+ a = imageGetOperand();
debug_printf(DEBUG_IMAGE_DRAW, "draw_char(%c)\n",
- a >= 0x20 && a < 0x7f ? a : '?');
+ a >= 0x20 && a < 0x7f ? a : '?');
g_draw_box(ctx->text_x, ctx->text_y,
- ctx->text_x + 6, ctx->text_y + 7, ctx->fill_color);
+ ctx->text_x + 6, ctx->text_y + 7, ctx->fill_color);
ctx->text_x += 8;
break;
@@ -234,19 +254,19 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
case 0xb0:
case 0xd0:
/* FIXME - unknown, one argument */
- a = image_get_operand(fb);
+ a = imageGetOperand();
debug_printf(DEBUG_IMAGE_DRAW, "unknown %.2x: (%.2x) '%c'\n",
- opcode, a,
- a >= 0x20 && a < 0x7f ? a : '?');
+ opcode, a,
+ a >= 0x20 && a < 0x7f ? a : '?');
break;
default:
/* FIXME - Unknown, two arguments */
- a = image_get_operand(fb);
- b = image_get_operand(fb);
+ a = imageGetOperand();
+ b = imageGetOperand();
debug_printf(DEBUG_IMAGE_DRAW,
- "unknown(%.2x, %.2x)\n", a, b);
+ "unknown(%.2x, %.2x)\n", a, b);
g_draw_pixel(a, b, 0x00ff00ff);
break;
}
@@ -254,34 +274,48 @@ static bool do_image_op(FileBuffer *fb, ImageContext *ctx)
return false;
}
-void draw_image(ImageData *info, unsigned index)
-{
- unsigned file_num;
- FileBuffer *fb;
- bool done = false;
+uint16 ImageFileData::imageGetOperand() {
+ return _fb.readByte();
+}
+
+/*-------------------------------------------------------*/
+
+ImageData::ImageData() {
+}
+
+
+void ImageData::clear() {
+ _files.clear();
+}
+
+void ImageData::load(const Common::Array<const char *> &filenames) {
+ // Set up files array
+ clear();
+ _files.resize(filenames.size());
+
+ // Iterate through loading each file
+ for (uint idx = 0; idx < filenames.size(); ++idx)
+ _files[idx].load(filenames[idx]);
+}
+
+/*-------------------------------------------------------*/
+
+void image_set_draw_flags(unsigned flags) {
+ draw_flags |= flags;
+}
+
+void draw_image(ImageData *info, unsigned index) {
ImageContext ctx = {
0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE, 0, 0
};
- file_num = index / IMAGES_PER_FILE;
- fb = &info->fb[file_num];
-
- if (index >= info->nr_images) {
+ if (index >= (info->size() * IMAGES_PER_FILE)) {
warning("Bad image index %.8x (max=%.8x)\n", index,
- (uint)info->nr_images);
+ (uint)info->size());
return;
}
- fb->seek(info->image_offsets[index]);
- while (!done) {
- done = do_image_op(fb, &ctx);
- if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
- getchar();
- g_flip_buffers();
- }
- }
-
- g_flip_buffers();
+ (*info)[index / IMAGES_PER_FILE].draw(index % IMAGES_PER_FILE, &ctx);
}
void draw_dark_room(void)
@@ -300,66 +334,5 @@ void draw_location_image(ImageData *info, unsigned index)
draw_image(info, index);
}
-static void load_image_file(ImageData *info, const char *filename,
- unsigned file_num)
-{
- unsigned base = file_num * IMAGES_PER_FILE;
- FileBuffer *fb;
- uint16 version;
- int i;
-
- info->fb[file_num] = FileBuffer(filename);
- fb = &info->fb[file_num];
-
- /*
- * In earlier versions of Comprehend the first word is 0x1000 and
- * the image offsets start four bytes in. In newer versions the
- * image offsets start at the beginning of the image file.
- */
- version = fb->readUint16LE();
- if (version == 0x1000)
- fb->seek(4);
- else
- fb->seek(0);
-
- /* Get the image offsets in the file */
- for (i = 0; i < IMAGES_PER_FILE; i++) {
- info->image_offsets[base + i] = fb->readUint16LE();
- if (version == 0x1000)
- info->image_offsets[base + i] += 4;
- }
-}
-
-static void load_image_files(ImageData *info,
- const Common::Array<const char *> filenames) {
- uint i;
-
- memset(info, 0, sizeof(*info));
-
- info->nr_images = filenames.size() * IMAGES_PER_FILE;
- info->fb = (FileBuffer *)xmalloc(info->nr_images * sizeof(*info->fb));
- info->image_offsets = (uint16 *)xmalloc(info->nr_images * sizeof(uint16));
-
- for (i = 0; i < filenames.size(); i++) {
- load_image_file(info, filenames[i], i);
- }
-}
-
-void comprehend_load_image_file(const char *filename, ImageData *info)
-{
- Common::Array<const char *> filenames;
- filenames.push_back(filename);
-
- load_image_files(info, filenames);
-}
-
-void comprehend_load_images(ComprehendGame *game) {
- load_image_files(&game->_roomImages,
- game->_locationGraphicFiles);
-
- load_image_files(&game->_itemImages,
- game->_itemGraphicFiles);
-}
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index 718b57c9aa..30b40175b9 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -23,6 +23,7 @@
#ifndef GLK_COMPREHEND_IMAGE_DATA_H
#define GLK_COMPREHEND_IMAGE_DATA_H
+#include "glk/comprehend/file_buf.h"
#include "common/scummsys.h"
namespace Glk {
@@ -30,17 +31,35 @@ namespace Comprehend {
class ComprehendGame;
struct FileBuffer;
+struct ImageContext;
-struct ImageData {
- FileBuffer *fb;
- uint16 *image_offsets;
- size_t nr_images;
+struct ImageFileData {
+private:
+ Common::Array<uint16> _imageOffsets;
+ FileBuffer _fb;
+
+private:
+ bool doImageOp(ImageContext *ctx);
+ uint16 imageGetOperand();
- ImageData() {
- clear();
- }
+ public:
+ void load(const char *filename);
+ void draw(uint index, ImageContext *ctx);
+};
+
+struct ImageData {
+private:
+ Common::Array<ImageFileData> _files;
+
+public:
+ ImageData();
void clear();
+
+ uint size() const { return _files.size(); }
+ ImageFileData &operator[](uint index) { return _files[index]; }
+
+ void load(const Common::Array<const char *> &filenames);
};
#define IMAGEF_OP_WAIT_KEYPRESS (1 << 0)
@@ -96,9 +115,6 @@ void draw_bright_room(void);
void draw_image(ImageData *info, unsigned index);
void draw_location_image(ImageData *info, unsigned index);
-void comprehend_load_image_file(const char *filename, ImageData *info);
-void comprehend_load_images(ComprehendGame *game);
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/image_view.cpp b/engines/glk/comprehend/image_view.cpp
deleted file mode 100644
index c059316e80..0000000000
--- a/engines/glk/comprehend/image_view.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/* 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/comprehend/image_data.h"
-#include "glk/comprehend/graphics.h"
-#include "glk/comprehend/util.h"
-#include "glk/comprehend/comprehend.h"
-
-namespace Glk {
-namespace Comprehend {
-
-#ifdef TODO
-static void usage(const char *progname)
-{
- printf("%s: [OPTION]... FILENAME INDEX\n", progname);
- printf("\nOptions:\n");
- printf(" -w, --width=WIDTH Graphics width\n");
- printf(" -h, --height=HEIGHT Graphics height\n");
- printf(" -c, --clear=COLOR Graphics clear color\n");
- printf(" -t, --color-table=INDEX Color table\n");
- printf(" -s, --sequence Disable sequence of images\n");
- printf(" -p, --pause Wait for keypress after each draw operation\n");
- printf(" -f, --floodfill-disable Disable floodfill operation\n");
- printf(" -d, --debug Enable debugging\n");
- exit(EXIT_FAILURE);
-}
-
-int main(int argc, char **argv)
-{
- struct option long_opts[] = {
- {"width", required_argument, 0, 'w'},
- {"height", required_argument, 0, 'h'},
- {"clear", required_argument, 0, 'c'},
- {"color-table", required_argument, 0, 't'},
- {"sequence", no_argument, 0, 's'},
- {"pause", no_argument, 0, 'p'},
- {"floodfill-disable", no_argument, 0, 'f'},
- {"debug", no_argument, 0, 'd'},
- {"help", no_argument, 0, '?'},
- {NULL, 0, 0, 0},
- };
- const char *short_opts = "w:h:c:t:spfd?";
- image_data info;
- const char *filename;
- unsigned index, clear_color = G_COLOR_WHITE,
- graphics_width = G_RENDER_WIDTH,
- graphics_height = G_RENDER_HEIGHT,
- color_table = 0;
- bool sequence = false;
- int c, opt_index;
-
- while (1) {
- c = getopt_long(argc, argv, short_opts, long_opts, &opt_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 'w':
- graphics_width = strtoul(optarg, NULL, 0);
- break;
-
- case 'h':
- graphics_height = strtoul(optarg, NULL, 0);
- break;
-
- case 'c':
- clear_color = strtoul(optarg, NULL, 0);
- break;
-
- case 't':
- color_table = strtoul(optarg, NULL, 0);
- break;
-
- case 's':
- sequence = true;
- break;
-
- case 'p':
- image_set_draw_flags(IMAGEF_OP_WAIT_KEYPRESS);
- break;
-
- case 'f':
- image_set_draw_flags(IMAGEF_NO_FLOODFILL);
- break;
-
- case 'd':
- debug_enable(DEBUG_IMAGE_DRAW);
- break;
-
- case '?':
- usage(argv[0]);
- break;
-
- default:
- printf("Invalid option\n");
- usage(argv[0]);
- break;
- }
- }
-
- if (optind >= argc || argc - optind != 2)
- usage(argv[0]);
-
- filename = argv[optind++];
- index = strtoul(argv[optind++], NULL, 0);
-
- g_init(graphics_width, graphics_height);
- g_set_color_table(color_table);
- comprehend_load_image_file(filename, &info);
-
- while (index < 16) {
- g_clear_screen(clear_color);
- draw_image(&info, index);
-
- c = getchar();
- if (!sequence || c == 'q' || c == 'Q')
- break;
-
- index++;
- printf("Image %d\n", index);
- }
-
- exit(EXIT_SUCCESS);
-}
-#endif
-
-} // namespace Comprehend
-} // namespace Glk
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 5bce6774f5..95b099f24a 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -180,7 +180,6 @@ MODULE_OBJS := \
comprehend/game_tr.o \
comprehend/graphics.o \
comprehend/image_data.o \
- comprehend/image_view.o \
comprehend/opcode_map.o \
comprehend/strings.o \
comprehend/util.o \
Commit: 4fc86e1bc9a4c4e0d71fe52488144c8356764275
https://github.com/scummvm/scummvm/commit/4fc86e1bc9a4c4e0d71fe52488144c8356764275
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Refactoring drawing code
Changed paths:
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/graphics.cpp
engines/glk/comprehend/graphics.h
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
graphics/font.h
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index a5c60bd699..668f8b6438 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -1024,7 +1024,7 @@ void comprehend_load_game(ComprehendGame *game) {
game->_itemImages.load(game->_itemGraphicFiles);
if (game->_colorTable)
- g_set_color_table(game->_colorTable);
+ DrawSurface::setColorTable(game->_colorTable);
}
/* FIXME - This can be merged, don't need to keep start room around */
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/graphics.cpp
index 13d215d10d..4f2268be7a 100644
--- a/engines/glk/comprehend/graphics.cpp
+++ b/engines/glk/comprehend/graphics.cpp
@@ -37,7 +37,7 @@ namespace Comprehend {
static bool graphics_enabled;
-static unsigned pen_colors[] = {
+const uint32 DrawSurface::PEN_COLORS[8] = {
G_COLOR_BLACK,
RGB(0x00, 0x66, 0x00),
RGB(0x00, 0xff, 0x00),
@@ -48,31 +48,8 @@ static unsigned pen_colors[] = {
RGB(0xff, 0x00, 0x00),
};
-struct GraphicsContext {
- Window *screen;
-
- /*
- * FIXME - Currently using two renderers. One for drawing the (possibly
- * scaled) image to the screen and the other for getting pixel
- * data for floodfill boundaries. This is almost certainly not
- * the best way to do this.
- */
- // SDL_Renderer *renderer[2];
-
- /* Used for pixel access for flood fills */
- // SDL_Surface *surface;
-};
-
-#ifdef TODO
-static GraphicsContext ctx;
-#endif
-
-unsigned g_set_pen_color(uint8 opcode) {
- return pen_colors[opcode - IMAGE_OP_PEN_COLOR_A];
-}
-
/* Used by Transylvania and Crimson Crown */
-static unsigned default_color_table[] = {
+const uint32 DrawSurface::DEFAULT_COLOR_TABLE[256] = {
G_COLOR_WHITE, // 00
G_COLOR_DARK_BLUE, // 01
G_COLOR_GRAY1, // 02
@@ -117,55 +94,10 @@ static unsigned default_color_table[] = {
/* Used by OO-topos */
/* FIXME - incomplete */
-static unsigned color_table_1[] = {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+const uint32 DrawSurface::COLOR_TABLE_1[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0,
0,
@@ -234,172 +166,44 @@ static unsigned color_table_1[] = {
0,
0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
-};
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static unsigned *color_tables[] = {
- default_color_table,
- color_table_1,
+const uint32 *DrawSurface::COLOR_TABLES[2] = {
+ DEFAULT_COLOR_TABLE,
+ COLOR_TABLE_1,
};
-static unsigned *color_table = default_color_table;
+const uint32 *DrawSurface::_colorTable = DEFAULT_COLOR_TABLE;
+
+uint32 DrawSurface::_renderColor;
+
+/*-------------------------------------------------------*/
+
+void DrawSurface::reset() {
+ create(G_RENDER_WIDTH, G_RENDER_HEIGHT,
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+}
-void g_set_color_table(unsigned index) {
- if (index >= ARRAY_SIZE(color_tables)) {
- printf("Bad color table %d - using default\n", index);
- color_table = default_color_table;
+void DrawSurface::setColorTable(uint index) {
+ if (index >= ARRAY_SIZE(COLOR_TABLES)) {
+ warning("Bad color table %d - using default", index);
+ _colorTable = DEFAULT_COLOR_TABLE;
}
- color_table = color_tables[index];
+ _colorTable = COLOR_TABLES[index];
}
-unsigned g_set_fill_color(uint8 index) {
+uint DrawSurface::getPenColor(uint8 opcode) const {
+ return PEN_COLORS[opcode - IMAGE_OP_PEN_COLOR_A];
+}
+
+uint32 DrawSurface::getFillColor(uint8 index) {
unsigned color;
- color = color_table[index];
+ color = _colorTable[index];
if (!color) {
/* Unknown color - use ugly purple */
debug_printf(DEBUG_IMAGE_DRAW, "Unknown color %.2x\n", index);
@@ -409,155 +213,119 @@ unsigned g_set_fill_color(uint8 index) {
return color;
}
-#ifdef TODO
-static void set_color(unsigned color) {
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
- SDL_SetRenderDrawColor(ctx.renderer[i],
- (color >> 24) & 0xff,
- (color >> 16) & 0xff,
- (color >> 8) & 0xff,
- (color >> 0) & 0xff);
+void DrawSurface::drawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color) {
+ Graphics::ManagedSurface::drawLine(x1, y1, x2, y2, color);
}
-#endif
-void g_draw_box(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
- unsigned color) {
- Rect r(x1, y1, x2, y2);
- g_comprehend->_topWindow->frameRect(color, r);
+void DrawSurface::drawBox(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
+ uint32 color) {
+ Common::Rect r(x1, y1, x2, y2);
+ frameRect(r, color);
}
-static void g_draw_filled_box(unsigned x1, unsigned y1,
- unsigned x2, unsigned y2, unsigned color) {
- Rect r(x1, y1, x2, y2);
- g_comprehend->_topWindow->fillRect(color, r);
+void DrawSurface::drawFilledBox(uint16 x1, uint16 y1,
+ uint16 x2, uint16 y2, uint32 color) {
+ Common::Rect r(x1, y1, x2, y2);
+ fillRect(r, color);
}
-unsigned g_get_pixel_color(int x, int y) {
-#ifdef TODO
- uint32 *pixels, val;
-
- pixels = ctx.surface->pixels;
- val = pixels[(y * G_RENDER_WIDTH) + x];
-
- /* FIXME - correct endianess on all platforms? */
- return be32toh(val);
-#else
- return 0;
-#endif
-}
-
-void g_draw_pixel(unsigned x, unsigned y, unsigned color) {
-#ifdef TODO
- int i;
-
- set_color(color);
- for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
- SDL_RenderDrawPoint(ctx.renderer[i], x, y);
-#endif
-}
-
-void g_draw_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
- unsigned color) {
- g_comprehend->_topWindow->drawLine(color, Point(x1, y1), Point(x2, y2));
-}
-
-void g_draw_shape(int x, int y, int shape_type, unsigned fill_color)
-{
+void DrawSurface::drawShape(int x, int y, int shape_type, uint32 fill_color) {
int i, j;
switch (shape_type) {
case IMAGE_OP_SHAPE_PIXEL:
- x += 7; y += 7;
- g_draw_pixel(x, y, fill_color);
+ x += 7;
+ y += 7;
+ drawPixel(x, y, fill_color);
break;
case IMAGE_OP_SHAPE_BOX:
- x += 6; y += 7;
- g_draw_filled_box(x, y, x + 2, y + 2, fill_color);
+ x += 6;
+ y += 7;
+ drawFilledBox(x, y, x + 2, y + 2, fill_color);
break;
case IMAGE_OP_SHAPE_CIRCLE_TINY:
x += 5;
y += 5;
- g_draw_filled_box(x + 1, y, x + 3, y + 4, fill_color);
- g_draw_filled_box(x, y + 1, x + 4, y + 3, fill_color);
+ drawFilledBox(x + 1, y, x + 3, y + 4, fill_color);
+ drawFilledBox(x, y + 1, x + 4, y + 3, fill_color);
break;
case IMAGE_OP_SHAPE_CIRCLE_SMALL:
- x += 4; y += 4;
- g_draw_filled_box(x + 1, y, x + 5, y + 6, fill_color);
- g_draw_filled_box(x, y + 1, x + 6, y + 5, fill_color);
+ x += 4;
+ y += 4;
+ drawFilledBox(x + 1, y, x + 5, y + 6, fill_color);
+ drawFilledBox(x, y + 1, x + 6, y + 5, fill_color);
break;
case IMAGE_OP_SHAPE_CIRCLE_MED:
- x += 1; y += 1;
- g_draw_filled_box(x + 1,
- y + 1,
- x + 1 + (2 + 4 + 2),
- y + 1 + (2 + 4 + 2),
- fill_color);
- g_draw_filled_box(x + 3,
- y,
- x + 3 + 4,
- y + (1 + 2 + 4 + 2 + 1),
- fill_color);
- g_draw_filled_box(x,
- y + 3,
- x + (1 + 2 + 4 + 2 + 1),
- y + 3 + 4,
- fill_color);
+ x += 1;
+ y += 1;
+ drawFilledBox(x + 1,
+ y + 1,
+ x + 1 + (2 + 4 + 2),
+ y + 1 + (2 + 4 + 2),
+ fill_color);
+ drawFilledBox(x + 3,
+ y,
+ x + 3 + 4,
+ y + (1 + 2 + 4 + 2 + 1),
+ fill_color);
+ drawFilledBox(x,
+ y + 3,
+ x + (1 + 2 + 4 + 2 + 1),
+ y + 3 + 4,
+ fill_color);
break;
case IMAGE_OP_SHAPE_CIRCLE_LARGE:
- g_draw_filled_box(x + 2,
- y + 1,
- x + 2 + (3 + 4 + 3),
- y + 1 + (1 + 3 + 4 + 3 + 1),
- fill_color);
- g_draw_filled_box(x + 1,
- y + 2,
- x + 1 + (1 + 3 + 4 + 3 + 1),
- y + 2 + (3 + 4 + 3),
- fill_color);
- g_draw_filled_box(x + 5,
- y,
- x + 5 + 4,
- y + 1 + 1 + 3 + 4 + 3 + 1 + 1,
- fill_color);
- g_draw_filled_box(x,
- y + 5,
- x + 1 + 1 + 3 + 4 + 3 + 1 + 1,
- y + 5 + 4,
- fill_color);
+ drawFilledBox(x + 2,
+ y + 1,
+ x + 2 + (3 + 4 + 3),
+ y + 1 + (1 + 3 + 4 + 3 + 1),
+ fill_color);
+ drawFilledBox(x + 1,
+ y + 2,
+ x + 1 + (1 + 3 + 4 + 3 + 1),
+ y + 2 + (3 + 4 + 3),
+ fill_color);
+ drawFilledBox(x + 5,
+ y,
+ x + 5 + 4,
+ y + 1 + 1 + 3 + 4 + 3 + 1 + 1,
+ fill_color);
+ drawFilledBox(x,
+ y + 5,
+ x + 1 + 1 + 3 + 4 + 3 + 1 + 1,
+ y + 5 + 4,
+ fill_color);
break;
case IMAGE_OP_SHAPE_A:
/* FIXME - very large circle? */
break;
- case IMAGE_OP_SHAPE_SPRAY:
- {
+ case IMAGE_OP_SHAPE_SPRAY: {
char spray[13][13] = {
- {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},
- {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
- {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1},
- {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
- {1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0},
- {0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0},
- {1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0},
- {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0},
- {1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0},
- {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0},
- {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0},
+ {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+ {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1},
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0},
+ {0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0},
+ {1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0},
+ {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0},
+ {1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0},
+ {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0},
};
for (i = 0; i < 13; i++)
for (j = 0; j < 13; j++)
if (spray[i][j])
- g_draw_pixel(x + i, y + j, fill_color);
+ drawPixel(x + i, y + j, fill_color);
break;
}
@@ -567,57 +335,79 @@ void g_draw_shape(int x, int y, int shape_type, unsigned fill_color)
}
}
-void g_floodfill(int x, int y, unsigned fill_color,
- unsigned old_color)
-{
+void DrawSurface::floodFill(int x, int y, uint32 fill_color, uint32 old_color) {
int x1, x2, i;
- if (g_get_pixel_color(x, y) != old_color || fill_color == old_color)
+ if (getPixelColor(x, y) != old_color || fill_color == old_color)
return;
/* Left end of scanline */
for (x1 = x; x1 > 0; x1--)
- if (g_get_pixel_color(x1 - 1, y) != old_color)
+ if (getPixelColor(x1 - 1, y) != old_color)
break;
/* Right end of scanline */
for (x2 = x; x2 < RENDER_X_MAX; x2++)
- if (g_get_pixel_color(x2 + 1, y) != old_color)
+ if (getPixelColor(x2 + 1, y) != old_color)
break;
- g_draw_line(x1, y, x2, y, fill_color);
+ drawLine(x1, y, x2, y, fill_color);
#ifdef TODO
SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
#endif
/* Scanline above */
for (i = x1; i < x2; i++)
- if (y > 0 && g_get_pixel_color(i, y - 1) == old_color)
- g_floodfill(i, y - 1, fill_color, old_color);
+ if (y > 0 && getPixelColor(i, y - 1) == old_color)
+ floodFill(i, y - 1, fill_color, old_color);
/* Scanline below */
for (i = x1; i < x2; i++)
- if (y < RENDER_Y_MAX && g_get_pixel_color(i, y + 1) == old_color)
- g_floodfill(i, y + 1, fill_color, old_color);
+ if (y < RENDER_Y_MAX && getPixelColor(i, y + 1) == old_color)
+ floodFill(i, y + 1, fill_color, old_color);
+}
+void DrawSurface::drawPixel(uint16 x, uint16 y, uint32 color) {
+ uint32 *ptr = (uint32 *)getBasePtr(x, y);
+ *ptr = color;
}
-void g_flip_buffers(void) {
-#ifdef TODO
- SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
-#endif
+uint32 DrawSurface::getPixelColor(uint16 x, uint16 y) {
+ uint32 *ptr = (uint32 *)getBasePtr(x, y);
+ return *ptr;
}
-void g_clear_screen(unsigned color) {
+void DrawSurface::clearScreen(uint32 color) {
+ fillRect(Common::Rect(0, 0, this->w, this->h), color);
+ render();
+}
+
+void DrawSurface::render() {
GraphicsWindow *win = g_comprehend->_topWindow;
- win->fillRect(color, Rect(0, 0, win->_w, win->_h));
+ win->drawPicture(*this, (uint)-2, 0, 0, win->_w, win->_h);
+}
+
+/*-------------------------------------------------------*/
+
+#ifdef TODO
+static void set_color(unsigned color) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
+ SDL_SetRenderDrawColor(ctx.renderer[i],
+ (color >> 24) & 0xff,
+ (color >> 16) & 0xff,
+ (color >> 8) & 0xff,
+ (color >> 0) & 0xff);
}
+#endif
void g_init() {
graphics_enabled = true;
+ DrawSurface::setColorTable(0);
+ DrawSurface::_renderColor = 0;
}
-bool g_enabled(void)
-{
+bool g_enabled(void) {
return graphics_enabled;
}
diff --git a/engines/glk/comprehend/graphics.h b/engines/glk/comprehend/graphics.h
index 99815b6b56..3c27491935 100644
--- a/engines/glk/comprehend/graphics.h
+++ b/engines/glk/comprehend/graphics.h
@@ -24,6 +24,7 @@
#define GLK_COMPREHEND_GRAPHICS_H
#include "common/scummsys.h"
+#include "graphics/managed_surface.h"
namespace Glk {
namespace Comprehend {
@@ -62,23 +63,45 @@ namespace Comprehend {
#define G_COLOR_BROWN1 0x7a5200ff
#define G_COLOR_BROWN2 0x663300ff
-void g_set_color_table(unsigned index);
+class DrawSurface : public Graphics::ManagedSurface {
+private:
+ static const uint32 PEN_COLORS[8];
+ static const uint32 DEFAULT_COLOR_TABLE[256];
+ static const uint32 COLOR_TABLE_1[256];
+ static const uint32 *COLOR_TABLES[2];
+ static const uint32 *_colorTable;
+
+public:
+ static uint32 _renderColor;
+public:
+ DrawSurface() {
+ reset();
+ }
+
+ /**
+ * Sets up the surface to the correct size and pixel format
+ */
+ void reset();
+
+ static void setColorTable(uint index);
+ uint getPenColor(uint8 opcode) const;
+ uint32 getFillColor(uint8 index);
+
+ void drawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color);
+ void drawBox(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color);
+ void drawFilledBox(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color);
+ void drawShape(int x, int y, int shape_type, uint32 fill_color);
+ void floodFill(int x, int y, uint32 fill_color, uint32 old_color);
+ void drawPixel(uint16 x, uint16 y, uint32 color);
+ uint32 getPixelColor(uint16 x, uint16 y);
+ void clearScreen(uint32 color);
+
+ /**
+ * Render the surface to the screen's picture window
+ */
+ void render();
+};
-unsigned g_set_fill_color(uint8 index);
-unsigned g_set_pen_color(uint8 opcode);
-
-unsigned g_get_pixel_color(int x, int y);
-
-void g_draw_pixel(unsigned x, unsigned y, unsigned color);
-void g_draw_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
- unsigned color);
-void g_draw_box(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
- unsigned color);
-void g_draw_shape(int x, int y, int shape_type, unsigned fill_color);
-void g_floodfill(int x, int y, unsigned fill_color, unsigned old_color);
-
-void g_clear_screen(unsigned color);
-void g_flip_buffers(void);
void g_init();
bool g_enabled(void);
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 50893e6c37..391145abf7 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -34,9 +34,9 @@ namespace Comprehend {
#define IMAGES_PER_FILE 16
struct ImageContext {
- unsigned x;
- unsigned y;
- unsigned pen_color;
+ unsigned _x;
+ unsigned _y;
+ unsigned _penColor;
unsigned fill_color;
unsigned shape;
@@ -76,17 +76,18 @@ void ImageFileData::load(const char *filename) {
void ImageFileData::draw(uint index, ImageContext *ctx) {
_fb.seek(_imageOffsets[index]);
+ DrawSurface ds;
for (bool done = false; !done;) {
- done = doImageOp(ctx);
+ done = doImageOp(&ds, ctx);
if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
getchar();
- g_flip_buffers();
+ ds.render();
}
}
}
-bool ImageFileData::doImageOp(ImageContext *ctx) {
+bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
uint8 opcode;
uint16 a, b;
@@ -109,7 +110,7 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
case IMAGE_OP_PEN_COLOR_G:
case IMAGE_OP_PEN_COLOR_H:
debug_printf(DEBUG_IMAGE_DRAW, "set_pen_color(%.2x)\n", opcode);
- ctx->pen_color = g_set_pen_color(opcode);
+ ctx->_penColor = ds->getPenColor(opcode);
break;
case IMAGE_OP_DRAW_LINE:
@@ -122,11 +123,11 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
debug_printf(DEBUG_IMAGE_DRAW,
"draw_line (%d, %d) - (%d, %d)\n", opcode,
- ctx->x, ctx->y, a, b);
- g_draw_line(ctx->x, ctx->y, a, b, ctx->pen_color);
+ ctx->_x, ctx->_y, a, b);
+ ds->drawLine(ctx->_x, ctx->_y, a, b, ctx->_penColor);
- ctx->x = a;
- ctx->y = b;
+ ctx->_x = a;
+ ctx->_y = b;
break;
case IMAGE_OP_DRAW_BOX:
@@ -139,9 +140,9 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
debug_printf(DEBUG_IMAGE_DRAW,
"draw_box (%d, %d) - (%d, %d)\n", opcode,
- ctx->x, ctx->y, a, b);
+ ctx->_x, ctx->_y, a, b);
- g_draw_box(ctx->x, ctx->y, a, b, ctx->pen_color);
+ ds->drawBox(ctx->_x, ctx->_y, a, b, ctx->_penColor);
break;
case IMAGE_OP_MOVE_TO:
@@ -154,8 +155,8 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
a += 255;
debug_printf(DEBUG_IMAGE_DRAW, "move_to(%d, %d)\n", a, b);
- ctx->x = a;
- ctx->y = b;
+ ctx->_x = a;
+ ctx->_y = b;
break;
case IMAGE_OP_SHAPE_PIXEL:
@@ -192,7 +193,7 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
"draw_shape(%d, %d), style=%.2x, fill=%.2x\n",
a, b, ctx->shape, ctx->fill_color);
- g_draw_shape(a, b, ctx->shape, ctx->fill_color);
+ ds->drawShape(a, b, ctx->shape, ctx->fill_color);
break;
case IMAGE_OP_PAINT:
@@ -206,14 +207,14 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
debug_printf(DEBUG_IMAGE_DRAW, "paint(%d, %d)\n", a, b);
if (!(draw_flags & IMAGEF_NO_FLOODFILL))
- g_floodfill(a, b, ctx->fill_color,
- g_get_pixel_color(a, b));
+ ds->floodFill(a, b, ctx->fill_color,
+ ds->getPixelColor(a, b));
break;
case IMAGE_OP_FILL_COLOR:
a = imageGetOperand();
debug_printf(DEBUG_IMAGE_DRAW, "set_fill_color(%.2x)\n", a);
- ctx->fill_color = g_set_fill_color(a);
+ ctx->fill_color = ds->getFillColor(a);
break;
case IMAGE_OP_SET_TEXT_POS:
@@ -230,7 +231,7 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
debug_printf(DEBUG_IMAGE_DRAW, "draw_char(%c)\n",
a >= 0x20 && a < 0x7f ? a : '?');
- g_draw_box(ctx->text_x, ctx->text_y,
+ ds->drawBox(ctx->text_x, ctx->text_y,
ctx->text_x + 6, ctx->text_y + 7, ctx->fill_color);
ctx->text_x += 8;
break;
@@ -267,7 +268,7 @@ bool ImageFileData::doImageOp(ImageContext *ctx) {
debug_printf(DEBUG_IMAGE_DRAW,
"unknown(%.2x, %.2x)\n", a, b);
- g_draw_pixel(a, b, 0x00ff00ff);
+ ds->drawPixel(a, b, 0x00ff00ff);
break;
}
@@ -318,19 +319,19 @@ void draw_image(ImageData *info, unsigned index) {
(*info)[index / IMAGES_PER_FILE].draw(index % IMAGES_PER_FILE, &ctx);
}
-void draw_dark_room(void)
-{
- g_clear_screen(G_COLOR_BLACK);
+void draw_dark_room() {
+ DrawSurface ds;
+ ds.clearScreen(G_COLOR_BLACK);
}
-void draw_bright_room(void)
-{
- g_clear_screen(G_COLOR_WHITE);
+void draw_bright_room() {
+ DrawSurface ds;
+ ds.clearScreen(G_COLOR_WHITE);
}
-void draw_location_image(ImageData *info, unsigned index)
-{
- g_clear_screen(G_COLOR_WHITE);
+void draw_location_image(ImageData *info, unsigned index) {
+ DrawSurface ds;
+ ds.clearScreen(G_COLOR_WHITE);
draw_image(info, index);
}
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index 30b40175b9..b048090629 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -24,6 +24,7 @@
#define GLK_COMPREHEND_IMAGE_DATA_H
#include "glk/comprehend/file_buf.h"
+#include "glk/comprehend/graphics.h"
#include "common/scummsys.h"
namespace Glk {
@@ -39,7 +40,7 @@ private:
FileBuffer _fb;
private:
- bool doImageOp(ImageContext *ctx);
+ bool doImageOp(DrawSurface *ds, ImageContext *ctx);
uint16 imageGetOperand();
public:
diff --git a/graphics/font.h b/graphics/font.h
index d9f81cca8c..4f5923e349 100644
--- a/graphics/font.h
+++ b/graphics/font.h
@@ -119,7 +119,7 @@ public:
* @return The actual area where the string is drawn.
*/
Common::Rect getBoundingBox(const Common::String &str, int x = 0, int y = 0, const int w = 0, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = false) const;
- Common::Rect getBoundingBox(const Common::U32String &str, int x = 0, int y = 0, const int w = 0, TextAlign align = kTextAlignLeft) const;
+ Common::Rect getBoundingBox(const Common::U32String &str, int x = 0, int _y = 0, const int w = 0, TextAlign align = kTextAlignLeft) const;
/**
* Draw a character at a specific point on a surface.
@@ -147,7 +147,7 @@ public:
// TODO: Add doxygen comments to this
void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
void drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0) const;
- void drawString(ManagedSurface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
+ void drawString(ManagedSurface *dst, const Common::String &str, int x, int _y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
void drawString(ManagedSurface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0) const;
/**
Commit: 207e8f4ba241b56f3d1227edd6ff4c6b334c0fb3
https://github.com/scummvm/scummvm/commit/207e8f4ba241b56f3d1227edd6ff4c6b334c0fb3
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Further refactoring of drawing
Changed paths:
A engines/glk/comprehend/draw_surface.cpp
A engines/glk/comprehend/draw_surface.h
R engines/glk/comprehend/graphics.cpp
R engines/glk/comprehend/graphics.h
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/image_data.h
engines/glk/module.mk
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index e9e54ad241..f5581d1527 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -24,13 +24,13 @@
#include "common/config-manager.h"
#include "common/translation.h"
#include "glk/comprehend/debugger.h"
+#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/game.h"
#include "glk/comprehend/game_cc.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/game_oo.h"
#include "glk/comprehend/game_tm.h"
#include "glk/comprehend/game_tr.h"
-#include "glk/comprehend/graphics.h"
#include "glk/quetzal.h"
namespace Glk {
@@ -122,7 +122,9 @@ int main(int argc, char **argv) {
}
#endif
-Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc), _saveSlot(-1), _game(nullptr) {
+Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) :
+ GlkAPI(syst, gameDesc), _saveSlot(-1), _game(nullptr),
+ _graphicsEnabled(true) {
g_comprehend = this;
}
@@ -144,6 +146,7 @@ void Comprehend::runGame() {
deinitialize();
}
void Comprehend::initialize() {
+ // Set up the GLK windows
g_conf->_wMarginX = 0;
g_conf->_wMarginY = 0;
@@ -155,7 +158,9 @@ void Comprehend::initialize() {
glk_set_window(_bottomWindow);
_topWindow->fillRect(0, Rect(0, 0, _topWindow->_w, _topWindow->_h));
- g_init();
+ // Initialize drawing
+ DrawSurface::setColorTable(0);
+ DrawSurface::_renderColor = 0;
}
void Comprehend::deinitialize() {
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 3f1bee6eb6..9e80fe9fa0 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -58,6 +58,7 @@ public:
GraphicsWindow *_topWindow;
TextBufferWindow *_bottomWindow;
ComprehendGame *_game;
+ bool _graphicsEnabled;
private:
/**
diff --git a/engines/glk/comprehend/graphics.cpp b/engines/glk/comprehend/draw_surface.cpp
similarity index 98%
rename from engines/glk/comprehend/graphics.cpp
rename to engines/glk/comprehend/draw_surface.cpp
index 4f2268be7a..70516c3083 100644
--- a/engines/glk/comprehend/graphics.cpp
+++ b/engines/glk/comprehend/draw_surface.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/image_data.h"
#include "glk/comprehend/util.h"
@@ -401,15 +401,5 @@ static void set_color(unsigned color) {
}
#endif
-void g_init() {
- graphics_enabled = true;
- DrawSurface::setColorTable(0);
- DrawSurface::_renderColor = 0;
-}
-
-bool g_enabled(void) {
- return graphics_enabled;
-}
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/graphics.h b/engines/glk/comprehend/draw_surface.h
similarity index 98%
rename from engines/glk/comprehend/graphics.h
rename to engines/glk/comprehend/draw_surface.h
index 3c27491935..5e1c95ffc4 100644
--- a/engines/glk/comprehend/graphics.h
+++ b/engines/glk/comprehend/draw_surface.h
@@ -102,9 +102,6 @@ public:
void render();
};
-void g_init();
-bool g_enabled(void);
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 60c9384cf0..7b6bdf5169 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -25,7 +25,7 @@
#include "glk/comprehend/debugger.h"
#include "glk/comprehend/dictionary.h"
#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/opcode_map.h"
#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
@@ -255,7 +255,7 @@ static void update_graphics(ComprehendGame *game) {
int type;
uint i;
- if (!g_enabled())
+ if (!g_comprehend->_graphicsEnabled)
return;
type = game->room_is_special(game->_currentRoom, NULL);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 668f8b6438..dabef81ce6 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -25,7 +25,7 @@
#include "glk/comprehend/dictionary.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
-#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
@@ -1018,7 +1018,7 @@ void comprehend_load_game(ComprehendGame *game) {
/* Load the main game data file */
load_game_data(game);
- if (g_enabled()) {
+ if (g_comprehend->_graphicsEnabled) {
// Set up image files
game->_roomImages.load(game->_locationGraphicFiles);
game->_itemImages.load(game->_itemGraphicFiles);
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 124f8d6e08..343c5549f2 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -22,7 +22,7 @@
#include "glk/comprehend/game_oo.h"
#include "glk/comprehend/comprehend.h"
-#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/draw_surface.h"
namespace Glk {
namespace Comprehend {
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 391145abf7..73c5f4b077 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -25,7 +25,7 @@
#include "glk/comprehend/game.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/image_data.h"
-#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/util.h"
namespace Glk {
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
index b048090629..3ea4f2e92b 100644
--- a/engines/glk/comprehend/image_data.h
+++ b/engines/glk/comprehend/image_data.h
@@ -24,7 +24,7 @@
#define GLK_COMPREHEND_IMAGE_DATA_H
#include "glk/comprehend/file_buf.h"
-#include "glk/comprehend/graphics.h"
+#include "glk/comprehend/draw_surface.h"
#include "common/scummsys.h"
namespace Glk {
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 95b099f24a..aab0ec1e32 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -171,6 +171,7 @@ MODULE_OBJS := \
comprehend/debugger_dumper.o \
comprehend/detection.o \
comprehend/dictionary.o \
+ comprehend/draw_surface.o \
comprehend/file_buf.o \
comprehend/game.o \
comprehend/game_cc.o \
@@ -178,7 +179,6 @@ MODULE_OBJS := \
comprehend/game_oo.o \
comprehend/game_tm.o \
comprehend/game_tr.o \
- comprehend/graphics.o \
comprehend/image_data.o \
comprehend/opcode_map.o \
comprehend/strings.o \
Commit: 645b2132d74ac9d92fa44a4b304b641144500438
https://github.com/scummvm/scummvm/commit/645b2132d74ac9d92fa44a4b304b641144500438
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Change debug_printf to use debugC
Changed paths:
engines/glk/comprehend/draw_surface.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/comprehend/util.cpp
engines/glk/comprehend/util.h
diff --git a/engines/glk/comprehend/draw_surface.cpp b/engines/glk/comprehend/draw_surface.cpp
index 70516c3083..f3cd999fa7 100644
--- a/engines/glk/comprehend/draw_surface.cpp
+++ b/engines/glk/comprehend/draw_surface.cpp
@@ -206,7 +206,7 @@ uint32 DrawSurface::getFillColor(uint8 index) {
color = _colorTable[index];
if (!color) {
/* Unknown color - use ugly purple */
- debug_printf(DEBUG_IMAGE_DRAW, "Unknown color %.2x\n", index);
+ debugC(kDebugGraphics, "Unknown color %.2x", index);
return RGB(0xff, 0x00, 0xff);
}
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 7b6bdf5169..242f5fc019 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -29,6 +29,7 @@
#include "glk/comprehend/opcode_map.h"
#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
+#include "common/debug-channels.h"
namespace Glk {
namespace Comprehend {
@@ -421,7 +422,7 @@ static void eval_instruction(ComprehendGame *game,
room = get_room(game, game->_currentRoom);
- if (gDebugLevel > 0) {
+ if (DebugMan.isDebugChannelEnabled(kDebugScripts)) {
Common::String line;
if (!instr->is_command) {
line += "? ";
@@ -433,7 +434,7 @@ static void eval_instruction(ComprehendGame *game,
}
line += g_debugger->dumpInstruction(game, func_state, instr);
- debug("%s", line.c_str());
+ debugC(kDebugScripts, "%s", line.c_str());
}
if (func_state->or_count)
@@ -879,8 +880,7 @@ static void eval_instruction(ComprehendGame *game,
fatal_error("Bad function %.4x >= %.4x\n",
index, (uint)game->_nr_functions);
- debug_printf(DEBUG_FUNCTIONS,
- "Calling subfunction %.4x\n", index);
+ debugC(kDebugScripts, "Calling subfunction %.4x", index);
eval_function(game, &game->_functions[index], verb, noun);
break;
@@ -946,12 +946,12 @@ static void eval_instruction(ComprehendGame *game,
default:
if (instr->opcode & 0x80) {
- debug_printf(DEBUG_FUNCTIONS,
- "Unhandled command opcode %.2x\n",
+ debugC(kDebugScripts,
+ "Unhandled command opcode %.2x",
instr->opcode);
} else {
- debug_printf(DEBUG_FUNCTIONS,
- "Unhandled test opcode %.2x - returning false\n",
+ debugC(kDebugScripts,
+ "Unhandled test opcode %.2x - returning false",
instr->opcode);
func_set_test_result(func_state, false);
}
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 73c5f4b077..d14bc60308 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -92,13 +92,12 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
uint16 a, b;
opcode = _fb.readByte();
- debug_printf(DEBUG_IMAGE_DRAW,
- " %.4x [%.2x]: ", _fb.pos() - 1, opcode);
+ debugCN(kDebugGraphics, " %.4x [%.2x]: ", _fb.pos() - 1, opcode);
switch (opcode) {
case IMAGE_OP_SCENE_END:
case IMAGE_OP_EOF:
- debug_printf(DEBUG_IMAGE_DRAW, "end\n");
+ debugC(kDebugGraphics, "end");
return true;
case IMAGE_OP_PEN_COLOR_A:
@@ -109,7 +108,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case IMAGE_OP_PEN_COLOR_F:
case IMAGE_OP_PEN_COLOR_G:
case IMAGE_OP_PEN_COLOR_H:
- debug_printf(DEBUG_IMAGE_DRAW, "set_pen_color(%.2x)\n", opcode);
+ debugC(kDebugGraphics, "set_pen_color(%.2x)", opcode);
ctx->_penColor = ds->getPenColor(opcode);
break;
@@ -121,8 +120,8 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
if (opcode & 0x1)
a += 255;
- debug_printf(DEBUG_IMAGE_DRAW,
- "draw_line (%d, %d) - (%d, %d)\n", opcode,
+ debugC(kDebugGraphics,
+ "draw_line (%d, %d) - (%d, %d)", opcode,
ctx->_x, ctx->_y, a, b);
ds->drawLine(ctx->_x, ctx->_y, a, b, ctx->_penColor);
@@ -138,8 +137,8 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
if (opcode & 0x1)
a += 255;
- debug_printf(DEBUG_IMAGE_DRAW,
- "draw_box (%d, %d) - (%d, %d)\n", opcode,
+ debugC(kDebugGraphics,
+ "draw_box (%d, %d) - (%d, %d)", opcode,
ctx->_x, ctx->_y, a, b);
ds->drawBox(ctx->_x, ctx->_y, a, b, ctx->_penColor);
@@ -154,7 +153,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
if (opcode & 0x1)
a += 255;
- debug_printf(DEBUG_IMAGE_DRAW, "move_to(%d, %d)\n", a, b);
+ debugC(kDebugGraphics, "move_to(%d, %d)", a, b);
ctx->_x = a;
ctx->_y = b;
break;
@@ -167,8 +166,8 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case IMAGE_OP_SHAPE_CIRCLE_LARGE:
case IMAGE_OP_SHAPE_A:
case IMAGE_OP_SHAPE_SPRAY:
- debug_printf(DEBUG_IMAGE_DRAW,
- "set_shape_type(%.2x)\n", opcode - 0x40);
+ debugC(kDebugGraphics,
+ "set_shape_type(%.2x)", opcode - 0x40);
ctx->shape = opcode;
break;
@@ -177,7 +176,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
* FIXME - This appears to be a shape type. Only used by
* OO-Topos.
*/
- debug_printf(DEBUG_IMAGE_DRAW, "shape_unknown()\n");
+ debugC(kDebugGraphics, "shape_unknown()");
ctx->shape = IMAGE_OP_SHAPE_PIXEL;
break;
@@ -189,8 +188,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
if (opcode & 0x1)
a += 255;
- debug_printf(DEBUG_IMAGE_DRAW,
- "draw_shape(%d, %d), style=%.2x, fill=%.2x\n",
+ debugC(kDebugGraphics, "draw_shape(%d, %d), style=%.2x, fill=%.2x",
a, b, ctx->shape, ctx->fill_color);
ds->drawShape(a, b, ctx->shape, ctx->fill_color);
@@ -205,7 +203,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
if (opcode & 0x1)
a += 255;
- debug_printf(DEBUG_IMAGE_DRAW, "paint(%d, %d)\n", a, b);
+ debugC(kDebugGraphics, "paint(%d, %d)", a, b);
if (!(draw_flags & IMAGEF_NO_FLOODFILL))
ds->floodFill(a, b, ctx->fill_color,
ds->getPixelColor(a, b));
@@ -213,14 +211,14 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case IMAGE_OP_FILL_COLOR:
a = imageGetOperand();
- debug_printf(DEBUG_IMAGE_DRAW, "set_fill_color(%.2x)\n", a);
+ debugC(kDebugGraphics, "set_fill_color(%.2x)", a);
ctx->fill_color = ds->getFillColor(a);
break;
case IMAGE_OP_SET_TEXT_POS:
a = imageGetOperand();
b = imageGetOperand();
- debug_printf(DEBUG_IMAGE_DRAW, "set_text_pos(%d, %d)\n", a, b);
+ debugC(kDebugGraphics, "set_text_pos(%d, %d)", a, b);
ctx->text_x = a;
ctx->text_y = b;
@@ -228,7 +226,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case IMAGE_OP_DRAW_CHAR:
a = imageGetOperand();
- debug_printf(DEBUG_IMAGE_DRAW, "draw_char(%c)\n",
+ debugC(kDebugGraphics, "draw_char(%c)",
a >= 0x20 && a < 0x7f ? a : '?');
ds->drawBox(ctx->text_x, ctx->text_y,
@@ -241,14 +239,14 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
* FIXME - Oo-Topos uses this at the beginning of some room
* images.
*/
- debug_printf(DEBUG_IMAGE_DRAW, "unknown()\n");
+ debugC(kDebugGraphics, "unknown()");
break;
case 0xb5:
case 0x82:
case 0x50:
/* FIXME - unknown, no arguments */
- debug_printf(DEBUG_IMAGE_DRAW, "unknown\n");
+ debugC(kDebugGraphics, "unknown");
break;
case 0x73:
@@ -256,7 +254,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case 0xd0:
/* FIXME - unknown, one argument */
a = imageGetOperand();
- debug_printf(DEBUG_IMAGE_DRAW, "unknown %.2x: (%.2x) '%c'\n",
+ debugC(kDebugGraphics, "unknown %.2x: (%.2x) '%c'",
opcode, a,
a >= 0x20 && a < 0x7f ? a : '?');
break;
@@ -266,8 +264,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
a = imageGetOperand();
b = imageGetOperand();
- debug_printf(DEBUG_IMAGE_DRAW,
- "unknown(%.2x, %.2x)\n", a, b);
+ debugC(kDebugGraphics, "unknown(%.2x, %.2x)", a, b);
ds->drawPixel(a, b, 0x00ff00ff);
break;
}
diff --git a/engines/glk/comprehend/util.cpp b/engines/glk/comprehend/util.cpp
index 62abe26163..5378798e5d 100644
--- a/engines/glk/comprehend/util.cpp
+++ b/engines/glk/comprehend/util.cpp
@@ -57,19 +57,5 @@ char *xstrndup(const char *str, size_t len) {
return p;
}
-void debug_printf(unsigned flags, const char *fmt, ...) {
-#ifdef TODO
- va_list args;
-
- if (debug_flags & flags) {
- va_start(args, fmt);
- Common::String msg = Common::String::vformat(fmt, args);
- va_end(args);
-
- debug(1, "%s", msg.c_str());
- }
- #endif
-}
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/util.h b/engines/glk/comprehend/util.h
index f979d17937..8e8224ffff 100644
--- a/engines/glk/comprehend/util.h
+++ b/engines/glk/comprehend/util.h
@@ -42,8 +42,6 @@ void fatal_strerror(int err, const char *fmt, ...);
void *xmalloc(size_t size);
char *xstrndup(const char *str, size_t size);
-void debug_printf(unsigned flags, const char *fmt, ...);
-
} // namespace Comprehend
} // namespace Glk
Commit: 17454429e443e5f0b37d39e094af6408d7636653
https://github.com/scummvm/scummvm/commit/17454429e443e5f0b37d39e094af6408d7636653
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Move floodfill disable to a debugger command
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/debugger.cpp
engines/glk/comprehend/debugger.h
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index f5581d1527..4ad03d6381 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -38,93 +38,9 @@ namespace Comprehend {
Comprehend *g_comprehend;
-#ifdef TODO
-int main(int argc, char **argv) {
- option long_opts[] = {
- {"debug", no_argument, 0, 'd'},
- {"dump", required_argument, 0, 'D'},
- {"no-play", no_argument, 0, 'p'},
- {"no-graphics", no_argument, 0, 'g'},
- {"no-floodfill", no_argument, 0, 'f'},
- {"graphics-width", required_argument, 0, 'w'},
- {"graphics-height", required_argument, 0, 'h'},
- {"help", no_argument, 0, '?'},
- {NULL, 0, 0, 0},
- };
- const char *short_opts = "dD:pgfw:h:?";
- ComprehendGame *game;
- const char *game_name, *game_dir;
- unsigned dump_flags = 0;
- int i, c, opt_index;
- unsigned graphics_width = G_RENDER_WIDTH,
- graphics_height = G_RENDER_HEIGHT;
- bool play_game = true, graphics_enabled = true;
-
- while (1) {
- c = getopt_long(argc, argv, short_opts, long_opts, &opt_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 'd':
- // FIXME
- debug_enable(DEBUG_FUNCTIONS);
- break;
-
- case 'D':
- for (i = 0; i < ARRAY_SIZE(dump_options); i++)
- if (strcmp(optarg, dump_options[i].option) == 0)
- break;
- if (i == ARRAY_SIZE(dump_options)) {
- printf("Invalid dump option '%s'\n", optarg);
- usage(argv[0]);
- }
-
- dump_flags |= dump_options[i].flag;
- break;
-
- case 'p':
- play_game = false;
- break;
-
- case 'g':
- graphics_enabled = false;
- break;
-
- case 'f':
- image_set_draw_flags(IMAGEF_NO_FLOODFILL);
- break;
-
- case 'w':
- graphics_width = strtoul(optarg, NULL, 0);
- break;
-
- case 'h':
- graphics_height = strtoul(optarg, NULL, 0);
- break;
-
- case '?':
- usage(argv[0]);
- break;
-
- default:
- printf("Invalid option\n");
- usage(argv[0]);
- break;
- }
- }
-
- if (optind >= argc || argc - optind != 2)
- usage(argv[0]);
-
- game_name = argv[optind++];
- game_dir = argv[optind++];
-}
-#endif
-
Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) :
GlkAPI(syst, gameDesc), _saveSlot(-1), _game(nullptr),
- _graphicsEnabled(true) {
+ _graphicsEnabled(true), _drawFlags(0) {
g_comprehend = this;
}
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 9e80fe9fa0..4b1c4a5856 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -59,6 +59,7 @@ public:
TextBufferWindow *_bottomWindow;
ComprehendGame *_game;
bool _graphicsEnabled;
+ uint _drawFlags;
private:
/**
diff --git a/engines/glk/comprehend/debugger.cpp b/engines/glk/comprehend/debugger.cpp
index 63d3e9f8d8..69deba5166 100644
--- a/engines/glk/comprehend/debugger.cpp
+++ b/engines/glk/comprehend/debugger.cpp
@@ -31,6 +31,7 @@ Debugger *g_debugger;
Debugger::Debugger() : Glk::Debugger() {
g_debugger = this;
registerCmd("dump", WRAP_METHOD(Debugger, cmdDump));
+ registerCmd("floodfills", WRAP_METHOD(Debugger, cmdFloodfills));
}
Debugger::~Debugger() {
@@ -56,5 +57,17 @@ bool Debugger::cmdDump(int argc, const char **argv) {
return true;
}
+bool Debugger::cmdFloodfills(int argc, const char **argv) {
+ if (argc == 2 && !strcmp(argv[1], "off")) {
+ g_comprehend->_drawFlags |= IMAGEF_NO_FLOODFILL;
+ debugPrintf("Floodfills are off\n");
+ } else {
+ g_comprehend->_drawFlags &= ~IMAGEF_NO_FLOODFILL;
+ debugPrintf("Floodfills are on\n");
+ }
+
+ return true;
+}
+
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/debugger.h b/engines/glk/comprehend/debugger.h
index d42a953d78..0c1113b7e2 100644
--- a/engines/glk/comprehend/debugger.h
+++ b/engines/glk/comprehend/debugger.h
@@ -36,6 +36,11 @@ private:
*/
bool cmdDump(int argc, const char **argv);
+ /**
+ * Sets whether floodfills are done when rendering images
+ */
+ bool cmdFloodfills(int argc, const char **argv);
+
protected:
void print(const char *fmt, ...) override;
Commit: 13b4698c832b60726edc973e4db2673ff1b86a3a
https://github.com/scummvm/scummvm/commit/13b4698c832b60726edc973e4db2673ff1b86a3a
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Skeleton for savegames within ScummVM
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tr.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 4ad03d6381..32efb8b8c7 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -128,5 +128,19 @@ void Comprehend::readLine(char *buffer, size_t maxLen) {
buffer[ev.val1] = 0;
}
+Common::Error Comprehend::readSaveData(Common::SeekableReadStream *rs) {
+ // TODO
+
+ _game->_updateFlags = UPDATE_ALL;
+ return Common::kNoError;
+}
+
+Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
+ // TODO
+
+ return Common::kNoError;
+}
+
+
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 4b1c4a5856..b8a2142132 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -103,17 +103,13 @@ public:
/**
* Load a savegame from the passed Quetzal file chunk stream
*/
- Common::Error readSaveData(Common::SeekableReadStream *rs) override {
- return Common::kReadingFailed;
- }
+ Common::Error readSaveData(Common::SeekableReadStream *rs) override;
/**
* Save the game. The passed write stream represents access to the UMem chunk
* in the Quetzal save file that will be created
*/
- Common::Error writeGameData(Common::WriteStream *ws) override {
- return Common::kWritingFailed;
- }
+ Common::Error writeGameData(Common::WriteStream *ws) override;
/**
* Print string to the buffer window
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 242f5fc019..bbeb84a4a6 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -30,6 +30,7 @@
#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
#include "common/debug-channels.h"
+#include "common/translation.h"
namespace Glk {
namespace Comprehend {
@@ -42,7 +43,6 @@ struct Sentence {
ComprehendGame::ComprehendGame() : _gameName(nullptr),
_shortName(nullptr),
_gameDataFile(nullptr),
- _savegameFileFormat(nullptr),
_colorTable(0),
_gameStrings(nullptr) {
}
@@ -163,7 +163,6 @@ Item *get_item(ComprehendGame *game, uint16 index) {
}
void game_save(ComprehendGame *game) {
- char filename[32];
int c;
console_println(game, game->_strings.strings[STRING_SAVE_GAME]);
@@ -178,12 +177,10 @@ void game_save(ComprehendGame *game) {
return;
}
- snprintf(filename, sizeof(filename), game->_savegameFileFormat, c - '0');
- comprehend_save_game(game, filename);
+ g_comprehend->saveGameState(c - '0', _("Savegame"));
}
void game_restore(ComprehendGame *game) {
- char filename[32];
int c;
console_println(game, game->_strings.strings[STRING_RESTORE_GAME]);
@@ -198,10 +195,7 @@ void game_restore(ComprehendGame *game) {
return;
}
- snprintf(filename, sizeof(filename), game->_savegameFileFormat, c - '0');
- comprehend_restore_game(game, filename);
-
- game->_updateFlags = UPDATE_ALL;
+ (void)g_comprehend->loadGameState(c - '0');
}
void game_restart(ComprehendGame *game) {
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 30d906ccf7..5ac930c186 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -43,7 +43,6 @@ public:
Common::Array<StringFile> _stringFiles;
Common::Array<const char *> _locationGraphicFiles;
Common::Array<const char *> _itemGraphicFiles;
- const char *_savegameFileFormat;
unsigned _colorTable;
struct GameStrings *_gameStrings;
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index da416aa32d..bfe544c53a 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -50,7 +50,6 @@ CrimsonCrownGame::CrimsonCrownGame() : ComprehendGame() {
_itemGraphicFiles.push_back("OA.MS1");
_itemGraphicFiles.push_back("OB.MS1");
- _savegameFileFormat = "G%d.MS0";
_gameStrings = &cc1_strings;
}
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 343c5549f2..2e8c49b1c4 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -55,7 +55,6 @@ OOToposGame::OOToposGame() : ComprehendGame() {
_itemGraphicFiles.push_back("OC");
_itemGraphicFiles.push_back("OD");
- _savegameFileFormat = "G%d";
_colorTable = 1;
}
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index b014d9dec6..d0d2b8567c 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -60,7 +60,6 @@ TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
_itemGraphicFiles.push_back("OB.MS1");
_itemGraphicFiles.push_back("OC.MS1");
- _savegameFileFormat = "G%d.MS0";
_gameStrings = &tr_strings;
}
Commit: e8c47aa747341ad6883edd5848908188fc5e6b0c
https://github.com/scummvm/scummvm/commit/e8c47aa747341ad6883edd5848908188fc5e6b0c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Implementing savegames
Changed paths:
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index bbeb84a4a6..bf97c75f34 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -21,16 +21,16 @@
*/
#include "glk/comprehend/game.h"
+#include "common/debug-channels.h"
+#include "common/translation.h"
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/debugger.h"
#include "glk/comprehend/dictionary.h"
-#include "glk/comprehend/game_data.h"
#include "glk/comprehend/draw_surface.h"
+#include "glk/comprehend/game_data.h"
#include "glk/comprehend/opcode_map.h"
#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
-#include "common/debug-channels.h"
-#include "common/translation.h"
namespace Glk {
namespace Comprehend {
@@ -50,6 +50,44 @@ ComprehendGame::ComprehendGame() : _gameName(nullptr),
ComprehendGame::~ComprehendGame() {
}
+void ComprehendGame::synchronizeSave(Common::Serializer &s) {
+ uint dir, i;
+ size_t nr_rooms, nr_items;
+
+ s.syncAsUint16LE(_currentRoom);
+
+ // Variables
+ for (i = 0; i < ARRAY_SIZE(_variables); i++)
+ s.syncAsUint16LE(_variables[i]);
+
+ // Flags
+ for (i = 0; i < ARRAY_SIZE(_flags); i++)
+ s.syncAsByte(_flags[i]);
+
+ // Rooms
+ nr_rooms = _nr_rooms;
+ s.syncAsByte(_nr_rooms);
+ assert(nr_rooms == _nr_rooms);
+
+ for (i = 0; i < _nr_rooms; ++i) {
+ s.syncAsUint16LE(_rooms[i].string_desc);
+ for (dir = 0; dir < NR_DIRECTIONS; dir++)
+ s.syncAsByte(_rooms[i].direction[dir]);
+
+ s.syncAsByte(_rooms[i].flags);
+ s.syncAsByte(_rooms[i].graphic);
+ }
+
+ // Objects
+ nr_items = _header.nr_items;
+ s.syncAsByte(_header.nr_items);
+
+ for (i = 0; i < nr_items; ++i)
+ _items[i].synchronize(s);
+}
+
+/*-------------------------------------------------------*/
+
static void console_init(void) {
// ioctl(STDOUT_FILENO, TIOCGWINSZ, &console_winsize);
}
@@ -207,7 +245,7 @@ void game_restart(ComprehendGame *game) {
}
static WordIndex *is_word_pair(ComprehendGame *game,
- Word *word1, Word *word2) {
+ Word *word1, Word *word2) {
WordMap *map;
uint i;
@@ -226,7 +264,7 @@ static WordIndex *is_word_pair(ComprehendGame *game,
}
static Item *get_item_by_noun(ComprehendGame *game,
- Word *noun) {
+ Word *noun) {
uint i;
if (!noun || !(noun->_type & WORD_TYPE_NOUN_MASK))
@@ -323,7 +361,7 @@ static void update(ComprehendGame *game) {
/* Check if the room is special (dark, too bright, etc) */
room_desc_string = room->string_desc;
room_type = game->room_is_special(game->_currentRoom,
- &room_desc_string);
+ &room_desc_string);
if (game->_updateFlags & UPDATE_ROOM_DESC)
console_println(game, string_lookup(game, room_desc_string));
@@ -341,7 +379,7 @@ static void move_to(ComprehendGame *game, uint8 room) {
game->_currentRoom = room;
game->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
- UPDATE_ITEM_LIST);
+ UPDATE_ITEM_LIST);
}
static void func_set_test_result(FunctionState *func_state, bool value) {
@@ -397,7 +435,7 @@ void move_object(ComprehendGame *game, Item *item, int new_room) {
* redraw, not the whole room.
*/
game->_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
- UPDATE_ITEM_LIST);
+ UPDATE_ITEM_LIST);
}
item->room = new_room;
@@ -941,12 +979,12 @@ static void eval_instruction(ComprehendGame *game,
default:
if (instr->opcode & 0x80) {
debugC(kDebugScripts,
- "Unhandled command opcode %.2x",
- instr->opcode);
+ "Unhandled command opcode %.2x",
+ instr->opcode);
} else {
debugC(kDebugScripts,
- "Unhandled test opcode %.2x - returning false",
- instr->opcode);
+ "Unhandled test opcode %.2x - returning false",
+ instr->opcode);
func_set_test_result(func_state, false);
}
break;
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 5ac930c186..f10cca9b7b 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -23,9 +23,10 @@
#ifndef GLK_ComprehendGame_H
#define GLK_ComprehendGame_H
-#include "common/array.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/opcode_map.h"
+#include "common/array.h"
+#include "common/serializer.h"
namespace Glk {
namespace Comprehend {
@@ -64,6 +65,8 @@ public:
return ROOM_IS_NORMAL;
}
virtual void handle_special_opcode(uint8 operand) {}
+
+ void synchronizeSave(Common::Serializer &s);
};
void console_println(ComprehendGame *game, const char *text);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index dabef81ce6..28e413076d 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -23,9 +23,9 @@
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/dictionary.h"
+#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
-#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
@@ -66,6 +66,15 @@ void Item::clear() {
graphic = 0;
}
+void Item::synchronize(Common::Serializer &s) {
+ s.syncAsUint16LE(string_desc);
+ s.syncAsUint16LE(long_string);
+ s.syncAsByte(room);
+ s.syncAsByte(flags);
+ s.syncAsByte(word);
+ s.syncAsByte(graphic);
+}
+
/*-------------------------------------------------------*/
void Word::clear() {
@@ -1027,183 +1036,9 @@ void comprehend_load_game(ComprehendGame *game) {
DrawSurface::setColorTable(game->_colorTable);
}
- /* FIXME - This can be merged, don't need to keep start room around */
+ // FIXME: This can be merged, don't need to keep start room around
game->_currentRoom = game->_startRoom;
}
-#ifdef TODO
-static void patch_string_desc(uint16 *desc) {
- /*
- * String descriptors in the save file sometimes are encoded as a
- * table/index value like the instruction opcodes used, and other
- * times the are encoded as an absolute index. We fix them up to
- * all be the former type.
- */
- if (!(*desc & 0x8000) && *desc >= 0x100) {
- *desc -= 0x100;
- *desc |= 0x8100;
- }
-}
-#endif
-
-void comprehend_save_game(ComprehendGame *game, const char *filename) {
-#ifdef TODO
- FILE *fd;
- uint8 bitmask;
- int dir, bit, flag_index, i;
- size_t nr_rooms, nr_items;
-
- fd = fopen(filename, "w");
- if (!fd) {
- printf("Error: Failed to open save file '%s': %s\n",
- filename, strerror(errno));
- return;
- }
-
- nr_rooms = game->nr_rooms;
- nr_items = game->header.nr_items;
-
- file_buf_put_u8(fd, 0);
- file_buf_put_u8(fd, game->current_room);
- file_buf_put_u8(fd, 0);
-
- /* Variables */
- for (i = 0; i < ARRAY_SIZE(game->variable); i++)
- file_buf_put_le16(fd, game->variable[i]);
-
- /* Flags */
- for (flag_index = 0, i = 0; i < ARRAY_SIZE(game->flags) / 8; i++) {
- bitmask = 0;
- for (bit = 7; bit >= 0; bit--) {
- bitmask |= (!!game->flags[flag_index]) << bit;
- flag_index++;
- }
-
- file_buf_put_u8(fd, bitmask);
- }
-
- /*
- * Re-Comprehend doesn't need this since the number of items is
- * determined by the currently loaded game, but the original games
- * won't load the file properly without it.
- */
- file_buf_put_skip(fd, 0x12c - ftell(fd));
- file_buf_put_u8(fd, nr_items);
-
- if (game->comprehend_version == 1)
- file_buf_put_skip(fd, 0x230 - ftell(fd));
- else
- file_buf_put_skip(fd, 0x130 - ftell(fd));
-
- /* Rooms */
- file_buf_put_array_le16(fd, 1, game->rooms,
- string_desc, nr_rooms);
- for (dir = 0; dir < NR_DIRECTIONS; dir++)
- file_buf_put_array_u8(fd, 1, game->rooms,
- direction[dir], nr_rooms);
- file_buf_put_array_u8(fd, 1, game->rooms, flags, nr_rooms);
- file_buf_put_array_u8(fd, 1, game->rooms, graphic, nr_rooms);
-
- /*
- * Objects
- *
- * Layout differs depending on Comprehend version. Version 2 also
- * has long string descriptions for each object.
- */
- file_buf_put_array_le16(fd, 0, game->item, string_desc, nr_items);
- if (game->comprehend_version == 1) {
- file_buf_put_array_u8(fd, 0, game->item, room, nr_items);
- file_buf_put_array_u8(fd, 0, game->item, flags, nr_items);
- file_buf_put_array_u8(fd, 0, game->item, word, nr_items);
- file_buf_put_array_u8(fd, 0, game->item, graphic, nr_items);
- } else {
- file_buf_put_array_le16(fd, 0, game->item, long_string, nr_items);
- file_buf_put_array_u8(fd, 0, game->item, word, nr_items);
- file_buf_put_array_u8(fd, 0, game->item, room, nr_items);
- file_buf_put_array_u8(fd, 0, game->item, flags, nr_items);
- file_buf_put_array_u8(fd, 0, game->item, graphic, nr_items);
- }
-
- fclose(fd);
-#else
- error("Save");
-#endif
-}
-
-void comprehend_restore_game(ComprehendGame *game, const char *filename) {
-#ifdef TODO
- FileBuffer fb;
- size_t nr_rooms, nr_items;
- uint err, dir, i;
-
- err = file_buf_map_may_fail(filename, &fb);
- if (err) {
- printf("Error: Failed to open save file '%s': %s\n",
- filename, strerror(-err));
- return;
- }
-
- nr_rooms = game->nr_rooms;
- nr_items = game->header.nr_items;
-
- /* Restore starting room */
- file_buf_set_pos(&fb, 1);
- game->current_room = fb->readByte();
-
- /* Restore flags and variables */
- file_buf_set_pos(&fb, 3);
- parse_variables(game, &fb);
- parse_flags(game, &fb);
-
- /* FIXME - unknown restore data, skip over it */
- if (game->comprehend_version == 1)
- file_buf_set_pos(&fb, 0x230);
- else
- file_buf_set_pos(&fb, 0x130);
-
- /* Restore rooms */
- file_buf_get_array_le16(&fb, 1, game->rooms,
- string_desc, nr_rooms);
- for (dir = 0; dir < NR_DIRECTIONS; dir++)
- file_buf_get_array_u8(&fb, 1, game->rooms,
- direction[dir], nr_rooms);
- file_buf_get_array_u8(&fb, 1, game->rooms, flags, nr_rooms);
- file_buf_get_array_u8(&fb, 1, game->rooms, graphic, nr_rooms);
-
- /*
- * Restore objects
- *
- * Layout differs depending on Comprehend version. Version 2 also
- * has long string descriptions for each object.
- */
- file_buf_get_array_le16(&fb, 0, game->item, string_desc, nr_items);
- if (game->comprehend_version == 1) {
- file_buf_get_array_u8(&fb, 0, game->item, room, nr_items);
- file_buf_get_array_u8(&fb, 0, game->item, flags, nr_items);
- file_buf_get_array_u8(&fb, 0, game->item, word, nr_items);
- file_buf_get_array_u8(&fb, 0, game->item, graphic, nr_items);
- } else {
- file_buf_get_array_le16(&fb, 0, game->item, long_string, nr_items);
- file_buf_get_array_u8(&fb, 0, game->item, word, nr_items);
- file_buf_get_array_u8(&fb, 0, game->item, room, nr_items);
- file_buf_get_array_u8(&fb, 0, game->item, flags, nr_items);
- file_buf_get_array_u8(&fb, 0, game->item, graphic, nr_items);
- }
-
- /*
- * FIXME - The save file has some string descriptors masked with 0x8000.
- * Not sure what this means, so just mask it out for now.
- */
- for (i = 1; i <= nr_rooms; i++)
- patch_string_desc(&game->rooms[i].string_desc);
- for (i = 0; i < nr_items; i++)
- patch_string_desc(&game->item[i].string_desc);
-
- file_buf_unmap(&fb);
-#else
- error("load");
-#endif
-}
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index f8a6e6f0fe..c4a6e94d19 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -24,6 +24,7 @@
#define GLK_ComprehendGame_DATA_H
#include "glk/comprehend/image_data.h"
+#include "common/serializer.h"
namespace Glk {
namespace Comprehend {
@@ -84,6 +85,8 @@ struct Item {
}
void clear();
+
+ void synchronize(Common::Serializer &s);
};
struct Word {
Commit: 0a2478984f0c32ebba0a263f49f4c12b4145444f
https://github.com/scummvm/scummvm/commit/0a2478984f0c32ebba0a263f49f4c12b4145444f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:10-07:00
Commit Message:
GLK: COMPREHEND: Change _replaceWords to be an Array
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index 362031efc6..8286551ecf 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -365,8 +365,8 @@ void DebuggerDumper::dumpReplaceWords() {
uint i;
print("Replacement words (%u entries)\n",
- (uint)_game->_nr_replace_words);
- for (i = 0; i < _game->_nr_replace_words; i++)
+ _game->_replaceWords.size());
+ for (i = 0; i < _game->_replaceWords.size(); i++)
print(" [%.2x] %s\n", i + 1, _game->_replaceWords[i]);
}
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index bf97c75f34..98eb644b61 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -125,7 +125,7 @@ void console_println(ComprehendGame *game, const char *text) {
case '@':
/* Replace word */
- if (game->_currentReplaceWord >= game->_nr_replace_words) {
+ if (game->_currentReplaceWord >= game->_replaceWords.size()) {
snprintf(bad_word, sizeof(bad_word),
"[BAD_REPLACE_WORD(%.2x)]",
game->_currentReplaceWord);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 28e413076d..f1344a40ee 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -179,7 +179,6 @@ void GameInfo::clearInfo() {
_nr_word_maps = 0;
_nr_actions = 0;
_nr_functions = 0;
- _nr_replace_words = 0;
_currentReplaceWord = 0;
_updateFlags = 0;
_strings.clear();
@@ -200,7 +199,10 @@ void GameInfo::clearInfo() {
Common::fill(&_flags[0], &_flags[MAX_FLAGS], false);
Common::fill(&_variables[0], &_variables[MAX_VARIABLES], 0);
- Common::fill(&_replaceWords[0], &_replaceWords[256], (char *)nullptr);
+
+ for (uint idx = 0; idx < _replaceWords.size(); ++idx)
+ free(_replaceWords[idx]);
+ _replaceWords.clear();
}
static void parse_header_le16(FileBuffer *fb, uint16 *val) {
@@ -843,12 +845,11 @@ static void parse_replace_words(ComprehendGame *game,
if (len == 0)
break;
- game->_replaceWords[i] = xstrndup((const char *)fb->dataPtr(), len);
+ game->_replaceWords.push_back(xstrndup((const char *)fb->dataPtr(), len));
fb->skip(len + (eof ? 0 : 1));
if (eof)
break;
}
- game->_nr_replace_words = i;
}
/*
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index c4a6e94d19..f75a65fdaf 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -251,15 +251,16 @@ struct GameInfo {
bool _flags[MAX_FLAGS];
uint16 _variables[MAX_VARIABLES];
- char *_replaceWords[256];
- size_t _nr_replace_words;
-
+ Common::Array<char *> _replaceWords;
uint8 _currentReplaceWord;
- unsigned _updateFlags;
+ uint _updateFlags;
GameInfo() {
clearInfo();
}
+ ~GameInfo() {
+ clearInfo();
+ }
void clearInfo();
};
Commit: 6447f64709d5785263e4b14dfca3c962c3b06417
https://github.com/scummvm/scummvm/commit/6447f64709d5785263e4b14dfca3c962c3b06417
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Merged string lookups into Game class
Changed paths:
R engines/glk/comprehend/strings.cpp
R engines/glk/comprehend/strings.h
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_data.cpp
engines/glk/module.mk
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index 8286551ecf..2457f85f95 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -23,7 +23,6 @@
#include "glk/comprehend/debugger_dumper.h"
#include "glk/comprehend/dictionary.h"
#include "glk/comprehend/game.h"
-#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
namespace Glk {
@@ -120,7 +119,7 @@ Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
opcode_map = game->_opcodeMap;
opcode = opcode_map[instr->opcode];
- line += " [%.2x] ", instr->opcode;
+ line += Common::String::format(" [%.2x] ", instr->opcode);
if (_opcodes.contains(opcode))
line += _opcodes[opcode];
else
@@ -129,7 +128,7 @@ Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
if (instr->nr_operands) {
line += "(";
for (i = 0; i < instr->nr_operands; i++)
- line += "%.2x%s", instr->operand[i],
+ line += Common::String::format("%.2x%s", instr->operand[i]),
i == instr->nr_operands - 1 ? ")" : ", ";
}
@@ -147,11 +146,11 @@ Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
str_table = instr->operand[2];
}
- line += " %s", instr_lookup_string(game, str_index, str_table);
+ line += Common::String::format(" %s", game->instrStringLookup(str_index, str_table).c_str());
break;
case OPCODE_SET_STRING_REPLACEMENT:
- line += " %s", game->_replaceWords[instr->operand[0] - 1];
+ line += Common::String::format(" %s", game->_replaceWords[instr->operand[0] - 1]);
break;
}
@@ -298,7 +297,7 @@ void DebuggerDumper::dumpRooms() {
print(" [%.2x] flags=%.2x, graphic=%.2x\n",
i, room->flags, room->graphic);
- print(" %s\n", string_lookup(_game, room->string_desc));
+ print(" %s\n", _game->stringLookup(room->string_desc).c_str());
print(" n: %.2x s: %.2x e: %.2x w: %.2x\n",
room->direction[DIRECTION_NORTH],
room->direction[DIRECTION_SOUTH],
@@ -322,10 +321,10 @@ void DebuggerDumper::dumpItems() {
item = &_game->_items[i];
print(" [%.2x] %s\n", i + 1,
- item->string_desc ? string_lookup(_game, item->string_desc) : "");
+ item->string_desc ? _game->stringLookup(item->string_desc).c_str() : "");
if (_game->_comprehendVersion == 2)
print(" long desc: %s\n",
- string_lookup(_game, item->long_string));
+ _game->stringLookup(item->long_string).c_str());
print(" words: ");
for (j = 0; j < _game->_nr_words; j++)
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 98eb644b61..8eca383515 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -29,7 +29,6 @@
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/opcode_map.h"
-#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
namespace Glk {
@@ -86,6 +85,51 @@ void ComprehendGame::synchronizeSave(Common::Serializer &s) {
_items[i].synchronize(s);
}
+Common::String ComprehendGame::stringLookup(uint16 index) {
+ uint16 string;
+ uint8 table;
+
+ /*
+ * There are two tables of strings. The first is stored in the main
+ * game data file, and the second is stored in multiple string files.
+ *
+ * In instructions string indexes are split into a table and index
+ * value. In other places such as the save files strings from the
+ * main table are occasionally just a straight 16-bit index. We
+ * convert all string indexes to the former case so that we can handle
+ * them the same everywhere.
+ */
+ table = (index >> 8) & 0xff;
+ string = index & 0xff;
+
+ switch (table) {
+ case 0x81:
+ case 0x01:
+ string += 0x100;
+ /* Fall-through */
+ case 0x00:
+ case 0x80:
+ if (string < _strings.nr_strings)
+ return _strings.strings[string];
+ break;
+
+ case 0x83:
+ string += 0x100;
+ /* Fall-through */
+ case 0x02:
+ case 0x82:
+ if (string < _strings2.nr_strings)
+ return _strings2.strings[string];
+ break;
+ }
+
+ return Common::String::format("BAD_STRING(%.4x)", index);
+}
+
+Common::String ComprehendGame::instrStringLookup(uint8 index, uint8 table) {
+ return stringLookup(table << 8 | index);
+}
+
/*-------------------------------------------------------*/
static void console_init(void) {
@@ -237,7 +281,7 @@ void game_restore(ComprehendGame *game) {
}
void game_restart(ComprehendGame *game) {
- console_println(game, string_lookup(game, game->_gameStrings->game_restart));
+ console_println(game, game->stringLookup(game->_gameStrings->game_restart).c_str());
console_get_key();
comprehend_load_game(game);
@@ -340,14 +384,14 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
}
if (count > 0) {
- console_println(game, string_lookup(game, STRING_YOU_SEE));
+ console_println(game, game->stringLookup(STRING_YOU_SEE).c_str());
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == game->_currentRoom &&
item->string_desc != 0)
- console_println(game, string_lookup(game, item->string_desc));
+ console_println(game, game->stringLookup(item->string_desc).c_str());
}
}
}
@@ -364,7 +408,7 @@ static void update(ComprehendGame *game) {
&room_desc_string);
if (game->_updateFlags & UPDATE_ROOM_DESC)
- console_println(game, string_lookup(game, room_desc_string));
+ console_println(game, game->stringLookup(room_desc_string).c_str());
if ((game->_updateFlags & UPDATE_ITEM_LIST) &&
room_type == ROOM_IS_NORMAL)
@@ -528,9 +572,8 @@ static void eval_instruction(ComprehendGame *game,
break;
case OPCODE_PRINT:
- console_println(game, instr_lookup_string(game,
- instr->operand[0],
- instr->operand[1]));
+ console_println(game, game->instrStringLookup(
+ instr->operand[0], instr->operand[1]).c_str());
break;
case OPCODE_TEST_NOT_ROOM_FLAG:
@@ -576,14 +619,14 @@ static void eval_instruction(ComprehendGame *game,
if (room->direction[verb->_index - 1])
move_to(game, room->direction[verb->_index - 1]);
else
- console_println(game, string_lookup(game, STRING_CANT_GO));
+ console_println(game, game->stringLookup(STRING_CANT_GO).c_str());
break;
case OPCODE_MOVE_DIRECTION:
if (room->direction[instr->operand[0] - 1])
move_to(game, room->direction[instr->operand[0] - 1]);
else
- console_println(game, string_lookup(game, STRING_CANT_GO));
+ console_println(game, game->stringLookup(STRING_CANT_GO).c_str());
break;
case OPCODE_ELSE:
@@ -626,7 +669,7 @@ static void eval_instruction(ComprehendGame *game,
* FIXME - unsure what the single operand is for.
*/
item = get_item_by_noun(game, noun);
- printf("%s\n", string_lookup(game, item->long_string));
+ printf("%s\n", game->stringLookup(item->long_string).c_str());
break;
case OPCODE_CURRENT_OBJECT_IN_ROOM:
@@ -771,32 +814,32 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_INVENTORY:
count = num_objects_in_room(game, ROOM_INVENTORY);
if (count == 0) {
- console_println(game, string_lookup(game, STRING_INVENTORY_EMPTY));
+ console_println(game, game->stringLookup(STRING_INVENTORY_EMPTY).c_str());
break;
}
- console_println(game, string_lookup(game, STRING_INVENTORY));
+ console_println(game, game->stringLookup(STRING_INVENTORY).c_str());
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == ROOM_INVENTORY)
printf("%s\n",
- string_lookup(game, item->string_desc));
+ game->stringLookup(item->string_desc).c_str());
}
break;
case OPCODE_INVENTORY_ROOM:
count = num_objects_in_room(game, instr->operand[0]);
if (count == 0) {
- console_println(game, string_lookup(game, instr->operand[1] + 1));
+ console_println(game, game->stringLookup(instr->operand[1] + 1).c_str());
break;
}
- console_println(game, string_lookup(game, instr->operand[1]));
+ console_println(game, game->stringLookup(instr->operand[1]).c_str());
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == instr->operand[0])
printf("%s\n",
- string_lookup(game, item->string_desc));
+ game->stringLookup(item->string_desc).c_str());
}
break;
@@ -1074,7 +1117,7 @@ static bool handle_sentence(ComprehendGame *game,
}
/* No matching action */
- console_println(game, string_lookup(game, STRING_DONT_UNDERSTAND));
+ console_println(game, game->stringLookup(STRING_DONT_UNDERSTAND).c_str());
return false;
}
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index f10cca9b7b..90d1a29032 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -67,6 +67,9 @@ public:
virtual void handle_special_opcode(uint8 operand) {}
void synchronizeSave(Common::Serializer &s);
+
+ Common::String stringLookup(uint16 index);
+ Common::String instrStringLookup(uint8 index, uint8 table);
};
void console_println(ComprehendGame *game, const char *text);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index f1344a40ee..6e9869b37e 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -26,7 +26,6 @@
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
-#include "glk/comprehend/strings.h"
#include "glk/comprehend/util.h"
namespace Glk {
diff --git a/engines/glk/comprehend/strings.cpp b/engines/glk/comprehend/strings.cpp
deleted file mode 100644
index 4b6ddb7f99..0000000000
--- a/engines/glk/comprehend/strings.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* 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/comprehend/comprehend.h"
-#include "glk/comprehend/game.h"
-#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/strings.h"
-
-namespace Glk {
-namespace Comprehend {
-
-static char bad_string[128];
-
-const char *string_lookup(ComprehendGame *game, uint16 index)
-{
- uint16 string;
- uint8 table;
-
- /*
- * There are two tables of strings. The first is stored in the main
- * game data file, and the second is stored in multiple string files.
- *
- * In instructions string indexes are split into a table and index
- * value. In other places such as the save files strings from the
- * main table are occasionally just a straight 16-bit index. We
- * convert all string indexes to the former case so that we can handle
- * them the same everywhere.
- */
- table = (index >> 8) & 0xff;
- string = index & 0xff;
-
- switch (table) {
- case 0x81:
- case 0x01:
- string += 0x100;
- /* Fall-through */
- case 0x00:
- case 0x80:
- if (string < game->_strings.nr_strings)
- return game->_strings.strings[string];
- break;
-
- case 0x83:
- string += 0x100;
- /* Fall-through */
- case 0x02:
- case 0x82:
- if (string < game->_strings2.nr_strings)
- return game->_strings2.strings[string];
- break;
- }
-
- snprintf(bad_string, sizeof(bad_string), "BAD_STRING(%.4x)", index);
- return bad_string;
-}
-
-const char *instr_lookup_string(ComprehendGame *game, uint8 index,
- uint8 table)
-{
- return string_lookup(game, table << 8 | index);
-}
-
-} // namespace Comprehend
-} // namespace Glk
diff --git a/engines/glk/comprehend/strings.h b/engines/glk/comprehend/strings.h
deleted file mode 100644
index 4d5a40db11..0000000000
--- a/engines/glk/comprehend/strings.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* 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_COMPREHEND_STRINGS_H
-#define GLK_COMPREHEND_STRINGS_H
-
-namespace Glk {
-namespace Comprehend {
-
-class ComprehendGame;
-
-const char *string_lookup(ComprehendGame *game, uint16 index);
-const char *instr_lookup_string(ComprehendGame *game, uint8 index,
- uint8 table);
-
-} // namespace Comprehend
-} // namespace Glk
-
-#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index aab0ec1e32..692892d709 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -181,7 +181,6 @@ MODULE_OBJS := \
comprehend/game_tr.o \
comprehend/image_data.o \
comprehend/opcode_map.o \
- comprehend/strings.o \
comprehend/util.o \
frotz/bitmap_font.o \
frotz/config.o \
Commit: 744580a3a0a9f3cb48e536a3edb7d989eb634655
https://github.com/scummvm/scummvm/commit/744580a3a0a9f3cb48e536a3edb7d989eb634655
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Change fatal_error to use error
Changed paths:
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/util.cpp
engines/glk/comprehend/util.h
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 8eca383515..1b2f0ef4c6 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -229,17 +229,17 @@ void console_println(ComprehendGame *game, const char *text) {
static Room *get_room(ComprehendGame *game, uint16 index) {
/* Room zero is reserved for the players inventory */
if (index == 0)
- fatal_error("Room index 0 (player inventory) is invalid");
+ error("Room index 0 (player inventory) is invalid");
if (index - 1 >= (int)game->_nr_rooms)
- fatal_error("Room index %d is invalid", index);
+ error("Room index %d is invalid", index);
return &game->_rooms[index];
}
Item *get_item(ComprehendGame *game, uint16 index) {
if (index >= game->_header.nr_items)
- fatal_error("Bad item %d\n", index);
+ error("Bad item %d\n", index);
return &game->_items[index];
}
@@ -419,7 +419,7 @@ static void update(ComprehendGame *game) {
static void move_to(ComprehendGame *game, uint8 room) {
if (room - 1 >= (int)game->_nr_rooms)
- fatal_error("Attempted to move to invalid room %.2x\n", room);
+ error("Attempted to move to invalid room %.2x\n", room);
game->_currentRoom = room;
game->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
@@ -613,7 +613,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_MOVE:
/* Move in the direction dictated by the current verb */
if (verb->_index - 1 >= NR_DIRECTIONS)
- fatal_error("Bad verb %d:%d in move",
+ error("Bad verb %d:%d in move",
verb->_index, verb->_type);
if (room->direction[verb->_index - 1])
@@ -846,7 +846,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM:
item = get_item_by_noun(game, noun);
if (!item)
- fatal_error("Bad current object\n");
+ error("Bad current object\n");
move_object(game, item, instr->operand[0]);
break;
@@ -859,7 +859,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_DROP_CURRENT_OBJECT:
item = get_item_by_noun(game, noun);
if (!item)
- fatal_error("Attempt to take object failed\n");
+ error("Attempt to take object failed\n");
move_object(game, item, game->_currentRoom);
break;
@@ -867,7 +867,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_TAKE_CURRENT_OBJECT:
item = get_item_by_noun(game, noun);
if (!item)
- fatal_error("Attempt to take object failed\n");
+ error("Attempt to take object failed\n");
move_object(game, item, ROOM_INVENTORY);
break;
@@ -927,7 +927,7 @@ static void eval_instruction(ComprehendGame *game,
room->string_desc = instr->operand[1] + 0x200;
break;
default:
- fatal_error("Bad string desc %.2x:%.2x\n",
+ error("Bad string desc %.2x:%.2x\n",
instr->operand[1], instr->operand[2]);
break;
}
@@ -952,7 +952,7 @@ static void eval_instruction(ComprehendGame *game,
if (instr->operand[1] == 0x81)
index += 256;
if (index >= game->_nr_functions)
- fatal_error("Bad function %.4x >= %.4x\n",
+ error("Bad function %.4x >= %.4x\n",
index, (uint)game->_nr_functions);
debugC(kDebugScripts, "Calling subfunction %.4x", index);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 6e9869b37e..90b93c66a0 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -243,7 +243,7 @@ static void parse_function(FileBuffer *fb, Function *func) {
p = (const uint8 *)memchr(fb->dataPtr(), 0x00, fb->size() - fb->pos());
if (!p)
- fatal_error("bad function @ %.4x", fb->pos());
+ error("bad function @ %.4x", fb->pos());
while (1) {
instruction = &func->instructions[func->nr_instructions];
@@ -254,7 +254,7 @@ static void parse_function(FileBuffer *fb, Function *func) {
func->nr_instructions++;
if (func->nr_instructions >= ARRAY_SIZE(func->instructions))
- fatal_error("Function has too many instructions");
+ error("Function has too many instructions");
}
}
@@ -879,7 +879,7 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
break;
default:
- fatal_error("Unknown game_data magic %.4x\n", header->magic);
+ error("Unknown game_data magic %.4x\n", header->magic);
break;
}
diff --git a/engines/glk/comprehend/util.cpp b/engines/glk/comprehend/util.cpp
index 5378798e5d..9b600c15df 100644
--- a/engines/glk/comprehend/util.cpp
+++ b/engines/glk/comprehend/util.cpp
@@ -28,20 +28,12 @@
namespace Glk {
namespace Comprehend {
-void __fatal_error(const char *func, unsigned line, const char *fmt, ...) {
- error("TODO");
-}
-
-void fatal_strerror(int err, const char *fmt, ...) {
- error("TODO");
-}
-
void *xmalloc(size_t size) {
void *p;
p = malloc(size);
if (!p)
- fatal_error("Out of memory");
+ error("Out of memory");
memset(p, 0, size);
return p;
@@ -53,7 +45,7 @@ char *xstrndup(const char *str, size_t len) {
Common::String s(str, len);
p = scumm_strdup(s.c_str());
if (!p)
- fatal_error("Out of memory");
+ error("Out of memory");
return p;
}
diff --git a/engines/glk/comprehend/util.h b/engines/glk/comprehend/util.h
index 8e8224ffff..573fb4aa7b 100644
--- a/engines/glk/comprehend/util.h
+++ b/engines/glk/comprehend/util.h
@@ -35,10 +35,6 @@ namespace Comprehend {
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-#define fatal_error error
-
-void __fatal_error(const char *func, unsigned line, const char *fmt, ...);
-void fatal_strerror(int err, const char *fmt, ...);
void *xmalloc(size_t size);
char *xstrndup(const char *str, size_t size);
Commit: 093825f759795d7567c41f66eb05f4b2a8ba8aa7
https://github.com/scummvm/scummvm/commit/093825f759795d7567c41f66eb05f4b2a8ba8aa7
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Changed StringTable to be a Common StringArray
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/debugger_dumper.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_tr.cpp
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index 2457f85f95..e3b92f4547 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -341,23 +341,23 @@ void DebuggerDumper::dumpItems() {
}
}
-void DebuggerDumper::dumpStringTable(StringTable *table) {
+void DebuggerDumper::dumpStringTable(Common::StringArray &table) {
uint i;
- for (i = 0; i < table->nr_strings; i++)
- print("[%.4x] %s\n", i, table->strings[i]);
+ for (i = 0; i < table.size(); i++)
+ print("[%.4x] %s\n", i, table[i].c_str());
}
void DebuggerDumper::dumpGameDataStrings() {
print("Main string table (%u entries)\n",
- (uint)_game->_strings.nr_strings);
- dumpStringTable(&_game->_strings);
+ _game->_strings.size());
+ dumpStringTable(_game->_strings);
}
void DebuggerDumper::dumpExtraStrings() {
print("Extra strings (%u entries)\n",
- (uint)_game->_strings2.nr_strings);
- dumpStringTable(&_game->_strings2);
+ _game->_strings2.size());
+ dumpStringTable(_game->_strings2);
}
void DebuggerDumper::dumpReplaceWords() {
diff --git a/engines/glk/comprehend/debugger_dumper.h b/engines/glk/comprehend/debugger_dumper.h
index add248e94d..895f8a4c1c 100644
--- a/engines/glk/comprehend/debugger_dumper.h
+++ b/engines/glk/comprehend/debugger_dumper.h
@@ -24,6 +24,7 @@
#define GLK_COMPREHEND_DEBUGGER_DUMPER_H
#include "common/hashmap.h"
+#include "common/str-array.h"
namespace Glk {
namespace Comprehend {
@@ -31,7 +32,6 @@ namespace Comprehend {
class ComprehendGame;
struct FunctionState;
struct Instruction;
-struct StringTable;
class DebuggerDumper {
private:
@@ -46,7 +46,7 @@ private:
void dumpWordMap();
void dumpRooms();
void dumpItems();
- void dumpStringTable(StringTable *table);
+ void dumpStringTable(Common::StringArray &table);
void dumpGameDataStrings();
void dumpExtraStrings();
void dumpReplaceWords();
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 1b2f0ef4c6..f65951dc06 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -109,8 +109,8 @@ Common::String ComprehendGame::stringLookup(uint16 index) {
/* Fall-through */
case 0x00:
case 0x80:
- if (string < _strings.nr_strings)
- return _strings.strings[string];
+ if (string < _strings.size())
+ return _strings[string];
break;
case 0x83:
@@ -118,8 +118,8 @@ Common::String ComprehendGame::stringLookup(uint16 index) {
/* Fall-through */
case 0x02:
case 0x82:
- if (string < _strings2.nr_strings)
- return _strings2.strings[string];
+ if (string < _strings2.size())
+ return _strings2[string];
break;
}
@@ -247,7 +247,7 @@ Item *get_item(ComprehendGame *game, uint16 index) {
void game_save(ComprehendGame *game) {
int c;
- console_println(game, game->_strings.strings[STRING_SAVE_GAME]);
+ console_println(game, game->_strings[STRING_SAVE_GAME].c_str());
c = console_get_key();
if (c < '1' || c > '3') {
@@ -265,7 +265,7 @@ void game_save(ComprehendGame *game) {
void game_restore(ComprehendGame *game) {
int c;
- console_println(game, game->_strings.strings[STRING_RESTORE_GAME]);
+ console_println(game, game->_strings[STRING_RESTORE_GAME].c_str());
c = console_get_key();
if (c < '1' || c > '3') {
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 90b93c66a0..459d1a6753 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -131,13 +131,6 @@ void Function::clear() {
/*-------------------------------------------------------*/
-void StringTable::clear() {
- nr_strings = 0;
- Common::fill(&strings[0], &strings[0xffff], (char *)nullptr);
-}
-
-/*-------------------------------------------------------*/
-
void GameHeader::clear() {
magic = 0;
room_desc_table = 0;
@@ -747,16 +740,16 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
* specifier). If a character has the value 0x1f then the next character is
* taken from the symbols table.
*/
-static char *parse_string(FileBuffer *fb) {
+static Common::String parseString(FileBuffer *fb) {
bool capital_next = false, special_next = false;
unsigned i, j, k = 0;
uint64 chunk;
uint8 elem, *encoded;
- char *string, c;
+ char c;
size_t encoded_len;
+ Common::String string;
encoded_len = fb->strlen();
- string = (char *)xmalloc(encoded_len * 2);
/* Get the encoded string */
encoded = (uint8 *)xmalloc(encoded_len + 5);
@@ -784,13 +777,13 @@ static char *parse_string(FileBuffer *fb) {
special_next);
special_next = false;
capital_next = false;
- string[k++] = c;
+ string += c;
+ k++;
}
}
}
done:
- string[k] = '\0';
free(encoded);
return string;
@@ -800,7 +793,7 @@ static void parse_string_table(FileBuffer *fb, unsigned start_addr,
uint32 end_addr, StringTable *table) {
fb->seek(start_addr);
while (1) {
- table->strings[table->nr_strings++] = parse_string(fb);
+ table->push_back(parseString(fb));
if (fb->pos() >= (int32)end_addr)
break;
}
@@ -996,9 +989,9 @@ static void load_extra_string_files(ComprehendGame *game) {
break;
// HACK - get string offsets correct
- game->_strings2.nr_strings = 0x40 * i;
- if (game->_strings2.nr_strings == 0)
- game->_strings2.nr_strings++;
+ game->_strings2.resize(0x40 * i);
+ if (game->_strings2.empty())
+ game->_strings2.push_back("");
load_extra_string_file(game, &game->_stringFiles[i]);
}
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index f75a65fdaf..5eb4b66787 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -25,6 +25,7 @@
#include "glk/comprehend/image_data.h"
#include "common/serializer.h"
+#include "common/str-array.h"
namespace Glk {
namespace Comprehend {
@@ -167,16 +168,7 @@ struct Function {
void clear();
};
-struct StringTable {
- char *strings[0xffff];
- size_t nr_strings;
-
- StringTable() {
- clear();
- }
-
- void clear();
-};
+typedef Common::StringArray StringTable;
struct GameHeader {
uint16 magic;
@@ -236,8 +228,8 @@ struct GameInfo {
struct WordMap _wordMaps[0xff];
size_t _nr_word_maps;
- struct StringTable _strings;
- struct StringTable _strings2;
+ StringTable _strings;
+ StringTable _strings2;
struct Action _actions[0xffff];
size_t _nr_actions;
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index d0d2b8567c..9e2a75fa8d 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -161,7 +161,7 @@ void TransylvaniaGame::before_game() {
char buffer[128];
// Welcome to Transylvania - sign your name
- console_println(this, _strings.strings[0x20]);
+ console_println(this, _strings[0x20].c_str());
g_comprehend->readLine(buffer, sizeof(buffer));
/*
@@ -178,7 +178,7 @@ void TransylvaniaGame::before_game() {
"%s", buffer);
// And your next of kin - This isn't stored by the game
- console_println(this, _strings.strings[0x21]);
+ console_println(this, _strings[0x21].c_str());
g_comprehend->readLine(buffer, sizeof(buffer));
}
Commit: 2671e9a07105b874c022f691f0a59163caa2ded8
https://github.com/scummvm/scummvm/commit/2671e9a07105b874c022f691f0a59163caa2ded8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Shifting DrawSurface to be a single instance of the engine
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/draw_surface.cpp
engines/glk/comprehend/draw_surface.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/image_data.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 32efb8b8c7..b74e71a266 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -39,12 +39,14 @@ namespace Comprehend {
Comprehend *g_comprehend;
Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) :
- GlkAPI(syst, gameDesc), _saveSlot(-1), _game(nullptr),
+ GlkAPI(syst, gameDesc), _topWindow(nullptr), _bottomWindow(nullptr),
+ _drawSurface(nullptr), _game(nullptr),_saveSlot(-1),
_graphicsEnabled(true), _drawFlags(0) {
g_comprehend = this;
}
Comprehend::~Comprehend() {
+ delete _drawSurface;
delete _game;
g_comprehend = nullptr;
@@ -75,8 +77,9 @@ void Comprehend::initialize() {
_topWindow->fillRect(0, Rect(0, 0, _topWindow->_w, _topWindow->_h));
// Initialize drawing
- DrawSurface::setColorTable(0);
- DrawSurface::_renderColor = 0;
+ _drawSurface = new DrawSurface();
+ _drawSurface->setColorTable(0);
+ _drawSurface->_renderColor = 0;
}
void Comprehend::deinitialize() {
@@ -114,6 +117,7 @@ void Comprehend::print(const char *fmt, ...) {
void Comprehend::readLine(char *buffer, size_t maxLen) {
event_t ev;
+ _drawSurface->renderIfDirty();
glk_request_line_event(_bottomWindow, buffer, maxLen - 1, 0);
for (;;) {
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index b8a2142132..3f5e1fd8f3 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -41,6 +41,7 @@ namespace Comprehend {
struct GameInfo;
struct gameState;
+class DrawSurface;
#define EXTRA_STRING_TABLE(x) (0x8200 | (x))
@@ -57,6 +58,7 @@ private:
public:
GraphicsWindow *_topWindow;
TextBufferWindow *_bottomWindow;
+ DrawSurface *_drawSurface;
ComprehendGame *_game;
bool _graphicsEnabled;
uint _drawFlags;
diff --git a/engines/glk/comprehend/draw_surface.cpp b/engines/glk/comprehend/draw_surface.cpp
index f3cd999fa7..19fc1a6a65 100644
--- a/engines/glk/comprehend/draw_surface.cpp
+++ b/engines/glk/comprehend/draw_surface.cpp
@@ -176,10 +176,6 @@ const uint32 *DrawSurface::COLOR_TABLES[2] = {
COLOR_TABLE_1,
};
-const uint32 *DrawSurface::_colorTable = DEFAULT_COLOR_TABLE;
-
-uint32 DrawSurface::_renderColor;
-
/*-------------------------------------------------------*/
void DrawSurface::reset() {
@@ -194,6 +190,7 @@ void DrawSurface::setColorTable(uint index) {
}
_colorTable = COLOR_TABLES[index];
+ _dirty = true;
}
uint DrawSurface::getPenColor(uint8 opcode) const {
@@ -213,20 +210,30 @@ uint32 DrawSurface::getFillColor(uint8 index) {
return color;
}
+void DrawSurface::setColor(uint32 color) {
+ _renderColor = color;
+}
+
void DrawSurface::drawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color) {
- Graphics::ManagedSurface::drawLine(x1, y1, x2, y2, color);
+ setColor(color);
+ Graphics::ManagedSurface::drawLine(x1, y1, x2, y2, _renderColor);
+ _dirty = true;
}
void DrawSurface::drawBox(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
uint32 color) {
+ setColor(color);
Common::Rect r(x1, y1, x2, y2);
- frameRect(r, color);
+ frameRect(r, _renderColor);
+ _dirty = true;
}
void DrawSurface::drawFilledBox(uint16 x1, uint16 y1,
uint16 x2, uint16 y2, uint32 color) {
+ setColor(color);
Common::Rect r(x1, y1, x2, y2);
- fillRect(r, color);
+ fillRect(r, _renderColor);
+ _dirty = true;
}
void DrawSurface::drawShape(int x, int y, int shape_type, uint32 fill_color) {
@@ -333,6 +340,8 @@ void DrawSurface::drawShape(int x, int y, int shape_type, uint32 fill_color) {
/* Unknown shape */
break;
}
+
+ _dirty = true;
}
void DrawSurface::floodFill(int x, int y, uint32 fill_color, uint32 old_color) {
@@ -352,9 +361,7 @@ void DrawSurface::floodFill(int x, int y, uint32 fill_color, uint32 old_color) {
break;
drawLine(x1, y, x2, y, fill_color);
-#ifdef TODO
- SDL_RenderPresent(ctx.renderer[RENDERER_SCREEN]);
-#endif
+
/* Scanline above */
for (i = x1; i < x2; i++)
if (y > 0 && getPixelColor(i, y - 1) == old_color)
@@ -364,11 +371,15 @@ void DrawSurface::floodFill(int x, int y, uint32 fill_color, uint32 old_color) {
for (i = x1; i < x2; i++)
if (y < RENDER_Y_MAX && getPixelColor(i, y + 1) == old_color)
floodFill(i, y + 1, fill_color, old_color);
+
+ _dirty = true;
}
void DrawSurface::drawPixel(uint16 x, uint16 y, uint32 color) {
+ setColor(color);
uint32 *ptr = (uint32 *)getBasePtr(x, y);
- *ptr = color;
+ *ptr = _renderColor;
+ _dirty = true;
}
uint32 DrawSurface::getPixelColor(uint16 x, uint16 y) {
@@ -377,29 +388,21 @@ uint32 DrawSurface::getPixelColor(uint16 x, uint16 y) {
}
void DrawSurface::clearScreen(uint32 color) {
- fillRect(Common::Rect(0, 0, this->w, this->h), color);
- render();
+ setColor(color);
+ fillRect(Common::Rect(0, 0, this->w, this->h), _renderColor);
+ _dirty = true;
}
-void DrawSurface::render() {
- GraphicsWindow *win = g_comprehend->_topWindow;
- win->drawPicture(*this, (uint)-2, 0, 0, win->_w, win->_h);
-}
-
-/*-------------------------------------------------------*/
-
-#ifdef TODO
-static void set_color(unsigned color) {
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx.renderer); i++)
- SDL_SetRenderDrawColor(ctx.renderer[i],
- (color >> 24) & 0xff,
- (color >> 16) & 0xff,
- (color >> 8) & 0xff,
- (color >> 0) & 0xff);
+void DrawSurface::renderIfDirty() {
+ if (_dirty) {
+ GraphicsWindow *win = g_comprehend->_topWindow;
+ win->drawPicture(*this, (uint)-2, 0, 0, win->_w, win->_h);
+ _dirty = false;
+ // FIXME: Get rid of this hack and properly use the graphics window
+ g_system->copyRectToScreen(getPixels(), pitch, 0, 0, w, h);
+ g_system->updateScreen();
+ }
}
-#endif
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/draw_surface.h b/engines/glk/comprehend/draw_surface.h
index 5e1c95ffc4..71316eba13 100644
--- a/engines/glk/comprehend/draw_surface.h
+++ b/engines/glk/comprehend/draw_surface.h
@@ -69,12 +69,14 @@ private:
static const uint32 DEFAULT_COLOR_TABLE[256];
static const uint32 COLOR_TABLE_1[256];
static const uint32 *COLOR_TABLES[2];
- static const uint32 *_colorTable;
+ bool _dirty;
public:
- static uint32 _renderColor;
+ uint32 _renderColor;
+ const uint32 *_colorTable;
public:
- DrawSurface() {
+ DrawSurface() : _renderColor(0), _colorTable(DEFAULT_COLOR_TABLE),
+ _dirty(false) {
reset();
}
@@ -83,9 +85,10 @@ public:
*/
void reset();
- static void setColorTable(uint index);
+ void setColorTable(uint index);
uint getPenColor(uint8 opcode) const;
uint32 getFillColor(uint8 index);
+ void setColor(uint32 color);
void drawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color);
void drawBox(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color);
@@ -97,9 +100,9 @@ public:
void clearScreen(uint32 color);
/**
- * Render the surface to the screen's picture window
+ * Render the surface to the screen if it's changed
*/
- void render();
+ void renderIfDirty();
};
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 459d1a6753..b1e0194f83 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -1026,7 +1026,7 @@ void comprehend_load_game(ComprehendGame *game) {
game->_itemImages.load(game->_itemGraphicFiles);
if (game->_colorTable)
- DrawSurface::setColorTable(game->_colorTable);
+ g_comprehend->_drawSurface->setColorTable(game->_colorTable);
}
// FIXME: This can be merged, don't need to keep start room around
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index d14bc60308..5dc6eaa32a 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -76,13 +76,11 @@ void ImageFileData::load(const char *filename) {
void ImageFileData::draw(uint index, ImageContext *ctx) {
_fb.seek(_imageOffsets[index]);
- DrawSurface ds;
for (bool done = false; !done;) {
- done = doImageOp(&ds, ctx);
+ done = doImageOp(g_comprehend->_drawSurface, ctx);
if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
getchar();
- ds.render();
}
}
}
@@ -317,18 +315,15 @@ void draw_image(ImageData *info, unsigned index) {
}
void draw_dark_room() {
- DrawSurface ds;
- ds.clearScreen(G_COLOR_BLACK);
+ g_comprehend->_drawSurface->clearScreen(G_COLOR_BLACK);
}
void draw_bright_room() {
- DrawSurface ds;
- ds.clearScreen(G_COLOR_WHITE);
+ g_comprehend->_drawSurface->clearScreen(G_COLOR_WHITE);
}
void draw_location_image(ImageData *info, unsigned index) {
- DrawSurface ds;
- ds.clearScreen(G_COLOR_WHITE);
+ g_comprehend->_drawSurface->clearScreen(G_COLOR_WHITE);
draw_image(info, index);
}
Commit: 3c4bcc9790fcb3eb32d0c3dfac18873c98e212a4
https://github.com/scummvm/scummvm/commit/3c4bcc9790fcb3eb32d0c3dfac18873c98e212a4
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Hooking up engine save/load methods
Changed paths:
engines/glk/comprehend/comprehend.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index b74e71a266..83e2ccb79e 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -133,14 +133,16 @@ void Comprehend::readLine(char *buffer, size_t maxLen) {
}
Common::Error Comprehend::readSaveData(Common::SeekableReadStream *rs) {
- // TODO
+ Common::Serializer s(rs, nullptr);
+ _game->synchronizeSave(s);
_game->_updateFlags = UPDATE_ALL;
return Common::kNoError;
}
Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
- // TODO
+ Common::Serializer s(nullptr, ws);
+ _game->synchronizeSave(s);
return Common::kNoError;
}
Commit: b26044de81e7f4a635ed50fccbf4e55774ef8129
https://github.com/scummvm/scummvm/commit/b26044de81e7f4a635ed50fccbf4e55774ef8129
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Changing _rooms to be a Common::Array
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index e3b92f4547..b176368aed 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -290,9 +290,9 @@ void DebuggerDumper::dumpRooms() {
Room *room;
uint i;
- /* Room zero acts as the players inventory */
- print("Rooms (%u entries)\n", (uint)_game->_nr_rooms);
- for (i = 1; i <= _game->_nr_rooms; i++) {
+ // Room zero acts as the players inventory
+ print("Rooms (%u entries)\n", (uint)_game->_rooms.size() - 1);
+ for (i = 1; i < _game->_rooms.size(); i++) {
room = &_game->_rooms[i];
print(" [%.2x] flags=%.2x, graphic=%.2x\n",
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index f65951dc06..1cc2658714 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -63,12 +63,12 @@ void ComprehendGame::synchronizeSave(Common::Serializer &s) {
for (i = 0; i < ARRAY_SIZE(_flags); i++)
s.syncAsByte(_flags[i]);
- // Rooms
- nr_rooms = _nr_rooms;
- s.syncAsByte(_nr_rooms);
- assert(nr_rooms == _nr_rooms);
+ // Rooms. Note that index 0 is the player's inventory
+ nr_rooms = _rooms.size();
+ s.syncAsByte(nr_rooms);
+ assert(nr_rooms == _rooms.size());
- for (i = 0; i < _nr_rooms; ++i) {
+ for (i = 1; i < _rooms.size(); ++i) {
s.syncAsUint16LE(_rooms[i].string_desc);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
s.syncAsByte(_rooms[i].direction[dir]);
@@ -231,7 +231,7 @@ static Room *get_room(ComprehendGame *game, uint16 index) {
if (index == 0)
error("Room index 0 (player inventory) is invalid");
- if (index - 1 >= (int)game->_nr_rooms)
+ if (index >= (int)game->_rooms.size())
error("Room index %d is invalid", index);
return &game->_rooms[index];
@@ -418,7 +418,7 @@ static void update(ComprehendGame *game) {
}
static void move_to(ComprehendGame *game, uint8 room) {
- if (room - 1 >= (int)game->_nr_rooms)
+ if (room >= (int)game->_rooms.size())
error("Attempted to move to invalid room %.2x\n", room);
game->_currentRoom = room;
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index b1e0194f83..5644c3b002 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -164,7 +164,6 @@ void GameInfo::clearInfo() {
_header.clear();
_comprehendVersion = 0;
_startRoom = 0;
- _nr_rooms = 0;
_currentRoom = 0;
_words = nullptr;
_nr_words = 0;
@@ -178,8 +177,7 @@ void GameInfo::clearInfo() {
_roomImages.clear();
_itemImages.clear();
- for (uint idx = 0; idx < 0x100; ++idx)
- _rooms[idx].clear();
+ _rooms.clear();
for (uint idx = 0; idx < 0xff; ++idx)
_items[idx].clear();
for (uint idx = 0; idx < 0xff; ++idx)
@@ -669,7 +667,7 @@ static void parse_items(ComprehendGame *game, FileBuffer *fb) {
}
static void parse_rooms(ComprehendGame *game, FileBuffer *fb) {
- size_t nr_rooms = game->_nr_rooms;
+ size_t nr_rooms = game->_rooms.size() - 1;
int i;
/* Room exit directions */
@@ -959,8 +957,8 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
parse_variables(game, fb);
parse_flags(game, fb);
- game->_nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
- header->room_direction_table[DIRECTION_NORTH];
+ game->_rooms.resize(header->room_direction_table[DIRECTION_SOUTH] -
+ header->room_direction_table[DIRECTION_NORTH] + 1);
game->_nr_words = (addr_dictionary_end -
header->addr_dictionary) /
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 5eb4b66787..014b9b4ce2 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -216,8 +216,7 @@ struct GameInfo {
uint8 _startRoom;
- Room _rooms[0x100];
- size_t _nr_rooms;
+ Common::Array<Room> _rooms;
uint8 _currentRoom;
struct Item _items[0xff];
Commit: 4d5146341ad2b032c2161c1bb7c8287db02dc018
https://github.com/scummvm/scummvm/commit/4d5146341ad2b032c2161c1bb7c8287db02dc018
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Change _items to Common::Array
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index b176368aed..64b9bc4f44 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -316,8 +316,8 @@ void DebuggerDumper::dumpItems() {
Item *item;
uint i, j;
- print("Items (%u entries)\n", (uint)_game->_header.nr_items);
- for (i = 0; i < _game->_header.nr_items; i++) {
+ print("Items (%u entries)\n", _game->_items.size());
+ for (i = 0; i < _game->_items.size(); i++) {
item = &_game->_items[i];
print(" [%.2x] %s\n", i + 1,
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 1cc2658714..97a2f2babe 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -78,10 +78,11 @@ void ComprehendGame::synchronizeSave(Common::Serializer &s) {
}
// Objects
- nr_items = _header.nr_items;
- s.syncAsByte(_header.nr_items);
+ nr_items = _items.size();
+ s.syncAsByte(nr_items);
+ assert(nr_items == _items.size());
- for (i = 0; i < nr_items; ++i)
+ for (i = 0; i < _items.size(); ++i)
_items[i].synchronize(s);
}
@@ -238,7 +239,7 @@ static Room *get_room(ComprehendGame *game, uint16 index) {
}
Item *get_item(ComprehendGame *game, uint16 index) {
- if (index >= game->_header.nr_items)
+ if (index >= game->_items.size())
error("Bad item %d\n", index);
return &game->_items[index];
@@ -319,7 +320,7 @@ static Item *get_item_by_noun(ComprehendGame *game,
* (the box and the snarl-in-a-box). The player is unable
* to drop the latter because this will match the former.
*/
- for (i = 0; i < game->_header.nr_items; i++)
+ for (i = 0; i < game->_items.size(); i++)
if (game->_items[i].word == noun->_index)
return &game->_items[i];
@@ -357,7 +358,7 @@ static void update_graphics(ComprehendGame *game) {
if ((game->_updateFlags & UPDATE_GRAPHICS) ||
(game->_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
- for (i = 0; i < game->_header.nr_items; i++) {
+ for (i = 0; i < game->_items.size(); i++) {
item = &game->_items[i];
if (item->room == game->_currentRoom &&
@@ -375,7 +376,7 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
size_t count = 0;
uint i;
- for (i = 0; i < game->_header.nr_items; i++) {
+ for (i = 0; i < game->_items.size(); i++) {
item = &game->_items[i];
if (item->room == game->_currentRoom &&
@@ -386,7 +387,7 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
if (count > 0) {
console_println(game, game->stringLookup(STRING_YOU_SEE).c_str());
- for (i = 0; i < game->_header.nr_items; i++) {
+ for (i = 0; i < game->_items.size(); i++) {
item = &game->_items[i];
if (item->room == game->_currentRoom &&
@@ -447,7 +448,7 @@ static void func_set_test_result(FunctionState *func_state, bool value) {
static size_t num_objects_in_room(ComprehendGame *game, int room) {
size_t count = 0, i;
- for (i = 0; i < game->_header.nr_items; i++)
+ for (i = 0; i < game->_items.size(); i++)
if (game->_items[i].room == room)
count++;
@@ -677,7 +678,7 @@ static void eval_instruction(ComprehendGame *game,
test = false;
if (noun) {
- for (i = 0; i < game->_header.nr_items; i++) {
+ for (i = 0; i < game->_items.size(); i++) {
Item *itemP = &game->_items[i];
if (itemP->word == noun->_index &&
@@ -819,7 +820,7 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, game->stringLookup(STRING_INVENTORY).c_str());
- for (i = 0; i < game->_header.nr_items; i++) {
+ for (i = 0; i < game->_items.size(); i++) {
item = &game->_items[i];
if (item->room == ROOM_INVENTORY)
printf("%s\n",
@@ -835,7 +836,7 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, game->stringLookup(instr->operand[1]).c_str());
- for (i = 0; i < game->_header.nr_items; i++) {
+ for (i = 0; i < game->_items.size(); i++) {
item = &game->_items[i];
if (item->room == instr->operand[0])
printf("%s\n",
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 5644c3b002..3a41ad66d0 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -178,8 +178,7 @@ void GameInfo::clearInfo() {
_itemImages.clear();
_rooms.clear();
- for (uint idx = 0; idx < 0xff; ++idx)
- _items[idx].clear();
+ _items.clear();
for (uint idx = 0; idx < 0xff; ++idx)
_wordMaps[idx].clear();
for (uint idx = 0; idx < 0xffff; ++idx)
@@ -637,6 +636,7 @@ static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
static void parse_items(ComprehendGame *game, FileBuffer *fb) {
size_t nr_items = game->_header.nr_items;
+ game->_items.resize(nr_items);
/* Item descriptions */
fb->seek(game->_header.addr_item_strings);
@@ -645,7 +645,7 @@ static void parse_items(ComprehendGame *game, FileBuffer *fb) {
if (game->_comprehendVersion == 2) {
/* Comprehend version 2 adds long string descriptions */
fb->seek(game->_header.addr_item_strings +
- (game->_header.nr_items * sizeof(uint16)));
+ (game->_items.size() * sizeof(uint16)));
file_buf_get_array_le16(fb, 0, game->_items, long_string, nr_items);
}
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 014b9b4ce2..04cae7aae7 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -214,12 +214,11 @@ struct GameInfo {
unsigned _comprehendVersion;
- uint8 _startRoom;
-
Common::Array<Room> _rooms;
uint8 _currentRoom;
+ uint8 _startRoom;
- struct Item _items[0xff];
+ Common::Array<Item> _items;
Word *_words;
size_t _nr_words;
Commit: 6015d9c914e7416f1ed538114d9aaa49e8012217
https://github.com/scummvm/scummvm/commit/6015d9c914e7416f1ed538114d9aaa49e8012217
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Change _wordMaps to Common::Array
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index 64b9bc4f44..a4b5779d3b 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -266,8 +266,8 @@ void DebuggerDumper::dumpWordMap() {
WordMap *map;
uint i, j;
- print("Word pairs (%u entries)\n", (uint)_game->_nr_word_maps);
- for (i = 0; i < _game->_nr_word_maps; i++) {
+ print("Word pairs (%u entries)\n", _game->_wordMaps.size());
+ for (i = 0; i < _game->_wordMaps.size(); i++) {
map = &_game->_wordMaps[i];
for (j = 0; j < 3; j++) {
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 97a2f2babe..7f5dc65801 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -295,7 +295,7 @@ static WordIndex *is_word_pair(ComprehendGame *game,
uint i;
/* Check if this is a word pair */
- for (i = 0; i < game->_nr_word_maps; i++) {
+ for (i = 0; i < game->_wordMaps.size(); i++) {
map = &game->_wordMaps[i];
if (map->word[0].index == word1->_index &&
@@ -305,7 +305,7 @@ static WordIndex *is_word_pair(ComprehendGame *game,
return &map->word[2];
}
- return NULL;
+ return nullptr;
}
static Item *get_item_by_noun(ComprehendGame *game,
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 3a41ad66d0..2b5414337d 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -167,7 +167,6 @@ void GameInfo::clearInfo() {
_currentRoom = 0;
_words = nullptr;
_nr_words = 0;
- _nr_word_maps = 0;
_nr_actions = 0;
_nr_functions = 0;
_currentReplaceWord = 0;
@@ -179,8 +178,7 @@ void GameInfo::clearInfo() {
_rooms.clear();
_items.clear();
- for (uint idx = 0; idx < 0xff; ++idx)
- _wordMaps[idx].clear();
+ _wordMaps.clear();
for (uint idx = 0; idx < 0xffff; ++idx)
_actions[idx].clear();
for (uint idx = 0; idx < 0xffff; ++idx)
@@ -588,11 +586,10 @@ static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
}
static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
- WordMap *map;
uint8 index, type;
uint i;
- game->_nr_word_maps = 0;
+ game->_wordMaps.clear();
fb->seek(game->_header.addr_word_map);
/*
@@ -600,7 +597,7 @@ static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
* index/type values for a first and second word.
*/
while (1) {
- map = &game->_wordMaps[game->_nr_word_maps];
+ WordMap map;
index = fb->readByte();
type = fb->readByte();
@@ -609,13 +606,13 @@ static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
break;
}
- map->word[0].index = index;
- map->word[0].type = type;
- map->flags = fb->readByte();
- map->word[1].index = fb->readByte();
- map->word[1].type = fb->readByte();
+ map.word[0].index = index;
+ map.word[0].type = type;
+ map.flags = fb->readByte();
+ map.word[1].index = fb->readByte();
+ map.word[1].type = fb->readByte();
- game->_nr_word_maps++;
+ game->_wordMaps.push_back(map);
}
/* Consume two more null bytes (type and index were also null) */
@@ -626,11 +623,11 @@ static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
* index/type. The first and second words from above map to the
* target word here. E.g. 'go north' -> 'north'.
*/
- for (i = 0; i < game->_nr_word_maps; i++) {
- map = &game->_wordMaps[i];
+ for (i = 0; i < game->_wordMaps.size(); i++) {
+ WordMap &map = game->_wordMaps[i];
- map->word[2].index = fb->readByte();
- map->word[2].type = fb->readByte();
+ map.word[2].index = fb->readByte();
+ map.word[2].type = fb->readByte();
}
}
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 04cae7aae7..fa3f440781 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -223,8 +223,7 @@ struct GameInfo {
Word *_words;
size_t _nr_words;
- struct WordMap _wordMaps[0xff];
- size_t _nr_word_maps;
+ Common::Array<WordMap> _wordMaps;
StringTable _strings;
StringTable _strings2;
Commit: 0ed3473e35ba608f51fc9f3202964d031cbca191
https://github.com/scummvm/scummvm/commit/0ed3473e35ba608f51fc9f3202964d031cbca191
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Change _actions to Common::Array
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index a4b5779d3b..fcb5e81a75 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -180,8 +180,8 @@ void DebuggerDumper::dumpActionTable() {
Word *word;
uint i, j;
- print("Action table (%u entries)\n", (uint)_game->_nr_actions);
- for (i = 0; i < _game->_nr_actions; i++) {
+ print("Action table (%u entries)\n", _game->_actions.size());
+ for (i = 0; i < _game->_actions.size(); i++) {
action = &_game->_actions[i];
print("(");
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 7f5dc65801..1af2aace0f 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -1086,7 +1086,7 @@ static bool handle_sentence(ComprehendGame *game,
return false;
/* Find a matching action */
- for (i = 0; i < game->_nr_actions; i++) {
+ for (i = 0; i < game->_actions.size(); i++) {
action = &game->_actions[i];
if (action->type == ACTION_VERB_OPT_NOUN &&
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 2b5414337d..819299f86b 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -167,7 +167,6 @@ void GameInfo::clearInfo() {
_currentRoom = 0;
_words = nullptr;
_nr_words = 0;
- _nr_actions = 0;
_nr_functions = 0;
_currentReplaceWord = 0;
_updateFlags = 0;
@@ -179,8 +178,7 @@ void GameInfo::clearInfo() {
_rooms.clear();
_items.clear();
_wordMaps.clear();
- for (uint idx = 0; idx < 0xffff; ++idx)
- _actions[idx].clear();
+ _actions.clear();
for (uint idx = 0; idx < 0xffff; ++idx)
_functions[idx].clear();
@@ -261,9 +259,7 @@ static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
}
}
-static void parse_action_table_vvnn(ComprehendGame *game,
- FileBuffer *fb, size_t *index) {
- Action *action;
+static void parse_action_table_vvnn(ComprehendGame *game, FileBuffer *fb) {
uint8 verb, count;
int i, j;
@@ -285,29 +281,27 @@ static void parse_action_table_vvnn(ComprehendGame *game,
count = fb->readByte();
for (i = 0; i < count; i++) {
- action = &game->_actions[*index];
- action->type = ACTION_VERB_VERB_NOUN_NOUN;
+ Action action;
+ action.type = ACTION_VERB_VERB_NOUN_NOUN;
- action->nr_words = 4;
- action->word_type[0] = WORD_TYPE_VERB;
- action->word_type[1] = WORD_TYPE_VERB;
- action->word_type[2] = WORD_TYPE_NOUN_MASK;
- action->word_type[3] = WORD_TYPE_NOUN_MASK;
+ action.nr_words = 4;
+ action.word_type[0] = WORD_TYPE_VERB;
+ action.word_type[1] = WORD_TYPE_VERB;
+ action.word_type[2] = WORD_TYPE_NOUN_MASK;
+ action.word_type[3] = WORD_TYPE_NOUN_MASK;
- action->word[0] = verb;
+ action.word[0] = verb;
for (j = 0; j < 3; j++)
- action->word[j + 1] = fb->readByte();
- action->function = fb->readUint16LE();
+ action.word[j + 1] = fb->readByte();
+ action.function = fb->readUint16LE();
- (*index)++;
+ game->_actions.push_back(action);
}
}
}
-static void parse_action_table_vnjn(ComprehendGame *game,
- FileBuffer *fb, size_t *index) {
- Action *action;
+static void parse_action_table_vnjn(ComprehendGame *game, FileBuffer *fb) {
uint8 join, count;
int i;
@@ -329,30 +323,28 @@ static void parse_action_table_vnjn(ComprehendGame *game,
count = fb->readByte();
for (i = 0; i < count; i++) {
- action = &game->_actions[*index];
- action->type = ACTION_VERB_NOUN_JOIN_NOUN;
+ Action action;
+ action.type = ACTION_VERB_NOUN_JOIN_NOUN;
- action->nr_words = 4;
- action->word_type[0] = WORD_TYPE_VERB;
- action->word_type[1] = WORD_TYPE_NOUN_MASK;
- action->word_type[2] = WORD_TYPE_JOIN;
- action->word_type[3] = WORD_TYPE_NOUN_MASK;
+ action.nr_words = 4;
+ action.word_type[0] = WORD_TYPE_VERB;
+ action.word_type[1] = WORD_TYPE_NOUN_MASK;
+ action.word_type[2] = WORD_TYPE_JOIN;
+ action.word_type[3] = WORD_TYPE_NOUN_MASK;
- action->word[2] = join;
+ action.word[2] = join;
- action->word[0] = fb->readByte();
- action->word[1] = fb->readByte();
- action->word[3] = fb->readByte();
- action->function = fb->readUint16LE();
+ action.word[0] = fb->readByte();
+ action.word[1] = fb->readByte();
+ action.word[3] = fb->readByte();
+ action.function = fb->readUint16LE();
- (*index)++;
+ game->_actions.push_back(action);
}
}
}
-static void parse_action_table_vjn(ComprehendGame *game,
- FileBuffer *fb, size_t *index) {
- Action *action;
+static void parse_action_table_vjn(ComprehendGame *game, FileBuffer *fb) {
uint8 join, count;
int i;
@@ -373,27 +365,25 @@ static void parse_action_table_vjn(ComprehendGame *game,
count = fb->readByte();
for (i = 0; i < count; i++) {
- action = &game->_actions[*index];
- action->type = ACTION_VERB_JOIN_NOUN;
- action->word[1] = join;
+ Action action;
+ action.type = ACTION_VERB_JOIN_NOUN;
+ action.word[1] = join;
- action->nr_words = 3;
- action->word_type[0] = WORD_TYPE_VERB;
- action->word_type[1] = WORD_TYPE_JOIN;
- action->word_type[2] = WORD_TYPE_NOUN_MASK;
+ action.nr_words = 3;
+ action.word_type[0] = WORD_TYPE_VERB;
+ action.word_type[1] = WORD_TYPE_JOIN;
+ action.word_type[2] = WORD_TYPE_NOUN_MASK;
- action->word[0] = fb->readByte();
- action->word[2] = fb->readByte();
- action->function = fb->readUint16LE();
+ action.word[0] = fb->readByte();
+ action.word[2] = fb->readByte();
+ action.function = fb->readUint16LE();
- (*index)++;
+ game->_actions.push_back(action);
}
}
}
-static void parse_action_table_vdn(ComprehendGame *game,
- FileBuffer *fb, size_t *index) {
- Action *action;
+static void parse_action_table_vdn(ComprehendGame *game, FileBuffer *fb) {
uint8 verb, count;
int i;
@@ -414,27 +404,25 @@ static void parse_action_table_vdn(ComprehendGame *game,
count = fb->readByte();
for (i = 0; i < count; i++) {
- action = &game->_actions[*index];
- action->type = ACTION_VERB_JOIN_NOUN;
- action->word[0] = verb;
+ Action action;
+ action.type = ACTION_VERB_JOIN_NOUN;
+ action.word[0] = verb;
- action->nr_words = 3;
- action->word_type[0] = WORD_TYPE_VERB;
- action->word_type[1] = WORD_TYPE_VERB;
- action->word_type[2] = WORD_TYPE_NOUN_MASK;
+ action.nr_words = 3;
+ action.word_type[0] = WORD_TYPE_VERB;
+ action.word_type[1] = WORD_TYPE_VERB;
+ action.word_type[2] = WORD_TYPE_NOUN_MASK;
- action->word[1] = fb->readByte();
- action->word[2] = fb->readByte();
- action->function = fb->readUint16LE();
+ action.word[1] = fb->readByte();
+ action.word[2] = fb->readByte();
+ action.function = fb->readUint16LE();
- (*index)++;
+ game->_actions.push_back(action);
}
}
}
-static void parse_action_table_vnn(ComprehendGame *game,
- FileBuffer *fb, size_t *index) {
- Action *action;
+static void parse_action_table_vnn(ComprehendGame *game, FileBuffer *fb) {
uint8 verb, count;
int i;
@@ -456,27 +444,25 @@ static void parse_action_table_vnn(ComprehendGame *game,
count = fb->readByte();
for (i = 0; i < count; i++) {
- action = &game->_actions[*index];
- action->type = ACTION_VERB_NOUN_NOUN;
- action->word[0] = verb;
+ Action action;
+ action.type = ACTION_VERB_NOUN_NOUN;
+ action.word[0] = verb;
- action->nr_words = 3;
- action->word_type[0] = WORD_TYPE_VERB;
- action->word_type[1] = WORD_TYPE_NOUN_MASK;
- action->word_type[2] = WORD_TYPE_NOUN_MASK;
+ action.nr_words = 3;
+ action.word_type[0] = WORD_TYPE_VERB;
+ action.word_type[1] = WORD_TYPE_NOUN_MASK;
+ action.word_type[2] = WORD_TYPE_NOUN_MASK;
- action->word[1] = fb->readByte();
- action->word[2] = fb->readByte();
- action->function = fb->readUint16LE();
+ action.word[1] = fb->readByte();
+ action.word[2] = fb->readByte();
+ action.function = fb->readUint16LE();
- (*index)++;
+ game->_actions.push_back(action);
}
}
}
-static void parse_action_table_vn(ComprehendGame *game,
- FileBuffer *fb, size_t *index) {
- Action *action;
+static void parse_action_table_vn(ComprehendGame *game, FileBuffer *fb) {
uint8 verb, count;
int i;
@@ -497,25 +483,23 @@ static void parse_action_table_vn(ComprehendGame *game,
count = fb->readByte();
for (i = 0; i < count; i++) {
- action = &game->_actions[*index];
- action->type = ACTION_VERB_NOUN;
- action->word[0] = verb;
+ Action action;
+ action.type = ACTION_VERB_NOUN;
+ action.word[0] = verb;
- action->nr_words = 2;
- action->word_type[0] = WORD_TYPE_VERB;
- action->word_type[1] = WORD_TYPE_NOUN_MASK;
+ action.nr_words = 2;
+ action.word_type[0] = WORD_TYPE_VERB;
+ action.word_type[1] = WORD_TYPE_NOUN_MASK;
- action->word[1] = fb->readByte();
- action->function = fb->readUint16LE();
+ action.word[1] = fb->readByte();
+ action.function = fb->readUint16LE();
- (*index)++;
+ game->_actions.push_back(action);
}
}
}
-static void parse_action_table_v(ComprehendGame *game,
- FileBuffer *fb, size_t *index) {
- Action *action;
+static void parse_action_table_v(ComprehendGame *game, FileBuffer *fb) {
uint8 verb, nr_funcs;
uint16 func;
int i;
@@ -533,13 +517,13 @@ static void parse_action_table_v(ComprehendGame *game,
if (verb == 0)
break;
- action = &game->_actions[*index];
- action->type = ACTION_VERB_OPT_NOUN;
- action->word[0] = verb;
+ Action action;
+ action.type = ACTION_VERB_OPT_NOUN;
+ action.word[0] = verb;
/* Can take an optional noun (nr_words here is maximum) */
- action->nr_words = 1;
- action->word_type[0] = WORD_TYPE_VERB;
+ action.nr_words = 1;
+ action.word_type[0] = WORD_TYPE_VERB;
/*
* Default actions can have more than one function, but only
@@ -549,29 +533,29 @@ static void parse_action_table_v(ComprehendGame *game,
for (i = 0; i < nr_funcs; i++) {
func = fb->readUint16LE();
if (i == 0)
- action->function = func;
+ action.function = func;
}
- (*index)++;
+ game->_actions.push_back(action);
}
}
static void parse_action_table(ComprehendGame *game,
FileBuffer *fb) {
- game->_nr_actions = 0;
+ game->_actions.clear();
if (game->_comprehendVersion == 1) {
- parse_action_table_vvnn(game, fb, &game->_nr_actions);
- parse_action_table_vdn(game, fb, &game->_nr_actions);
+ parse_action_table_vvnn(game, fb);
+ parse_action_table_vdn(game, fb);
}
if (game->_comprehendVersion >= 2) {
- parse_action_table_vnn(game, fb, &game->_nr_actions);
+ parse_action_table_vnn(game, fb);
}
- parse_action_table_vnjn(game, fb, &game->_nr_actions);
- parse_action_table_vjn(game, fb, &game->_nr_actions);
- parse_action_table_vn(game, fb, &game->_nr_actions);
- parse_action_table_v(game, fb, &game->_nr_actions);
+ parse_action_table_vnjn(game, fb);
+ parse_action_table_vjn(game, fb);
+ parse_action_table_vn(game, fb);
+ parse_action_table_v(game, fb);
}
static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index fa3f440781..a3c737ed93 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -224,13 +224,11 @@ struct GameInfo {
size_t _nr_words;
Common::Array<WordMap> _wordMaps;
+ Common::Array<Action> _actions;
StringTable _strings;
StringTable _strings2;
- struct Action _actions[0xffff];
- size_t _nr_actions;
-
struct Function _functions[0xffff];
size_t _nr_functions;
Commit: f91628971d0ad2854b2d4d6b0b8306a13d31645b
https://github.com/scummvm/scummvm/commit/f91628971d0ad2854b2d4d6b0b8306a13d31645b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Change _functions to Common::Array
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index fcb5e81a75..f2485c1d89 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -162,8 +162,8 @@ void DebuggerDumper::dumpFunctions() {
Function *func;
uint i, j;
- print("Functions (%u entries)\n", (uint)_game->_nr_functions);
- for (i = 0; i < _game->_nr_functions; i++) {
+ print("Functions (%u entries)\n", _game->_functions.size());
+ for (i = 0; i < _game->_functions.size(); i++) {
func = &_game->_functions[i];
print("[%.4x] (%u instructions)\n", i, (uint)func->nr_instructions);
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 1af2aace0f..b76f4c42b7 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -952,9 +952,9 @@ static void eval_instruction(ComprehendGame *game,
index = instr->operand[0];
if (instr->operand[1] == 0x81)
index += 256;
- if (index >= game->_nr_functions)
+ if (index >= game->_functions.size())
error("Bad function %.4x >= %.4x\n",
- index, (uint)game->_nr_functions);
+ index, game->_functions.size());
debugC(kDebugScripts, "Calling subfunction %.4x", index);
eval_function(game, &game->_functions[index], verb, noun);
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 819299f86b..1be140269f 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -167,7 +167,6 @@ void GameInfo::clearInfo() {
_currentRoom = 0;
_words = nullptr;
_nr_words = 0;
- _nr_functions = 0;
_currentReplaceWord = 0;
_updateFlags = 0;
_strings.clear();
@@ -179,8 +178,7 @@ void GameInfo::clearInfo() {
_items.clear();
_wordMaps.clear();
_actions.clear();
- for (uint idx = 0; idx < 0xffff; ++idx)
- _functions[idx].clear();
+ _functions.clear();
Common::fill(&_flags[0], &_flags[MAX_FLAGS], false);
Common::fill(&_variables[0], &_variables[MAX_VARIABLES], 0);
@@ -245,17 +243,16 @@ static void parse_function(FileBuffer *fb, Function *func) {
}
static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
- Function *func;
-
fb->seek(game->_header.addr_vm);
+
while (1) {
- func = &game->_functions[game->_nr_functions];
+ Function func;
- parse_function(fb, func);
- if (func->nr_instructions == 0)
+ parse_function(fb, &func);
+ if (func.nr_instructions == 0)
break;
- game->_nr_functions++;
+ game->_functions.push_back(func);
}
}
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index a3c737ed93..c118f1c088 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -225,13 +225,11 @@ struct GameInfo {
Common::Array<WordMap> _wordMaps;
Common::Array<Action> _actions;
+ Common::Array<Function> _functions;
StringTable _strings;
StringTable _strings2;
- struct Function _functions[0xffff];
- size_t _nr_functions;
-
struct ImageData _roomImages;
struct ImageData _itemImages;
Commit: 08de10a9ec87af8472da77fe84c0a852c5815525
https://github.com/scummvm/scummvm/commit/08de10a9ec87af8472da77fe84c0a852c5815525
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Change _replaceWords to a StringArray
Changed paths:
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_tr.cpp
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index f2485c1d89..a84a80e878 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -150,7 +150,7 @@ Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
break;
case OPCODE_SET_STRING_REPLACEMENT:
- line += Common::String::format(" %s", game->_replaceWords[instr->operand[0] - 1]);
+ line += Common::String::format(" %s", game->_replaceWords[instr->operand[0] - 1].c_str());
break;
}
@@ -366,7 +366,7 @@ void DebuggerDumper::dumpReplaceWords() {
print("Replacement words (%u entries)\n",
_game->_replaceWords.size());
for (i = 0; i < _game->_replaceWords.size(); i++)
- print(" [%.2x] %s\n", i + 1, _game->_replaceWords[i]);
+ print(" [%.2x] %s\n", i + 1, _game->_replaceWords[i].c_str());
}
void DebuggerDumper::dumpHeader() {
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index b76f4c42b7..9ce268ddd4 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -176,7 +176,7 @@ void console_println(ComprehendGame *game, const char *text) {
game->_currentReplaceWord);
word = bad_word;
} else {
- word = game->_replaceWords[game->_currentReplaceWord];
+ word = game->_replaceWords[game->_currentReplaceWord].c_str();
}
word_len = strlen(word);
p++;
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 1be140269f..f9690264d4 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -179,13 +179,10 @@ void GameInfo::clearInfo() {
_wordMaps.clear();
_actions.clear();
_functions.clear();
+ _replaceWords.clear();
Common::fill(&_flags[0], &_flags[MAX_FLAGS], false);
Common::fill(&_variables[0], &_variables[MAX_VARIABLES], 0);
-
- for (uint idx = 0; idx < _replaceWords.size(); ++idx)
- free(_replaceWords[idx]);
- _replaceWords.clear();
}
static void parse_header_le16(FileBuffer *fb, uint16 *val) {
@@ -813,7 +810,7 @@ static void parse_replace_words(ComprehendGame *game,
if (len == 0)
break;
- game->_replaceWords.push_back(xstrndup((const char *)fb->dataPtr(), len));
+ game->_replaceWords.push_back(Common::String((const char *)fb->dataPtr(), len));
fb->skip(len + (eof ? 0 : 1));
if (eof)
break;
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index c118f1c088..c79fc0df2f 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -226,6 +226,7 @@ struct GameInfo {
Common::Array<WordMap> _wordMaps;
Common::Array<Action> _actions;
Common::Array<Function> _functions;
+ Common::StringArray _replaceWords;
StringTable _strings;
StringTable _strings2;
@@ -236,7 +237,6 @@ struct GameInfo {
bool _flags[MAX_FLAGS];
uint16 _variables[MAX_VARIABLES];
- Common::Array<char *> _replaceWords;
uint8 _currentReplaceWord;
uint _updateFlags;
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 9e2a75fa8d..d8ad0a6d72 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -164,18 +164,8 @@ void TransylvaniaGame::before_game() {
console_println(this, _strings[0x20].c_str());
g_comprehend->readLine(buffer, sizeof(buffer));
- /*
- * Transylvania uses replace word 0 as the player's name, the game
- * data file stores a bunch of dummy characters, so the length is
- * limited (the original game will break if you put a name in that
- * is too long).
- */
- if (!_replaceWords[0])
- _replaceWords[0] = xstrndup(buffer, strlen(buffer));
- else
- snprintf(_replaceWords[0],
- strlen(_replaceWords[0]),
- "%s", buffer);
+ // The player's name is stored in word 0
+ _replaceWords[0] = Common::String(buffer);
// And your next of kin - This isn't stored by the game
console_println(this, _strings[0x21].c_str());
Commit: 0831f0d93c1021167caa50b0c2dabc9a312ddadc
https://github.com/scummvm/scummvm/commit/0831f0d93c1021167caa50b0c2dabc9a312ddadc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Remove deprecated utils file
Changed paths:
R engines/glk/comprehend/util.cpp
R engines/glk/comprehend/util.h
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/draw_surface.cpp
engines/glk/comprehend/file_buf.cpp
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/image_data.cpp
engines/glk/module.mk
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index a84a80e878..2153f776ce 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -23,7 +23,6 @@
#include "glk/comprehend/debugger_dumper.h"
#include "glk/comprehend/dictionary.h"
#include "glk/comprehend/game.h"
-#include "glk/comprehend/util.h"
namespace Glk {
namespace Comprehend {
@@ -244,7 +243,7 @@ void DebuggerDumper::dumpDictionary() {
uint i;
/* Sort the dictionary by index */
- dictionary = (Word *)xmalloc(sizeof(*words) * _game->_nr_words);
+ dictionary = (Word *)malloc(sizeof(*words) * _game->_nr_words);
memcpy(dictionary, _game->_words,
sizeof(*words) * _game->_nr_words);
qsort(dictionary, _game->_nr_words, sizeof(*words),
diff --git a/engines/glk/comprehend/draw_surface.cpp b/engines/glk/comprehend/draw_surface.cpp
index 19fc1a6a65..f452470f1a 100644
--- a/engines/glk/comprehend/draw_surface.cpp
+++ b/engines/glk/comprehend/draw_surface.cpp
@@ -23,7 +23,6 @@
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/image_data.h"
-#include "glk/comprehend/util.h"
#include "glk/window_graphics.h"
namespace Glk {
diff --git a/engines/glk/comprehend/file_buf.cpp b/engines/glk/comprehend/file_buf.cpp
index 426cbf4672..e20dc0fc9f 100644
--- a/engines/glk/comprehend/file_buf.cpp
+++ b/engines/glk/comprehend/file_buf.cpp
@@ -23,7 +23,6 @@
#include "glk/comprehend/file_buf.h"
#include "common/algorithm.h"
#include "common/file.h"
-#include "glk/comprehend/util.h"
namespace Glk {
namespace Comprehend {
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 9ce268ddd4..2e5d32525d 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -29,7 +29,6 @@
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/opcode_map.h"
-#include "glk/comprehend/util.h"
namespace Glk {
namespace Comprehend {
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index f9690264d4..ab9483c61f 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -26,7 +26,6 @@
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
-#include "glk/comprehend/util.h"
namespace Glk {
namespace Comprehend {
@@ -556,7 +555,7 @@ static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
uint i;
// FIXME - fixed size 0xff array?
- game->_words = (Word *)xmalloc(game->_nr_words * sizeof(Word));
+ game->_words = (Word *)malloc(game->_nr_words * sizeof(Word));
fb->seek(game->_header.addr_dictionary);
for (i = 0; i < game->_nr_words; i++)
@@ -725,7 +724,7 @@ static Common::String parseString(FileBuffer *fb) {
encoded_len = fb->strlen();
/* Get the encoded string */
- encoded = (uint8 *)xmalloc(encoded_len + 5);
+ encoded = (uint8 *)malloc(encoded_len + 5);
memset(encoded, 0, encoded_len);
fb->read(encoded, encoded_len);
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index c79fc0df2f..42eee01cf9 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -32,6 +32,7 @@ namespace Comprehend {
#define MAX_FLAGS 64
#define MAX_VARIABLES 128
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
enum {
DIRECTION_NORTH,
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index d8ad0a6d72..220ddef4d7 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -23,7 +23,6 @@
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/game_tr.h"
-#include "glk/comprehend/util.h"
namespace Glk {
namespace Comprehend {
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 5dc6eaa32a..a06ac936c8 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -26,7 +26,6 @@
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/image_data.h"
#include "glk/comprehend/draw_surface.h"
-#include "glk/comprehend/util.h"
namespace Glk {
namespace Comprehend {
diff --git a/engines/glk/comprehend/util.cpp b/engines/glk/comprehend/util.cpp
deleted file mode 100644
index 9b600c15df..0000000000
--- a/engines/glk/comprehend/util.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* 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/comprehend/util.h"
-#include "common/debug.h"
-#include "common/str.h"
-#include "common/textconsole.h"
-
-namespace Glk {
-namespace Comprehend {
-
-void *xmalloc(size_t size) {
- void *p;
-
- p = malloc(size);
- if (!p)
- error("Out of memory");
-
- memset(p, 0, size);
- return p;
-}
-
-char *xstrndup(const char *str, size_t len) {
- char *p;
-
- Common::String s(str, len);
- p = scumm_strdup(s.c_str());
- if (!p)
- error("Out of memory");
- return p;
-}
-
-} // namespace Comprehend
-} // namespace Glk
diff --git a/engines/glk/comprehend/util.h b/engines/glk/comprehend/util.h
deleted file mode 100644
index 573fb4aa7b..0000000000
--- a/engines/glk/comprehend/util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* 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_COMPREHEND_UTIL_H
-#define GLK_COMPREHEND_UTIL_H
-
-#include "common/scummsys.h"
-
-namespace Glk {
-namespace Comprehend {
-
-#define DEBUG_IMAGE_DRAW (1 << 0)
-#define DEBUG_GAME_STATE (1 << 1)
-#define DEBUG_FUNCTIONS (1 << 2)
-#define DEBUG_ALL (~0U)
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
-void *xmalloc(size_t size);
-char *xstrndup(const char *str, size_t size);
-
-} // namespace Comprehend
-} // namespace Glk
-
-#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 692892d709..4f173fc742 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -181,7 +181,6 @@ MODULE_OBJS := \
comprehend/game_tr.o \
comprehend/image_data.o \
comprehend/opcode_map.o \
- comprehend/util.o \
frotz/bitmap_font.o \
frotz/config.o \
frotz/detection.o \
Commit: 604b8f91ca16432ad860dfb830e5a8e22adbe407
https://github.com/scummvm/scummvm/commit/604b8f91ca16432ad860dfb830e5a8e22adbe407
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Fix gcc warnings
Changed paths:
engines/glk/comprehend/debugger.h
engines/glk/comprehend/debugger_dumper.cpp
engines/glk/comprehend/debugger_dumper.h
engines/glk/comprehend/draw_surface.cpp
engines/glk/comprehend/image_data.cpp
diff --git a/engines/glk/comprehend/debugger.h b/engines/glk/comprehend/debugger.h
index 0c1113b7e2..ec6fcf8e13 100644
--- a/engines/glk/comprehend/debugger.h
+++ b/engines/glk/comprehend/debugger.h
@@ -46,7 +46,7 @@ protected:
public:
Debugger();
- ~Debugger();
+ virtual ~Debugger();
};
extern Debugger *g_debugger;
diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index 2153f776ce..fdb56ee2c4 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -127,8 +127,9 @@ Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
if (instr->nr_operands) {
line += "(";
for (i = 0; i < instr->nr_operands; i++)
- line += Common::String::format("%.2x%s", instr->operand[i]),
- i == instr->nr_operands - 1 ? ")" : ", ";
+ line += Common::String::format("%.2x%s",
+ instr->operand[i],
+ i == (instr->nr_operands - 1) ? ")" : ", ");
}
switch (opcode) {
diff --git a/engines/glk/comprehend/debugger_dumper.h b/engines/glk/comprehend/debugger_dumper.h
index 895f8a4c1c..89eda38936 100644
--- a/engines/glk/comprehend/debugger_dumper.h
+++ b/engines/glk/comprehend/debugger_dumper.h
@@ -61,9 +61,10 @@ protected:
public:
DebuggerDumper();
+ virtual ~DebuggerDumper() {}
Common::String dumpInstruction(ComprehendGame *game,
- FunctionState *func_state, Instruction *instr);
+ FunctionState *func_state, Instruction *instr);
bool dumpGameData(ComprehendGame *game, const Common::String &type);
};
diff --git a/engines/glk/comprehend/draw_surface.cpp b/engines/glk/comprehend/draw_surface.cpp
index f452470f1a..cdc4a01860 100644
--- a/engines/glk/comprehend/draw_surface.cpp
+++ b/engines/glk/comprehend/draw_surface.cpp
@@ -34,8 +34,6 @@ namespace Comprehend {
#define RENDERER_SCREEN 0
#define RENDERER_PIXEL_DATA 1
-static bool graphics_enabled;
-
const uint32 DrawSurface::PEN_COLORS[8] = {
G_COLOR_BLACK,
RGB(0x00, 0x66, 0x00),
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index a06ac936c8..3f9b8fd8e2 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -117,9 +117,8 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
if (opcode & 0x1)
a += 255;
- debugC(kDebugGraphics,
- "draw_line (%d, %d) - (%d, %d)", opcode,
- ctx->_x, ctx->_y, a, b);
+ debugC(kDebugGraphics, "draw_line (%d, %d) - (%d, %d)",
+ ctx->_x, ctx->_y, a, b);
ds->drawLine(ctx->_x, ctx->_y, a, b, ctx->_penColor);
ctx->_x = a;
@@ -134,9 +133,8 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
if (opcode & 0x1)
a += 255;
- debugC(kDebugGraphics,
- "draw_box (%d, %d) - (%d, %d)", opcode,
- ctx->_x, ctx->_y, a, b);
+ debugC(kDebugGraphics, "draw_box (%d, %d) - (%d, %d)",
+ ctx->_x, ctx->_y, a, b);
ds->drawBox(ctx->_x, ctx->_y, a, b, ctx->_penColor);
break;
Commit: 9609ef72ccb4bb91417e6a32aeb3a4892c4ebce0
https://github.com/scummvm/scummvm/commit/9609ef72ccb4bb91417e6a32aeb3a4892c4ebce0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Implement engine readChar method
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/image_data.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 83e2ccb79e..a009403082 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -38,10 +38,9 @@ namespace Comprehend {
Comprehend *g_comprehend;
-Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) :
- GlkAPI(syst, gameDesc), _topWindow(nullptr), _bottomWindow(nullptr),
- _drawSurface(nullptr), _game(nullptr),_saveSlot(-1),
- _graphicsEnabled(true), _drawFlags(0) {
+Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc), _topWindow(nullptr), _bottomWindow(nullptr),
+ _drawSurface(nullptr), _game(nullptr), _saveSlot(-1),
+ _graphicsEnabled(true), _drawFlags(0) {
g_comprehend = this;
}
@@ -132,6 +131,24 @@ void Comprehend::readLine(char *buffer, size_t maxLen) {
buffer[ev.val1] = 0;
}
+int Comprehend::readChar() {
+ _drawSurface->renderIfDirty();
+
+ glk_request_char_event(_bottomWindow);
+
+ event_t ev;
+ while (ev.type != evtype_CharInput) {
+ glk_select(&ev);
+
+ if (ev.type == evtype_Quit) {
+ glk_cancel_char_event(_bottomWindow);
+ return -1;
+ }
+ }
+
+ return ev.val1;
+}
+
Common::Error Comprehend::readSaveData(Common::SeekableReadStream *rs) {
Common::Serializer s(rs, nullptr);
_game->synchronizeSave(s);
@@ -147,6 +164,5 @@ Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
return Common::kNoError;
}
-
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 3f5e1fd8f3..c1362f8897 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -34,8 +34,6 @@ namespace Comprehend {
#undef printf
#define printf debugN
-#undef getchar
-#define getchar() (0)
#define PATH_MAX 256
@@ -122,6 +120,11 @@ public:
* Read an input line
*/
void readLine(char *buffer, size_t maxLen);
+
+ /**
+ * Read in a character
+ */
+ int readChar();
};
extern Comprehend *g_comprehend;
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 2e5d32525d..a2972a4a4c 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -139,11 +139,11 @@ static void console_init(void) {
int console_get_key(void) {
int c, dummy;
- dummy = c = getchar();
+ dummy = c = g_comprehend->readChar();
/* Clear input buffer */
while (dummy != '\n' && dummy != EOF)
- dummy = getchar();
+ dummy = g_comprehend->readChar();
return c;
}
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/image_data.cpp
index 3f9b8fd8e2..8dc7c2d08a 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/image_data.cpp
@@ -79,7 +79,8 @@ void ImageFileData::draw(uint index, ImageContext *ctx) {
for (bool done = false; !done;) {
done = doImageOp(g_comprehend->_drawSurface, ctx);
if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
- getchar();
+ if (g_comprehend->readChar() == -1)
+ return;
}
}
}
Commit: 967c6a277efe8df36a4833c96fcaa04e66351cb0
https://github.com/scummvm/scummvm/commit/967c6a277efe8df36a4833c96fcaa04e66351cb0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Remove use of printf macro
Changed paths:
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game_data.cpp
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index c1362f8897..83b5a343f2 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -32,9 +32,6 @@
namespace Glk {
namespace Comprehend {
-#undef printf
-#define printf debugN
-
#define PATH_MAX 256
struct GameInfo;
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index a2972a4a4c..2a5e2f0037 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -154,7 +154,7 @@ void console_println(ComprehendGame *game, const char *text) {
int word_len = 0;
if (!text) {
- printf("\n");
+ g_comprehend->print("\n");
return;
}
@@ -163,7 +163,7 @@ void console_println(ComprehendGame *game, const char *text) {
case '\n':
word = NULL;
word_len = 0;
- printf("\n");
+ g_comprehend->print("\n");
p++;
break;
@@ -206,7 +206,7 @@ void console_println(ComprehendGame *game, const char *text) {
/* Print this word */
if (line_length + word_len > console_winsize.ws_col) {
/* Too long - insert a line break */
- printf("\n");
+ g_comprehend->print("\n");
line_length = 0;
}
#endif
@@ -523,7 +523,7 @@ static void eval_instruction(ComprehendGame *game,
do_command = func_state->test_result;
if (func_state->or_count != 0)
- printf("Warning: or_count == %d\n",
+ g_comprehend->print("Warning: or_count == %d\n",
func_state->or_count);
func_state->or_count = 0;
@@ -669,7 +669,7 @@ static void eval_instruction(ComprehendGame *game,
* FIXME - unsure what the single operand is for.
*/
item = get_item_by_noun(game, noun);
- printf("%s\n", game->stringLookup(item->long_string).c_str());
+ g_comprehend->print("%s\n", game->stringLookup(item->long_string).c_str());
break;
case OPCODE_CURRENT_OBJECT_IN_ROOM:
@@ -822,7 +822,7 @@ static void eval_instruction(ComprehendGame *game,
for (i = 0; i < game->_items.size(); i++) {
item = &game->_items[i];
if (item->room == ROOM_INVENTORY)
- printf("%s\n",
+ g_comprehend->print("%s\n",
game->stringLookup(item->string_desc).c_str());
}
break;
@@ -838,7 +838,7 @@ static void eval_instruction(ComprehendGame *game,
for (i = 0; i < game->_items.size(); i++) {
item = &game->_items[i];
if (item->room == instr->operand[0])
- printf("%s\n",
+ g_comprehend->print("%s\n",
game->stringLookup(item->string_desc).c_str());
}
break;
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index ab9483c61f..d6dbb96572 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -699,8 +699,8 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
}
}
- /* Unknown character */
- printf("Unknown char %d, caps=%d, special=%d\n", c, capital, special);
+ // Unknown character
+ g_comprehend->print("Unknown char %d, caps=%d, special=%d\n", c, capital, special);
return '*';
}
Commit: d59873704ca780244645cf190469d112bccbf2d8
https://github.com/scummvm/scummvm/commit/d59873704ca780244645cf190469d112bccbf2d8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Converting picture drawing to an Archive abstraction
Changed paths:
A engines/glk/comprehend/pics.cpp
A engines/glk/comprehend/pics.h
R engines/glk/comprehend/image_data.cpp
R engines/glk/comprehend/image_data.h
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/debugger.cpp
engines/glk/comprehend/draw_surface.cpp
engines/glk/comprehend/draw_surface.h
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.h
engines/glk/comprehend/game_tm.h
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/game_tr.h
engines/glk/module.mk
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index a009403082..3ea7ea2f88 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -31,6 +31,7 @@
#include "glk/comprehend/game_oo.h"
#include "glk/comprehend/game_tm.h"
#include "glk/comprehend/game_tr.h"
+#include "glk/comprehend/pics.h"
#include "glk/quetzal.h"
namespace Glk {
@@ -39,8 +40,8 @@ namespace Comprehend {
Comprehend *g_comprehend;
Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc), _topWindow(nullptr), _bottomWindow(nullptr),
- _drawSurface(nullptr), _game(nullptr), _saveSlot(-1),
- _graphicsEnabled(true), _drawFlags(0) {
+ _drawSurface(nullptr), _game(nullptr), _pics(nullptr), _saveSlot(-1),
+ _graphicsEnabled(true), _drawFlags(0) {
g_comprehend = this;
}
@@ -75,10 +76,11 @@ void Comprehend::initialize() {
glk_set_window(_bottomWindow);
_topWindow->fillRect(0, Rect(0, 0, _topWindow->_w, _topWindow->_h));
- // Initialize drawing
+ // Initialize drawing surface, and the archive that abstracts
+ // the room and item graphics as as individual files
_drawSurface = new DrawSurface();
- _drawSurface->setColorTable(0);
- _drawSurface->_renderColor = 0;
+ _pics = new Pics();
+ SearchMan.add("Pics", _pics, 99, false);
}
void Comprehend::deinitialize() {
@@ -116,7 +118,6 @@ void Comprehend::print(const char *fmt, ...) {
void Comprehend::readLine(char *buffer, size_t maxLen) {
event_t ev;
- _drawSurface->renderIfDirty();
glk_request_line_event(_bottomWindow, buffer, maxLen - 1, 0);
for (;;) {
@@ -132,8 +133,6 @@ void Comprehend::readLine(char *buffer, size_t maxLen) {
}
int Comprehend::readChar() {
- _drawSurface->renderIfDirty();
-
glk_request_char_event(_bottomWindow);
event_t ev;
@@ -164,5 +163,17 @@ Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
return Common::kNoError;
}
+void Comprehend::drawLocationPicture(int pictureNum, bool clearBg) {
+ glk_image_draw(_topWindow, pictureNum + (clearBg ? LOCATIONS_OFFSET : LOCATIONS_NO_BG_OFFSET), 0, 0);
+}
+
+void Comprehend::drawItemPicture(int pictureNum) {
+ glk_image_draw(_topWindow, pictureNum + ITEMS_OFFSET, 0, 0);
+}
+
+void Comprehend::clearScreen(bool isBright) {
+ glk_image_draw(_topWindow, isBright ? BRIGHT_ROOM : DARK_ROOM, 0, 0);
+}
+
} // namespace Comprehend
} // namespace Glk
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 83b5a343f2..9327280e68 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -37,6 +37,7 @@ namespace Comprehend {
struct GameInfo;
struct gameState;
class DrawSurface;
+class Pics;
#define EXTRA_STRING_TABLE(x) (0x8200 | (x))
@@ -55,6 +56,7 @@ public:
TextBufferWindow *_bottomWindow;
DrawSurface *_drawSurface;
ComprehendGame *_game;
+ Pics *_pics;
bool _graphicsEnabled;
uint _drawFlags;
@@ -122,6 +124,21 @@ public:
* Read in a character
*/
int readChar();
+
+ /**
+ * Draw a location image
+ */
+ void drawLocationPicture(int pictureNum, bool clearBg = true);
+
+ /**
+ * Draw an item image
+ */
+ void drawItemPicture(int pictureNum);
+
+ /**
+ * Clear the picture area
+ */
+ void clearScreen(bool isBright);
};
extern Comprehend *g_comprehend;
diff --git a/engines/glk/comprehend/debugger.cpp b/engines/glk/comprehend/debugger.cpp
index 69deba5166..bbd9b0555e 100644
--- a/engines/glk/comprehend/debugger.cpp
+++ b/engines/glk/comprehend/debugger.cpp
@@ -22,6 +22,7 @@
#include "glk/comprehend/debugger.h"
#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/pics.h"
namespace Glk {
namespace Comprehend {
diff --git a/engines/glk/comprehend/draw_surface.cpp b/engines/glk/comprehend/draw_surface.cpp
index cdc4a01860..eb9cb99616 100644
--- a/engines/glk/comprehend/draw_surface.cpp
+++ b/engines/glk/comprehend/draw_surface.cpp
@@ -22,7 +22,7 @@
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/comprehend.h"
-#include "glk/comprehend/image_data.h"
+#include "glk/comprehend/pics.h"
#include "glk/window_graphics.h"
namespace Glk {
@@ -187,7 +187,6 @@ void DrawSurface::setColorTable(uint index) {
}
_colorTable = COLOR_TABLES[index];
- _dirty = true;
}
uint DrawSurface::getPenColor(uint8 opcode) const {
@@ -214,7 +213,6 @@ void DrawSurface::setColor(uint32 color) {
void DrawSurface::drawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 color) {
setColor(color);
Graphics::ManagedSurface::drawLine(x1, y1, x2, y2, _renderColor);
- _dirty = true;
}
void DrawSurface::drawBox(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
@@ -222,7 +220,6 @@ void DrawSurface::drawBox(uint16 x1, uint16 y1, uint16 x2, uint16 y2,
setColor(color);
Common::Rect r(x1, y1, x2, y2);
frameRect(r, _renderColor);
- _dirty = true;
}
void DrawSurface::drawFilledBox(uint16 x1, uint16 y1,
@@ -230,7 +227,6 @@ void DrawSurface::drawFilledBox(uint16 x1, uint16 y1,
setColor(color);
Common::Rect r(x1, y1, x2, y2);
fillRect(r, _renderColor);
- _dirty = true;
}
void DrawSurface::drawShape(int x, int y, int shape_type, uint32 fill_color) {
@@ -337,8 +333,6 @@ void DrawSurface::drawShape(int x, int y, int shape_type, uint32 fill_color) {
/* Unknown shape */
break;
}
-
- _dirty = true;
}
void DrawSurface::floodFill(int x, int y, uint32 fill_color, uint32 old_color) {
@@ -368,15 +362,12 @@ void DrawSurface::floodFill(int x, int y, uint32 fill_color, uint32 old_color) {
for (i = x1; i < x2; i++)
if (y < RENDER_Y_MAX && getPixelColor(i, y + 1) == old_color)
floodFill(i, y + 1, fill_color, old_color);
-
- _dirty = true;
}
void DrawSurface::drawPixel(uint16 x, uint16 y, uint32 color) {
setColor(color);
uint32 *ptr = (uint32 *)getBasePtr(x, y);
*ptr = _renderColor;
- _dirty = true;
}
uint32 DrawSurface::getPixelColor(uint16 x, uint16 y) {
@@ -387,18 +378,6 @@ uint32 DrawSurface::getPixelColor(uint16 x, uint16 y) {
void DrawSurface::clearScreen(uint32 color) {
setColor(color);
fillRect(Common::Rect(0, 0, this->w, this->h), _renderColor);
- _dirty = true;
-}
-
-void DrawSurface::renderIfDirty() {
- if (_dirty) {
- GraphicsWindow *win = g_comprehend->_topWindow;
- win->drawPicture(*this, (uint)-2, 0, 0, win->_w, win->_h);
- _dirty = false;
- // FIXME: Get rid of this hack and properly use the graphics window
- g_system->copyRectToScreen(getPixels(), pitch, 0, 0, w, h);
- g_system->updateScreen();
- }
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/draw_surface.h b/engines/glk/comprehend/draw_surface.h
index 71316eba13..c0de482353 100644
--- a/engines/glk/comprehend/draw_surface.h
+++ b/engines/glk/comprehend/draw_surface.h
@@ -69,14 +69,12 @@ private:
static const uint32 DEFAULT_COLOR_TABLE[256];
static const uint32 COLOR_TABLE_1[256];
static const uint32 *COLOR_TABLES[2];
- bool _dirty;
public:
uint32 _renderColor;
const uint32 *_colorTable;
public:
- DrawSurface() : _renderColor(0), _colorTable(DEFAULT_COLOR_TABLE),
- _dirty(false) {
+ DrawSurface() : _renderColor(0), _colorTable(DEFAULT_COLOR_TABLE) {
reset();
}
@@ -98,11 +96,6 @@ public:
void drawPixel(uint16 x, uint16 y, uint32 color);
uint32 getPixelColor(uint16 x, uint16 y);
void clearScreen(uint32 color);
-
- /**
- * Render the surface to the screen if it's changed
- */
- void renderIfDirty();
};
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 2a5e2f0037..b758a5b5e6 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -340,19 +340,18 @@ static void update_graphics(ComprehendGame *game) {
switch (type) {
case ROOM_IS_DARK:
if (game->_updateFlags & UPDATE_GRAPHICS)
- draw_dark_room();
+ g_comprehend->clearScreen(false);
break;
case ROOM_IS_TOO_BRIGHT:
if (game->_updateFlags & UPDATE_GRAPHICS)
- draw_bright_room();
+ g_comprehend->clearScreen(false);
break;
default:
if (game->_updateFlags & UPDATE_GRAPHICS) {
room = get_room(game, game->_currentRoom);
- draw_location_image(&game->_roomImages,
- room->graphic - 1);
+ g_comprehend->drawLocationPicture(room->graphic - 1);
}
if ((game->_updateFlags & UPDATE_GRAPHICS) ||
@@ -362,8 +361,7 @@ static void update_graphics(ComprehendGame *game) {
if (item->room == game->_currentRoom &&
item->graphic != 0)
- draw_image(&game->_itemImages,
- item->graphic - 1);
+ g_comprehend->drawItemPicture(item->graphic - 1);
}
}
break;
@@ -1002,12 +1000,11 @@ static void eval_instruction(ComprehendGame *game,
break;
case OPCODE_DRAW_ROOM:
- draw_location_image(&game->_roomImages,
- instr->operand[0] - 1);
+ g_comprehend->drawLocationPicture(instr->operand[0] - 1);
break;
case OPCODE_DRAW_OBJECT:
- draw_image(&game->_itemImages, instr->operand[0] - 1);
+ g_comprehend->drawItemPicture(instr->operand[0] - 1);
break;
case OPCODE_WAIT_KEY:
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 90d1a29032..f9a959bfa0 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_ComprehendGame_H
-#define GLK_ComprehendGame_H
+#ifndef GLK_COMPREHEND_GAME_H
+#define GLK_COMPREHEND_GAME_H
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/opcode_map.h"
@@ -42,8 +42,8 @@ public:
const char *_gameDataFile;
Common::Array<StringFile> _stringFiles;
- Common::Array<const char *> _locationGraphicFiles;
- Common::Array<const char *> _itemGraphicFiles;
+ Common::StringArray _locationGraphicFiles;
+ Common::StringArray _itemGraphicFiles;
unsigned _colorTable;
struct GameStrings *_gameStrings;
diff --git a/engines/glk/comprehend/game_cc.h b/engines/glk/comprehend/game_cc.h
index a60d9f2317..7ca5bd10b2 100644
--- a/engines/glk/comprehend/game_cc.h
+++ b/engines/glk/comprehend/game_cc.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_ComprehendGame_CC_H
-#define GLK_ComprehendGame_CC_H
+#ifndef GLK_COMPREHEND_GAME_CC_H
+#define GLK_COMPREHEND_GAME_CC_H
#include "glk/comprehend/game.h"
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index d6dbb96572..add5462f83 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -26,6 +26,7 @@
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
+#include "glk/comprehend/pics.h"
namespace Glk {
namespace Comprehend {
@@ -170,8 +171,6 @@ void GameInfo::clearInfo() {
_updateFlags = 0;
_strings.clear();
_strings2.clear();
- _roomImages.clear();
- _itemImages.clear();
_rooms.clear();
_items.clear();
@@ -993,9 +992,9 @@ void comprehend_load_game(ComprehendGame *game) {
load_game_data(game);
if (g_comprehend->_graphicsEnabled) {
- // Set up image files
- game->_roomImages.load(game->_locationGraphicFiles);
- game->_itemImages.load(game->_itemGraphicFiles);
+ // Set up the picture archive
+ g_comprehend->_pics->load(game->_locationGraphicFiles,
+ game->_itemGraphicFiles);
if (game->_colorTable)
g_comprehend->_drawSurface->setColorTable(game->_colorTable);
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 42eee01cf9..557c16e015 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef GLK_ComprehendGame_DATA_H
-#define GLK_ComprehendGame_DATA_H
+#ifndef GLK_COMPREHEND_GAME_DATA_H
+#define GLK_COMPREHEND_GAME_DATA_H
-#include "glk/comprehend/image_data.h"
+#include "glk/comprehend/file_buf.h"
#include "common/serializer.h"
#include "common/str-array.h"
@@ -34,6 +34,8 @@ namespace Comprehend {
#define MAX_VARIABLES 128
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+class ComprehendGame;
+
enum {
DIRECTION_NORTH,
DIRECTION_SOUTH,
@@ -232,9 +234,6 @@ struct GameInfo {
StringTable _strings;
StringTable _strings2;
- struct ImageData _roomImages;
- struct ImageData _itemImages;
-
bool _flags[MAX_FLAGS];
uint16 _variables[MAX_VARIABLES];
diff --git a/engines/glk/comprehend/game_oo.h b/engines/glk/comprehend/game_oo.h
index 469a85e384..bfac91ec9b 100644
--- a/engines/glk/comprehend/game_oo.h
+++ b/engines/glk/comprehend/game_oo.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_ComprehendGame_OO_H
-#define GLK_ComprehendGame_OO_H
+#ifndef GLK_COMPREHEND_GAME_OO_H
+#define GLK_COMPREHEND_GAME_OO_H
#include "glk/comprehend/game.h"
diff --git a/engines/glk/comprehend/game_tm.h b/engines/glk/comprehend/game_tm.h
index 86c9cf20bb..0e1fc33038 100644
--- a/engines/glk/comprehend/game_tm.h
+++ b/engines/glk/comprehend/game_tm.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_ComprehendGame_TM_H
-#define GLK_ComprehendGame_TM_H
+#ifndef GLK_COMPREHEND_GAME_TM_H
+#define GLK_COMPREHEND_GAME_TM_H
#include "glk/comprehend/game.h"
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 220ddef4d7..0cd7a8bd78 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -149,7 +149,7 @@ void TransylvaniaGame::handle_special_opcode(uint8 operand)
* Show the Zin screen in reponse to doing 'sing some enchanted
* evening' in his cabin.
*/
- draw_location_image(&_roomImages, 41);
+ g_comprehend->drawLocationPicture(41);
console_get_key();
_updateFlags |= UPDATE_GRAPHICS;
break;
diff --git a/engines/glk/comprehend/game_tr.h b/engines/glk/comprehend/game_tr.h
index c9d4fdddb7..ef20981efb 100644
--- a/engines/glk/comprehend/game_tr.h
+++ b/engines/glk/comprehend/game_tr.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef GLK_ComprehendGame_TR_H
-#define GLK_ComprehendGame_TR_H
+#ifndef GLK_COMPREHEND_GAME_TR_H
+#define GLK_COMPREHEND_GAME_TR_H
#include "glk/comprehend/game.h"
diff --git a/engines/glk/comprehend/image_data.h b/engines/glk/comprehend/image_data.h
deleted file mode 100644
index 3ea4f2e92b..0000000000
--- a/engines/glk/comprehend/image_data.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* 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_COMPREHEND_IMAGE_DATA_H
-#define GLK_COMPREHEND_IMAGE_DATA_H
-
-#include "glk/comprehend/file_buf.h"
-#include "glk/comprehend/draw_surface.h"
-#include "common/scummsys.h"
-
-namespace Glk {
-namespace Comprehend {
-
-class ComprehendGame;
-struct FileBuffer;
-struct ImageContext;
-
-struct ImageFileData {
-private:
- Common::Array<uint16> _imageOffsets;
- FileBuffer _fb;
-
-private:
- bool doImageOp(DrawSurface *ds, ImageContext *ctx);
- uint16 imageGetOperand();
-
- public:
- void load(const char *filename);
-
- void draw(uint index, ImageContext *ctx);
-};
-
-struct ImageData {
-private:
- Common::Array<ImageFileData> _files;
-
-public:
- ImageData();
- void clear();
-
- uint size() const { return _files.size(); }
- ImageFileData &operator[](uint index) { return _files[index]; }
-
- void load(const Common::Array<const char *> &filenames);
-};
-
-#define IMAGEF_OP_WAIT_KEYPRESS (1 << 0)
-#define IMAGEF_NO_FLOODFILL (1 << 1)
-
-#define IMAGE_OP_SCENE_END 0x00
-
-#define IMAGE_OP_SET_TEXT_POS 0x10
-
-#define IMAGE_OP_PEN_COLOR_A 0x20
-#define IMAGE_OP_PEN_COLOR_B 0x21
-#define IMAGE_OP_PEN_COLOR_C 0x22
-#define IMAGE_OP_PEN_COLOR_D 0x23
-#define IMAGE_OP_PEN_COLOR_E 0x24
-#define IMAGE_OP_PEN_COLOR_F 0x25
-#define IMAGE_OP_PEN_COLOR_G 0x26
-#define IMAGE_OP_PEN_COLOR_H 0x27
-
-#define IMAGE_OP_DRAW_CHAR 0x30
-
-#define IMAGE_OP_SHAPE_PIXEL 0x40
-#define IMAGE_OP_SHAPE_BOX 0x41
-#define IMAGE_OP_SHAPE_CIRCLE_TINY 0x42
-#define IMAGE_OP_SHAPE_CIRCLE_SMALL 0x43
-#define IMAGE_OP_SHAPE_CIRCLE_MED 0x44
-#define IMAGE_OP_SHAPE_CIRCLE_LARGE 0x45
-#define IMAGE_OP_SHAPE_A 0x46
-#define IMAGE_OP_SHAPE_SPRAY 0x47
-
-#define IMAGE_OP_EOF 0x55
-
-#define IMAGE_OP_FILL_COLOR 0x60
-
-#define IMAGE_OP_MOVE_TO 0x80
-#define IMAGE_OP_MOVE_TO_FAR 0x81
-
-#define IMAGE_OP_DRAW_BOX 0x90
-#define IMAGE_OP_DRAW_BOX_FAR 0x91
-
-#define IMAGE_OP_DRAW_LINE 0xa0
-#define IMAGE_OP_DRAW_LINE_FAR 0xa1
-
-#define IMAGE_OP_DRAW_SHAPE 0xc0
-#define IMAGE_OP_DRAW_SHAPE_FAR 0xc1
-
-#define IMAGE_OP_PAINT 0xe0
-#define IMAGE_OP_PAINT_FAR 0xe1
-
-void image_set_draw_flags(unsigned flags);
-
-void draw_dark_room(void);
-void draw_bright_room(void);
-void draw_image(ImageData *info, unsigned index);
-void draw_location_image(ImageData *info, unsigned index);
-
-} // namespace Comprehend
-} // namespace Glk
-
-#endif
diff --git a/engines/glk/comprehend/image_data.cpp b/engines/glk/comprehend/pics.cpp
similarity index 51%
rename from engines/glk/comprehend/image_data.cpp
rename to engines/glk/comprehend/pics.cpp
index 8dc7c2d08a..0b7ff1e5d7 100644
--- a/engines/glk/comprehend/image_data.cpp
+++ b/engines/glk/comprehend/pics.cpp
@@ -24,7 +24,7 @@
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/image_data.h"
+#include "glk/comprehend/pics.h"
#include "glk/comprehend/draw_surface.h"
namespace Glk {
@@ -32,65 +32,53 @@ namespace Comprehend {
#define IMAGES_PER_FILE 16
-struct ImageContext {
- unsigned _x;
- unsigned _y;
- unsigned _penColor;
- unsigned fill_color;
- unsigned shape;
-
- unsigned text_x;
- unsigned text_y;
-};
-
-static unsigned draw_flags;
-
/*-------------------------------------------------------*/
-void ImageFileData::load(const char *filename) {
+Pics::ImageFile::ImageFile(const Common::String &filename) {
+ Common::File f;
uint16 version;
int i;
- _fb = FileBuffer(filename);
+ if (!f.open(filename))
+ error("Could not open file - %s", filename.c_str());
/*
* In earlier versions of Comprehend the first word is 0x1000 and
* the image offsets start four bytes in. In newer versions the
* image offsets start at the beginning of the image file.
*/
- version = _fb.readUint16LE();
+ version = f.readUint16LE();
if (version == 0x1000)
- _fb.seek(4);
+ f.seek(4);
else
- _fb.seek(0);
+ f.seek(0);
// Get the image offsets in the file
_imageOffsets.resize(IMAGES_PER_FILE);
for (i = 0; i < IMAGES_PER_FILE; i++) {
- _imageOffsets[i] = _fb.readUint16LE();
+ _imageOffsets[i] = f.readUint16LE();
if (version == 0x1000)
_imageOffsets[i] += 4;
}
}
-void ImageFileData::draw(uint index, ImageContext *ctx) {
- _fb.seek(_imageOffsets[index]);
+void Pics::ImageFile::draw(uint index, ImageContext *ctx) {
+ if (!ctx->_file.open(_filename))
+ error("Opening image file");
+
+ ctx->_file.seek(_imageOffsets[index]);
for (bool done = false; !done;) {
- done = doImageOp(g_comprehend->_drawSurface, ctx);
- if (!done && (draw_flags & IMAGEF_OP_WAIT_KEYPRESS)) {
- if (g_comprehend->readChar() == -1)
- return;
- }
+ done = doImageOp(ctx);
}
}
-bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
+bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) {
uint8 opcode;
uint16 a, b;
- opcode = _fb.readByte();
- debugCN(kDebugGraphics, " %.4x [%.2x]: ", _fb.pos() - 1, opcode);
+ opcode = ctx->_file.readByte();
+ debugCN(kDebugGraphics, " %.4x [%.2x]: ", ctx->_file.pos() - 1, opcode);
switch (opcode) {
case IMAGE_OP_SCENE_END:
@@ -107,20 +95,20 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case IMAGE_OP_PEN_COLOR_G:
case IMAGE_OP_PEN_COLOR_H:
debugC(kDebugGraphics, "set_pen_color(%.2x)", opcode);
- ctx->_penColor = ds->getPenColor(opcode);
+ ctx->_penColor = ctx->_drawSurface->getPenColor(opcode);
break;
case IMAGE_OP_DRAW_LINE:
case IMAGE_OP_DRAW_LINE_FAR:
- a = imageGetOperand();
- b = imageGetOperand();
+ a = imageGetOperand(ctx);
+ b = imageGetOperand(ctx);
if (opcode & 0x1)
a += 255;
debugC(kDebugGraphics, "draw_line (%d, %d) - (%d, %d)",
ctx->_x, ctx->_y, a, b);
- ds->drawLine(ctx->_x, ctx->_y, a, b, ctx->_penColor);
+ ctx->_drawSurface->drawLine(ctx->_x, ctx->_y, a, b, ctx->_penColor);
ctx->_x = a;
ctx->_y = b;
@@ -128,8 +116,8 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case IMAGE_OP_DRAW_BOX:
case IMAGE_OP_DRAW_BOX_FAR:
- a = imageGetOperand();
- b = imageGetOperand();
+ a = imageGetOperand(ctx);
+ b = imageGetOperand(ctx);
if (opcode & 0x1)
a += 255;
@@ -137,14 +125,14 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
debugC(kDebugGraphics, "draw_box (%d, %d) - (%d, %d)",
ctx->_x, ctx->_y, a, b);
- ds->drawBox(ctx->_x, ctx->_y, a, b, ctx->_penColor);
+ ctx->_drawSurface->drawBox(ctx->_x, ctx->_y, a, b, ctx->_penColor);
break;
case IMAGE_OP_MOVE_TO:
case IMAGE_OP_MOVE_TO_FAR:
/* Move to */
- a = imageGetOperand();
- b = imageGetOperand();
+ a = imageGetOperand(ctx);
+ b = imageGetOperand(ctx);
if (opcode & 0x1)
a += 255;
@@ -164,70 +152,70 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case IMAGE_OP_SHAPE_SPRAY:
debugC(kDebugGraphics,
"set_shape_type(%.2x)", opcode - 0x40);
- ctx->shape = opcode;
+ ctx->_shape = opcode;
break;
case 0x48:
/*
- * FIXME - This appears to be a shape type. Only used by
+ * FIXME - This appears to be a _shape type. Only used by
* OO-Topos.
*/
debugC(kDebugGraphics, "shape_unknown()");
- ctx->shape = IMAGE_OP_SHAPE_PIXEL;
+ ctx->_shape = IMAGE_OP_SHAPE_PIXEL;
break;
case IMAGE_OP_DRAW_SHAPE:
case IMAGE_OP_DRAW_SHAPE_FAR:
- a = imageGetOperand();
- b = imageGetOperand();
+ a = imageGetOperand(ctx);
+ b = imageGetOperand(ctx);
if (opcode & 0x1)
a += 255;
debugC(kDebugGraphics, "draw_shape(%d, %d), style=%.2x, fill=%.2x",
- a, b, ctx->shape, ctx->fill_color);
+ a, b, ctx->_shape, ctx->_fillColor);
- ds->drawShape(a, b, ctx->shape, ctx->fill_color);
+ ctx->_drawSurface->drawShape(a, b, ctx->_shape, ctx->_fillColor);
break;
case IMAGE_OP_PAINT:
case IMAGE_OP_PAINT_FAR:
/* Paint */
- a = imageGetOperand();
- b = imageGetOperand();
+ a = imageGetOperand(ctx);
+ b = imageGetOperand(ctx);
if (opcode & 0x1)
a += 255;
debugC(kDebugGraphics, "paint(%d, %d)", a, b);
- if (!(draw_flags & IMAGEF_NO_FLOODFILL))
- ds->floodFill(a, b, ctx->fill_color,
- ds->getPixelColor(a, b));
+ if (!(ctx->_drawFlags & IMAGEF_NO_FLOODFILL))
+ ctx->_drawSurface->floodFill(a, b, ctx->_fillColor,
+ ctx->_drawSurface->getPixelColor(a, b));
break;
case IMAGE_OP_FILL_COLOR:
- a = imageGetOperand();
+ a = imageGetOperand(ctx);
debugC(kDebugGraphics, "set_fill_color(%.2x)", a);
- ctx->fill_color = ds->getFillColor(a);
+ ctx->_fillColor = ctx->_drawSurface->getFillColor(a);
break;
case IMAGE_OP_SET_TEXT_POS:
- a = imageGetOperand();
- b = imageGetOperand();
+ a = imageGetOperand(ctx);
+ b = imageGetOperand(ctx);
debugC(kDebugGraphics, "set_text_pos(%d, %d)", a, b);
- ctx->text_x = a;
- ctx->text_y = b;
+ ctx->_textX = a;
+ ctx->_textY = b;
break;
case IMAGE_OP_DRAW_CHAR:
- a = imageGetOperand();
+ a = imageGetOperand(ctx);
debugC(kDebugGraphics, "draw_char(%c)",
a >= 0x20 && a < 0x7f ? a : '?');
- ds->drawBox(ctx->text_x, ctx->text_y,
- ctx->text_x + 6, ctx->text_y + 7, ctx->fill_color);
- ctx->text_x += 8;
+ ctx->_drawSurface->drawBox(ctx->_textX, ctx->_textY,
+ ctx->_textX + 6, ctx->_textY + 7, ctx->_fillColor);
+ ctx->_textX += 8;
break;
case 0xf3:
@@ -249,7 +237,7 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
case 0xb0:
case 0xd0:
/* FIXME - unknown, one argument */
- a = imageGetOperand();
+ a = imageGetOperand(ctx);
debugC(kDebugGraphics, "unknown %.2x: (%.2x) '%c'",
opcode, a,
a >= 0x20 && a < 0x7f ? a : '?');
@@ -257,72 +245,109 @@ bool ImageFileData::doImageOp(DrawSurface *ds, ImageContext *ctx) {
default:
/* FIXME - Unknown, two arguments */
- a = imageGetOperand();
- b = imageGetOperand();
+ a = imageGetOperand(ctx);
+ b = imageGetOperand(ctx);
debugC(kDebugGraphics, "unknown(%.2x, %.2x)", a, b);
- ds->drawPixel(a, b, 0x00ff00ff);
+ ctx->_drawSurface->drawPixel(a, b, 0x00ff00ff);
break;
}
return false;
}
-uint16 ImageFileData::imageGetOperand() {
- return _fb.readByte();
+uint16 Pics::ImageFile::imageGetOperand(ImageContext *ctx) {
+ return ctx->_file.readByte();
}
/*-------------------------------------------------------*/
-ImageData::ImageData() {
+void Pics::clear() {
+ _rooms.clear();
+ _items.clear();
}
+void Pics::load(const Common::StringArray &roomFiles,
+ const Common::StringArray &itemFiles) {
+ clear();
-void ImageData::clear() {
- _files.clear();
+ for (uint idx = 0; idx < roomFiles.size(); ++idx)
+ _rooms.push_back(ImageFile(roomFiles[idx]));
+ for (uint idx = 0; idx < itemFiles.size(); ++idx)
+ _items.push_back(ImageFile(itemFiles[idx]));
}
-void ImageData::load(const Common::Array<const char *> &filenames) {
- // Set up files array
- clear();
- _files.resize(filenames.size());
+int Pics::getPictureNumber(const Common::String &filename) const {
+ // Ensure prefix and suffix
+ if (!filename.hasPrefixIgnoreCase("pic") ||
+ !filename.hasSuffixIgnoreCase(".png"))
+ return -1;
- // Iterate through loading each file
- for (uint idx = 0; idx < filenames.size(); ++idx)
- _files[idx].load(filenames[idx]);
+ // Get the number part
+ Common::String num(filename.c_str() + 3, filename.size() - 7);
+ if (num.empty() || !Common::isDigit(num[0]))
+ return -1;
+
+ return atoi(num.c_str());
}
-/*-------------------------------------------------------*/
+bool Pics::hasFile(const Common::String &name) const {
+ int num = getPictureNumber(name);
+ if (num == -1)
+ return false;
+
+ if (num == DARK_ROOM || num == BRIGHT_ROOM)
+ return true;
+ if (num >= ITEMS_OFFSET && num < (int)(ITEMS_OFFSET + _items.size() * IMAGES_PER_FILE))
+ return true;
+ if (num < ITEMS_OFFSET && (num % 100) < (int)(_rooms.size() * IMAGES_PER_FILE))
+ return true;
-void image_set_draw_flags(unsigned flags) {
- draw_flags |= flags;
+ return false;
}
-void draw_image(ImageData *info, unsigned index) {
- ImageContext ctx = {
- 0, 0, G_COLOR_BLACK, G_COLOR_BLACK, IMAGE_OP_SHAPE_CIRCLE_LARGE, 0, 0
- };
+int Pics::listMembers(Common::ArchiveMemberList &list) const {
+ return list.size();
+}
- if (index >= (info->size() * IMAGES_PER_FILE)) {
- warning("Bad image index %.8x (max=%.8x)\n", index,
- (uint)info->size());
- return;
- }
+const Common::ArchiveMemberPtr Pics::getMember(const Common::String &name) const {
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
- (*info)[index / IMAGES_PER_FILE].draw(index % IMAGES_PER_FILE, &ctx);
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
-void draw_dark_room() {
- g_comprehend->_drawSurface->clearScreen(G_COLOR_BLACK);
-}
+Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::String &name) const {
+ // Get the picture number
+ int num = getPictureNumber(name);
+ if (num == -1 || !hasFile(name))
+ return nullptr;
-void draw_bright_room() {
- g_comprehend->_drawSurface->clearScreen(G_COLOR_WHITE);
+ // TODO
+ error("TODO: createReadStream");
}
-void draw_location_image(ImageData *info, unsigned index) {
- g_comprehend->_drawSurface->clearScreen(G_COLOR_WHITE);
- draw_image(info, index);
+void Pics::drawPicture(int pictureNum) {
+ ImageContext ctx(g_comprehend->_drawSurface, g_comprehend->_drawFlags);
+
+ if (pictureNum == DARK_ROOM) {
+ ctx._drawSurface->clearScreen(G_COLOR_BLACK);
+
+ } else if (pictureNum == BRIGHT_ROOM) {
+ ctx._drawSurface->clearScreen(G_COLOR_WHITE);
+
+ } else if (pictureNum >= ITEMS_OFFSET) {
+ _items[pictureNum / IMAGES_PER_FILE].draw(
+ pictureNum % IMAGES_PER_FILE, &ctx);
+
+ } else {
+ if (pictureNum < LOCATIONS_NO_BG_OFFSET)
+ ctx._drawSurface->clearScreen(G_COLOR_WHITE);
+
+ pictureNum %= 100;
+ _rooms[pictureNum / IMAGES_PER_FILE].draw(
+ pictureNum % IMAGES_PER_FILE, &ctx);
+ }
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/pics.h b/engines/glk/comprehend/pics.h
new file mode 100644
index 0000000000..8e4fc57806
--- /dev/null
+++ b/engines/glk/comprehend/pics.h
@@ -0,0 +1,176 @@
+/* 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_COMPREHEND_PICS_H
+#define GLK_COMPREHEND_PICS_H
+
+#include "glk/comprehend/draw_surface.h"
+#include "common/archive.h"
+
+namespace Glk {
+namespace Comprehend {
+
+#define IMAGE_OP_SCENE_END 0x00
+
+#define IMAGE_OP_SET_TEXT_POS 0x10
+
+#define IMAGE_OP_PEN_COLOR_A 0x20
+#define IMAGE_OP_PEN_COLOR_B 0x21
+#define IMAGE_OP_PEN_COLOR_C 0x22
+#define IMAGE_OP_PEN_COLOR_D 0x23
+#define IMAGE_OP_PEN_COLOR_E 0x24
+#define IMAGE_OP_PEN_COLOR_F 0x25
+#define IMAGE_OP_PEN_COLOR_G 0x26
+#define IMAGE_OP_PEN_COLOR_H 0x27
+
+#define IMAGE_OP_DRAW_CHAR 0x30
+
+#define IMAGE_OP_SHAPE_PIXEL 0x40
+#define IMAGE_OP_SHAPE_BOX 0x41
+#define IMAGE_OP_SHAPE_CIRCLE_TINY 0x42
+#define IMAGE_OP_SHAPE_CIRCLE_SMALL 0x43
+#define IMAGE_OP_SHAPE_CIRCLE_MED 0x44
+#define IMAGE_OP_SHAPE_CIRCLE_LARGE 0x45
+#define IMAGE_OP_SHAPE_A 0x46
+#define IMAGE_OP_SHAPE_SPRAY 0x47
+
+#define IMAGE_OP_EOF 0x55
+
+#define IMAGE_OP_FILL_COLOR 0x60
+
+#define IMAGE_OP_MOVE_TO 0x80
+#define IMAGE_OP_MOVE_TO_FAR 0x81
+
+#define IMAGE_OP_DRAW_BOX 0x90
+#define IMAGE_OP_DRAW_BOX_FAR 0x91
+
+#define IMAGE_OP_DRAW_LINE 0xa0
+#define IMAGE_OP_DRAW_LINE_FAR 0xa1
+
+#define IMAGE_OP_DRAW_SHAPE 0xc0
+#define IMAGE_OP_DRAW_SHAPE_FAR 0xc1
+
+#define IMAGE_OP_PAINT 0xe0
+#define IMAGE_OP_PAINT_FAR 0xe1
+
+#define IMAGEF_NO_FLOODFILL (1 << 1)
+
+enum {
+ LOCATIONS_OFFSET = 0,
+ LOCATIONS_NO_BG_OFFSET = 100,
+ ITEMS_OFFSET = 200,
+ DARK_ROOM = 1000,
+ BRIGHT_ROOM = 1001
+};
+
+class Pics : public Common::Archive {
+ struct ImageContext {
+ Common::File _file;
+ DrawSurface *_drawSurface;
+ uint _drawFlags;
+
+ uint16 _x;
+ uint16 _y;
+ uint32 _penColor;
+ uint32 _fillColor;
+ uint32 _shape;
+
+ uint16 _textX;
+ uint16 _textY;
+
+ ImageContext(DrawSurface *drawSurface, uint flags) :
+ _drawSurface(drawSurface), _drawFlags(0), _x(0), _y(0),
+ _penColor(G_COLOR_BLACK), _fillColor(G_COLOR_BLACK),
+ _shape(IMAGE_OP_SHAPE_CIRCLE_LARGE), _textX(0), _textY(0) {
+ }
+
+ };
+
+ struct ImageFile {
+ private:
+ Common::Array<uint16> _imageOffsets;
+ Common::String _filename;
+
+ private:
+ bool doImageOp(ImageContext *ctx);
+ uint16 imageGetOperand(ImageContext *ctx);
+
+ public:
+ ImageFile() {}
+ ImageFile(const Common::String &filename);
+
+ void draw(uint index, ImageContext *ctx);
+ };
+
+private:
+ Common::Array<ImageFile> _rooms;
+ Common::Array<ImageFile> _items;
+
+private:
+ /**
+ * Returns the image number if the passed filename is a picture
+ */
+ int getPictureNumber(const Common::String &filename) const;
+
+ /**
+ * Draw the specified picture
+ */
+ void drawPicture(int pictureNum);
+
+public:
+ void clear();
+
+ void load(const Common::StringArray &roomFiles,
+ const Common::StringArray &itemFiles);
+
+ /**
+ * Check if a member with the given name is present in the Archive.
+ * Patterns are not allowed, as this is meant to be a quick File::exists()
+ * replacement.
+ */
+ bool hasFile(const Common::String &name) const override;
+
+ /**
+ * Add all members of the Archive to list.
+ * Must only append to list, and not remove elements from it.
+ *
+ * @return the number of names added to list
+ */
+ int listMembers(Common::ArchiveMemberList &list) const override;
+
+ /**
+ * Returns a ArchiveMember representation of the given file.
+ */
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+
+ /**
+ * Create a stream bound to a member with the specified name in the
+ * archive. If no member with this name exists, 0 is returned.
+ * @return the newly created input stream
+ */
+ Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+};
+
+} // namespace Comprehend
+} // namespace Glk
+
+#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 4f173fc742..aa5c0aba34 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -179,8 +179,8 @@ MODULE_OBJS := \
comprehend/game_oo.o \
comprehend/game_tm.o \
comprehend/game_tr.o \
- comprehend/image_data.o \
comprehend/opcode_map.o \
+ comprehend/pics.o \
frotz/bitmap_font.o \
frotz/config.o \
frotz/detection.o \
Commit: f7e40621ce24feda8c44cf47348e1ad7ca2ad5dc
https://github.com/scummvm/scummvm/commit/f7e40621ce24feda8c44cf47348e1ad7ca2ad5dc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Finish implementing PIcs archive
Changed paths:
engines/glk/comprehend/pics.cpp
engines/glk/comprehend/pics.h
engines/glk/raw_decoder.cpp
diff --git a/engines/glk/comprehend/pics.cpp b/engines/glk/comprehend/pics.cpp
index 0b7ff1e5d7..16299e3010 100644
--- a/engines/glk/comprehend/pics.cpp
+++ b/engines/glk/comprehend/pics.cpp
@@ -26,6 +26,7 @@
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/pics.h"
#include "glk/comprehend/draw_surface.h"
+#include "common/memstream.h"
namespace Glk {
namespace Comprehend {
@@ -39,6 +40,7 @@ Pics::ImageFile::ImageFile(const Common::String &filename) {
uint16 version;
int i;
+ _filename = filename;
if (!f.open(filename))
error("Could not open file - %s", filename.c_str());
@@ -62,7 +64,7 @@ Pics::ImageFile::ImageFile(const Common::String &filename) {
}
}
-void Pics::ImageFile::draw(uint index, ImageContext *ctx) {
+void Pics::ImageFile::draw(uint index, ImageContext *ctx) const {
if (!ctx->_file.open(_filename))
error("Opening image file");
@@ -73,7 +75,7 @@ void Pics::ImageFile::draw(uint index, ImageContext *ctx) {
}
}
-bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) {
+bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
uint8 opcode;
uint16 a, b;
@@ -256,7 +258,7 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) {
return false;
}
-uint16 Pics::ImageFile::imageGetOperand(ImageContext *ctx) {
+uint16 Pics::ImageFile::imageGetOperand(ImageContext *ctx) const {
return ctx->_file.readByte();
}
@@ -280,7 +282,7 @@ void Pics::load(const Common::StringArray &roomFiles,
int Pics::getPictureNumber(const Common::String &filename) const {
// Ensure prefix and suffix
if (!filename.hasPrefixIgnoreCase("pic") ||
- !filename.hasSuffixIgnoreCase(".png"))
+ !filename.hasSuffixIgnoreCase(".raw"))
return -1;
// Get the number part
@@ -323,11 +325,22 @@ Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::String
if (num == -1 || !hasFile(name))
return nullptr;
- // TODO
- error("TODO: createReadStream");
+ // Draw the image
+ drawPicture(num);
+
+ // Create a stream with the data for the surface
+ Common::MemoryReadWriteStream *stream =
+ new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
+ const DrawSurface &ds = *g_comprehend->_drawSurface;
+ stream->writeUint16LE(ds.w);
+ stream->writeUint16LE(ds.h);
+ stream->writeUint16LE(0); // Palette size
+ stream->write(ds.getPixels(), ds.w * ds.h * 4);
+
+ return stream;
}
-void Pics::drawPicture(int pictureNum) {
+void Pics::drawPicture(int pictureNum) const {
ImageContext ctx(g_comprehend->_drawSurface, g_comprehend->_drawFlags);
if (pictureNum == DARK_ROOM) {
diff --git a/engines/glk/comprehend/pics.h b/engines/glk/comprehend/pics.h
index 8e4fc57806..99c931016b 100644
--- a/engines/glk/comprehend/pics.h
+++ b/engines/glk/comprehend/pics.h
@@ -111,14 +111,14 @@ class Pics : public Common::Archive {
Common::String _filename;
private:
- bool doImageOp(ImageContext *ctx);
- uint16 imageGetOperand(ImageContext *ctx);
+ bool doImageOp(ImageContext *ctx) const;
+ uint16 imageGetOperand(ImageContext *ctx) const;
public:
ImageFile() {}
ImageFile(const Common::String &filename);
- void draw(uint index, ImageContext *ctx);
+ void draw(uint index, ImageContext *ctx) const;
};
private:
@@ -134,7 +134,7 @@ private:
/**
* Draw the specified picture
*/
- void drawPicture(int pictureNum);
+ void drawPicture(int pictureNum) const;
public:
void clear();
diff --git a/engines/glk/raw_decoder.cpp b/engines/glk/raw_decoder.cpp
index cf3700371b..d2643307e6 100644
--- a/engines/glk/raw_decoder.cpp
+++ b/engines/glk/raw_decoder.cpp
@@ -47,28 +47,37 @@ bool RawDecoder::loadStream(Common::SeekableReadStream &stream) {
uint width = stream.readUint16LE();
uint height = stream.readUint16LE();
_paletteColorCount = stream.readUint16LE();
- assert(_paletteColorCount > 0);
+ assert(_paletteColorCount == 0 || _paletteColorCount <= 0x100);
- // Read in the palette
- _palette = new byte[_paletteColorCount * 3];
- stream.read(_palette, _paletteColorCount * 3);
+ if (_paletteColorCount != 0) {
+ // Read in the palette
+ _palette = new byte[_paletteColorCount * 3];
+ stream.read(_palette, _paletteColorCount * 3);
- // Get the transparent color
- byte transColor = stream.readByte();
- if (transColor < _paletteColorCount)
- _transColor = transColor;
+ // Get the transparent color
+ byte transColor = stream.readByte();
+ if (transColor < _paletteColorCount)
+ _transColor = transColor;
+ } else {
+ _transColor = 0;
+ }
- // Set up the surface and read it in
- _surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ // Set up the surface
+ _surface.create(width, height, (_paletteColorCount == 0) ?
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0) :
+ Graphics::PixelFormat::createFormatCLUT8());
- assert((stream.size() - stream.pos()) == (int)(width * height));
+ assert((stream.size() - stream.pos()) ==
+ (int)(width * height * _surface.format.bytesPerPixel));
byte *pixels = (byte *)_surface.getPixels();
- stream.read(pixels, width * height);
+ stream.read(pixels, width * height * _surface.format.bytesPerPixel);
- for (uint idx = 0; idx < width * height; ++idx, ++pixels) {
- assert(*pixels != 0xff);
- if (*pixels >= _paletteColorCount)
- *pixels = _paletteColorCount - 1;
+ if (_palette) {
+ for (uint idx = 0; idx < width * height; ++idx, ++pixels) {
+ assert(*pixels != 0xff);
+ if (*pixels >= _paletteColorCount)
+ *pixels = _paletteColorCount - 1;
+ }
}
return true;
Commit: ead0a1bdd47063a076426e8ba1f541121585ed02
https://github.com/scummvm/scummvm/commit/ead0a1bdd47063a076426e8ba1f541121585ed02
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:11-07:00
Commit Message:
GLK: COMPREHEND: Proper freeing of Pics on exit
Changed paths:
engines/glk/comprehend/comprehend.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 3ea7ea2f88..646863fb4b 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -48,6 +48,7 @@ Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkA
Comprehend::~Comprehend() {
delete _drawSurface;
delete _game;
+ SearchMan.remove("Pics"); // This also deletes it
g_comprehend = nullptr;
}
@@ -80,7 +81,7 @@ void Comprehend::initialize() {
// the room and item graphics as as individual files
_drawSurface = new DrawSurface();
_pics = new Pics();
- SearchMan.add("Pics", _pics, 99, false);
+ SearchMan.add("Pics", _pics, 99, true);
}
void Comprehend::deinitialize() {
Commit: 088bb3caf452be9503379fd3d8a51698b1d2bcad
https://github.com/scummvm/scummvm/commit/088bb3caf452be9503379fd3d8a51698b1d2bcad
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Draw images doubled-sized to properly fill screen
Changed paths:
engines/glk/comprehend/comprehend.cpp
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 646863fb4b..9ee1830e9b 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -165,15 +165,16 @@ Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
}
void Comprehend::drawLocationPicture(int pictureNum, bool clearBg) {
- glk_image_draw(_topWindow, pictureNum + (clearBg ? LOCATIONS_OFFSET : LOCATIONS_NO_BG_OFFSET), 0, 0);
+ glk_image_draw_scaled(_topWindow, pictureNum + (clearBg ? LOCATIONS_OFFSET : LOCATIONS_NO_BG_OFFSET),
+ 0, 0, 640, 480);
}
void Comprehend::drawItemPicture(int pictureNum) {
- glk_image_draw(_topWindow, pictureNum + ITEMS_OFFSET, 0, 0);
+ glk_image_draw_scaled(_topWindow, pictureNum + ITEMS_OFFSET, 0, 0, 640, 480);
}
void Comprehend::clearScreen(bool isBright) {
- glk_image_draw(_topWindow, isBright ? BRIGHT_ROOM : DARK_ROOM, 0, 0);
+ glk_image_draw_scaled(_topWindow, isBright ? BRIGHT_ROOM : DARK_ROOM, 0, 0, 640, 480);
}
} // namespace Comprehend
Commit: 9a8d5e51d29bbbfb174ccaf47b91223280a78551
https://github.com/scummvm/scummvm/commit/9a8d5e51d29bbbfb174ccaf47b91223280a78551
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Fix drawing of items on-screen
Changed paths:
engines/glk/comprehend/pics.cpp
diff --git a/engines/glk/comprehend/pics.cpp b/engines/glk/comprehend/pics.cpp
index 16299e3010..09a1203822 100644
--- a/engines/glk/comprehend/pics.cpp
+++ b/engines/glk/comprehend/pics.cpp
@@ -350,6 +350,7 @@ void Pics::drawPicture(int pictureNum) const {
ctx._drawSurface->clearScreen(G_COLOR_WHITE);
} else if (pictureNum >= ITEMS_OFFSET) {
+ pictureNum -= ITEMS_OFFSET;
_items[pictureNum / IMAGES_PER_FILE].draw(
pictureNum % IMAGES_PER_FILE, &ctx);
Commit: 21eb8249785f51c3f712acd3b9467df3e6ea38da
https://github.com/scummvm/scummvm/commit/21eb8249785f51c3f712acd3b9467df3e6ea38da
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Fix parsing string table
Changed paths:
engines/glk/comprehend/game_data.cpp
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index add5462f83..7ad7e9b895 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -713,7 +713,7 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
*/
static Common::String parseString(FileBuffer *fb) {
bool capital_next = false, special_next = false;
- unsigned i, j, k = 0;
+ unsigned i, j;
uint64 chunk;
uint8 elem, *encoded;
char c;
@@ -724,7 +724,7 @@ static Common::String parseString(FileBuffer *fb) {
/* Get the encoded string */
encoded = (uint8 *)malloc(encoded_len + 5);
- memset(encoded, 0, encoded_len);
+ Common::fill(encoded, encoded + encoded_len + 5, 0);
fb->read(encoded, encoded_len);
/* Skip over the zero byte */
@@ -749,7 +749,6 @@ static Common::String parseString(FileBuffer *fb) {
special_next = false;
capital_next = false;
string += c;
- k++;
}
}
}
Commit: c6346f2db033e9cae2001cd0e958c01872bf3afe
https://github.com/scummvm/scummvm/commit/c6346f2db033e9cae2001cd0e958c01872bf3afe
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Better placement of location images
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/draw_surface.h
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 9ee1830e9b..22e0eda472 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -21,8 +21,6 @@
*/
#include "glk/comprehend/comprehend.h"
-#include "common/config-manager.h"
-#include "common/translation.h"
#include "glk/comprehend/debugger.h"
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/game.h"
@@ -33,10 +31,17 @@
#include "glk/comprehend/game_tr.h"
#include "glk/comprehend/pics.h"
#include "glk/quetzal.h"
+#include "common/config-manager.h"
+#include "common/translation.h"
+#include "engines/util.h"
namespace Glk {
namespace Comprehend {
+// Even with no ScummVM scaling, internally we do a 2x scaling to
+// render on a 640x480 window, to allow for better looking text
+#define SCALE_FACTOR 2
+
Comprehend *g_comprehend;
Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc), _topWindow(nullptr), _bottomWindow(nullptr),
@@ -53,6 +58,11 @@ Comprehend::~Comprehend() {
g_comprehend = nullptr;
}
+void Comprehend::initGraphicsMode() {
+ Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+ initGraphics(640, 400, &pixelFormat);
+}
+
void Comprehend::runGame() {
initialize();
@@ -64,6 +74,7 @@ void Comprehend::runGame() {
deinitialize();
}
+
void Comprehend::initialize() {
// Set up the GLK windows
g_conf->_wMarginX = 0;
@@ -72,7 +83,7 @@ void Comprehend::initialize() {
_bottomWindow = (TextBufferWindow *)glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
_topWindow = (GraphicsWindow *)glk_window_open(_bottomWindow,
winmethod_Above | winmethod_Fixed,
- 400, wintype_Graphics, 2);
+ 160 * SCALE_FACTOR, wintype_Graphics, 2);
glk_set_window(_bottomWindow);
_topWindow->fillRect(0, Rect(0, 0, _topWindow->_w, _topWindow->_h));
@@ -166,15 +177,17 @@ Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
void Comprehend::drawLocationPicture(int pictureNum, bool clearBg) {
glk_image_draw_scaled(_topWindow, pictureNum + (clearBg ? LOCATIONS_OFFSET : LOCATIONS_NO_BG_OFFSET),
- 0, 0, 640, 480);
+ 20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
}
void Comprehend::drawItemPicture(int pictureNum) {
- glk_image_draw_scaled(_topWindow, pictureNum + ITEMS_OFFSET, 0, 0, 640, 480);
+ glk_image_draw_scaled(_topWindow, pictureNum + ITEMS_OFFSET,
+ 20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
}
void Comprehend::clearScreen(bool isBright) {
- glk_image_draw_scaled(_topWindow, isBright ? BRIGHT_ROOM : DARK_ROOM, 0, 0, 640, 480);
+ glk_image_draw_scaled(_topWindow, isBright ? BRIGHT_ROOM : DARK_ROOM,
+ 20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index 9327280e68..a70ab80b33 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -94,6 +94,11 @@ public:
*/
InterpreterType getInterpreterType() const override { return INTERPRETER_SCOTT; }
+ /**
+ * Initialize the graphics
+ */
+ void initGraphicsMode() override;
+
/**
* Execute the game
*/
diff --git a/engines/glk/comprehend/draw_surface.h b/engines/glk/comprehend/draw_surface.h
index c0de482353..2ed332b063 100644
--- a/engines/glk/comprehend/draw_surface.h
+++ b/engines/glk/comprehend/draw_surface.h
@@ -29,39 +29,39 @@
namespace Glk {
namespace Comprehend {
-#define G_RENDER_WIDTH 320
-#define G_RENDER_HEIGHT 240
+#define G_RENDER_WIDTH 280
+#define G_RENDER_HEIGHT 200
#define RGB(r, g, b) (uint32)(((r) << 24) | ((g) << 16) | ((b) << 8) | 0xff)
-#define G_COLOR_BLACK 0x000000ff
-#define G_COLOR_WHITE 0xffffffff
-#define G_COLOR_CYAN 0x3366ffff
-#define G_COLOR_YELLOW 0xffff00ff
-#define G_COLOR_RED 0xff0000ff
+#define G_COLOR_BLACK 0x000000ff
+#define G_COLOR_WHITE 0xffffffff
+#define G_COLOR_CYAN 0x3366ffff
+#define G_COLOR_YELLOW 0xffff00ff
+#define G_COLOR_RED 0xff0000ff
-#define G_COLOR_GRAY0 0x202020ff
-#define G_COLOR_GRAY1 0x404040ff
-#define G_COLOR_GRAY2 0x808080ff
-#define G_COLOR_GRAY3 0xc0c0c0ff
+#define G_COLOR_GRAY0 0x202020ff
+#define G_COLOR_GRAY1 0x404040ff
+#define G_COLOR_GRAY2 0x808080ff
+#define G_COLOR_GRAY3 0xc0c0c0ff
-#define G_COLOR_LIGHT_ORANGE 0xff9966ff
-#define G_COLOR_ORANGE 0xff9900ff
-#define G_COLOR_DARK_PURPLE 0x666699ff
-#define G_COLOR_DARK_BLUE 0x000099ff
+#define G_COLOR_LIGHT_ORANGE 0xff9966ff
+#define G_COLOR_ORANGE 0xff9900ff
+#define G_COLOR_DARK_PURPLE 0x666699ff
+#define G_COLOR_DARK_BLUE 0x000099ff
-#define G_COLOR_DARK_RED 0xcc0033ff
-#define G_COLOR_DITHERED_PINK 0xff6699ff
+#define G_COLOR_DARK_RED 0xcc0033ff
+#define G_COLOR_DITHERED_PINK 0xff6699ff
-#define G_COLOR_DARK_GREEN1 0x009966ff
-#define G_COLOR_DARK_GREEN2 0x003300ff
+#define G_COLOR_DARK_GREEN1 0x009966ff
+#define G_COLOR_DARK_GREEN2 0x003300ff
-#define G_COLOR_AQUA 0x33ccccff
+#define G_COLOR_AQUA 0x33ccccff
-#define G_COLOR_GREEN 0x33cc00ff
+#define G_COLOR_GREEN 0x33cc00ff
-#define G_COLOR_BROWN1 0x7a5200ff
-#define G_COLOR_BROWN2 0x663300ff
+#define G_COLOR_BROWN1 0x7a5200ff
+#define G_COLOR_BROWN2 0x663300ff
class DrawSurface : public Graphics::ManagedSurface {
private:
Commit: a06ed9ef2fdfbeb3a1d471f691f9974277881de9
https://github.com/scummvm/scummvm/commit/a06ed9ef2fdfbeb3a1d471f691f9974277881de9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Added loading of Transylvania title
Changed paths:
engines/glk/comprehend/comprehend.cpp
engines/glk/comprehend/comprehend.h
engines/glk/comprehend/game.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_tr.cpp
engines/glk/comprehend/pics.cpp
engines/glk/comprehend/pics.h
diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 22e0eda472..a661568ef8 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -175,19 +175,21 @@ Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
return Common::kNoError;
}
+void Comprehend::drawPicture(uint pictureNum) {
+ glk_image_draw_scaled(_topWindow, pictureNum,
+ 20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
+}
+
void Comprehend::drawLocationPicture(int pictureNum, bool clearBg) {
- glk_image_draw_scaled(_topWindow, pictureNum + (clearBg ? LOCATIONS_OFFSET : LOCATIONS_NO_BG_OFFSET),
- 20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
+ drawPicture(pictureNum + (clearBg ? LOCATIONS_OFFSET : LOCATIONS_NO_BG_OFFSET));
}
void Comprehend::drawItemPicture(int pictureNum) {
- glk_image_draw_scaled(_topWindow, pictureNum + ITEMS_OFFSET,
- 20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
+ drawPicture(pictureNum + ITEMS_OFFSET);
}
void Comprehend::clearScreen(bool isBright) {
- glk_image_draw_scaled(_topWindow, isBright ? BRIGHT_ROOM : DARK_ROOM,
- 20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
+ drawPicture(isBright ? BRIGHT_ROOM : DARK_ROOM);
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index a70ab80b33..25bc6549ba 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -24,10 +24,10 @@
#define GLK_COMPREHEND_COMPREHEND_H
#include "common/scummsys.h"
+#include "glk/comprehend/game.h"
#include "glk/glk_api.h"
#include "glk/window_graphics.h"
#include "glk/window_text_buffer.h"
-#include "glk/comprehend/game.h"
namespace Glk {
namespace Comprehend {
@@ -50,7 +50,7 @@ struct GameStrings {
*/
class Comprehend : public GlkAPI {
private:
- int _saveSlot; ///< Save slot when loading savegame from launcher
+ int _saveSlot; ///< Save slot when loading savegame from launcher
public:
GraphicsWindow *_topWindow;
TextBufferWindow *_bottomWindow;
@@ -130,6 +130,11 @@ public:
*/
int readChar();
+ /**
+ * Draw a picture
+ */
+ void drawPicture(uint pictureNum);
+
/**
* Draw a location image
*/
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index f9a959bfa0..c6f7c0e668 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -44,6 +44,7 @@ public:
Common::Array<StringFile> _stringFiles;
Common::StringArray _locationGraphicFiles;
Common::StringArray _itemGraphicFiles;
+ Common::String _titleGraphicFile;
unsigned _colorTable;
struct GameStrings *_gameStrings;
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 7ad7e9b895..45cbab53c0 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -993,7 +993,7 @@ void comprehend_load_game(ComprehendGame *game) {
if (g_comprehend->_graphicsEnabled) {
// Set up the picture archive
g_comprehend->_pics->load(game->_locationGraphicFiles,
- game->_itemGraphicFiles);
+ game->_itemGraphicFiles, game->_titleGraphicFile);
if (game->_colorTable)
g_comprehend->_drawSurface->setColorTable(game->_colorTable);
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 0cd7a8bd78..c63e7c7b9c 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -23,6 +23,7 @@
#include "glk/comprehend/comprehend.h"
#include "glk/comprehend/game_data.h"
#include "glk/comprehend/game_tr.h"
+#include "glk/comprehend/pics.h"
namespace Glk {
namespace Comprehend {
@@ -59,6 +60,7 @@ TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
_itemGraphicFiles.push_back("OB.MS1");
_itemGraphicFiles.push_back("OC.MS1");
+ _titleGraphicFile = "trtitle.ms1";
_gameStrings = &tr_strings;
}
@@ -159,6 +161,9 @@ void TransylvaniaGame::handle_special_opcode(uint8 operand)
void TransylvaniaGame::before_game() {
char buffer[128];
+ // Draw the title
+ g_comprehend->drawPicture(TITLE_IMAGE);
+
// Welcome to Transylvania - sign your name
console_println(this, _strings[0x20].c_str());
g_comprehend->readLine(buffer, sizeof(buffer));
diff --git a/engines/glk/comprehend/pics.cpp b/engines/glk/comprehend/pics.cpp
index 09a1203822..3105c6b000 100644
--- a/engines/glk/comprehend/pics.cpp
+++ b/engines/glk/comprehend/pics.cpp
@@ -20,18 +20,18 @@
*
*/
+#include "glk/comprehend/pics.h"
+#include "common/memstream.h"
#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
#include "glk/comprehend/game_data.h"
-#include "glk/comprehend/pics.h"
-#include "glk/comprehend/draw_surface.h"
-#include "common/memstream.h"
namespace Glk {
namespace Comprehend {
-#define IMAGES_PER_FILE 16
+#define IMAGES_PER_FILE 16
/*-------------------------------------------------------*/
@@ -50,6 +50,12 @@ Pics::ImageFile::ImageFile(const Common::String &filename) {
* image offsets start at the beginning of the image file.
*/
version = f.readUint16LE();
+ if (version == 0x6300 /* Single image file */) {
+ _imageOffsets.resize(1);
+ _imageOffsets[0] = 4;
+ return;
+ }
+
if (version == 0x1000)
f.seek(4);
else
@@ -109,7 +115,7 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
a += 255;
debugC(kDebugGraphics, "draw_line (%d, %d) - (%d, %d)",
- ctx->_x, ctx->_y, a, b);
+ ctx->_x, ctx->_y, a, b);
ctx->_drawSurface->drawLine(ctx->_x, ctx->_y, a, b, ctx->_penColor);
ctx->_x = a;
@@ -125,7 +131,7 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
a += 255;
debugC(kDebugGraphics, "draw_box (%d, %d) - (%d, %d)",
- ctx->_x, ctx->_y, a, b);
+ ctx->_x, ctx->_y, a, b);
ctx->_drawSurface->drawBox(ctx->_x, ctx->_y, a, b, ctx->_penColor);
break;
@@ -153,7 +159,7 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
case IMAGE_OP_SHAPE_A:
case IMAGE_OP_SHAPE_SPRAY:
debugC(kDebugGraphics,
- "set_shape_type(%.2x)", opcode - 0x40);
+ "set_shape_type(%.2x)", opcode - 0x40);
ctx->_shape = opcode;
break;
@@ -175,7 +181,7 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
a += 255;
debugC(kDebugGraphics, "draw_shape(%d, %d), style=%.2x, fill=%.2x",
- a, b, ctx->_shape, ctx->_fillColor);
+ a, b, ctx->_shape, ctx->_fillColor);
ctx->_drawSurface->drawShape(a, b, ctx->_shape, ctx->_fillColor);
break;
@@ -192,7 +198,7 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
debugC(kDebugGraphics, "paint(%d, %d)", a, b);
if (!(ctx->_drawFlags & IMAGEF_NO_FLOODFILL))
ctx->_drawSurface->floodFill(a, b, ctx->_fillColor,
- ctx->_drawSurface->getPixelColor(a, b));
+ ctx->_drawSurface->getPixelColor(a, b));
break;
case IMAGE_OP_FILL_COLOR:
@@ -213,10 +219,10 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
case IMAGE_OP_DRAW_CHAR:
a = imageGetOperand(ctx);
debugC(kDebugGraphics, "draw_char(%c)",
- a >= 0x20 && a < 0x7f ? a : '?');
+ a >= 0x20 && a < 0x7f ? a : '?');
ctx->_drawSurface->drawBox(ctx->_textX, ctx->_textY,
- ctx->_textX + 6, ctx->_textY + 7, ctx->_fillColor);
+ ctx->_textX + 6, ctx->_textY + 7, ctx->_fillColor);
ctx->_textX += 8;
break;
@@ -241,8 +247,8 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
/* FIXME - unknown, one argument */
a = imageGetOperand(ctx);
debugC(kDebugGraphics, "unknown %.2x: (%.2x) '%c'",
- opcode, a,
- a >= 0x20 && a < 0x7f ? a : '?');
+ opcode, a,
+ a >= 0x20 && a < 0x7f ? a : '?');
break;
default:
@@ -270,13 +276,17 @@ void Pics::clear() {
}
void Pics::load(const Common::StringArray &roomFiles,
- const Common::StringArray &itemFiles) {
+ const Common::StringArray &itemFiles,
+ const Common::String &titleFile) {
clear();
for (uint idx = 0; idx < roomFiles.size(); ++idx)
_rooms.push_back(ImageFile(roomFiles[idx]));
for (uint idx = 0; idx < itemFiles.size(); ++idx)
_items.push_back(ImageFile(itemFiles[idx]));
+
+ if (!titleFile.empty())
+ _title = ImageFile(titleFile);
}
int Pics::getPictureNumber(const Common::String &filename) const {
@@ -298,7 +308,7 @@ bool Pics::hasFile(const Common::String &name) const {
if (num == -1)
return false;
- if (num == DARK_ROOM || num == BRIGHT_ROOM)
+ if (num == DARK_ROOM || num == BRIGHT_ROOM || num == TITLE_IMAGE)
return true;
if (num >= ITEMS_OFFSET && num < (int)(ITEMS_OFFSET + _items.size() * IMAGES_PER_FILE))
return true;
@@ -334,7 +344,7 @@ Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::String
const DrawSurface &ds = *g_comprehend->_drawSurface;
stream->writeUint16LE(ds.w);
stream->writeUint16LE(ds.h);
- stream->writeUint16LE(0); // Palette size
+ stream->writeUint16LE(0); // Palette size
stream->write(ds.getPixels(), ds.w * ds.h * 4);
return stream;
@@ -349,6 +359,9 @@ void Pics::drawPicture(int pictureNum) const {
} else if (pictureNum == BRIGHT_ROOM) {
ctx._drawSurface->clearScreen(G_COLOR_WHITE);
+ } else if (pictureNum == TITLE_IMAGE) {
+ _title.draw(0, &ctx);
+
} else if (pictureNum >= ITEMS_OFFSET) {
pictureNum -= ITEMS_OFFSET;
_items[pictureNum / IMAGES_PER_FILE].draw(
@@ -360,7 +373,7 @@ void Pics::drawPicture(int pictureNum) const {
pictureNum %= 100;
_rooms[pictureNum / IMAGES_PER_FILE].draw(
- pictureNum % IMAGES_PER_FILE, &ctx);
+ pictureNum % IMAGES_PER_FILE, &ctx);
}
}
diff --git a/engines/glk/comprehend/pics.h b/engines/glk/comprehend/pics.h
index 99c931016b..9856584fec 100644
--- a/engines/glk/comprehend/pics.h
+++ b/engines/glk/comprehend/pics.h
@@ -25,6 +25,8 @@
#include "glk/comprehend/draw_surface.h"
#include "common/archive.h"
+#include "common/file.h"
+#include "common/str-array.h"
namespace Glk {
namespace Comprehend {
@@ -79,7 +81,8 @@ enum {
LOCATIONS_NO_BG_OFFSET = 100,
ITEMS_OFFSET = 200,
DARK_ROOM = 1000,
- BRIGHT_ROOM = 1001
+ BRIGHT_ROOM = 1001,
+ TITLE_IMAGE = 9999
};
class Pics : public Common::Archive {
@@ -124,6 +127,7 @@ class Pics : public Common::Archive {
private:
Common::Array<ImageFile> _rooms;
Common::Array<ImageFile> _items;
+ ImageFile _title;
private:
/**
@@ -140,7 +144,8 @@ public:
void clear();
void load(const Common::StringArray &roomFiles,
- const Common::StringArray &itemFiles);
+ const Common::StringArray &itemFiles,
+ const Common::String &titleFile);
/**
* Check if a member with the given name is present in the Archive.
Commit: 508a65a02ede77b50c20e7d43b305a7bcf345e5e
https://github.com/scummvm/scummvm/commit/508a65a02ede77b50c20e7d43b305a7bcf345e5e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Renaming constant arrays to be uppercase
Changed paths:
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_tr.cpp
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index bfe544c53a..d937920f10 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -26,7 +26,7 @@
namespace Glk {
namespace Comprehend {
-static GameStrings cc1_strings = {0x9};
+static GameStrings CC1_STRINGS = {0x9};
#ifdef TODO
static game_ops cc2_ops = {
@@ -50,7 +50,7 @@ CrimsonCrownGame::CrimsonCrownGame() : ComprehendGame() {
_itemGraphicFiles.push_back("OA.MS1");
_itemGraphicFiles.push_back("OB.MS1");
- _gameStrings = &cc1_strings;
+ _gameStrings = &CC1_STRINGS;
}
#ifdef TODO
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 45cbab53c0..67728bdff1 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -31,8 +31,8 @@
namespace Glk {
namespace Comprehend {
-static char charset[] = "..abcdefghijklmnopqrstuvwxyz .";
-static char special_charset[] = "[]\n!\"#$%&'(),-/0123456789:;?<>";
+static const char CHARSET[] = "..abcdefghijklmnopqrstuvwxyz .";
+static const char SPECIAL_CHARSET[] = "[]\n!\"#$%&'(),-/0123456789:;?<>";
static uint16 magic_offset;
@@ -677,11 +677,11 @@ static uint64 string_get_chunk(uint8 *string) {
static char decode_string_elem(uint8 c, bool capital, bool special) {
if (special) {
- if (c < sizeof(special_charset) - 1)
- return special_charset[c];
+ if (c < sizeof(SPECIAL_CHARSET) - 1)
+ return SPECIAL_CHARSET[c];
} else {
- if (c < sizeof(charset) - 1) {
- c = charset[c];
+ if (c < sizeof(CHARSET) - 1) {
+ c = CHARSET[c];
if (capital) {
/*
* A capital space means that the character
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index c63e7c7b9c..58c44ce9da 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -36,7 +36,7 @@ const TransylvaniaMonster TransylvaniaGame::VAMPIRE = {
0x26, 5, (1 << 7), 0, 5
};
-static GameStrings tr_strings = {
+static GameStrings TR_STRINGS = {
EXTRA_STRING_TABLE(0x8a)
};
@@ -61,7 +61,7 @@ TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
_itemGraphicFiles.push_back("OC.MS1");
_titleGraphicFile = "trtitle.ms1";
- _gameStrings = &tr_strings;
+ _gameStrings = &TR_STRINGS;
}
void TransylvaniaGame::update_monster(const TransylvaniaMonster *monster_info) {
Commit: 243adfe901726ad83ef158c70d8ca6c22dfe8791
https://github.com/scummvm/scummvm/commit/243adfe901726ad83ef158c70d8ca6c22dfe8791
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Implemented game font
Changed paths:
A engines/glk/comprehend/charset.cpp
A engines/glk/comprehend/charset.h
engines/glk/comprehend/pics.cpp
engines/glk/comprehend/pics.h
engines/glk/module.mk
engines/glk/picture.cpp
diff --git a/engines/glk/comprehend/charset.cpp b/engines/glk/comprehend/charset.cpp
new file mode 100644
index 0000000000..0302973823
--- /dev/null
+++ b/engines/glk/comprehend/charset.cpp
@@ -0,0 +1,62 @@
+/* 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/comprehend/charset.h"
+#include "common/file.h"
+#include "graphics/surface.h"
+
+namespace Glk {
+namespace Comprehend {
+
+CharSet::CharSet() : Graphics::Font() {
+ Common::File f;
+ if (!f.open("charset.gda"))
+ error("Could not open char set");
+
+ uint version = f.readUint16LE();
+ if (version != 0x1100)
+ error("Unknown char set version");
+
+ f.seek(4);
+ for (int idx = 0; idx < 128 - 32; ++idx)
+ f.read(&_data[idx][0], 8);
+
+ f.close();
+}
+
+void CharSet::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
+ assert(dst->format.bytesPerPixel == 4);
+ assert(chr >= 32 && chr < 128);
+
+ for (uint yp = 0; yp < 8; ++yp) {
+ uint32 *lineP = (uint32 *)dst->getBasePtr(x, y + yp);
+ byte bits = _data[chr - 32][yp];
+
+ for (uint xp = 0; xp < 8; ++xp, ++lineP, bits >>= 1) {
+ if (bits & 1)
+ *lineP = color;
+ }
+ }
+}
+
+} // namespace Comprehend
+} // namespace Glk
diff --git a/engines/glk/comprehend/charset.h b/engines/glk/comprehend/charset.h
new file mode 100644
index 0000000000..98585ed9f6
--- /dev/null
+++ b/engines/glk/comprehend/charset.h
@@ -0,0 +1,83 @@
+/* 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_COMPREHEND_CHARSET_H
+#define GLK_COMPREHEND_CHARSET_H
+
+#include "graphics/font.h"
+
+namespace Glk {
+namespace Comprehend {
+
+class CharSet : public Graphics::Font {
+private:
+ byte _data[128 - 32][8];
+
+public:
+ CharSet();
+
+ /**
+ */
+ int getFontHeight() const override {
+ return 8;
+ }
+
+ /**
+ * Query the maximum width of the font.
+ */
+ int getMaxCharWidth() const override {
+ return 8;
+ }
+
+ /**
+ * Query the width of a specific character.
+ */
+ int getCharWidth(uint32 chr) const override {
+ return 8;
+ }
+
+ /**
+ * Query the kerning offset between two characters.
+ */
+ int getKerningOffset(uint32 left, uint32 right) const override {
+ return 0;
+ }
+
+ /**
+ * Calculate the bounding box of a character. It is assumed that
+ * the character shall be drawn at position (0, 0).
+ */
+ Common::Rect getBoundingBox(uint32 chr) const override {
+ assert(chr < 127);
+ return Common::Rect(0, 0, 8, 8);
+ }
+
+ /**
+ * Draw a character at a specific point on a surface.
+ */
+ void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
+};
+
+} // End of namespace Comprehend
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/comprehend/pics.cpp b/engines/glk/comprehend/pics.cpp
index 3105c6b000..fcb77eccba 100644
--- a/engines/glk/comprehend/pics.cpp
+++ b/engines/glk/comprehend/pics.cpp
@@ -23,6 +23,7 @@
#include "glk/comprehend/pics.h"
#include "common/memstream.h"
#include "glk/comprehend/comprehend.h"
+#include "glk/comprehend/charset.h"
#include "glk/comprehend/draw_surface.h"
#include "glk/comprehend/file_buf.h"
#include "glk/comprehend/game.h"
@@ -218,12 +219,14 @@ bool Pics::ImageFile::doImageOp(Pics::ImageContext *ctx) const {
case IMAGE_OP_DRAW_CHAR:
a = imageGetOperand(ctx);
- debugC(kDebugGraphics, "draw_char(%c)",
- a >= 0x20 && a < 0x7f ? a : '?');
-
- ctx->_drawSurface->drawBox(ctx->_textX, ctx->_textY,
- ctx->_textX + 6, ctx->_textY + 7, ctx->_fillColor);
- ctx->_textX += 8;
+ if (a < 0x20 || a >= 0x7f) {
+ warning("Invalid character - %c", a);
+ a = '?';
+ }
+
+ debugC(kDebugGraphics, "draw_char(%c)", a);
+ ctx->_font->drawChar(ctx->_drawSurface, a, ctx->_textX, ctx->_textY, ctx->_penColor);
+ ctx->_textX += ctx->_font->getCharWidth(a);
break;
case 0xf3:
@@ -270,6 +273,15 @@ uint16 Pics::ImageFile::imageGetOperand(ImageContext *ctx) const {
/*-------------------------------------------------------*/
+Pics::Pics() : _font(nullptr) {
+ if (Common::File::exists("charset.gda"))
+ _font = new CharSet();
+}
+
+Pics::~Pics() {
+ delete _font;
+}
+
void Pics::clear() {
_rooms.clear();
_items.clear();
@@ -351,7 +363,7 @@ Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::String
}
void Pics::drawPicture(int pictureNum) const {
- ImageContext ctx(g_comprehend->_drawSurface, g_comprehend->_drawFlags);
+ ImageContext ctx(g_comprehend->_drawSurface, _font, g_comprehend->_drawFlags);
if (pictureNum == DARK_ROOM) {
ctx._drawSurface->clearScreen(G_COLOR_BLACK);
diff --git a/engines/glk/comprehend/pics.h b/engines/glk/comprehend/pics.h
index 9856584fec..9140b959b3 100644
--- a/engines/glk/comprehend/pics.h
+++ b/engines/glk/comprehend/pics.h
@@ -89,6 +89,7 @@ class Pics : public Common::Archive {
struct ImageContext {
Common::File _file;
DrawSurface *_drawSurface;
+ Graphics::Font *_font;
uint _drawFlags;
uint16 _x;
@@ -100,9 +101,9 @@ class Pics : public Common::Archive {
uint16 _textX;
uint16 _textY;
- ImageContext(DrawSurface *drawSurface, uint flags) :
- _drawSurface(drawSurface), _drawFlags(0), _x(0), _y(0),
- _penColor(G_COLOR_BLACK), _fillColor(G_COLOR_BLACK),
+ ImageContext(DrawSurface *drawSurface, Graphics::Font *font, uint flags) :
+ _drawSurface(drawSurface), _font(font), _drawFlags(0),
+ _x(0), _y(0), _penColor(G_COLOR_BLACK), _fillColor(G_COLOR_BLACK),
_shape(IMAGE_OP_SHAPE_CIRCLE_LARGE), _textX(0), _textY(0) {
}
@@ -128,6 +129,7 @@ private:
Common::Array<ImageFile> _rooms;
Common::Array<ImageFile> _items;
ImageFile _title;
+ Graphics::Font *_font;
private:
/**
@@ -141,6 +143,9 @@ private:
void drawPicture(int pictureNum) const;
public:
+ Pics();
+ ~Pics();
+
void clear();
void load(const Common::StringArray &roomFiles,
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index aa5c0aba34..dafed0a320 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -166,6 +166,7 @@ MODULE_OBJS := \
archetype/sys_object.o \
archetype/timestamp.o \
archetype/token.o \
+ comprehend/charset.o \
comprehend/comprehend.o \
comprehend/debugger.o \
comprehend/debugger_dumper.o \
diff --git a/engines/glk/picture.cpp b/engines/glk/picture.cpp
index 5cb44c8857..4c3f8454ed 100644
--- a/engines/glk/picture.cpp
+++ b/engines/glk/picture.cpp
@@ -214,7 +214,7 @@ Picture *Pictures::scale(Picture *src, size_t sx, size_t sy) {
dst = new Picture(sx, sy, src->format);
dst->_id = src->_id;
dst->_scaled = true;
- dst->transBlitFrom(*src, src->getBounds(), dst->getBounds(), (uint)-1);
+ dst->transBlitFrom(*src, src->getBounds(), dst->getBounds(), (uint)0x8888);
storeScaled(dst);
return dst;
Commit: 88c1d4ecf1df5d9472fb234f2e542551d55d5ced
https://github.com/scummvm/scummvm/commit/88c1d4ecf1df5d9472fb234f2e542551d55d5ced
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Cleanup of Crimson Crown code, remove deprecated data
Changed paths:
engines/glk/comprehend/game.cpp
engines/glk/comprehend/game.h
engines/glk/comprehend/game_cc.cpp
engines/glk/comprehend/game_cc.h
engines/glk/comprehend/game_data.cpp
engines/glk/comprehend/game_data.h
engines/glk/comprehend/game_oo.cpp
engines/glk/comprehend/game_tm.cpp
engines/glk/comprehend/game_tr.cpp
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index b758a5b5e6..06b04fb4a9 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -38,9 +38,7 @@ struct Sentence {
size_t nr_words;
};
-ComprehendGame::ComprehendGame() : _gameName(nullptr),
- _shortName(nullptr),
- _gameDataFile(nullptr),
+ComprehendGame::ComprehendGame() : _gameDataFile(nullptr),
_colorTable(0),
_gameStrings(nullptr) {
}
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index c6f7c0e668..8e82a44dd0 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -37,10 +37,7 @@ namespace Comprehend {
class ComprehendGame : public GameInfo, public OpcodeMap {
public:
- const char *_gameName;
- const char *_shortName;
-
- const char *_gameDataFile;
+ Common::String _gameDataFile;
Common::Array<StringFile> _stringFiles;
Common::StringArray _locationGraphicFiles;
Common::StringArray _itemGraphicFiles;
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index d937920f10..401cf420db 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -28,55 +28,36 @@ namespace Comprehend {
static GameStrings CC1_STRINGS = {0x9};
-#ifdef TODO
-static game_ops cc2_ops = {
- nullptr,
- cc2_before_prompt,
- nullptr,
- nullptr,
- nullptr,
- cc2_handle_special_opcode};
-#endif
-
CrimsonCrownGame::CrimsonCrownGame() : ComprehendGame() {
- _gameName = "Crimson Crown";
- _shortName = "cc1";
- _gameDataFile = "cc1.gda";
-
- _stringFiles.push_back(StringFile("ma.ms1", 0x89));
- _locationGraphicFiles.push_back("RA.MS1");
- _locationGraphicFiles.push_back("RB.MS1");
- _locationGraphicFiles.push_back("RC.MS1");
- _itemGraphicFiles.push_back("OA.MS1");
- _itemGraphicFiles.push_back("OB.MS1");
-
- _gameStrings = &CC1_STRINGS;
+ setupDisk(1);
}
-#ifdef TODO
-ComprehendGame game_crimson_crown_2 = {
- "Crimson Crown (Part 2/2)",
- "cc2",
- "CC2.GDA",
- {{"MA.MS2", 0x89}},
- {"RA.MS2", "RB.MS2"},
- {"OA.MS2", "OB.MS2"},
- "G%d.MS0",
- 0,
- nullptr,
- &cc2_ops,
- nullptr};
-#endif
-
-static void cc_clear_companion_flags(ComprehendGame *game) {
- /* Clear the Sabrina/Erik action flags */
- game->_flags[0xa] = 0;
- game->_flags[0xb] = 0;
+void CrimsonCrownGame::setupDisk(uint diskNum) {
+ assert(diskNum == 1 || diskNum == 2);
+
+ _gameDataFile = Common::String::format("cc%u.gda", diskNum);
+ _stringFiles.push_back(StringFile(Common::String::format("ma.ms%u", diskNum), 0x89));
+ _locationGraphicFiles.push_back(Common::String::format("ra.ms%u", diskNum));
+ _locationGraphicFiles.push_back(Common::String::format("rb.ms%u", diskNum));
+ if (diskNum == 1)
+ _locationGraphicFiles.push_back("RC.ms1");
+ _itemGraphicFiles.push_back(Common::String::format("oa.ms%u", diskNum));
+ _itemGraphicFiles.push_back(Common::String::format("ob.ms%u", diskNum));
+
+ if (diskNum == 1)
+ _gameStrings = &CC1_STRINGS;
+ else
+ _gameStrings = nullptr;
}
-static bool cc_common_handle_special_opcode(ComprehendGame *game,
- uint8 operand) {
+void CrimsonCrownGame::handle_special_opcode(uint8 operand) {
switch (operand) {
+ case 0x01:
+ // Enter the Vampire's throne room
+ assert(_diskNum == 1);
+ eval_function(this, &_functions[0xe], nullptr, nullptr);
+ break;
+
case 0x03:
/*
* Game over - failure.
@@ -84,69 +65,37 @@ static bool cc_common_handle_special_opcode(ComprehendGame *game,
* FIXME - If playing the second disk this should restart
* from the beginning of the first disk.
*/
- game_restart(game);
+ game_restart(this);
break;
- case 0x06:
- game_save(game);
- break;
-
- case 0x07:
- /*
- * FIXME - This will only correctly restore games that were
- * saved for the disk currently being played.
- */
- game_restore(game);
- return true;
- }
-
- return false;
-}
-
-void CrimsonCrownGame::handle_special_opcode(uint8 operand) {
- if (cc_common_handle_special_opcode(this, operand))
- return;
-
- switch (operand) {
case 0x05:
- /*
- * Completed first part (disk 1) of the game.
- *
- * FIXME - This should automatically load disk 2.
- */
- error("[Completed disk 1 - to continue run Re-Comprehend with the 'cc2' game]");
+ if (_diskNum == 1) {
+ // Finished disk 1
+ error("[Completed disk 1 - handle switch to disk 2]");
+ } else {
+ // Won the game.
+ // FIXME: The merchant ship should arrives, etc.
+ game_restart(this);
+ }
break;
- }
-}
-static void cc2_handle_special_opcode(ComprehendGame *game,
- uint8 operand) {
- if (cc_common_handle_special_opcode(game, operand))
- return;
+ case 0x06:
+ game_save(this);
+ break;
- switch (operand) {
- case 0x01:
- /* Enter the Vampire's throne room */
- eval_function(game, &game->_functions[0xe], NULL, NULL);
+ case 0x07:
+ game_restore(this);
break;
- case 0x05:
- /*
- * Won the game.
- *
- * FIXME - The merchant ship should arrives, etc.
- */
- game_restart(game);
+ default:
break;
}
}
-static void cc2_before_prompt(ComprehendGame *game) {
- cc_clear_companion_flags(game);
-}
-
void CrimsonCrownGame::before_prompt() {
- cc_clear_companion_flags(this);
+ // Clear the Sabrina/Erik action flags
+ _flags[0xa] = 0;
+ _flags[0xb] = 0;
}
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_cc.h b/engines/glk/comprehend/game_cc.h
index 7ca5bd10b2..d69eab2b66 100644
--- a/engines/glk/comprehend/game_cc.h
+++ b/engines/glk/comprehend/game_cc.h
@@ -29,12 +29,17 @@ namespace Glk {
namespace Comprehend {
class CrimsonCrownGame : public ComprehendGame {
+private:
+ uint _diskNum;
+
public:
CrimsonCrownGame();
~CrimsonCrownGame() override {}
void before_prompt() override;
void handle_special_opcode(uint8 operand) override;
+
+ void setupDisk(uint diskNum);
};
} // namespace Comprehend
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index 67728bdff1..4dbe472e0c 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -954,10 +954,7 @@ static void load_extra_string_file(ComprehendGame *game,
static void load_extra_string_files(ComprehendGame *game) {
uint i;
- for (i = 0; i < ARRAY_SIZE(game->_stringFiles); i++) {
- if (!game->_stringFiles[i].filename)
- break;
-
+ for (i = 0; i < game->_stringFiles.size(); i++) {
// HACK - get string offsets correct
game->_strings2.resize(0x40 * i);
if (game->_strings2.empty())
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 557c16e015..420888e1fd 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -251,12 +251,12 @@ struct GameInfo {
};
struct StringFile {
- const char *filename;
+ Common::String filename;
uint32 base_offset;
uint32 end_offset;
StringFile() : filename(nullptr), base_offset(0), end_offset(0) {}
- StringFile(const char *fname, uint32 baseOfs, uint32 endO = 0) : filename(fname), base_offset(baseOfs), end_offset(endO) {
+ StringFile(const Common::String &fname, uint32 baseOfs, uint32 endO = 0) : filename(fname), base_offset(baseOfs), end_offset(endO) {
}
};
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 2e8c49b1c4..bba0a7fc89 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -35,8 +35,6 @@ namespace Comprehend {
#define OO_FLAG_FLASHLIGHT_ON 0x27
OOToposGame::OOToposGame() : ComprehendGame() {
- _gameName = "Oo-Topos";
- _shortName = "oo";
_gameDataFile = "g0";
// Extra strings are (annoyingly) stored in the game binary
diff --git a/engines/glk/comprehend/game_tm.cpp b/engines/glk/comprehend/game_tm.cpp
index 6ba9ff960a..7fefaf06ea 100644
--- a/engines/glk/comprehend/game_tm.cpp
+++ b/engines/glk/comprehend/game_tm.cpp
@@ -29,8 +29,6 @@ namespace Comprehend {
/* FIXME - This is broken */
TalismanGame::TalismanGame() : ComprehendGame() {
- _gameName = "Talisman, Challenging the Sands of Time (broken)";
- _shortName = "tm";
_gameDataFile = "G0";
_locationGraphicFiles.push_back("RA");
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 58c44ce9da..ea2209198a 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -42,8 +42,6 @@ static GameStrings TR_STRINGS = {
TransylvaniaGame::TransylvaniaGame() : ComprehendGame() {
- _gameName = "Transylvania";
- _shortName = "tr";
_gameDataFile = "tr.gda";
_stringFiles.push_back(StringFile("MA.MS1", 0x88));
Commit: 3aacc800a964583641fa25b764f0052bdd199ca9
https://github.com/scummvm/scummvm/commit/3aacc800a964583641fa25b764f0052bdd199ca9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-02T18:22:12-07:00
Commit Message:
GLK: COMPREHEND: Flesh out and fixes for detection code
Changed paths:
engines/glk/comprehend/detection.cpp
engines/glk/comprehend/detection_tables.h
diff --git a/engines/glk/comprehend/detection.cpp b/engines/glk/comprehend/detection.cpp
index 8624a3b7b9..5621f581f1 100644
--- a/engines/glk/comprehend/detection.cpp
+++ b/engines/glk/comprehend/detection.cpp
@@ -31,12 +31,12 @@ namespace Glk {
namespace Comprehend {
void ComprehendMetaEngine::getSupportedGames(PlainGameList &games) {
- for (const PlainGameDescriptor *pd = ComprehendGame_LIST; pd->gameId; ++pd)
+ for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd)
games.push_back(*pd);
}
GameDescriptor ComprehendMetaEngine::findGame(const char *gameId) {
- for (const PlainGameDescriptor *pd = ComprehendGame_LIST; pd->gameId; ++pd) {
+ for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd) {
if (!strcmp(gameId, pd->gameId))
return *pd;
}
@@ -51,9 +51,14 @@ bool ComprehendMetaEngine::detectGames(const Common::FSList &fslist, DetectedGam
if (file->isDirectory())
continue;
+ // Check if file occurs in the list
Common::String filename = file->getName();
- bool hasExt = filename.hasSuffixIgnoreCase(".gda");
- if (!hasExt)
+ bool isPossible = false;
+ const ComprehendDetectionEntry *p = COMPREHEND_GAMES;
+ for (; p->_gameId && !isPossible; ++p)
+ isPossible = filename.equalsIgnoreCase(p->_filename);
+
+ if (!isPossible)
continue;
// Get the file's MD5
@@ -64,7 +69,7 @@ bool ComprehendMetaEngine::detectGames(const Common::FSList &fslist, DetectedGam
gameFile.close();
// Iterate through the known games
- const ComprehendDetectionEntry *p = ComprehendGameS;
+ p = COMPREHEND_GAMES;
for (; p->_gameId; ++p) {
if (filename.equalsIgnoreCase(p->_filename)) {
// Check for an md5 match
@@ -81,7 +86,7 @@ bool ComprehendMetaEngine::detectGames(const Common::FSList &fslist, DetectedGam
}
void ComprehendMetaEngine::detectClashes(Common::StringMap &map) {
- for (const PlainGameDescriptor *pd = ComprehendGame_LIST; pd->gameId; ++pd) {
+ for (const PlainGameDescriptor *pd = COMPREHEND_GAME_LIST; pd->gameId; ++pd) {
if (map.contains(pd->gameId))
error("Duplicate game Id found - %s", pd->gameId);
map[pd->gameId] = "";
diff --git a/engines/glk/comprehend/detection_tables.h b/engines/glk/comprehend/detection_tables.h
index 5b744f86b2..0e26bbd7de 100644
--- a/engines/glk/comprehend/detection_tables.h
+++ b/engines/glk/comprehend/detection_tables.h
@@ -27,12 +27,14 @@
namespace Glk {
namespace Comprehend {
-const PlainGameDescriptor ComprehendGame_LIST[] = {
+const PlainGameDescriptor COMPREHEND_GAME_LIST[] = {
{"crimsoncrown", "Crimson Crown"},
{"ootopis", "OO-Topos"},
+#ifndef RELEASE_BUILD
+ {"talisman", "Talisman: Challenging the Sands of Time"},
+#endif
{"transylvania", "Transylvania"},
- {"talisman", "Talisman"},
- {nullptr, nullptr}
+ {nullptr, nullptr}
};
struct ComprehendDetectionEntry {
@@ -41,12 +43,16 @@ struct ComprehendDetectionEntry {
const char *const _md5;
};
-const ComprehendDetectionEntry ComprehendGameS[] = {
- // DOS games
+const ComprehendDetectionEntry COMPREHEND_GAMES[] = {
{"crimsoncrown", "cc1.gda", "f2abf019675ac5c9bcfd81032bc7787b"},
+ {"ootopis", "g0", "56460c1ee669c253607534155d7e9db4"},
+#ifndef RELEASE_BUILD
+ {"talisman", "g0", "35770d4815e610b5252e3fcd9f11def3"},
+#endif
{"transylvania", "tr.gda", "22e08633eea02ceee49b909dfd982d22"},
- {nullptr, nullptr, nullptr}};
+ {nullptr, nullptr, nullptr}
+};
} // End of namespace Comprehend
} // End of namespace Glk
More information about the Scummvm-git-logs
mailing list