[Scummvm-git-logs] scummvm master -> 239fbce8e3741a4b02339c2ecc5fce53cee6562e
dreammaster
paulfgilbert at gmail.com
Thu Sep 26 05:17:19 CEST 2019
This automated email contains information about 28 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
60c860c6a6 GLK: ADRIFT: Skeleton sub-engine commit
58c71a23db GLK: ADRIFT: Fixes to startup code
b87d5ef162 GLK: ADRIFT: Adding detection entries
146199f29b GLK: ADRIFT: Adding Blorb support
7fe81a7f2f GLK: ADRIFT: Added Italian detection
58917059ae GLK: ADRIFT: Adding competition detection entries
ebc12d193b GLK: ADRIFT: Added remaining detection entries
f560ccb5bd GLK: ADRIFT: Hooking up game code to skeleton engine class
855b75f6df GLK: ADRIFT: Flag loading game message as translatable
c03b7a50ea GLK: ADRIFT: Implement zlib decompression
068375e48c GLK: ADRIFT: Fix exiting game out of debug prompt
fc410a88a0 GLK: ADRIFT: Method renaming
ac9b8fd43d GLK: ADRIFT: Formatting
c147d0fda0 GLK: ADRIFT: Formatting
60c23ffaaf GLK: ADRIFT: Fix save serialization to memos
0026f9ab5e GLK: ADRIFT: In progress implementing savegames
994afedd33 GLK: ADRIFT: Encapsulation serialization code into their own classes
41c7d31fb6 GLK: ADRIFT: Refactoring load serializer to not use longjmp
c098422a0d GLK: ADRIFT: Fixes for loading savegames to work
ac74424178 GLK: ADRIFT: Add loading savegames from launcher
a401ccc61e GLK: Remove some outstanding longjmp artifacts from sub-engines
1e483ec0f5 GLK: ADRIFT: Refactor tokenizer to not use longjmp
f6f4d3ee11 GLK: ADRIFT: Convert parser code to no longer use longjmp
97686a7c03 GLK: ADRIFT: Refactor TAF file parser to not use longjmp
043093209e GLK: ALAN3: Merge duplicate jumps.h
b44d36e97b GLK: ADRIFT: Convert overall game quit long jump to use contexts
9e17ff0c75 GLK: ADRIFT: Convert remaining long_jmp to use context
239fbce8e3 GLK: ADRIFT: gcc compilation fixes
Commit: 60c860c6a6c37b95ab8265d658cbcc144d51153b
https://github.com/scummvm/scummvm/commit/60c860c6a6c37b95ab8265d658cbcc144d51153b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Skeleton sub-engine commit
Changed paths:
A engines/glk/adrift/adrift.cpp
A engines/glk/adrift/adrift.h
A engines/glk/adrift/os_glk.cpp
A engines/glk/adrift/scare.h
A engines/glk/adrift/scdebug.cpp
A engines/glk/adrift/scevents.cpp
A engines/glk/adrift/scexpr.cpp
A engines/glk/adrift/scgamest.cpp
A engines/glk/adrift/scgamest.h
A engines/glk/adrift/scinterf.cpp
A engines/glk/adrift/sclibrar.cpp
A engines/glk/adrift/sclocale.cpp
A engines/glk/adrift/scmemos.cpp
A engines/glk/adrift/scnpcs.cpp
A engines/glk/adrift/scobjcts.cpp
A engines/glk/adrift/scparser.cpp
A engines/glk/adrift/scprintf.cpp
A engines/glk/adrift/scprops.cpp
A engines/glk/adrift/scprotos.h
A engines/glk/adrift/scresour.cpp
A engines/glk/adrift/screstrs.cpp
A engines/glk/adrift/scrunner.cpp
A engines/glk/adrift/scserial.cpp
A engines/glk/adrift/sctaffil.cpp
A engines/glk/adrift/sctafpar.cpp
A engines/glk/adrift/sctasks.cpp
A engines/glk/adrift/scutils.cpp
A engines/glk/adrift/scvars.cpp
A engines/glk/adrift/sxfile.cpp
A engines/glk/adrift/sxglob.cpp
A engines/glk/adrift/sxmain.cpp
A engines/glk/adrift/sxprotos.h
A engines/glk/adrift/sxscript.cpp
A engines/glk/adrift/sxstubs.cpp
A engines/glk/adrift/sxtester.cpp
A engines/glk/adrift/sxutils.cpp
engines/glk/glk_types.h
engines/glk/module.mk
diff --git a/engines/glk/adrift/adrift.cpp b/engines/glk/adrift/adrift.cpp
new file mode 100644
index 0000000..4f02b40
--- /dev/null
+++ b/engines/glk/adrift/adrift.cpp
@@ -0,0 +1,56 @@
+/* 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/adrift/adrift.h"
+
+namespace Glk {
+namespace Adrift {
+
+Adrift *g_vm = nullptr;
+
+Adrift::Adrift(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc) {
+ g_vm = this;
+}
+
+void Adrift::runGame() {
+ // TODO: run
+
+ deinitialize();
+}
+
+bool Adrift::initialize() {
+ return true;
+}
+
+void Adrift::deinitialize() {
+}
+
+Common::Error Adrift::readSaveData(Common::SeekableReadStream *rs) {
+ return Common::kNoError;
+}
+
+Common::Error Adrift::writeGameData(Common::WriteStream *ws) {
+ return Common::kNoError;
+}
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/adrift/adrift.h b/engines/glk/adrift/adrift.h
new file mode 100644
index 0000000..81d7d30
--- /dev/null
+++ b/engines/glk/adrift/adrift.h
@@ -0,0 +1,84 @@
+/* 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_ADRIFT_ADRIFT
+#define GLK_ADRIFT_ADRIFT
+
+#include "common/scummsys.h"
+#include "common/serializer.h"
+#include "common/stack.h"
+#include "glk/glk_api.h"
+
+namespace Glk {
+namespace Adrift {
+
+/**
+ * Adrift game interpreter
+ */
+class Adrift : public GlkAPI {
+private:
+ /**
+ * Initialization
+ */
+ bool initialize();
+
+ /**
+ * Deinitialization
+ */
+ void deinitialize();
+public:
+ /**
+ * Constructor
+ */
+ Adrift(OSystem *syst, const GlkGameDescription &gameDesc);
+
+ /**
+ * Run the game
+ */
+ void runGame();
+
+ /**
+ * Returns the running interpreter type
+ */
+ virtual InterpreterType getInterpreterType() const override {
+ return INTERPRETER_ADRIFT;
+ }
+
+ /**
+ * Load a savegame from the passed Quetzal file chunk stream
+ */
+ virtual 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
+ */
+ virtual Common::Error writeGameData(Common::WriteStream *ws) override;
+
+};
+
+extern Adrift *g_vm;
+
+} // End of namespace Alan2
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
new file mode 100644
index 0000000..98f4f34
--- /dev/null
+++ b/engines/glk/adrift/os_glk.cpp
@@ -0,0 +1,3565 @@
+/* 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/adrift/adrift.h"
+#include "glk/adrift/scare.h"
+#include "glk/adrift/scprotos.h"
+#include "glk/glk.h"
+#include "glk/streams.h"
+#include "glk/windows.h"
+#include "common/textconsole.h"
+
+namespace Glk {
+namespace Adrift {
+
+/*
+ * Module notes:
+ *
+ * o The Glk interface makes no effort to set text colors, background colors,
+ * and so forth, and minimal effort to set fonts and other style effects.
+ */
+
+#undef _WIN32 /* Gargoyle */
+
+/*
+ * True and false definitions -- usually defined in glkstart.h, but we need
+ * them early, so we'll define them here too. We also need nullptr, but that's
+ * normally from stdio.h or one of it's cousins.
+ */
+#ifndef FALSE
+# define FALSE 0
+#endif
+#ifndef TRUE
+# define TRUE (!FALSE)
+#endif
+
+
+/*---------------------------------------------------------------------*/
+/* Module variables, miscellaneous other stuff */
+/*---------------------------------------------------------------------*/
+
+/* Glk SCARE interface version number. */
+static const glui32 GSC_PORT_VERSION = 0x00010310;
+
+/* Two windows, one for the main text, and one for a status line. */
+static winid_t gsc_main_window = nullptr,
+ gsc_status_window = nullptr;
+
+/*
+ * Transcript stream and input log. These are nullptr if there is no current
+ * collection of these strings.
+ */
+static strid_t gsc_transcript_stream = nullptr,
+ gsc_inputlog_stream = nullptr;
+
+/* Input read log stream, for reading back an input log. */
+static strid_t gsc_readlog_stream = nullptr;
+
+/* Options that may be turned off or set by command line flags. */
+static int gsc_commands_enabled = TRUE,
+ gsc_abbreviations_enabled = TRUE,
+ gsc_unicode_enabled = TRUE;
+
+/* Adrift game to interpret. */
+static sc_game gsc_game = nullptr;
+
+/* Special out-of-band os_confirm() options used locally with os_glk. */
+static const sc_int GSC_CONF_SUBTLE_HINT = INT_MAX,
+ GSC_CONF_UNSUBTLE_HINT = INT_MAX - 1,
+ GSC_CONF_CONTINUE_HINTS = INT_MAX - 2;
+
+/* Forward declaration of event wait functions, and a short delay. */
+static void gsc_event_wait_2 (glui32 wait_type_1,
+ glui32 wait_type_2, event_t *event);
+static void gsc_event_wait (glui32 wait_type, event_t *event);
+static void gsc_short_delay();
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port utility functions */
+/*---------------------------------------------------------------------*/
+
+/*
+ * gsc_fatal()
+ *
+ * Fatal error handler. The function returns, expecting the caller to
+ * abort() or otherwise handle the error.
+ */
+static void
+gsc_fatal (const char *string)
+{
+ /*
+ * If the failure happens too early for us to have a window, print
+ * the message to stderr.
+ */
+ if (!gsc_main_window) {
+ error("\n\nINTERNAL ERROR: %s\n", string);
+ }
+
+ /* Cancel all possible pending window input events. */
+ g_vm->glk_cancel_line_event (gsc_main_window, nullptr);
+ g_vm->glk_cancel_char_event (gsc_main_window);
+
+ /* Print a message indicating the error, and exit. */
+ g_vm->glk_set_window (gsc_main_window);
+ g_vm->glk_set_style (style_Normal);
+ g_vm->glk_put_string ("\n\nINTERNAL ERROR: ");
+ g_vm->glk_put_string ((char *) string);
+
+ g_vm->glk_put_string ("\n\nPlease record the details of this error, try to"
+ " note down everything you did to cause it, and email"
+ " this information to simon_baldwin at yahoo.com.\n\n");
+}
+
+
+/*
+ * gsc_malloc()
+ *
+ * Non-failing malloc; call gsc_fatal and exit if memory allocation fails.
+ */
+static void *
+gsc_malloc (size_t size)
+{
+ void *pointer;
+
+ pointer = malloc (size > 0 ? size : 1);
+ if (!pointer)
+ {
+ gsc_fatal ("GLK: Out of system memory");
+ g_vm->glk_exit ();
+ }
+
+ return pointer;
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port locale data */
+/*---------------------------------------------------------------------*/
+
+/* Unicode values up to 256 are equivalent to iso 8859-1. */
+static const glui32 GSC_ISO_8859_EQUIVALENCE = 256;
+
+/*
+ * Lookup table pair for converting a given single character into unicode and
+ * iso 8859-1 (the lower byte of the unicode representation, assuming an upper
+ * byte of zero), and an ascii substitute should nothing else be available.
+ * Tables are 256 elements; although the first 128 characters of a codepage
+ * are usually standard ascii, making tables full-sized allows for support of
+ * codepages where they're not (dingbats, for example).
+ */
+enum { GSC_TABLE_SIZE = 256 };
+typedef struct {
+ const glui32 unicode[GSC_TABLE_SIZE];
+ const sc_char *const ascii[GSC_TABLE_SIZE];
+} gsc_codepages_t;
+
+/*
+ * Locale contains a name and a pair of codepage structures, a main one and
+ * an alternate. The latter is intended for monospaced output.
+ */
+typedef struct {
+ const sc_char *const name;
+ const gsc_codepages_t main;
+ const gsc_codepages_t alternate;
+} gsc_locale_t;
+
+
+/*
+ * Locale for Latin1 -- cp1252 and cp850.
+ *
+ * The ascii representations of characters in this table are based on the
+ * general look of the characters, rather than pronounciation. Accented
+ * characters are generally rendered unaccented, and box drawing, shading,
+ * and other non-alphanumeric glyphs as either a similar shape, or as a
+ * character that might be recognizable as what it's trying to emulate.
+ */
+static const gsc_locale_t GSC_LATIN1_LOCALE = {
+ "Latin1",
+ /* cp1252 to unicode. */
+{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020,
+ 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
+ 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc,
+ 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178, 0x00a0, 0x00a1,
+ 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa,
+ 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
+ 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc,
+ 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5,
+ 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
+ 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0,
+ 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9,
+ 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
+ 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
+ 0x00fc, 0x00fd, 0x00fe, 0x00ff },
+ /* cp1252 to ascii. */
+ { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, "E", nullptr, ",",
+ "f", ",,", "...", "+", "#", "^", "%", "S", "<", "OE", nullptr,
+ "Z", nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", "~",
+ "[TM]","s", ">", "oe", nullptr, "z", "Y", " ", "!", "c", "GBP",
+ "*", "Y", "|", "S", "\"", "(C)", "a", "<<", "-", "-", "(R)",
+ "-", "o", "+/-", "2", "3", "'", "u", "P", "*", ",", "1",
+ "o", ">>", "1/4", "1/2", "3/4", "?", "A", "A", "A", "A", "A",
+ "A", "AE", "C", "E", "E", "E", "E", "I", "I", "I", "I",
+ "D", "N", "O", "O", "O", "O", "O", "x", "O", "U", "U",
+ "U", "U", "Y", "p", "ss", "a", "a", "a", "a", "a", "a",
+ "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "d",
+ "n", "o", "o", "o", "o", "o", "/", "o", "u", "u", "u",
+ "u", "y", "P", "y" } },
+ /* cp850 to unicode. */
+{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5,
+ 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
+ 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff,
+ 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, 0x00e1, 0x00ed,
+ 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae, 0x00ac,
+ 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502,
+ 0x2524, 0x00c1, 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d,
+ 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c,
+ 0x00e3, 0x00c3, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c,
+ 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce,
+ 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, 0x00d3,
+ 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, 0x00de, 0x00da,
+ 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1, 0x2017,
+ 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, 0x00b0, 0x00a8, 0x00b7, 0x00b9,
+ 0x00b3, 0x00b2, 0x25a0, 0x00a0 },
+ /* cp850 to ascii. */
+ { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, "C", "u", "e",
+ "a", "a", "a", "a", "c", "e", "e", "e", "i", "i", "i",
+ "A", "A", "E", "ae", "AE", "o", "o", "o", "u", "u", "y",
+ "O", "U", "o", "GBP", "O", "x", "f", "a", "i", "o", "u",
+ "n", "N", "a", "o", "?", "(R)", "-", "1/2", "1/4", "i", "<<",
+ ">>", "#", "#", "#", "|", "+", "A", "A", "A", "(C)", "+",
+ "|", "+", "+", "c", "Y", "+", "+", "+", "+", "+", "-",
+ "+", "a", "A", "+", "+", "+", "+", "+", "=", "+", "*",
+ "d", "D", "E", "E", "E", "i", "I", "I", "I", "+", "+",
+ ".", ".", "|", "I", ".", "O", "ss", "O", "O", "o", "O",
+ "u", "p", "P", "U", "U", "U", "y", "Y", "-", "'", "-",
+ "+/-", "=", "3/4", "P", "S", "/", ",", "deg", "\"", "*", "1",
+ "3", "2", ".", " " } }
+};
+
+
+/*
+ * Locale for Cyrillic -- cp1251 and cp866.
+ *
+ * The ascii representations in this table, for alphabetic characters, follow
+ * linguistic rather than appearance rules, the essence of gost 16876-71.
+ * Capitalized cyrillic letters that translate to multiple ascii characters
+ * have the first ascii character only of the sequence translated. This gives
+ * the best appearance in normal sentences, but is not optimal in a run of
+ * all capitals (headings, for example). For non-alphanumeric characters,
+ * the general appearance and shape of the character being emulated is used.
+ */
+static const gsc_locale_t GSC_CYRILLIC_LOCALE = {
+ "Cyrillic",
+ /* cp1251 to unicode. */
+{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020,
+ 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
+ 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000,
+ 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, 0x00a0, 0x040e,
+ 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404,
+ 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, 0x00b0, 0x00b1, 0x0406, 0x0456,
+ 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458,
+ 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
+ 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430,
+ 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439,
+ 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442,
+ 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b,
+ 0x044c, 0x044d, 0x044e, 0x044f },
+ /* cp1251 to gost 16876-71 ascii. */
+ { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, nullptr, nullptr, ",",
+ nullptr, ",,", "...", "+", "#", "E", "%", nullptr, "<", nullptr, nullptr,
+ nullptr, nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", nullptr,
+ "[TM]",nullptr, ">", nullptr, nullptr, nullptr, nullptr, " ", nullptr, nullptr, nullptr,
+ "*", "G", "|", "S", "Jo", "(C)", "Je", "<<", "-", "-", "(R)",
+ "Ji", "o", "+/-", "I", "i", "g", "u", "P", "*", "jo", nullptr,
+ "je", ">>", "j", "S", "s", "ji", "A", "B", "V", "G", "D",
+ "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N", "O", "P",
+ "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh", "Shh", "\"",
+ "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g", "d", "e",
+ "zh", "z", "i", "jj", "k", "l", "m", "n", "o", "p", "r",
+ "s", "t", "u", "f", "kh", "c", "ch", "sh", "shh", "\"", "y",
+ "'", "eh", "ju", "ja" } },
+ /* cp866 to unicode. */
+{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416,
+ 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
+ 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431,
+ 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a,
+ 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x2591, 0x2592, 0x2593, 0x2502,
+ 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d,
+ 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c,
+ 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c,
+ 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
+ 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x0440,
+ 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449,
+ 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0401, 0x0451, 0x0404,
+ 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, 0x00b0, 0x2022, 0x00b7, 0x221a,
+ 0x2116, 0x00a4, 0x25a0, 0x00a0 },
+ /* cp866 to gost 16876-71 ascii. */
+ { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, "A", "B", "V",
+ "G", "D", "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N",
+ "O", "P", "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh",
+ "Shh", "\"", "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g",
+ "d", "e", "zh", "z", "i", "jj", "k", "l", "m", "n", "o",
+ "p", "#", "#", "#", "|", "+", "+", "+", "+", "+", "+",
+ "|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "-",
+ "+", "+", "+", "+", "+", "+", "+", "+", "|", "+", "+",
+ "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+",
+ "+", ".", ".", ".", ".", "r", "s", "t", "u", "f", "kh",
+ "c", "ch", "sh", "shh", "\"", "y", "'", "eh", "ju", "ja", "Jo",
+ "jo", "Je", "je", "Ji", "ji", nullptr, nullptr, "deg", "*", "*", nullptr,
+ nullptr, "*", ".", " " } }
+};
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port locale control and conversion functions */
+/*---------------------------------------------------------------------*/
+
+#ifdef GLK_MODULE_UNICODE
+static const sc_bool gsc_has_unicode = TRUE;
+#else
+static const sc_bool gsc_has_unicode = FALSE;
+
+/* Gestalt selector and stubs for non-unicode capable libraries. */
+static const glui32 gestalt_Unicode = 15;
+
+static void glk_put_char_uni (glui32 ch)
+{
+ glui32 unused;
+ unused = ch;
+ gsc_fatal ("GLK: Stub unicode function called");
+}
+
+static void glk_request_line_event_uni (winid_t win,
+ glui32 *buf, glui32 maxlen, glui32 initlen)
+{
+ winid_t unused1;
+ glui32 *unused2;
+ glui32 unused3, unused4;
+ unused1 = win;
+ unused2 = buf;
+ unused3 = maxlen;
+ unused4 = initlen;
+ gsc_fatal ("GLK: Stub unicode function called");
+}
+
+#endif
+
+/*
+ * Known valid character printing range. Some Glk libraries aren't accurate
+ * about what will and what won't print when queried with g_vm->glk_gestalt(), so
+ * we also make an explicit range check against guaranteed to print chars.
+ */
+static const glui32 GSC_MIN_PRINTABLE = ' ',
+ GSC_MAX_PRINTABLE = '~';
+
+
+/* List of pointers to supported and available locales, nullptr terminated. */
+static const gsc_locale_t *const GSC_AVAILABLE_LOCALES[] = {
+ &GSC_LATIN1_LOCALE,
+ &GSC_CYRILLIC_LOCALE,
+ nullptr
+};
+
+/*
+ * The locale for the game, set below explicitly or on game startup, and
+ * a fallback locale to use in case none has been set.
+ */
+static const gsc_locale_t *gsc_locale = nullptr;
+static const gsc_locale_t *const gsc_fallback_locale = &GSC_LATIN1_LOCALE;
+
+
+/*
+ * gsc_set_locale()
+ *
+ * Set a locale explicitly from the name passed in.
+ */
+static void
+gsc_set_locale (const sc_char *name)
+{
+ const gsc_locale_t *matched = nullptr;
+ const gsc_locale_t *const *iterator;
+ assert (name);
+
+ /*
+ * Search locales for a matching name, abbreviated if necessary. Stop on
+ * the first match found.
+ */
+ for (iterator = GSC_AVAILABLE_LOCALES; *iterator; iterator++)
+ {
+ const gsc_locale_t *const locale = *iterator;
+
+ if (sc_strncasecmp (name, locale->name, strlen (name)) == 0)
+ {
+ matched = locale;
+ break;
+ }
+ }
+
+ /* If matched, set the global locale. */
+ if (matched)
+ gsc_locale = matched;
+}
+
+
+/*
+ * gsc_put_char_uni()
+ *
+ * Wrapper around g_vm->glk_put_char_uni(). Handles, inelegantly, the problem of
+ * having to write transcripts as ascii.
+ */
+static void
+gsc_put_char_uni (glui32 unicode, const char *ascii)
+{
+ /* If there is an transcript stream, temporarily disconnect it. */
+ if (gsc_transcript_stream)
+ g_vm->glk_window_set_echo_stream (gsc_main_window, nullptr);
+
+ g_vm->glk_put_char_uni (unicode);
+
+ /* Print ascii to the transcript, then reattach it. */
+ if (gsc_transcript_stream)
+ {
+ if (ascii)
+ g_vm->glk_put_string_stream (gsc_transcript_stream, (char *) ascii);
+ else
+ g_vm->glk_put_char_stream (gsc_transcript_stream, '?');
+
+ g_vm->glk_window_set_echo_stream (gsc_main_window, gsc_transcript_stream);
+ }
+}
+
+
+/*
+ * gsc_put_char_locale()
+ *
+ * Write a single character using the supplied locale. Select either the
+ * main or the alternate codepage depending on the flag passed in.
+ */
+static void
+gsc_put_char_locale (sc_char ch,
+ const gsc_locale_t *locale, sc_bool is_alternate)
+{
+ const gsc_codepages_t *codepage;
+ unsigned char character;
+ glui32 unicode;
+ const char *ascii;
+
+ /*
+ * Select either the main or the alternate codepage for this locale, and
+ * retrieve the unicode and ascii representations of the character.
+ */
+ codepage = is_alternate ? &locale->alternate : &locale->main;
+ character = (unsigned char) ch;
+ unicode = codepage->unicode[character];
+ ascii = codepage->ascii[character];
+
+ /*
+ * If a unicode representation exists, use for either iso 8859-1 or, if
+ * possible, direct unicode output.
+ */
+ if (unicode > 0)
+ {
+ /*
+ * If unicode is in the range 1-255, this value is directly equivalent
+ * to the iso 8859-1 representation; otherwise the character has no
+ * direct iso 8859-1 glyph.
+ */
+ if (unicode < GSC_ISO_8859_EQUIVALENCE)
+ {
+ /*
+ * If the iso 8859-1 character is one that this Glk library will
+ * print exactly, print and return. We add a check here for the
+ * guaranteed printable characters, since some Glk libraries don't
+ * return the correct values for gestalt_CharOutput for these.
+ */
+ if (unicode == '\n'
+ || (unicode >= GSC_MIN_PRINTABLE && unicode <= GSC_MAX_PRINTABLE)
+ || g_vm->glk_gestalt (gestalt_CharOutput,
+ unicode) == gestalt_CharOutput_ExactPrint)
+ {
+ g_vm->glk_put_char ((unsigned char) unicode);
+ return;
+ }
+ }
+
+ /*
+ * If no usable iso 8859-1 representation, see if unicode is enabled and
+ * if the Glk library can print the character exactly. If yes, output
+ * the character that way.
+ *
+ * TODO Using unicode output currently disrupts transcript output. Any
+ * echo stream connected for a transcript here will be a text rather than
+ * a unicode stream, so probably won't output the character correctly.
+ * For now, if there's a transcript, we try to write ascii output.
+ */
+ if (gsc_unicode_enabled)
+ {
+ if (g_vm->glk_gestalt (gestalt_CharOutput,
+ unicode) == gestalt_CharOutput_ExactPrint)
+ {
+ gsc_put_char_uni (unicode, ascii);
+ return;
+ }
+ }
+ }
+
+ /*
+ * No success with iso 8859-1 or unicode, so try for an ascii substitute.
+ * Substitute strings use only 7-bit ascii, and so all are safe to print
+ * directly with Glk.
+ */
+ if (ascii)
+ {
+ g_vm->glk_put_string ((char *) ascii);
+ return;
+ }
+
+ /* No apparent way to output this character, so print a '?'. */
+ g_vm->glk_put_char ('?');
+}
+
+
+/*
+ * gsc_put_char()
+ * gsc_put_char_alternate()
+ * gsc_put_buffer_using()
+ * gsc_put_buffer()
+ * gsc_put_string()
+ * gsc_put_string_alternate()
+ *
+ * Public functions for writing using the current or fallback locale.
+ */
+static void
+gsc_put_char (const sc_char character)
+{
+ const gsc_locale_t *locale;
+
+ locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
+ gsc_put_char_locale (character, locale, FALSE);
+}
+
+static void
+gsc_put_char_alternate (const sc_char character)
+{
+ const gsc_locale_t *locale;
+
+ locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
+ gsc_put_char_locale (character, locale, TRUE);
+}
+
+static void
+gsc_put_buffer_using (const sc_char *buffer,
+ sc_int length, void (*putchar_function) (sc_char))
+{
+ sc_int index_;
+
+ for (index_ = 0; index_ < length; index_++)
+ putchar_function (buffer[index_]);
+}
+
+static void
+gsc_put_buffer (const sc_char *buffer, sc_int length)
+{
+ assert (buffer);
+
+ gsc_put_buffer_using (buffer, length, gsc_put_char);
+}
+
+static void
+gsc_put_string (const sc_char *string)
+{
+ assert (string);
+
+ gsc_put_buffer_using (string, strlen (string), gsc_put_char);
+}
+
+static void
+gsc_put_string_alternate (const sc_char *string)
+{
+ assert (string);
+
+ gsc_put_buffer_using (string, strlen (string), gsc_put_char_alternate);
+}
+
+
+/*
+ * gsc_unicode_to_locale()
+ * gsc_unicode_buffer_to_locale()
+ *
+ * Convert a unicode character back to an sc_char through a locale. Used for
+ * reverse translations in line input. Returns '?' if there is no translation
+ * available.
+ */
+static sc_char
+gsc_unicode_to_locale (glui32 unicode, const gsc_locale_t *locale)
+{
+ const gsc_codepages_t *codepage;
+ sc_int character;
+
+ /* Always use the main codepage for input. */
+ codepage = &locale->main;
+
+ /*
+ * Search the unicode table sequentially for the input character. This is
+ * inefficient, but because game input is usually not copious, excusable.
+ */
+ for (character = 0; character < GSC_TABLE_SIZE; character++)
+ {
+ if (codepage->unicode[character] == unicode)
+ break;
+ }
+
+ /* Return the character translation, or '?' if none. */
+ return character < GSC_TABLE_SIZE ? (sc_char) character : '?';
+}
+
+static void
+gsc_unicode_buffer_to_locale (const glui32 *unicode, sc_int length,
+ sc_char *buffer, const gsc_locale_t *locale)
+{
+ sc_int index_;
+
+ for (index_ = 0; index_ < length; index_++)
+ buffer[index_] = gsc_unicode_to_locale (unicode[index_], locale);
+}
+
+
+/*
+ * gsc_read_line_locale()
+ *
+ * Read in a line and translate out of the given locale. Returns the count
+ * of characters placed in the buffer.
+ */
+static sc_int
+gsc_read_line_locale (sc_char *buffer,
+ sc_int length, const gsc_locale_t *locale)
+{
+ event_t event;
+
+ /*
+ * If we have unicode, we have to use it to ensure that characters not in
+ * the Latin1 locale are properly translated.
+ */
+ if (gsc_unicode_enabled)
+ {
+ glui32 *unicode;
+
+ /*
+ * Allocate a unicode buffer long enough to hold all the characters,
+ * then read in a unicode line.
+ */
+ unicode = (glui32 *)gsc_malloc (length * sizeof (*unicode));
+ g_vm->glk_request_line_event_uni (gsc_main_window, unicode, length, 0);
+ gsc_event_wait (evtype_LineInput, &event);
+
+ /* Convert the unicode buffer out, then free it. */
+ gsc_unicode_buffer_to_locale (unicode, event.val1, buffer, locale);
+ free (unicode);
+
+ /* Return the count of characters placed in the buffer. */
+ return event.val1;
+ }
+
+ /* No success with unicode, so fall back to standard line input. */
+ g_vm->glk_request_line_event (gsc_main_window, buffer, length, 0);
+ gsc_event_wait (evtype_LineInput, &event);
+
+ /* Return the count of characters placed in the buffer. */
+ return event.val1;
+}
+
+
+/*
+ * gsc_read_line()
+ *
+ * Public function for reading using the current or fallback locale.
+ */
+static sc_int
+gsc_read_line (sc_char *buffer, sc_int length)
+{
+ const gsc_locale_t *locale;
+
+ locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
+ return gsc_read_line_locale (buffer, length, locale);
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port status line functions */
+/*---------------------------------------------------------------------*/
+
+/*
+ * Slop for right-justification of status lines, as an attempt to compensate
+ * for the fact that some characters in a games status line may use more than
+ * one position when printed, a particular problem in gost 16876-71 Cyrillic.
+ */
+static const sc_int GSC_STATUS_SLOP = 10;
+
+/* Size of saved status buffer used for non-windowing Glk status lines. */
+enum { GSC_STATUS_BUFFER_LENGTH = 74 };
+
+/* Whitespace characters, used to detect empty status elements. */
+static const sc_char *const GSC_WHITESPACE = "\t\n\v\f\r ";
+
+
+/*
+ * gsc_is_string_usable()
+ *
+ * Return TRUE if string is non-null, not zero-length or contains characters
+ * other than whitespace.
+ */
+static sc_bool
+gsc_is_string_usable (const sc_char *string)
+{
+ /* If non-null, scan for any non-space character. */
+ if (string)
+ {
+ sc_int index_;
+
+ for (index_ = 0; string[index_] != '\0'; index_++)
+ {
+ if (!strchr (GSC_WHITESPACE, string[index_]))
+ return TRUE;
+ }
+ }
+
+ /* nullptr, or no characters other than whitespace. */
+ return FALSE;
+}
+
+
+/*
+ * gsc_status_update()
+ *
+ * Update the status line from the current game state. This is for windowing
+ * Glk libraries.
+ */
+static void
+gsc_status_update()
+{
+ glui32 width, height;
+ uint index;
+ assert (gsc_status_window);
+
+ g_vm->glk_window_get_size (gsc_status_window, &width, &height);
+ if (height > 0)
+ {
+ const sc_char *room;
+
+ g_vm->glk_window_clear (gsc_status_window);
+ g_vm->glk_window_move_cursor (gsc_status_window, 0, 0);
+ g_vm->glk_set_window (gsc_status_window);
+
+ g_vm->glk_set_style(style_User1);
+ for (index = 0; index < width; index++)
+ g_vm->glk_put_char (' ');
+ g_vm->glk_window_move_cursor (gsc_status_window, 0, 0);
+
+ /* See if the game is indicating any current player room. */
+ room = sc_get_game_room (gsc_game);
+ if (!gsc_is_string_usable (room))
+ {
+ /*
+ * Player location is indeterminate, so print out a generic status,
+ * showing the game name and author.
+ */
+ g_vm->glk_window_move_cursor (gsc_status_window, 1, 0);
+ gsc_put_string (sc_get_game_name (gsc_game));
+ g_vm->glk_put_string (" | ");
+ gsc_put_string (sc_get_game_author (gsc_game));
+ }
+ else
+ {
+ const sc_char *status;
+ char score[64];
+
+ /* Print the player location. */
+ g_vm->glk_window_move_cursor (gsc_status_window, 1, 0);
+ gsc_put_string (room);
+
+ /* Get the game's status line, or if none, format score. */
+ status = sc_get_game_status_line (gsc_game);
+ if (!gsc_is_string_usable (status))
+ {
+ sprintf (score, "Score: %ld", sc_get_game_score (gsc_game));
+ status = score;
+ }
+
+ /* Print the status line or score at window right, if it fits. */
+ if (width > strlen (status) + GSC_STATUS_SLOP + 1)
+ {
+ glui32 position;
+
+ position = width - strlen (status) - GSC_STATUS_SLOP;
+ g_vm->glk_window_move_cursor (gsc_status_window, position - 1, 0);
+ gsc_put_string (status);
+ }
+ }
+
+ g_vm->glk_set_window (gsc_main_window);
+ }
+}
+
+
+/*
+ * gsc_status_safe_strcat()
+ *
+ * Helper for gsc_status_print(), concatenates strings only up to the
+ * available length.
+ */
+static void
+gsc_status_safe_strcat (char *dest, size_t length, const char *src)
+{
+ size_t available, src_length;
+
+ /* Append only as many characters as will fit. */
+ src_length = strlen (src);
+ available = length - strlen (dest) - 1;
+ if (available > 0)
+ strncat (dest, src, src_length < available ? src_length : available);
+}
+
+
+/*
+ * gsc_status_print()
+ *
+ * Print the current contents of the completed status line buffer out in the
+ * main window, if it has changed since the last call. This is for non-
+ * windowing Glk libraries.
+ */
+static void
+gsc_status_print()
+{
+ static char current_status[GSC_STATUS_BUFFER_LENGTH + 1];
+
+ const sc_char *room;
+
+ /* Do nothing if the game isn't indicating any current player room. */
+ room = sc_get_game_room (gsc_game);
+ if (gsc_is_string_usable (room))
+ {
+ char buffer[GSC_STATUS_BUFFER_LENGTH + 1];
+ const sc_char *status;
+ char score[64];
+
+ /* Make an attempt at a status line, starting with player location. */
+ strcpy (buffer, "");
+ gsc_status_safe_strcat (buffer, sizeof (buffer), room);
+
+ /* Get the game's status line, or if none, format score. */
+ status = sc_get_game_status_line (gsc_game);
+ if (!gsc_is_string_usable (status))
+ {
+ sprintf (score, "Score: %ld", sc_get_game_score (gsc_game));
+ status = score;
+ }
+
+ /* Append the status line or score. */
+ gsc_status_safe_strcat (buffer, sizeof (buffer), " | ");
+ gsc_status_safe_strcat (buffer, sizeof (buffer), status);
+
+ /* If this matches the current saved status line, do nothing more. */
+ if (strcmp (buffer, current_status) != 0)
+ {
+ /* Bracket, and output the status line buffer. */
+ g_vm->glk_put_string ("[ ");
+ gsc_put_string (buffer);
+ g_vm->glk_put_string (" ]\n");
+
+ /* Save the details of the printed status buffer. */
+ strcpy (current_status, buffer);
+ }
+ }
+}
+
+
+/*
+ * gsc_status_notify()
+ *
+ * Front end function for updating status. Either updates the status window
+ * or prints the status line to the main window.
+ */
+static void
+gsc_status_notify()
+{
+ if (gsc_status_window)
+ gsc_status_update ();
+ else
+ gsc_status_print ();
+}
+
+
+/*
+ * gsc_status_redraw()
+ *
+ * Redraw the contents of any status window with the constructed status string.
+ * This function should be called on the appropriate Glk window resize and
+ * arrange events.
+ */
+static void
+gsc_status_redraw()
+{
+ if (gsc_status_window)
+ {
+ winid_t parent;
+
+ /*
+ * Rearrange the status window, without changing its actual arrangement
+ * in any way. This is a hack to work round incorrect window repainting
+ * in Xglk; it forces a complete repaint of affected windows on Glk
+ * window resize and arrange events, and works in part because Xglk
+ * doesn't check for actual arrangement changes in any way before
+ * invalidating its windows. The hack should be harmless to Glk
+ * libraries other than Xglk, moreover, we're careful to activate it
+ * only on resize and arrange events.
+ */
+ parent = g_vm->glk_window_get_parent (gsc_status_window);
+ g_vm->glk_window_set_arrangement (parent,
+ winmethod_Above | winmethod_Fixed, 1, nullptr);
+ gsc_status_update ();
+ }
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port output functions */
+/*---------------------------------------------------------------------*/
+
+/*
+ * Flag for if the user entered "help" as their last input, or if hints have
+ * been silenced as a result of already using a Glk command.
+ */
+static int gsc_help_requested = FALSE,
+ gsc_help_hints_silenced = FALSE;
+
+/* Font descriptor type, encapsulating size and monospaced boolean. */
+typedef struct {
+ sc_bool is_monospaced;
+ sc_int size;
+} gsc_font_size_t;
+
+/* Font stack and attributes for nesting tags. */
+enum { GSC_MAX_STYLE_NESTING = 32 };
+static gsc_font_size_t gsc_font_stack[GSC_MAX_STYLE_NESTING];
+static glui32 gsc_font_index = 0;
+static glui32 gsc_attribute_bold = 0,
+ gsc_attribute_italic = 0,
+ gsc_attribute_underline = 0,
+ gsc_attribute_secondary_color = 0;
+
+/* Notional default font size, and limit font sizes. */
+static const sc_int GSC_DEFAULT_FONT_SIZE = 12,
+ GSC_MEDIUM_FONT_SIZE = 14,
+ GSC_LARGE_FONT_SIZE = 16;
+
+/* Milliseconds per second and timeouts count for delay tags. */
+static const glui32 GSC_MILLISECONDS_PER_SECOND = 1000;
+static const glui32 GSC_TIMEOUTS_COUNT = 10;
+
+/* Number of hints to refuse before offering to end hint display. */
+static const sc_int GSC_HINT_REFUSAL_LIMIT = 5;
+
+/* The keypresses used to cancel any <wait x.x> early. */
+static const glui32 GSC_CANCEL_WAIT_1 = ' ',
+ GSC_CANCEL_WAIT_2 = keycode_Return;
+
+
+/*
+ * gsc_output_register_help_request()
+ * gsc_output_silence_help_hints()
+ * gsc_output_provide_help_hint()
+ *
+ * Register a request for help, and print a note of how to get Glk command
+ * help from the interpreter unless silenced.
+ */
+static void
+gsc_output_register_help_request()
+{
+ gsc_help_requested = TRUE;
+}
+
+static void
+gsc_output_silence_help_hints()
+{
+ gsc_help_hints_silenced = TRUE;
+}
+
+static void
+gsc_output_provide_help_hint()
+{
+ if (gsc_help_requested && !gsc_help_hints_silenced)
+ {
+ g_vm->glk_set_style (style_Emphasized);
+ g_vm->glk_put_string ("[Try 'glk help' for help on special interpreter"
+ " commands]\n");
+
+ gsc_help_requested = FALSE;
+ g_vm->glk_set_style (style_Normal);
+ }
+}
+
+
+/*
+ * gsc_set_glk_style()
+ *
+ * Set a Glk style based on the top of the font stack and attributes.
+ */
+static void gsc_set_glk_style()
+{
+ sc_bool is_monospaced;
+ sc_int font_size;
+
+ /* Get the current font stack top, or default value. */
+ if (gsc_font_index > 0)
+ {
+ is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
+ font_size = gsc_font_stack[gsc_font_index - 1].size;
+ }
+ else
+ {
+ is_monospaced = FALSE;
+ font_size = GSC_DEFAULT_FONT_SIZE;
+ }
+
+ /*
+ * Map the font and current attributes into a Glk style. Because Glk styles
+ * aren't cumulative this has to be done by precedences.
+ */
+ if (is_monospaced)
+ {
+ /*
+ * No matter the size or attributes, if monospaced use Preformatted
+ * style, as it's all we have.
+ */
+ g_vm->glk_set_style (style_Preformatted);
+ }
+ else
+ {
+ /*
+ * For large and medium point sizes, use Header or Subheader styles
+ * respectively.
+ */
+ if (font_size >= GSC_LARGE_FONT_SIZE)
+ g_vm->glk_set_style (style_Header);
+ else if (font_size >= GSC_MEDIUM_FONT_SIZE)
+ g_vm->glk_set_style (style_Subheader);
+ else
+ {
+ /*
+ * For bold, use Subheader; for italics, underline, or secondary
+ * color, use Emphasized.
+ */
+ if (gsc_attribute_bold > 0)
+ g_vm->glk_set_style (style_Subheader);
+ else if (gsc_attribute_italic > 0
+ || gsc_attribute_underline > 0
+ || gsc_attribute_secondary_color > 0)
+ g_vm->glk_set_style (style_Emphasized);
+ else
+ {
+ /*
+ * There's nothing special about this text, so drop down to
+ * Normal style.
+ */
+ g_vm->glk_set_style (style_Normal);
+ }
+ }
+ }
+}
+
+
+/*
+ * gsc_handle_font_tag()
+ * gsc_handle_endfont_tag()
+ *
+ * Push the settings of a font tag onto the font stack, and pop on end of
+ * font tag. Set the appropriate Glk style.
+ */
+static void
+gsc_handle_font_tag (const sc_char *argument)
+{
+ /* Ignore the call on stack overrun. */
+ if (gsc_font_index < GSC_MAX_STYLE_NESTING)
+ {
+ sc_char *lower, *face, *size;
+ sc_bool is_monospaced;
+ sc_int index_, font_size;
+
+ /* Get the current top of stack, or default on empty stack. */
+ if (gsc_font_index > 0)
+ {
+ is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
+ font_size = gsc_font_stack[gsc_font_index - 1].size;
+ }
+ else
+ {
+ is_monospaced = FALSE;
+ font_size = GSC_DEFAULT_FONT_SIZE;
+ }
+
+ /* Copy and convert argument to all lowercase. */
+ lower = (sc_char *)gsc_malloc (strlen (argument) + 1);
+ strcpy (lower, argument);
+ for (index_ = 0; lower[index_] != '\0'; index_++)
+ lower[index_] = g_vm->glk_char_to_lower (lower[index_]);
+
+ /* Find any face= portion of the tag argument. */
+ face = strstr (lower, "face=");
+ if (face)
+ {
+ /*
+ * There may be plenty of monospaced fonts, but we do only courier
+ * and terminal.
+ */
+ is_monospaced = strncmp (face, "face=\"courier\"", 14) == 0
+ || strncmp (face, "face=\"terminal\"", 15) == 0;
+ }
+
+ /* Find the size= portion of the tag argument. */
+ size = strstr (lower, "size=");
+ if (size)
+ {
+ sc_uint value;
+
+ /* Deal with incremental and absolute sizes. */
+ if (strncmp (size, "size=+", 6) == 0
+ && sscanf (size, "size=+%lu", &value) == 1)
+ font_size += value;
+ else if (strncmp (size, "size=-", 6) == 0
+ && sscanf (size, "size=-%lu", &value) == 1)
+ font_size -= value;
+ else if (sscanf (size, "size=%lu", &value) == 1)
+ font_size = value;
+ }
+
+ /* Done with tag argument copy. */
+ free (lower);
+
+ /*
+ * Push the new font setting onto the font stack, and set Glk style.
+ */
+ gsc_font_stack[gsc_font_index].is_monospaced = is_monospaced;
+ gsc_font_stack[gsc_font_index++].size = font_size;
+ gsc_set_glk_style();
+ }
+}
+
+static void
+gsc_handle_endfont_tag()
+{
+ /* Unless underrun, pop the font stack and set Glk style. */
+ if (gsc_font_index > 0)
+ {
+ gsc_font_index--;
+ gsc_set_glk_style();
+ }
+}
+
+
+/*
+ * gsc_handle_attribute_tag()
+ *
+ * Increment the required attribute nesting counter, or decrement on end
+ * tag. Set the appropriate Glk style.
+ */
+static void
+gsc_handle_attribute_tag (sc_int tag)
+{
+ /*
+ * Increment the required attribute nesting counter, and set Glk style.
+ */
+ switch (tag)
+ {
+ case SC_TAG_BOLD:
+ gsc_attribute_bold++;
+ break;
+ case SC_TAG_ITALICS:
+ gsc_attribute_italic++;
+ break;
+ case SC_TAG_UNDERLINE:
+ gsc_attribute_underline++;
+ break;
+ case SC_TAG_COLOR:
+ gsc_attribute_secondary_color++;
+ break;
+ default:
+ break;
+ }
+ gsc_set_glk_style();
+}
+
+static void
+gsc_handle_endattribute_tag (sc_int tag)
+{
+ /*
+ * Decrement the required attribute nesting counter, unless underrun, and
+ * set Glk style.
+ */
+ switch (tag)
+ {
+ case SC_TAG_ENDBOLD:
+ if (gsc_attribute_bold > 0)
+ gsc_attribute_bold--;
+ break;
+ case SC_TAG_ENDITALICS:
+ if (gsc_attribute_italic > 0)
+ gsc_attribute_italic--;
+ break;
+ case SC_TAG_ENDUNDERLINE:
+ if (gsc_attribute_underline > 0)
+ gsc_attribute_underline--;
+ break;
+ case SC_TAG_ENDCOLOR:
+ if (gsc_attribute_secondary_color > 0)
+ gsc_attribute_secondary_color--;
+ break;
+ default:
+ break;
+ }
+ gsc_set_glk_style();
+}
+
+
+/*
+ * gsc_handle_wait_tag()
+ *
+ * If Glk offers timers, delay for the requested period. Otherwise, this
+ * function does nothing.
+ */
+static void gsc_handle_wait_tag(const sc_char *argument)
+{
+ double delay = 0.0;
+
+ /* Ignore the wait tag if the Glk doesn't have timers. */
+ if (!g_vm->glk_gestalt (gestalt_Timer, 0))
+ return;
+
+ /* Determine the delay time, and convert to milliseconds. */
+ if (sscanf (argument, "%lf", &delay) == 1 && delay > 0.0)
+ {
+ glui32 milliseconds, timeout;
+
+ /*
+ * Work with timeouts at 1/10 of the wait period, to minimize Glk
+ * timer jitter. Allow the timeout to be canceled by keypress, as a
+ * user convenience.
+ */
+ milliseconds = (glui32) (delay * GSC_MILLISECONDS_PER_SECOND);
+ timeout = milliseconds / GSC_TIMEOUTS_COUNT;
+ if (timeout > 0)
+ {
+ glui32 delayed;
+ sc_bool is_completed;
+
+ /* Request timer events, and let a keypress cancel the wait. */
+ g_vm->glk_request_char_event (gsc_main_window);
+ g_vm->glk_request_timer_events (timeout);
+
+ /* Loop until delay completed or canceled by a keypress. */
+ is_completed = TRUE;
+ for (delayed = 0; delayed < milliseconds; delayed += timeout)
+ {
+ event_t event;
+
+ gsc_event_wait_2 (evtype_CharInput, evtype_Timer, &event);
+ if (event.type == evtype_CharInput)
+ {
+ /* Cancel the delay, or reissue the input request. */
+ if (event.val1 == GSC_CANCEL_WAIT_1
+ || event.val1 == GSC_CANCEL_WAIT_2)
+ {
+ is_completed = FALSE;
+ break;
+ }
+ else
+ g_vm->glk_request_char_event (gsc_main_window);
+ }
+ }
+
+ /* Cancel any pending character input, and stop timers. */
+ if (is_completed)
+ g_vm->glk_cancel_char_event (gsc_main_window);
+ g_vm->glk_request_timer_events (0);
+ }
+ }
+}
+
+
+/*
+ * gsc_reset_glk_style()
+ *
+ * Drop all stacked fonts and nested attributes, and return to normal Glk
+ * style.
+ */
+static void
+gsc_reset_glk_style()
+{
+ /* Reset the font stack and attributes, and set a normal style. */
+ gsc_font_index = 0;
+ gsc_attribute_bold = 0;
+ gsc_attribute_italic = 0;
+ gsc_attribute_underline = 0;
+ gsc_attribute_secondary_color = 0;
+ gsc_set_glk_style();
+}
+
+
+/*
+ * os_print_tag()
+ *
+ * Interpret selected Adrift output control tags. Not all are implemented
+ * here; several are ignored.
+ */
+void
+os_print_tag (sc_int tag, const sc_char *argument)
+{
+ event_t event;
+ assert (argument);
+
+ switch (tag)
+ {
+ case SC_TAG_CLS:
+ /* Clear the main text display window. */
+ g_vm->glk_window_clear (gsc_main_window);
+ break;
+
+ case SC_TAG_FONT:
+ /* Handle with specific tag handler function. */
+ gsc_handle_font_tag (argument);
+ break;
+
+ case SC_TAG_ENDFONT:
+ /* Handle with specific endtag handler function. */
+ gsc_handle_endfont_tag ();
+ break;
+
+ case SC_TAG_BOLD:
+ case SC_TAG_ITALICS:
+ case SC_TAG_UNDERLINE:
+ case SC_TAG_COLOR:
+ /* Handle with common attribute tag handler function. */
+ gsc_handle_attribute_tag (tag);
+ break;
+
+ case SC_TAG_ENDBOLD:
+ case SC_TAG_ENDITALICS:
+ case SC_TAG_ENDUNDERLINE:
+ case SC_TAG_ENDCOLOR:
+ /* Handle with common attribute endtag handler function. */
+ gsc_handle_endattribute_tag (tag);
+ break;
+
+ case SC_TAG_CENTER:
+ case SC_TAG_RIGHT:
+ case SC_TAG_ENDCENTER:
+ case SC_TAG_ENDRIGHT:
+ /*
+ * We don't center or justify text, but so that things look right we do
+ * want a newline on starting or ending such a section.
+ */
+ g_vm->glk_put_char ('\n');
+ break;
+
+ case SC_TAG_WAIT:
+ /*
+ * Update the status line now only if it has its own window, then
+ * handle with a specialized handler.
+ */
+ if (gsc_status_window)
+ gsc_status_notify ();
+ gsc_handle_wait_tag (argument);
+ break;
+
+ case SC_TAG_WAITKEY:
+ /*
+ * If reading an input log, ignore; it disrupts replay. Write a newline
+ * to separate off any unterminated game output instead.
+ */
+ if (!gsc_readlog_stream)
+ {
+ /* Update the status line now only if it has its own window. */
+ if (gsc_status_window)
+ gsc_status_notify ();
+
+ /* Request a character event, and wait for it to be filled. */
+ g_vm->glk_request_char_event (gsc_main_window);
+ gsc_event_wait (evtype_CharInput, &event);
+ }
+ else
+ g_vm->glk_put_char ('\n');
+ break;
+
+ default:
+ /* Ignore unimplemented and unknown tags. */
+ break;
+ }
+}
+
+
+/*
+ * os_print_string()
+ *
+ * Print a text string to the main output window.
+ */
+void os_print_string(const sc_char *string) {
+ sc_bool is_monospaced;
+ assert (string);
+ assert (g_vm->glk_stream_get_current ());
+
+ /*
+ * Get the monospace font setting from the current top of stack, or
+ * default on empty stack. If set, we may need to use an alternative
+ * function to write this string.
+ */
+ if (gsc_font_index > 0)
+ is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
+ else
+ is_monospaced = FALSE;
+
+ /*
+ * The main window should always be the currently set window at this point,
+ * so we never be attempting monospaced output to the status window.
+ * Nevertheless, check anyway.
+ */
+ if (is_monospaced
+ && g_vm->glk_stream_get_current () == g_vm->glk_window_get_stream (gsc_main_window))
+ gsc_put_string_alternate (string);
+ else
+ gsc_put_string (string);
+}
+
+
+/*
+ * os_print_string_debug()
+ *
+ * Debugging output goes to the main Glk window -- no special effects or
+ * dedicated debugging window attempted.
+ */
+void
+os_print_string_debug (const sc_char *string)
+{
+ assert (string);
+ assert (g_vm->glk_stream_get_current ());
+
+ gsc_put_string (string);
+}
+
+
+/*
+ * gsc_styled_string()
+ * gsc_styled_char()
+ * gsc_standout_string()
+ * gsc_standout_char()
+ * gsc_normal_string()
+ * gsc_normal_char()
+ * gsc_header_string()
+ *
+ * Convenience functions to print strings in assorted styles. A standout
+ * string is one that hints that it's from the interpreter, not the game.
+ */
+static void
+gsc_styled_string (glui32 style, const char *message)
+{
+ assert (message);
+
+ g_vm->glk_set_style (style);
+ g_vm->glk_put_string ((char *) message);
+ g_vm->glk_set_style (style_Normal);
+}
+
+static void
+gsc_styled_char (glui32 style, char c)
+{
+ char buffer[2];
+
+ buffer[0] = c;
+ buffer[1] = '\0';
+ gsc_styled_string (style, buffer);
+}
+
+static void
+gsc_standout_string (const char *message)
+{
+ gsc_styled_string (style_Emphasized, message);
+}
+
+static void
+gsc_standout_char (char c)
+{
+ gsc_styled_char (style_Emphasized, c);
+}
+
+static void
+gsc_normal_string (const char *message)
+{
+ gsc_styled_string (style_Normal, message);
+}
+
+static void
+gsc_normal_char (char c)
+{
+ gsc_styled_char (style_Normal, c);
+}
+
+static void
+gsc_header_string (const char *message)
+{
+ gsc_styled_string (style_Header, message);
+}
+
+
+/*
+ * os_display_hints()
+ *
+ * This is a very basic hints display. In mitigation, very few games use
+ * hints at all, and those that do are usually sparse in what they hint at, so
+ * it's sort of good enough for the moment.
+ */
+void
+os_display_hints (sc_game game)
+{
+ sc_game_hint hint;
+ sc_int refused;
+
+ /* For each hint, print the question, and confirm hint display. */
+ refused = 0;
+ for (hint = sc_get_first_game_hint (game);
+ hint; hint = sc_get_next_game_hint (game, hint))
+ {
+ const sc_char *hint_question, *hint_text;
+
+ /* If enough refusals, offer a way out of the loop. */
+ if (refused >= GSC_HINT_REFUSAL_LIMIT)
+ {
+ if (!os_confirm (GSC_CONF_CONTINUE_HINTS))
+ break;
+ refused = 0;
+ }
+
+ /* Pop the question. */
+ hint_question = sc_get_game_hint_question (game, hint);
+ gsc_normal_char ('\n');
+ gsc_standout_string (hint_question);
+ gsc_normal_char ('\n');
+
+ /* Print the subtle hint, or on to the next hint. */
+ hint_text = sc_get_game_subtle_hint (game, hint);
+ if (hint_text)
+ {
+ if (!os_confirm (GSC_CONF_SUBTLE_HINT))
+ {
+ refused++;
+ continue;
+ }
+ gsc_normal_char ('\n');
+ gsc_standout_string (hint_text);
+ gsc_normal_string ("\n\n");
+ }
+
+ /* Print the less than subtle hint, or on to the next hint. */
+ hint_text = sc_get_game_unsubtle_hint (game, hint);
+ if (hint_text)
+ {
+ if (!os_confirm (GSC_CONF_UNSUBTLE_HINT))
+ {
+ refused++;
+ continue;
+ }
+ gsc_normal_char ('\n');
+ gsc_standout_string (hint_text);
+ gsc_normal_string ("\n\n");
+ }
+ }
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk resource handling functions */
+/*---------------------------------------------------------------------*/
+
+/*
+ * os_play_sound()
+ * os_stop_sound()
+ *
+ * Stub functions. The unused variables defeat gcc warnings.
+ */
+void
+os_play_sound (const sc_char *filepath,
+ sc_int offset, sc_int length, sc_bool is_looping)
+{
+ const sc_char *unused1;
+ sc_int unused2, unused3;
+ sc_bool unused4;
+ unused1 = filepath;
+ unused2 = offset;
+ unused3 = length;
+ unused4 = is_looping;
+}
+
+void
+os_stop_sound()
+{
+}
+
+
+/*
+ * os_show_graphic()
+ *
+ * For graphic-capable Glk libraries on Linux, attempt graphics using xv. The
+ * graphic capability test isn't really required, it's just a way of having
+ * graphics behave without surprises; someone using a non-graphical Glk
+ * probably won't expect graphics to pop up.
+ *
+ * For other cases, this is a stub function, with unused variables to defeat
+ * gcc warnings.
+ */
+#ifdef LINUX_GRAPHICS
+static int gsclinux_graphics_enabled = TRUE;
+static char *gsclinux_game_file = nullptr;
+void
+os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length)
+{
+ const sc_char *unused1;
+ unused1 = filepath;
+
+ if (length > 0
+ && gsclinux_graphics_enabled && g_vm->glk_gestalt (gestalt_Graphics, 0))
+ {
+ sc_char *buffer;
+
+ /*
+ * Try to extract data with dd. Assuming that works, background xv to
+ * display the image, then background a job to delay ten seconds and
+ * then delete the temporary file containing the image. Systems lacking
+ * xv can usually use a small script, named xv, to invoke eog or an
+ * alternative image display binary. Not exactly finessed.
+ */
+ assert (gsclinux_game_file);
+ buffer = gsc_malloc (strlen (gsclinux_game_file) + 128);
+ sprintf (buffer, "dd if=%s ibs=1c skip=%ld count=%ld obs=100k"
+ " of=/tmp/scare.jpg 2>/dev/null",
+ gsclinux_game_file, offset, length);
+ system (buffer);
+ free (buffer);
+ system ("xv /tmp/scare.jpg >/dev/null 2>&1 &");
+ system ("( sleep 10; rm /tmp/scare.jpg ) >/dev/null 2>&1 &");
+ }
+}
+#else
+void
+os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length)
+{
+ const sc_char *unused1;
+ sc_int unused2, unused3;
+ unused1 = filepath;
+ unused2 = offset;
+ unused3 = length;
+}
+#endif
+
+
+/*---------------------------------------------------------------------*/
+/* Glk command escape functions */
+/*---------------------------------------------------------------------*/
+
+/*
+ * gsc_command_script()
+ *
+ * Turn game output scripting (logging) on and off.
+ */
+static void
+gsc_command_script (const char *argument)
+{
+ assert (argument);
+
+ if (sc_strcasecmp (argument, "on") == 0)
+ {
+ frefid_t fileref;
+
+ if (gsc_transcript_stream)
+ {
+ gsc_normal_string ("Glk transcript is already on.\n");
+ return;
+ }
+
+ fileref = g_vm->glk_fileref_create_by_prompt (fileusage_Transcript
+ | fileusage_TextMode,
+ filemode_WriteAppend, 0);
+ if (!fileref)
+ {
+ gsc_standout_string ("Glk transcript failed.\n");
+ return;
+ }
+
+ gsc_transcript_stream = g_vm->glk_stream_open_file (fileref,
+ filemode_WriteAppend, 0);
+ g_vm->glk_fileref_destroy (fileref);
+ if (!gsc_transcript_stream)
+ {
+ gsc_standout_string ("Glk transcript failed.\n");
+ return;
+ }
+
+ g_vm->glk_window_set_echo_stream (gsc_main_window, gsc_transcript_stream);
+
+ gsc_normal_string ("Glk transcript is now on.\n");
+ }
+
+ else if (sc_strcasecmp (argument, "off") == 0)
+ {
+ if (!gsc_transcript_stream)
+ {
+ gsc_normal_string ("Glk transcript is already off.\n");
+ return;
+ }
+
+ g_vm->glk_stream_close (gsc_transcript_stream, nullptr);
+ gsc_transcript_stream = nullptr;
+
+ g_vm->glk_window_set_echo_stream (gsc_main_window, nullptr);
+
+ gsc_normal_string ("Glk transcript is now off.\n");
+ }
+
+ else if (strlen (argument) == 0)
+ {
+ gsc_normal_string ("Glk transcript is ");
+ gsc_normal_string (gsc_transcript_stream ? "on" : "off");
+ gsc_normal_string (".\n");
+ }
+
+ else
+ {
+ gsc_normal_string ("Glk transcript can be ");
+ gsc_standout_string ("on");
+ gsc_normal_string (", or ");
+ gsc_standout_string ("off");
+ gsc_normal_string (".\n");
+ }
+}
+
+
+/*
+ * gsc_command_inputlog()
+ *
+ * Turn game input logging on and off.
+ */
+static void
+gsc_command_inputlog (const char *argument)
+{
+ assert (argument);
+
+ if (sc_strcasecmp (argument, "on") == 0)
+ {
+ frefid_t fileref;
+
+ if (gsc_inputlog_stream)
+ {
+ gsc_normal_string ("Glk input logging is already on.\n");
+ return;
+ }
+
+ fileref = g_vm->glk_fileref_create_by_prompt (fileusage_InputRecord
+ | fileusage_BinaryMode,
+ filemode_WriteAppend, 0);
+ if (!fileref)
+ {
+ gsc_standout_string ("Glk input logging failed.\n");
+ return;
+ }
+
+ gsc_inputlog_stream = g_vm->glk_stream_open_file (fileref,
+ filemode_WriteAppend, 0);
+ g_vm->glk_fileref_destroy (fileref);
+ if (!gsc_inputlog_stream)
+ {
+ gsc_standout_string ("Glk input logging failed.\n");
+ return;
+ }
+
+ gsc_normal_string ("Glk input logging is now on.\n");
+ }
+
+ else if (sc_strcasecmp (argument, "off") == 0)
+ {
+ if (!gsc_inputlog_stream)
+ {
+ gsc_normal_string ("Glk input logging is already off.\n");
+ return;
+ }
+
+ g_vm->glk_stream_close (gsc_inputlog_stream, nullptr);
+ gsc_inputlog_stream = nullptr;
+
+ gsc_normal_string ("Glk input log is now off.\n");
+ }
+
+ else if (strlen (argument) == 0)
+ {
+ gsc_normal_string ("Glk input logging is ");
+ gsc_normal_string (gsc_inputlog_stream ? "on" : "off");
+ gsc_normal_string (".\n");
+ }
+
+ else
+ {
+ gsc_normal_string ("Glk input logging can be ");
+ gsc_standout_string ("on");
+ gsc_normal_string (", or ");
+ gsc_standout_string ("off");
+ gsc_normal_string (".\n");
+ }
+}
+
+
+/*
+ * gsc_command_readlog()
+ *
+ * Set the game input log, to read input from a file.
+ */
+static void
+gsc_command_readlog (const char *argument)
+{
+ assert (argument);
+
+ if (sc_strcasecmp (argument, "on") == 0)
+ {
+ frefid_t fileref;
+
+ if (gsc_readlog_stream)
+ {
+ gsc_normal_string ("Glk read log is already on.\n");
+ return;
+ }
+
+ fileref = g_vm->glk_fileref_create_by_prompt (fileusage_InputRecord
+ | fileusage_BinaryMode,
+ filemode_Read, 0);
+ if (!fileref)
+ {
+ gsc_standout_string ("Glk read log failed.\n");
+ return;
+ }
+
+ if (!g_vm->glk_fileref_does_file_exist (fileref))
+ {
+ g_vm->glk_fileref_destroy (fileref);
+ gsc_standout_string ("Glk read log failed.\n");
+ return;
+ }
+
+ gsc_readlog_stream = g_vm->glk_stream_open_file (fileref, filemode_Read, 0);
+ g_vm->glk_fileref_destroy (fileref);
+ if (!gsc_readlog_stream)
+ {
+ gsc_standout_string ("Glk read log failed.\n");
+ return;
+ }
+
+ gsc_normal_string ("Glk read log is now on.\n");
+ }
+
+ else if (sc_strcasecmp (argument, "off") == 0)
+ {
+ if (!gsc_readlog_stream)
+ {
+ gsc_normal_string ("Glk read log is already off.\n");
+ return;
+ }
+
+ g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+
+ gsc_normal_string ("Glk read log is now off.\n");
+ }
+
+ else if (strlen (argument) == 0)
+ {
+ gsc_normal_string ("Glk read log is ");
+ gsc_normal_string (gsc_readlog_stream ? "on" : "off");
+ gsc_normal_string (".\n");
+ }
+
+ else
+ {
+ gsc_normal_string ("Glk read log can be ");
+ gsc_standout_string ("on");
+ gsc_normal_string (", or ");
+ gsc_standout_string ("off");
+ gsc_normal_string (".\n");
+ }
+}
+
+
+/*
+ * gsc_command_abbreviations()
+ *
+ * Turn abbreviation expansions on and off.
+ */
+static void
+gsc_command_abbreviations (const char *argument)
+{
+ assert (argument);
+
+ if (sc_strcasecmp (argument, "on") == 0)
+ {
+ if (gsc_abbreviations_enabled)
+ {
+ gsc_normal_string ("Glk abbreviation expansions are already on.\n");
+ return;
+ }
+
+ gsc_abbreviations_enabled = TRUE;
+ gsc_normal_string ("Glk abbreviation expansions are now on.\n");
+ }
+
+ else if (sc_strcasecmp (argument, "off") == 0)
+ {
+ if (!gsc_abbreviations_enabled)
+ {
+ gsc_normal_string ("Glk abbreviation expansions are already off.\n");
+ return;
+ }
+
+ gsc_abbreviations_enabled = FALSE;
+ gsc_normal_string ("Glk abbreviation expansions are now off.\n");
+ }
+
+ else if (strlen (argument) == 0)
+ {
+ gsc_normal_string ("Glk abbreviation expansions are ");
+ gsc_normal_string (gsc_abbreviations_enabled ? "on" : "off");
+ gsc_normal_string (".\n");
+ }
+
+ else
+ {
+ gsc_normal_string ("Glk abbreviation expansions can be ");
+ gsc_standout_string ("on");
+ gsc_normal_string (", or ");
+ gsc_standout_string ("off");
+ gsc_normal_string (".\n");
+ }
+}
+
+
+/*
+ * gsc_command_print_version_number()
+ * gsc_command_version()
+ *
+ * Print out the Glk library version number.
+ */
+static void
+gsc_command_print_version_number (glui32 version)
+{
+ char buffer[64];
+
+ sprintf (buffer, "%lu.%lu.%lu",
+ (unsigned long) version >> 16,
+ (unsigned long) (version >> 8) & 0xff,
+ (unsigned long) version & 0xff);
+ gsc_normal_string (buffer);
+}
+
+static void
+gsc_command_version (const char *argument)
+{
+ glui32 version;
+ assert (argument);
+
+ gsc_normal_string ("This is version ");
+ gsc_command_print_version_number (GSC_PORT_VERSION);
+ gsc_normal_string (" of the Glk SCARE port.\n");
+
+ version = g_vm->glk_gestalt (gestalt_Version, 0);
+ gsc_normal_string ("The Glk library version is ");
+ gsc_command_print_version_number (version);
+ gsc_normal_string (".\n");
+}
+
+
+/*
+ * gsc_command_commands()
+ *
+ * Turn command escapes off. Once off, there's no way to turn them back on.
+ * Commands must be on already to enter this function.
+ */
+static void
+gsc_command_commands (const char *argument)
+{
+ assert (argument);
+
+ if (sc_strcasecmp (argument, "on") == 0)
+ {
+ gsc_normal_string ("Glk commands are already on.\n");
+ }
+
+ else if (sc_strcasecmp (argument, "off") == 0)
+ {
+ gsc_commands_enabled = FALSE;
+ gsc_normal_string ("Glk commands are now off.\n");
+ }
+
+ else if (strlen (argument) == 0)
+ {
+ gsc_normal_string ("Glk commands are ");
+ gsc_normal_string (gsc_commands_enabled ? "on" : "off");
+ gsc_normal_string (".\n");
+ }
+
+ else
+ {
+ gsc_normal_string ("Glk commands can be ");
+ gsc_standout_string ("on");
+ gsc_normal_string (", or ");
+ gsc_standout_string ("off");
+ gsc_normal_string (".\n");
+ }
+}
+
+
+/*
+ * gsc_command_license()
+ *
+ * Print licensing terms.
+ */
+static void
+gsc_command_license (const char *argument)
+{
+ assert (argument);
+
+ gsc_normal_string ("This program is free software; you can redistribute it"
+ " and/or modify it under the terms of version 2 of the"
+ " GNU General Public License as published by the Free"
+ " Software Foundation.\n\n");
+
+ gsc_normal_string ("This program is distributed in the hope that it will be"
+ " useful, but ");
+ gsc_standout_string ("WITHOUT ANY WARRANTY");
+ gsc_normal_string ("; without even the implied warranty of ");
+ gsc_standout_string ("MERCHANTABILITY");
+ gsc_normal_string (" or ");
+ gsc_standout_string ("FITNESS FOR A PARTICULAR PURPOSE");
+ gsc_normal_string (". See the GNU General Public License for more"
+ " details.\n\n");
+
+ gsc_normal_string ("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\n\n");
+
+ gsc_normal_string ("Please report any bugs, omissions, or misfeatures to ");
+ gsc_standout_string ("simon_baldwin at yahoo.com");
+ gsc_normal_string (".\n");
+}
+
+
+/* Glk subcommands and handler functions. */
+typedef const struct
+{
+ const char * const command; /* Glk subcommand. */
+ void (* const handler) (const char *argument); /* Subcommand handler. */
+ const int takes_argument; /* Argument flag. */
+} gsc_command_t;
+typedef gsc_command_t *gsc_commandref_t;
+
+static void gsc_command_summary (const char *argument);
+static void gsc_command_help (const char *argument);
+
+static gsc_command_t GSC_COMMAND_TABLE[] = {
+ {"summary", gsc_command_summary, FALSE},
+ {"script", gsc_command_script, TRUE},
+ {"inputlog", gsc_command_inputlog, TRUE},
+ {"readlog", gsc_command_readlog, TRUE},
+ {"abbreviations", gsc_command_abbreviations, TRUE},
+ {"version", gsc_command_version, FALSE},
+ {"commands", gsc_command_commands, TRUE},
+ {"license", gsc_command_license, FALSE},
+ {"help", gsc_command_help, TRUE},
+ {nullptr, nullptr, FALSE}
+};
+
+
+/*
+ * gsc_command_summary()
+ *
+ * Report all current Glk settings.
+ */
+static void
+gsc_command_summary (const char *argument)
+{
+ gsc_commandref_t entry;
+ assert (argument);
+
+ /*
+ * Call handlers that have status to report with an empty argument,
+ * prompting each to print its current setting.
+ */
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
+ {
+ if (entry->handler == gsc_command_summary
+ || entry->handler == gsc_command_license
+ || entry->handler == gsc_command_help)
+ continue;
+
+ entry->handler ("");
+ }
+}
+
+
+/*
+ * gsc_command_help()
+ *
+ * Document the available Glk commands.
+ */
+static void
+gsc_command_help (const char *command)
+{
+ gsc_commandref_t entry, matched;
+ assert (command);
+
+ if (strlen (command) == 0)
+ {
+ gsc_normal_string ("Glk commands are");
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
+ {
+ gsc_commandref_t next;
+
+ next = entry + 1;
+ gsc_normal_string (next->command ? " " : " and ");
+ gsc_standout_string (entry->command);
+ gsc_normal_string (next->command ? "," : ".\n\n");
+ }
+
+ gsc_normal_string ("Glk commands may be abbreviated, as long as"
+ " the abbreviation is unambiguous. Use ");
+ gsc_standout_string ("glk help");
+ gsc_normal_string (" followed by a Glk command name for help on that"
+ " command.\n");
+ return;
+ }
+
+ matched = nullptr;
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
+ {
+ if (sc_strncasecmp (command, entry->command, strlen (command)) == 0)
+ {
+ if (matched)
+ {
+ gsc_normal_string ("The Glk command ");
+ gsc_standout_string (command);
+ gsc_normal_string (" is ambiguous. Try ");
+ gsc_standout_string ("glk help");
+ gsc_normal_string (" for more information.\n");
+ return;
+ }
+ matched = entry;
+ }
+ }
+ if (!matched)
+ {
+ gsc_normal_string ("The Glk command ");
+ gsc_standout_string (command);
+ gsc_normal_string (" is not valid. Try ");
+ gsc_standout_string ("glk help");
+ gsc_normal_string (" for more information.\n");
+ return;
+ }
+
+ if (matched->handler == gsc_command_summary)
+ {
+ gsc_normal_string ("Prints a summary of all the current Glk SCARE"
+ " settings.\n");
+ }
+
+ else if (matched->handler == gsc_command_script)
+ {
+ gsc_normal_string ("Logs the game's output to a file.\n\nUse ");
+ gsc_standout_string ("glk script on");
+ gsc_normal_string (" to begin logging game output, and ");
+ gsc_standout_string ("glk script off");
+ gsc_normal_string (" to end it. Glk SCARE will ask you for a file"
+ " when you turn scripts on.\n");
+ }
+
+ else if (matched->handler == gsc_command_inputlog)
+ {
+ gsc_normal_string ("Records the commands you type into a game.\n\nUse ");
+ gsc_standout_string ("glk inputlog on");
+ gsc_normal_string (", to begin recording your commands, and ");
+ gsc_standout_string ("glk inputlog off");
+ gsc_normal_string (" to turn off input logs. You can play back"
+ " recorded commands into a game with the ");
+ gsc_standout_string ("glk readlog");
+ gsc_normal_string (" command.\n");
+ }
+
+ else if (matched->handler == gsc_command_readlog)
+ {
+ gsc_normal_string ("Plays back commands recorded with ");
+ gsc_standout_string ("glk inputlog on");
+ gsc_normal_string (".\n\nUse ");
+ gsc_standout_string ("glk readlog on");
+ gsc_normal_string (". Command play back stops at the end of the"
+ " file. You can also play back commands from a"
+ " text file created using any standard editor.\n");
+ }
+
+ else if (matched->handler == gsc_command_abbreviations)
+ {
+ gsc_normal_string ("Controls abbreviation expansion.\n\nGlk SCARE"
+ " automatically expands several standard single"
+ " letter abbreviations for you; for example, \"x\""
+ " becomes \"examine\". Use ");
+ gsc_standout_string ("glk abbreviations on");
+ gsc_normal_string (" to turn this feature on, and ");
+ gsc_standout_string ("glk abbreviations off");
+ gsc_normal_string (" to turn it off. While the feature is on, you"
+ " can bypass abbreviation expansion for an"
+ " individual game command by prefixing it with a"
+ " single quote.\n");
+ }
+
+ else if (matched->handler == gsc_command_version)
+ {
+ gsc_normal_string ("Prints the version numbers of the Glk library"
+ " and the Glk SCARE port.\n");
+ }
+
+ else if (matched->handler == gsc_command_commands)
+ {
+ gsc_normal_string ("Turn off Glk commands.\n\nUse ");
+ gsc_standout_string ("glk commands off");
+ gsc_normal_string (" to disable all Glk commands, including this one."
+ " Once turned off, there is no way to turn Glk"
+ " commands back on while inside the game.\n");
+ }
+
+ else if (matched->handler == gsc_command_license)
+ {
+ gsc_normal_string ("Prints Glk SCARE's software license.\n");
+ }
+
+ else if (matched->handler == gsc_command_help)
+ gsc_command_help ("");
+
+ else
+ gsc_normal_string ("There is no help available on that Glk command."
+ " Sorry.\n");
+}
+
+
+/*
+ * gsc_command_escape()
+ *
+ * This function is handed each input line. If the line contains a specific
+ * Glk port command, handle it and return TRUE, otherwise return FALSE.
+ */
+static int
+gsc_command_escape (const char *string)
+{
+ int posn;
+ char *string_copy, *command, *argument;
+ assert (string);
+
+ /*
+ * Return FALSE if the string doesn't begin with the Glk command escape
+ * introducer.
+ */
+ posn = strspn (string, "\t ");
+ if (sc_strncasecmp (string + posn, "glk", strlen ("glk")) != 0)
+ return FALSE;
+
+ /* Take a copy of the string, without any leading space or introducer. */
+ string_copy = (char *)gsc_malloc (strlen (string + posn) + 1 - strlen ("glk"));
+ strcpy (string_copy, string + posn + strlen ("glk"));
+
+ /*
+ * Find the subcommand; the first word in the string copy. Find its end,
+ * and ensure it terminates with a NUL.
+ */
+ posn = strspn (string_copy, "\t ");
+ command = string_copy + posn;
+ posn += strcspn (string_copy + posn, "\t ");
+ if (string_copy[posn] != '\0')
+ string_copy[posn++] = '\0';
+
+ /*
+ * Now find any argument data for the command, ensuring it too terminates
+ * with a NUL.
+ */
+ posn += strspn (string_copy + posn, "\t ");
+ argument = string_copy + posn;
+ posn += strcspn (string_copy + posn, "\t ");
+ string_copy[posn] = '\0';
+
+ /*
+ * Try to handle the command and argument as a Glk subcommand. If it
+ * doesn't run unambiguously, print command usage. Treat an empty command
+ * as "help".
+ */
+ if (strlen (command) > 0)
+ {
+ gsc_commandref_t entry, matched;
+ int matches;
+
+ /*
+ * Search for the first unambiguous table command string matching
+ * the command passed in.
+ */
+ matches = 0;
+ matched = nullptr;
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
+ {
+ if (sc_strncasecmp (command, entry->command, strlen (command)) == 0)
+ {
+ matches++;
+ matched = entry;
+ }
+ }
+
+ /* If the match was unambiguous, call the command handler. */
+ if (matches == 1)
+ {
+ gsc_normal_char ('\n');
+ matched->handler (argument);
+
+ if (!matched->takes_argument && strlen (argument) > 0)
+ {
+ gsc_normal_string ("[The ");
+ gsc_standout_string (matched->command);
+ gsc_normal_string (" command ignores arguments.]\n");
+ }
+ }
+
+ /* No match, or the command was ambiguous. */
+ else
+ {
+ gsc_normal_string ("\nThe Glk command ");
+ gsc_standout_string (command);
+ gsc_normal_string (" is ");
+ gsc_normal_string (matches == 0 ? "not valid" : "ambiguous");
+ gsc_normal_string (". Try ");
+ gsc_standout_string ("glk help");
+ gsc_normal_string (" for more information.\n");
+ }
+ }
+ else
+ {
+ gsc_normal_char ('\n');
+ gsc_command_help ("");
+ }
+
+ /* The string contained a Glk command; return TRUE. */
+ free (string_copy);
+ return TRUE;
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port input functions */
+/*---------------------------------------------------------------------*/
+
+/* Quote used to suppress abbreviation expansion and local commands. */
+static const char GSC_QUOTED_INPUT = '\'';
+
+
+/* Table of single-character command abbreviations. */
+typedef const struct
+{
+ const char abbreviation; /* Abbreviation character. */
+ const char *const expansion; /* Expansion string. */
+} gsc_abbreviation_t;
+typedef gsc_abbreviation_t *gsc_abbreviationref_t;
+
+static gsc_abbreviation_t GSC_ABBREVIATIONS[] = {
+ {'c', "close"}, {'g', "again"}, {'i', "inventory"},
+ {'k', "attack"}, {'l', "look"}, {'p', "open"},
+ {'q', "quit"}, {'r', "drop"}, {'t', "take"},
+ {'x', "examine"}, {'y', "yes"}, {'z', "wait"},
+ {'\0', nullptr}
+};
+
+
+/*
+ * gsc_expand_abbreviations()
+ *
+ * Expand a few common one-character abbreviations commonly found in other
+ * game systems.
+ */
+static void
+gsc_expand_abbreviations (char *buffer, int size)
+{
+ char *command, abbreviation;
+ const char *expansion;
+ gsc_abbreviationref_t entry;
+ assert (buffer);
+
+ /* Ignore anything that isn't a single letter command. */
+ command = buffer + strspn (buffer, "\t ");
+ if (!(strlen (command) == 1
+ || (strlen (command) > 1 && Common::isSpace(command[1]))))
+ return;
+
+ /* Scan the abbreviations table for a match. */
+ abbreviation = g_vm->glk_char_to_lower ((unsigned char) command[0]);
+ expansion = nullptr;
+ for (entry = GSC_ABBREVIATIONS; entry->expansion; entry++)
+ {
+ if (entry->abbreviation == abbreviation)
+ {
+ expansion = entry->expansion;
+ break;
+ }
+ }
+
+ /*
+ * If a match found, check for a fit, then replace the character with the
+ * expansion string.
+ */
+ if (expansion)
+ {
+ if (strlen (buffer) + strlen (expansion) - 1 >= (unsigned int) size)
+ return;
+
+ memmove (command + strlen (expansion) - 1, command, strlen (command) + 1);
+ memcpy (command, expansion, strlen (expansion));
+
+ gsc_standout_string ("[");
+ gsc_standout_char (abbreviation);
+ gsc_standout_string (" -> ");
+ gsc_standout_string (expansion);
+ gsc_standout_string ("]\n");
+ }
+}
+
+
+/*
+ * os_read_line()
+ *
+ * Read and return a line of player input.
+ */
+sc_bool
+os_read_line (sc_char *buffer, sc_int length)
+{
+ sc_int characters;
+ assert (buffer && length > 0);
+
+ /* If a help request is pending, provide a user hint. */
+ gsc_output_provide_help_hint ();
+
+ /*
+ * Ensure normal style, update the status line, and issue an input prompt.
+ */
+ gsc_reset_glk_style ();
+ gsc_status_notify ();
+ g_vm->glk_put_string (">");
+
+ /*
+ * If we have an input log to read from, use that until it is exhausted.
+ * On end of file, close the stream and resume input from line requests.
+ */
+ if (gsc_readlog_stream)
+ {
+ glui32 chars;
+
+ /* Get the next line from the log stream. */
+ chars = g_vm->glk_get_line_stream (gsc_readlog_stream, buffer, length);
+ if (chars > 0)
+ {
+ /* Echo the line just read in input style. */
+ g_vm->glk_set_style (style_Input);
+ gsc_put_buffer (buffer, chars);
+ g_vm->glk_set_style (style_Normal);
+
+ /* Return this line as player input. */
+ return TRUE;
+ }
+
+ /*
+ * We're at the end of the log stream. Close it, and then continue
+ * on to request a line from Glk.
+ */
+ g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+ }
+
+ /*
+ * No input log being read, or we just hit the end of file on one. Revert
+ * to normal line input; start by getting a new line from Glk.
+ */
+ characters = gsc_read_line (buffer, length - 1);
+ assert (characters <= length);
+ buffer[characters] = '\0';
+
+ /*
+ * If neither abbreviations nor local commands are enabled, use the data
+ * read above without further massaging.
+ */
+ if (gsc_abbreviations_enabled || gsc_commands_enabled)
+ {
+ char *command;
+
+ /*
+ * If the first non-space input character is a quote, bypass all
+ * abbreviation expansion and local command recognition, and use the
+ * unadulterated input, less introductory quote.
+ */
+ command = buffer + strspn (buffer, "\t ");
+ if (command[0] == GSC_QUOTED_INPUT)
+ {
+ /* Delete the quote with memmove(). */
+ memmove (command, command + 1, strlen (command));
+ }
+ else
+ {
+ /* Check for, and expand, and abbreviated commands. */
+ if (gsc_abbreviations_enabled)
+ gsc_expand_abbreviations (buffer, length);
+
+ /*
+ * Check for standalone "help", then for Glk port special commands;
+ * suppress the interpreter's use of this input for Glk commands by
+ * returning FALSE.
+ */
+ if (gsc_commands_enabled)
+ {
+ int posn;
+
+ posn = strspn (buffer, "\t ");
+ if (sc_strncasecmp (buffer + posn, "help", strlen ("help"))== 0)
+ {
+ if (strspn (buffer + posn + strlen ("help"), "\t ")
+ == strlen (buffer + posn + strlen ("help")))
+ {
+ gsc_output_register_help_request ();
+ }
+ }
+
+ if (gsc_command_escape (buffer))
+ {
+ gsc_output_silence_help_hints ();
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ /*
+ * If there is an input log active, log this input string to it. Note that
+ * by logging here we get any abbreviation expansions but we won't log glk
+ * special commands, nor any input read from a current open input log.
+ */
+ if (gsc_inputlog_stream)
+ {
+ g_vm->glk_put_string_stream (gsc_inputlog_stream, buffer);
+ g_vm->glk_put_char_stream (gsc_inputlog_stream, '\n');
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * os_read_line_debug()
+ *
+ * Read and return a debugger command line. There's no dedicated debugging
+ * window, so this is just a call to the normal readline, with an additional
+ * prompt.
+ */
+sc_bool
+os_read_line_debug (sc_char *buffer, sc_int length)
+{
+ gsc_output_silence_help_hints ();
+ gsc_reset_glk_style ();
+ g_vm->glk_put_string ("[SCARE debug]");
+ return os_read_line (buffer, length);
+}
+
+
+/*
+ * os_confirm()
+ *
+ * Confirm a game action with a yes/no prompt.
+ */
+sc_bool
+os_confirm (sc_int type)
+{
+ sc_char response;
+
+ /*
+ * Always allow game saves and hint display, and if we're reading from an
+ * input log, allow everything no matter what, on the assumption that the
+ * user knows what they are doing.
+ */
+ if (gsc_readlog_stream
+ || type == SC_CONF_SAVE || type == SC_CONF_VIEW_HINTS)
+ return TRUE;
+
+ /* Ensure back to normal style, and update status. */
+ gsc_reset_glk_style ();
+ gsc_status_notify ();
+
+ /* Prompt for the confirmation, based on the type. */
+ if (type == GSC_CONF_SUBTLE_HINT)
+ g_vm->glk_put_string ("View the subtle hint for this topic");
+ else if (type == GSC_CONF_UNSUBTLE_HINT)
+ g_vm->glk_put_string ("View the unsubtle hint for this topic");
+ else if (type == GSC_CONF_CONTINUE_HINTS)
+ g_vm->glk_put_string ("Continue with hints");
+ else
+ {
+ g_vm->glk_put_string ("Do you really want to ");
+ switch (type)
+ {
+ case SC_CONF_QUIT:
+ g_vm->glk_put_string ("quit");
+ break;
+ case SC_CONF_RESTART:
+ g_vm->glk_put_string ("restart");
+ break;
+ case SC_CONF_SAVE:
+ g_vm->glk_put_string ("save");
+ break;
+ case SC_CONF_RESTORE:
+ g_vm->glk_put_string ("restore");
+ break;
+ case SC_CONF_VIEW_HINTS:
+ g_vm->glk_put_string ("view hints");
+ break;
+ default:
+ g_vm->glk_put_string ("do that");
+ break;
+ }
+ }
+ g_vm->glk_put_string ("? ");
+
+ /* Loop until 'yes' or 'no' returned. */
+ do
+ {
+ event_t event;
+
+ /* Wait for a standard key, ignoring Glk special keys. */
+ do
+ {
+ g_vm->glk_request_char_event (gsc_main_window);
+ gsc_event_wait (evtype_CharInput, &event);
+ }
+ while (event.val1 > UCHAR_MAX);
+ response = g_vm->glk_char_to_upper (event.val1);
+ }
+ while (response != 'Y' && response != 'N');
+
+ /* Echo the confirmation response, and a new line. */
+ g_vm->glk_set_style (style_Input);
+ g_vm->glk_put_string (response == 'Y' ? "Yes" : "No");
+ g_vm->glk_set_style (style_Normal);
+ g_vm->glk_put_char ('\n');
+
+ /* Use a short delay on restarts, if confirmed. */
+ if (type == SC_CONF_RESTART && response == 'Y')
+ gsc_short_delay ();
+
+ /* Return TRUE if 'Y' was entered. */
+ return (response == 'Y');
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port event functions */
+/*---------------------------------------------------------------------*/
+
+/* Short delay before restarts; 1s, in 100ms segments. */
+static const glui32 GSC_DELAY_TIMEOUT = 100;
+static const glui32 GSC_DELAY_TIMEOUTS_COUNT = 10;
+
+/*
+ * gsc_short_delay()
+ *
+ * Delay for a short period; used before restarting a completed game, to
+ * improve the display where 'r', or confirming restart, triggers an otherwise
+ * immediate, and abrupt, restart.
+ */
+static void
+gsc_short_delay()
+{
+ /* Ignore the call if the Glk doesn't have timers. */
+ if (g_vm->glk_gestalt (gestalt_Timer, 0))
+ {
+ glui32 timeout;
+
+ /* Timeout in small chunks to minimize Glk jitter. */
+ g_vm->glk_request_timer_events (GSC_DELAY_TIMEOUT);
+ for (timeout = 0; timeout < GSC_DELAY_TIMEOUTS_COUNT; timeout++)
+ {
+ event_t event;
+
+ gsc_event_wait (evtype_Timer, &event);
+ }
+ g_vm->glk_request_timer_events (0);
+ }
+}
+
+
+/*
+ * gsc_event_wait_2()
+ * gsc_event_wait()
+ *
+ * Process Glk events until one of the expected type, or types, arrives.
+ * Return the event of that type.
+ */
+static void
+gsc_event_wait_2 (glui32 wait_type_1, glui32 wait_type_2, event_t * event)
+{
+ assert (event);
+
+ do
+ {
+ g_vm->glk_select (event);
+
+ switch (event->type)
+ {
+ case evtype_Arrange:
+ case evtype_Redraw:
+ /* Refresh any sensitive windows on size events. */
+ gsc_status_redraw ();
+ break;
+ }
+ }
+ while (!(event->type == (EvType)wait_type_1 || event->type == (EvType)wait_type_2));
+}
+
+static void
+gsc_event_wait (glui32 wait_type, event_t * event)
+{
+ assert (event);
+
+ gsc_event_wait_2 (wait_type, evtype_None, event);
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk port file functions */
+/*---------------------------------------------------------------------*/
+
+/*
+ * os_open_file()
+ *
+ * Open a file for save or restore, and return a Glk stream for the opened
+ * file.
+ */
+void *os_open_file (sc_bool is_save) {
+ glui32 usage, fmode;
+ frefid_t fileref;
+ strid_t stream;
+
+ usage = fileusage_SavedGame | fileusage_BinaryMode;
+ fmode = is_save ? filemode_Write : filemode_Read;
+
+ fileref = g_vm->glk_fileref_create_by_prompt(usage, (FileMode)fmode, 0);
+ if (!fileref)
+ return nullptr;
+
+ if (!is_save && !g_vm->glk_fileref_does_file_exist (fileref))
+ {
+ g_vm->glk_fileref_destroy (fileref);
+ return nullptr;
+ }
+
+ stream = g_vm->glk_stream_open_file (fileref, (FileMode)fmode, 0);
+ g_vm->glk_fileref_destroy (fileref);
+
+ return stream;
+}
+
+
+/*
+ * os_write_file()
+ * os_read_file()
+ *
+ * Write/read the given buffered data to/from the open Glk stream.
+ */
+void
+os_write_file (void *opaque, const sc_byte *buffer, sc_int length)
+{
+ strid_t stream = (strid_t) opaque;
+ assert (opaque && buffer);
+
+ g_vm->glk_put_buffer_stream (stream, (char *) buffer, length);
+}
+
+sc_int
+os_read_file (void *opaque, sc_byte *buffer, sc_int length)
+{
+ strid_t stream = (strid_t) opaque;
+ assert (opaque && buffer);
+
+ return g_vm->glk_get_buffer_stream (stream, (char *) buffer, length);
+}
+
+
+/*
+ * os_close_file()
+ *
+ * Close the opened Glk stream.
+ */
+void
+os_close_file (void *opaque)
+{
+ strid_t stream = (strid_t) opaque;
+ assert (opaque);
+
+ g_vm->glk_stream_close (stream, nullptr);
+}
+
+
+/*---------------------------------------------------------------------*/
+/* main() and options parsing */
+/*---------------------------------------------------------------------*/
+
+/* Loading message flush delay timeout. */
+static const glui32 GSC_LOADING_TIMEOUT = 100;
+
+/* Enumerated game end options. */
+enum gsc_end_option { GAME_RESTART, GAME_UNDO, GAME_QUIT };
+
+/*
+ * The following value needs to be passed between the startup_code and main
+ * functions.
+ */
+static char *gsc_game_message = nullptr;
+
+
+/*
+ * gsc_callback()
+ *
+ * Callback function for reading in game and restore file data; fills a
+ * buffer with TAF or TAS file data from a Glk stream, and returns the byte
+ * count.
+ */
+static sc_int
+gsc_callback (void *opaque, sc_byte *buffer, sc_int length)
+{
+ strid_t stream = (strid_t) opaque;
+ assert (stream);
+
+ return g_vm->glk_get_buffer_stream (stream, (char *) buffer, length);
+}
+
+
+/*
+ * gsc_get_ending_option()
+ *
+ * Offer the option to restart, undo, or quit. Returns the selected game
+ * end option. Called on game completion.
+ */
+static enum gsc_end_option
+gsc_get_ending_option()
+{
+ sc_char response;
+
+ /* Ensure back to normal style, and update status. */
+ gsc_reset_glk_style ();
+ gsc_status_notify ();
+
+ /* Prompt for restart, undo, or quit. */
+ g_vm->glk_put_string ("\nWould you like to RESTART, UNDO a turn, or QUIT? ");
+
+ /* Loop until 'restart', 'undo' or 'quit'. */
+ do
+ {
+ event_t event;
+
+ do
+ {
+ g_vm->glk_request_char_event (gsc_main_window);
+ gsc_event_wait (evtype_CharInput, &event);
+ }
+ while (event.val1 > UCHAR_MAX);
+ response = g_vm->glk_char_to_upper (event.val1);
+ }
+ while (response != 'R' && response != 'U' && response != 'Q');
+
+ /* Echo the confirmation response, and a new line. */
+ g_vm->glk_set_style (style_Input);
+ switch (response)
+ {
+ case 'R':
+ g_vm->glk_put_string ("Restart");
+ break;
+ case 'U':
+ g_vm->glk_put_string ("Undo");
+ break;
+ case 'Q':
+ g_vm->glk_put_string ("Quit");
+ break;
+ default:
+ gsc_fatal ("GLK: Invalid response encountered");
+ g_vm->glk_exit ();
+ }
+ g_vm->glk_set_style (style_Normal);
+ g_vm->glk_put_char ('\n');
+
+ /* Return the appropriate value for response. */
+ switch (response)
+ {
+ case 'R':
+ return GAME_RESTART;
+ case 'U':
+ return GAME_UNDO;
+ case 'Q':
+ return GAME_QUIT;
+ default:
+ gsc_fatal ("GLK: Invalid response encountered");
+ g_vm->glk_exit ();
+ }
+
+ /* Unreachable; supplied to suppress compiler warning. */
+ return GAME_QUIT;
+}
+
+
+/*
+ * gsc_startup_code()
+ * gsc_main
+ *
+ * Together, these functions take the place of the original main(). The
+ * first one is called from the platform-specific startup_code(), to parse
+ * and generally handle options. The second is called from g_vm->glk_main, and
+ * does the real work of running the game.
+ */
+static int
+gsc_startup_code (strid_t game_stream, strid_t restore_stream,
+ sc_uint trace_flags, sc_bool enable_debugger,
+ sc_bool stable_random, const sc_char *locale)
+{
+ winid_t window;
+ assert (game_stream);
+
+ /* Open a temporary Glk main window. */
+ window = g_vm->glk_window_open (0, 0, 0, wintype_TextBuffer, 0);
+ if (window)
+ {
+ /* Clear and initialize the temporary window. */
+ g_vm->glk_window_clear (window);
+ g_vm->glk_set_window (window);
+ g_vm->glk_set_style (style_Normal);
+
+ /*
+ * Display a brief loading game message; here we have to use a timeout
+ * to ensure that the text is flushed to Glk.
+ */
+ g_vm->glk_put_string ("Loading game...\n");
+ if (g_vm->glk_gestalt (gestalt_Timer, 0))
+ {
+ event_t event;
+
+ g_vm->glk_request_timer_events (GSC_LOADING_TIMEOUT);
+ do
+ {
+ g_vm->glk_select (&event);
+ }
+ while (event.type != evtype_Timer);
+ g_vm->glk_request_timer_events (0);
+ }
+ }
+
+ /* If the Glk libarary does not support unicode, disable it. */
+ if (!gsc_has_unicode || !g_vm->glk_gestalt (gestalt_Unicode, 0))
+ gsc_unicode_enabled = FALSE;
+
+ /*
+ * If a locale was requested, set it in the core interpreter now. This
+ * locale will preempt any auto-detected one found from inspecting the
+ * game on creation. After game creation, the Glk locale is synchronized
+ * to the core interpreter's locale.
+ */
+ if (locale)
+ sc_set_locale (locale);
+
+ /*
+ * Set tracing flags, then try to create a SCARE game reference from the
+ * TAF file. Since we need this in our call from g_vm->glk_main, we have to keep
+ * it in a module static variable. If we can't open the TAF file, then
+ * we'll set the pointer to nullptr, and complain about it later in main.
+ * Passing the message string around like this is a nuisance...
+ */
+ sc_set_trace_flags (trace_flags);
+ gsc_game = sc_game_from_callback (gsc_callback, game_stream);
+ if (!gsc_game)
+ {
+ gsc_game = nullptr;
+ gsc_game_message = "Unable to load an Adrift game from the"
+ " requested file.";
+ }
+ else
+ gsc_game_message = nullptr;
+ g_vm->glk_stream_close (game_stream, nullptr);
+
+ /*
+ * If the game was created successfully and there is a restore stream, try
+ * to immediately restore the game from that stream.
+ */
+ if (gsc_game && restore_stream)
+ {
+ if (!sc_load_game_from_callback (gsc_game, gsc_callback, restore_stream))
+ {
+ sc_free_game (gsc_game);
+ gsc_game = nullptr;
+ gsc_game_message = "Unable to restore this Adrift game from the"
+ " requested file.";
+ }
+ else
+ gsc_game_message = nullptr;
+ }
+ if (restore_stream)
+ g_vm->glk_stream_close (restore_stream, nullptr);
+
+ /* If successful, set game debugging and synchronize to the core's locale. */
+ if (gsc_game)
+ {
+ sc_set_game_debugger_enabled (gsc_game, enable_debugger);
+ gsc_set_locale (sc_get_locale ());
+ }
+
+ /* Set portable and predictable random number generation if requested. */
+ if (stable_random)
+ {
+ sc_set_portable_random (TRUE);
+ sc_reseed_random_sequence (1);
+ }
+
+ /* Close the temporary window. */
+ if (window)
+ g_vm->glk_window_close (window, nullptr);
+
+ /* Set title of game */
+#ifdef GARGLK
+ g_vm->garglk_set_story_name(sc_get_game_name(gsc_game));
+#endif
+
+ /* Game set up, perhaps successfully. */
+ return TRUE;
+}
+
+static void
+gsc_main()
+{
+ sc_bool is_running;
+
+ /* Ensure SCARE internal types have the right sizes. */
+ if (!(sizeof (sc_byte) == 1 && sizeof (sc_char) == 1
+ && sizeof (sc_uint) >= 4 && sizeof (sc_int) >= 4
+ && sizeof (sc_uint) <= 8 && sizeof (sc_int) <= 8))
+ {
+ gsc_fatal ("GLK: Types sized incorrectly, recompilation is needed");
+ g_vm->glk_exit ();
+ }
+
+ /* Create the Glk window, and set its stream as the current one. */
+ gsc_main_window = g_vm->glk_window_open (0, 0, 0, wintype_TextBuffer, 0);
+ if (!gsc_main_window)
+ {
+ gsc_fatal ("GLK: Can't open main window");
+ g_vm->glk_exit ();
+ }
+ g_vm->glk_window_clear (gsc_main_window);
+ g_vm->glk_set_window (gsc_main_window);
+ g_vm->glk_set_style (style_Normal);
+
+ /* If there's a problem with the game file, complain now. */
+ if (!gsc_game)
+ {
+ assert (gsc_game_message);
+ gsc_header_string ("Glk SCARE Error\n\n");
+ gsc_normal_string (gsc_game_message);
+ gsc_normal_char ('\n');
+ g_vm->glk_exit ();
+ }
+
+ /* Try to create a one-line status window. We can live without it. */
+ g_vm->glk_stylehint_set (wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
+ gsc_status_window = g_vm->glk_window_open (gsc_main_window,
+ winmethod_Above | winmethod_Fixed,
+ 1, wintype_TextGrid, 0);
+
+ /* Repeat the game until no more restarts requested. */
+ is_running = TRUE;
+ while (is_running)
+ {
+ /* Run the game until it ends, or the user quits. */
+ gsc_status_notify ();
+ sc_interpret_game (gsc_game);
+
+ /*
+ * If the game did not complete, the user quit explicitly, so leave the
+ * game repeat loop.
+ */
+ if (!sc_has_game_completed (gsc_game))
+ {
+ is_running = FALSE;
+ break;
+ }
+
+ /*
+ * If reading from an input log, close it now. We need to request a
+ * user selection, probably modal, and after that we probably don't
+ * want the follow-on readlog data being used as game input.
+ */
+ if (gsc_readlog_stream)
+ {
+ g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+ }
+
+ /*
+ * Get user selection of restart, undo a turn, or quit completed game.
+ * If undo is unavailable (this should not be possible), degrade to
+ * restart.
+ */
+ switch (gsc_get_ending_option ())
+ {
+ case GAME_RESTART:
+ gsc_short_delay ();
+ sc_restart_game (gsc_game);
+ break;
+
+ case GAME_UNDO:
+ if (sc_is_game_undo_available (gsc_game))
+ {
+ sc_undo_game_turn (gsc_game);
+ gsc_normal_string ("The previous turn has been undone.\n");
+ }
+ else
+ {
+ gsc_normal_string ("Sorry, no undo is available.\n");
+ gsc_short_delay ();
+ sc_restart_game (gsc_game);
+ }
+ break;
+
+ case GAME_QUIT:
+ is_running = FALSE;
+ break;
+ }
+ }
+
+ /* All done -- release game resources. */
+ sc_free_game (gsc_game);
+
+ /* Close any open transcript, input log, and/or read log. */
+ if (gsc_transcript_stream)
+ {
+ g_vm->glk_stream_close (gsc_transcript_stream, nullptr);
+ gsc_transcript_stream = nullptr;
+ }
+ if (gsc_inputlog_stream)
+ {
+ g_vm->glk_stream_close (gsc_inputlog_stream, nullptr);
+ gsc_inputlog_stream = nullptr;
+ }
+ if (gsc_readlog_stream)
+ {
+ g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+ }
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Linkage between Glk entry/exit calls and the real interpreter */
+/*---------------------------------------------------------------------*/
+
+/*
+ * Safety flags, to ensure we always get startup before main, and that
+ * we only get a call to main once.
+ */
+static int gsc_startup_called = FALSE,
+ gsc_main_called = FALSE;
+
+/*
+ * g_vm->glk_main()
+ *
+ * Main entry point for Glk. Here, all startup is done, and we call our
+ * function to run the game, or to report errors if gsc_game_message is set.
+ */
+void glk_main() {
+ assert (gsc_startup_called && !gsc_main_called);
+ gsc_main_called = TRUE;
+
+ /* Call the generic interpreter main function. */
+ gsc_main ();
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Glk linkage relevant only to the UNIX platform */
+/*---------------------------------------------------------------------*/
+#ifdef UNUSED
+
+/*
+ * Glk arguments for UNIX versions of the Glk interpreter.
+ */
+glkunix_argumentlist_t glkunix_arguments[] = {
+ {(char *) "-nc", glkunix_arg_NoValue,
+ (char *) "-nc No local handling for Glk special commands"},
+ {(char *) "-na", glkunix_arg_NoValue,
+ (char *) "-na Turn off abbreviation expansions"},
+ {(char *) "-nu", glkunix_arg_NoValue,
+ (char *) "-nu Turn off any use of Unicode output"},
+#ifdef LINUX_GRAPHICS
+ {(char *) "-ng", glkunix_arg_NoValue,
+ (char *) "-ng Turn off attempts at game graphics"},
+#endif
+ {(char *) "-r", glkunix_arg_ValueFollows,
+ (char *) "-r FILE Restore from FILE on starting the game"},
+ {(char *) "", glkunix_arg_ValueCanFollow,
+ (char *) "filename game to run"},
+ {nullptr, glkunix_arg_End, nullptr}
+};
+
+
+/*
+ * glkunix_startup_code()
+ *
+ * Startup entry point for UNIX versions of Glk interpreter. Glk will call
+ * glkunix_startup_code() to pass in arguments. On startup, parse arguments
+ * and open a Glk stream to the game, then call the generic gsc_startup_code()
+ * to build a game from the stream. On error, set the message in
+ * gsc_game_message; the core gsc_main() will report it when it's called.
+ */
+int
+glkunix_startup_code (glkunix_startup_t * data)
+{
+ int argc = data->argc;
+ sc_char **argv = data->argv;
+ int argv_index;
+ sc_char *restore_from;
+ const sc_char *locale;
+ strid_t game_stream, restore_stream;
+ sc_uint trace_flags;
+ sc_bool enable_debugger, stable_random;
+ assert (!gsc_startup_called);
+ gsc_startup_called = TRUE;
+
+#ifdef GARGLK
+ garg_vm->glk_set_program_name("SCARE " SCARE_VERSION);
+ garg_vm->glk_set_program_info("SCARE " SCARE_VERSION
+ " by Simon Baldwin and Mark J. Tilford");
+#endif
+
+ /* Handle command line arguments. */
+ restore_from = nullptr;
+ for (argv_index = 1;
+ argv_index < argc && argv[argv_index][0] == '-'; argv_index++)
+ {
+ if (strcmp (argv[argv_index], "-nc") == 0)
+ {
+ gsc_commands_enabled = FALSE;
+ continue;
+ }
+ if (strcmp (argv[argv_index], "-na") == 0)
+ {
+ gsc_abbreviations_enabled = FALSE;
+ continue;
+ }
+ if (strcmp (argv[argv_index], "-nu") == 0)
+ {
+ gsc_unicode_enabled = FALSE;
+ continue;
+ }
+#ifdef LINUX_GRAPHICS
+ if (strcmp (argv[argv_index], "-ng") == 0)
+ {
+ gsclinux_graphics_enabled = FALSE;
+ continue;
+ }
+#endif
+ if (strcmp (argv[argv_index], "-r") == 0)
+ {
+ restore_from = argv[++argv_index];
+ continue;
+ }
+ return FALSE;
+ }
+
+ /* On invalid usage, set a complaint message and return. */
+ if (argv_index != argc - 1)
+ {
+ gsc_game = nullptr;
+ if (argv_index < argc - 1)
+ gsc_game_message = "More than one game file"
+ " was given on the command line.";
+ else
+ gsc_game_message = "No game file was given on the command line.";
+ return TRUE;
+ }
+
+ /* Open a stream to the TAF file, complain if this fails. */
+ game_stream = glkunix_stream_open_pathname (argv[argv_index], FALSE, 0);
+ if (!game_stream)
+ {
+ gsc_game = nullptr;
+ gsc_game_message = "Unable to open the requested game file.";
+ return TRUE;
+ }
+ else
+ gsc_game_message = nullptr;
+
+ /*
+ * If a restore requested, open a stream to the TAF (TAS) file, and
+ * again, complain if this fails.
+ */
+ if (restore_from)
+ {
+ restore_stream = glkunix_stream_open_pathname (restore_from, FALSE, 0);
+ if (!restore_stream)
+ {
+ g_vm->glk_stream_close (game_stream, nullptr);
+ gsc_game = nullptr;
+ gsc_game_message = "Unable to open the requested restore file.";
+ return TRUE;
+ }
+ else
+ gsc_game_message = nullptr;
+ }
+ else
+ restore_stream = nullptr;
+
+ /* Set SCARE trace flags and other general setup from the environment. */
+ if (getenv ("SC_TRACE_FLAGS"))
+ trace_flags = strtoul (getenv ("SC_TRACE_FLAGS"), nullptr, 0);
+ else
+ trace_flags = 0;
+ enable_debugger = (getenv ("SC_DEBUGGER_ENABLED") != nullptr);
+ stable_random = (getenv ("SC_STABLE_RANDOM_ENABLED") != nullptr);
+ locale = getenv ("SC_LOCALE");
+
+#ifdef LINUX_GRAPHICS
+ /* Note the path to the game file for graphics extraction. */
+ gsclinux_game_file = argv[argv_index];
+#endif
+
+ /* Use the generic startup code to complete startup. */
+ return gsc_startup_code (game_stream, restore_stream, trace_flags,
+ enable_debugger, stable_random, locale);
+}
+#endif /* __unix */
+
+
+/*---------------------------------------------------------------------*/
+/* Glk linkage relevant only to the Windows platform */
+/*---------------------------------------------------------------------*/
+#ifdef _WIN32
+
+#include <windows.h>
+
+#include "WinGlk.h"
+#include "resource.h"
+
+/* Windows constants and external definitions. */
+static const unsigned int GSCWIN_glk_INIT_VERSION = 0x601;
+extern int InitGlk (unsigned int iVersion);
+
+/*
+ * WinMain()
+ *
+ * Entry point for all Glk applications.
+ */
+int WINAPI
+WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, int nCmdShow)
+{
+ /* Attempt to initialize both the Glk library and SCARE. */
+ if (!(InitGlk (GSCWIN_glk_INIT_VERSION) && wing_vm->glk_startup_code (lpCmdLine)))
+ return 0;
+
+ /* Run the application; no return from this routine. */
+ g_vm->glk_main ();
+ g_vm->glk_exit ();
+ return 0;
+}
+
+
+/*
+ * wing_vm->glk_startup_code()
+ *
+ * Startup entry point for Windows versions of Glk interpreter.
+ */
+int
+wing_vm->glk_startup_code (const char *cmdline)
+{
+ const char *filename, *locale;
+ frefid_t fileref;
+ strid_t game_stream;
+ sc_uint trace_flags;
+ sc_bool enable_debugger, stable_random;
+ assert (!gsc_startup_called);
+ gsc_startup_called = TRUE;
+
+ /* Set up application and window. */
+ wing_vm->glk_app_set_name ("Scare");
+ wing_vm->glk_set_menu_name ("&Scare");
+ wing_vm->glk_window_set_title ("Scare Adrift Interpreter");
+ wing_vm->glk_set_about_text ("Windows Scare 1.3.10");
+ wing_vm->glk_set_gui (IDI_SCARE);
+
+ /* Open a stream to the game. */
+ filename = wing_vm->glk_get_initial_filename (cmdline,
+ "Select an Adrift game to run",
+ "Adrift Files (.taf)|*.taf;All Files (*.*)|*.*||");
+ if (!filename)
+ return 0;
+
+ fileref = wing_vm->glk_fileref_create_by_name (fileusage_BinaryMode
+ | fileusage_Data,
+ (char *) filename, 0, 0);
+ if (!fileref)
+ return 0;
+
+ game_stream = g_vm->glk_stream_open_file (fileref, filemode_Read, 0);
+ g_vm->glk_fileref_destroy (fileref);
+ if (!game_stream)
+ return 0;
+
+ /* Set trace, debugger, and portable random flags. */
+ if (getenv ("SC_TRACE_FLAGS"))
+ trace_flags = strtoul (getenv ("SC_TRACE_FLAGS"), nullptr, 0);
+ else
+ trace_flags = 0;
+ enable_debugger = (getenv ("SC_DEBUGGER_ENABLED") != nullptr);
+ stable_random = (getenv ("SC_STABLE_RANDOM_ENABLED") != nullptr);
+ locale = getenv ("SC_LOCALE");
+
+ /* Use the generic startup code to complete startup. */
+ return gsc_startup_code (game_stream, nullptr, trace_flags,
+ enable_debugger, stable_random, locale);
+}
+#endif /* _WIN32 */
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/adrift/scare.h b/engines/glk/adrift/scare.h
new file mode 100644
index 0000000..43ce75a
--- /dev/null
+++ b/engines/glk/adrift/scare.h
@@ -0,0 +1,188 @@
+/* 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 ADRIFT_ADRIFT_H
+#define ADRIFT_ADRIFT_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+#undef longjmp
+#undef setjmp
+#include <setjmp.h>
+
+namespace Glk {
+namespace Adrift {
+
+/*
+ * Base type definitions. SCARE integer types need to be at least 32 bits,
+ * so using long here is a good bet for almost all ANSI C implementations for
+ * 32 and 64 bit platforms; maybe also for any 16 bit ones. For 64 bit
+ * platforms configured for LP64, SCARE integer types will consume more space
+ * in data structures. Values won't wrap identically to 32 bit ones, but
+ * games shouldn't be relying on wrapping anyway. One final note -- in several
+ * places, SCARE allocates 32 bytes into which it will sprintf() a long; this
+ * is fine for both standard 32 bit and LP64 64 bit platforms, but is unsafe
+ * should SCARE ever be configured for 128 bit definitions of sc_[u]int.
+ */
+typedef char sc_char;
+typedef unsigned char sc_byte;
+typedef long sc_int;
+typedef unsigned long sc_uint;
+typedef int sc_bool;
+
+/* Enumerated confirmation types, passed to os_confirm(). */
+enum
+{ SC_CONF_QUIT = 0,
+ SC_CONF_RESTART, SC_CONF_SAVE, SC_CONF_RESTORE, SC_CONF_VIEW_HINTS
+};
+
+/* HTML-like tag enumerated values, passed to os_print_tag(). */
+enum
+{ SC_TAG_UNKNOWN = 0, SC_TAG_ITALICS, SC_TAG_ENDITALICS, SC_TAG_BOLD,
+ SC_TAG_ENDBOLD, SC_TAG_UNDERLINE, SC_TAG_ENDUNDERLINE, SC_TAG_COLOR,
+ SC_TAG_ENDCOLOR, SC_TAG_FONT, SC_TAG_ENDFONT, SC_TAG_BGCOLOR, SC_TAG_CENTER,
+ SC_TAG_ENDCENTER, SC_TAG_RIGHT, SC_TAG_ENDRIGHT, SC_TAG_WAIT, SC_TAG_WAITKEY,
+ SC_TAG_CLS,
+
+ /* British spelling equivalents. */
+ SC_TAG_COLOUR = SC_TAG_COLOR,
+ SC_TAG_ENDCOLOUR = SC_TAG_ENDCOLOR,
+ SC_TAG_BGCOLOUR = SC_TAG_BGCOLOR,
+ SC_TAG_CENTRE = SC_TAG_CENTER,
+ SC_TAG_ENDCENTRE = SC_TAG_ENDCENTER
+};
+
+/* OS interface function prototypes; interpreters must define these. */
+typedef void *sc_game;
+extern void os_print_string (const sc_char *string);
+extern void os_print_tag(sc_int tag, const sc_char *argument);
+extern void os_play_sound (const sc_char *filepath,
+ sc_int offset, sc_int length, sc_bool is_looping);
+extern void os_stop_sound();
+extern void os_show_graphic (const sc_char *filepath,
+ sc_int offset, sc_int length);
+extern sc_bool os_read_line(sc_char *buffer, sc_int length);
+extern sc_bool os_confirm(sc_int type);
+extern void *os_open_file(sc_bool is_save);
+extern void os_write_file (void *opaque, const sc_byte *buffer, sc_int length);
+extern sc_int os_read_file (void *opaque, sc_byte *buffer, sc_int length);
+extern void os_close_file (void *opaque);
+extern void os_display_hints(sc_game game);
+
+extern void os_print_string_debug (const sc_char *string);
+extern sc_bool os_read_line_debug(sc_char *buffer, sc_int length);
+
+/* Interpreter trace flag bits, passed to sc_set_trace_flags(). */
+enum
+{ SC_TRACE_PARSE = 1, SC_TRACE_PROPERTIES = 2, SC_TRACE_VARIABLES = 4,
+ SC_TRACE_PARSER = 8, SC_TRACE_LIBRARY = 16, SC_TRACE_EVENTS = 32,
+ SC_TRACE_NPCS = 64, SC_TRACE_OBJECTS = 128, SC_TRACE_TASKS = 256,
+ SC_TRACE_PRINTFILTER = 512,
+
+ SC_DUMP_TAF = 1024, SC_DUMP_PROPERTIES = 2048, SC_DUMP_VARIABLES = 4096,
+ SC_DUMP_PARSER_TREES = 8192, SC_DUMP_LOCALE_TABLES = 16384
+};
+
+/* Module-wide trace control function prototype. */
+extern void sc_set_trace_flags(sc_uint trace_flags);
+
+/* Interpreter interface function prototypes. */
+extern sc_game sc_game_from_filename (const sc_char *filename);
+extern sc_game sc_game_from_stream (Common::SeekableReadStream *stream);
+extern sc_game sc_game_from_callback(sc_int (*callback)
+ (void *, sc_byte *, sc_int),
+ void *opaque);
+extern void sc_interpret_game(sc_game game);
+extern void sc_restart_game(sc_game game);
+extern sc_bool sc_save_game(sc_game game);
+extern sc_bool sc_load_game(sc_game game);
+extern sc_bool sc_undo_game_turn(sc_game game);
+extern void sc_quit_game(sc_game game);
+extern sc_bool sc_save_game_to_filename(sc_game game, const sc_char *filename);
+extern void sc_save_game_to_stream(sc_game game, Common::SeekableReadStream *stream);
+extern void sc_save_game_to_callback(sc_game game,
+ void (*callback)
+ (void *, const sc_byte *, sc_int),
+ void *opaque);
+extern sc_bool sc_load_game_from_filename(sc_game game,
+ const sc_char *filename);
+extern sc_bool sc_load_game_from_stream(sc_game game, Common::SeekableReadStream *stream);
+extern sc_bool sc_load_game_from_callback(sc_game game,
+ sc_int (*callback)
+ (void *, sc_byte *, sc_int),
+ void *opaque);
+extern void sc_free_game(sc_game game);
+extern sc_bool sc_is_game_running(sc_game game);
+extern const sc_char *sc_get_game_name(sc_game game);
+extern const sc_char *sc_get_game_author(sc_game game);
+extern const sc_char *sc_get_game_compile_date(sc_game game);
+extern sc_int sc_get_game_turns(sc_game game);
+extern sc_int sc_get_game_score(sc_game game);
+extern sc_int sc_get_game_max_score(sc_game game);
+extern const sc_char *sc_get_game_room(sc_game game);
+extern const sc_char *sc_get_game_status_line(sc_game game);
+extern const sc_char *sc_get_game_preferred_font(sc_game game);
+extern sc_bool sc_get_game_bold_room_names(sc_game game);
+extern sc_bool sc_get_game_verbose(sc_game game);
+extern sc_bool sc_get_game_notify_score_change(sc_game game);
+extern sc_bool sc_has_game_completed(sc_game game);
+extern sc_bool sc_is_game_undo_available(sc_game game);
+extern void sc_set_game_bold_room_names(sc_game game, sc_bool flag);
+extern void sc_set_game_verbose(sc_game game, sc_bool flag);
+extern void sc_set_game_notify_score_change(sc_game game, sc_bool flag);
+
+extern sc_bool sc_does_game_use_sounds(sc_game);
+extern sc_bool sc_does_game_use_graphics(sc_game);
+
+typedef void *sc_game_hint;
+extern sc_game_hint sc_get_first_game_hint(sc_game game);
+extern sc_game_hint sc_get_next_game_hint(sc_game game, sc_game_hint hint);
+extern const sc_char *sc_get_game_hint_question(sc_game game,
+ sc_game_hint hint);
+extern const sc_char *sc_get_game_subtle_hint(sc_game game,
+ sc_game_hint hint);
+extern const sc_char *sc_get_game_unsubtle_hint(sc_game game,
+ sc_game_hint hint);
+
+extern void sc_set_game_debugger_enabled(sc_game game, sc_bool flag);
+extern sc_bool sc_get_game_debugger_enabled(sc_game game);
+extern sc_bool sc_run_game_debugger_command(sc_game game,
+ const sc_char *debug_command);
+extern void sc_set_portable_random(sc_bool flag);
+extern void sc_reseed_random_sequence(sc_uint new_seed);
+
+/* Locale control and query functions. */
+extern sc_bool sc_set_locale (const sc_char *name);
+extern const sc_char *sc_get_locale();
+
+/* A few possibly useful utilities. */
+extern sc_int sc_strncasecmp (const sc_char *s1, const sc_char *s2, sc_int n);
+extern sc_int sc_strcasecmp (const sc_char *s1, const sc_char *s2);
+extern const sc_char *sc_scare_version();
+extern sc_int sc_scare_emulation();
+
+extern char *adrift_fgets(char *buf, int max, Common::SeekableReadStream *s);
+
+} // End of namespace Adrift
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/adrift/scdebug.cpp b/engines/glk/adrift/scdebug.cpp
new file mode 100644
index 0000000..e2472cc
--- /dev/null
+++ b/engines/glk/adrift/scdebug.cpp
@@ -0,0 +1,2717 @@
+/* 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/adrift/scare.h"
+#include "glk/adrift/scprotos.h"
+#include "glk/adrift/scgamest.h"
+
+namespace Glk {
+namespace Adrift {
+
+/* Assorted definitions and constants. */
+static const sc_uint DEBUG_MAGIC = 0xc4584d2e;
+enum { DEBUG_BUFFER_SIZE = 256 };
+
+/* Debugging command and command argument type. */
+typedef enum
+{ DEBUG_NONE = 0, DEBUG_CONTINUE, DEBUG_STEP, DEBUG_BUFFER, DEBUG_RESOURCES,
+ DEBUG_HELP, DEBUG_GAME,
+ DEBUG_PLAYER, DEBUG_ROOMS, DEBUG_OBJECTS, DEBUG_NPCS, DEBUG_EVENTS,
+ DEBUG_TASKS, DEBUG_VARIABLES,
+ DEBUG_OLDPLAYER, DEBUG_OLDROOMS, DEBUG_OLDOBJECTS, DEBUG_OLDNPCS,
+ DEBUG_OLDEVENTS, DEBUG_OLDTASKS, DEBUG_OLDVARIABLES,
+ DEBUG_WATCHPLAYER, DEBUG_WATCHOBJECTS, DEBUG_WATCHNPCS, DEBUG_WATCHEVENTS,
+ DEBUG_WATCHTASKS, DEBUG_WATCHVARIABLES,
+ DEBUG_CLEARPLAYER, DEBUG_CLEAROBJECTS, DEBUG_CLEARNPCS, DEBUG_CLEAREVENTS,
+ DEBUG_CLEARTASKS, DEBUG_CLEARVARIABLES,
+ DEBUG_WATCHALL, DEBUG_CLEARALL, DEBUG_RANDOM,
+ DEBUG_QUIT
+}
+sc_command_t;
+
+typedef enum
+{ COMMAND_QUERY = 0, COMMAND_RANGE, COMMAND_ONE, COMMAND_ALL }
+sc_command_type_t;
+
+/* Table connecting debugging command strings to commands. */
+typedef struct
+{
+ const sc_char *const command_string;
+ const sc_command_t command;
+} sc_strings_t;
+static const sc_strings_t DEBUG_COMMANDS[] = {
+ {"continue", DEBUG_CONTINUE}, {"step", DEBUG_STEP}, {"buffer", DEBUG_BUFFER},
+ {"resources", DEBUG_RESOURCES}, {"help", DEBUG_HELP}, {"game", DEBUG_GAME},
+ {"player", DEBUG_PLAYER}, {"rooms", DEBUG_ROOMS}, {"objects", DEBUG_OBJECTS},
+ {"npcs", DEBUG_NPCS}, {"events", DEBUG_EVENTS}, {"tasks", DEBUG_TASKS},
+ {"variables", DEBUG_VARIABLES},
+ {"oldplayer", DEBUG_OLDPLAYER}, {"oldrooms", DEBUG_OLDROOMS},
+ {"oldobjects", DEBUG_OLDOBJECTS}, {"oldnpcs", DEBUG_OLDNPCS},
+ {"oldevents", DEBUG_OLDEVENTS}, {"oldtasks", DEBUG_OLDTASKS},
+ {"oldvariables", DEBUG_OLDVARIABLES},
+ {"watchplayer", DEBUG_WATCHPLAYER}, {"clearplayer", DEBUG_CLEARPLAYER},
+ {"watchobjects", DEBUG_WATCHOBJECTS}, {"watchnpcs", DEBUG_WATCHNPCS},
+ {"watchevents", DEBUG_WATCHEVENTS}, {"watchtasks", DEBUG_WATCHTASKS},
+ {"watchvariables", DEBUG_WATCHVARIABLES},
+ {"clearobjects", DEBUG_CLEAROBJECTS}, {"clearnpcs", DEBUG_CLEARNPCS},
+ {"clearevents", DEBUG_CLEAREVENTS}, {"cleartasks", DEBUG_CLEARTASKS},
+ {"clearvariables", DEBUG_CLEARVARIABLES}, {"watchall", DEBUG_WATCHALL},
+ {"clearall", DEBUG_CLEARALL}, {"random", DEBUG_RANDOM}, {"quit", DEBUG_QUIT},
+ {NULL, DEBUG_NONE}
+};
+
+/*
+ * Debugging control information structure. The structure is created and
+ * added to the game on enabling debug, and removed and destroyed on
+ * disabling debugging.
+ */
+typedef struct sc_debugger_s
+{
+ sc_uint magic;
+ sc_bool *watch_objects;
+ sc_bool *watch_npcs;
+ sc_bool *watch_events;
+ sc_bool *watch_tasks;
+ sc_bool *watch_variables;
+ sc_bool watch_player;
+ sc_bool single_step;
+ sc_bool quit_pending;
+ sc_uint elapsed_seconds;
+} sc_debugger_t;
+
+
+/*
+ * debug_is_valid()
+ *
+ * Return TRUE if pointer is a valid debugger, FALSE otherwise.
+ */
+static sc_bool
+debug_is_valid (sc_debuggerref_t debug)
+{
+ return debug && debug->magic == DEBUG_MAGIC;
+}
+
+
+/*
+ * debug_get_debugger()
+ *
+ * Return the debugger reference from a game, or NULL if none.
+ */
+static sc_debuggerref_t
+debug_get_debugger (sc_gameref_t game)
+{
+ assert (gs_is_game_valid (game));
+
+ return game->debugger;
+}
+
+
+/*
+ * debug_variable_count()
+ *
+ * Common helper to return the count of variables defined in a game.
+ */
+static sc_int
+debug_variable_count (sc_gameref_t game)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key;
+ sc_int variable_count;
+
+ /* Find and return the variables count. */
+ vt_key.string = "Variables";
+ variable_count = prop_get_child_count (bundle, "I<-s", &vt_key);
+
+ return variable_count;
+}
+
+
+/*
+ * debug_initialize()
+ *
+ * Create a new set of debug control information, and append it to the
+ * game passed in.
+ */
+static void
+debug_initialize (sc_gameref_t game)
+{
+ sc_debuggerref_t debug;
+
+ /* Create the easy bits of the new debugging set. */
+ debug = (sc_debuggerref_t)sc_malloc (sizeof (*debug));
+ debug->magic = DEBUG_MAGIC;
+ debug->watch_player = FALSE;
+ debug->single_step = FALSE;
+ debug->quit_pending = FALSE;
+ debug->elapsed_seconds = 0;
+
+ /* Allocate watchpoints for everything we can watch. */
+ debug->watch_objects = (sc_bool *)sc_malloc (gs_object_count (game)
+ * sizeof (*debug->watch_objects));
+ debug->watch_npcs = (sc_bool *)sc_malloc (gs_npc_count (game)
+ * sizeof (*debug->watch_npcs));
+ debug->watch_events = (sc_bool *)sc_malloc (gs_event_count (game)
+ * sizeof (*debug->watch_events));
+ debug->watch_tasks = (sc_bool *)sc_malloc (gs_task_count (game)
+ * sizeof (*debug->watch_tasks));
+ debug->watch_variables = (sc_bool *)sc_malloc (debug_variable_count (game)
+ * sizeof (*debug->watch_variables));
+
+ /* Clear all watchpoint arrays. */
+ memset (debug->watch_objects, FALSE,
+ gs_object_count (game) * sizeof (*debug->watch_objects));
+ memset (debug->watch_npcs, FALSE,
+ gs_npc_count (game) * sizeof (*debug->watch_npcs));
+ memset (debug->watch_events, FALSE,
+ gs_event_count (game) * sizeof (*debug->watch_events));
+ memset (debug->watch_tasks, FALSE,
+ gs_task_count (game) * sizeof (*debug->watch_tasks));
+ memset (debug->watch_variables, FALSE,
+ debug_variable_count (game) * sizeof (*debug->watch_variables));
+
+ /* Append the new debugger set to the game. */
+ assert (!game->debugger);
+ game->debugger = debug;
+}
+
+
+/*
+ * debug_finalize()
+ *
+ * Destroy a debug data set, free its heap memory, and remove its reference
+ * from the game.
+ */
+static void
+debug_finalize (sc_gameref_t game)
+{
+ sc_debuggerref_t debug = debug_get_debugger (game);
+ assert (debug_is_valid (debug));
+
+ /* Free all allocated watchpoint arrays. */
+ sc_free (debug->watch_objects);
+ sc_free (debug->watch_npcs);
+ sc_free (debug->watch_events);
+ sc_free (debug->watch_tasks);
+ sc_free (debug->watch_variables);
+
+ /* Poison and free the debugger itself. */
+ memset (debug, 0xaa, sizeof (*debug));
+ sc_free (debug);
+
+ /* Remove the debug reference from the game. */
+ game->debugger = NULL;
+}
+
+
+/*
+ * debug_help()
+ *
+ * Print debugging help.
+ */
+static void
+debug_help (sc_command_t topic)
+{
+ /* Is help general, or specific? */
+ if (topic == DEBUG_NONE)
+ {
+ if_print_debug (
+ "The following debugging commands examine game state:\n\n");
+ if_print_debug (
+ " game -- Print general game information,"
+ " and class counts\n"
+ " player -- Show the player location and position\n"
+ " rooms [Range] -- Print information on game rooms\n"
+ " objects [Range] -- Print information on objects in the game\n"
+ " npcs [Range] -- Print information on game NPCs\n"
+ " events [Range] -- Print information on the game's events\n"
+ " tasks [Range] -- Print information on the game's tasks\n"
+ " variables [Range] -- Show variables defined by the game\n\n");
+ if_print_debug (
+ "Most commands take range inputs. This can be a single number, to"
+ " apply the command to just that item, a range such as '0 to 10' (or"
+ " '0 - 10', '0 .. 10', or simply '0 10') to apply to that range of"
+ " items, or '*' to apply the command to all items of the class. If"
+ " omitted, the command is applied only to the items of the class"
+ " 'relevant' to the current game state; see the help for specific"
+ " commands for more on what is 'relevant'.\n\n");
+ if_print_debug (
+ "The 'player', 'objects', 'npcs', 'events', 'tasks', and 'variables'"
+ " commands may be prefixed with 'old', in which case the values"
+ " printed will be those for the previous game turn, rather than the"
+ " current values.\n\n");
+ if_print_debug (
+ "These debugging commands manage watchpoints:\n\n");
+ if_print_debug (
+ "The 'player', 'objects', 'npcs', 'events', 'tasks', and 'variables'"
+ " commands may be prefixed with 'watch', to set watchpoints."
+ " Watchpoints automatically enter the debugger when the item changes"
+ " state during a game turn. For example 'watchobject 10' monitors"
+ " object 10 for changes, and 'watchnpc *' monitors all NPCs. A"
+ " 'watch' command with no range prints out all watchpoints set for"
+ " that class.\n\n");
+ if_print_debug (
+ "Prefix commands with 'clear' to clear watchpoints, for example"
+ " 'clearnpcs *'. Use 'watchall' to obtain a complete list of every"
+ " watchpoint set, and 'clearall' to clear all watchpoints in one go."
+ " A 'clear' command with no range behaves the same as a 'watch'"
+ " command with no range.\n\n");
+ if_print_debug (
+ "These debugging commands print details of game output and control the"
+ " debugger and interpreter:\n\n");
+ if_print_debug (
+ " buffer -- Show the current buffered game text\n"
+ " resources -- Show current and requested game resources\n"
+ " random [Seed] -- Control the random number generator\n"
+ " step -- Run one game turn, then re-enter the debugger\n"
+ " continue -- Leave the debugger and resume the game\n"
+ " quit -- Exit the interpreter main loop\n"
+ " help [Command] -- Print help specific to Command\n\n");
+ if_print_debug (
+ "Debugging commands may be abbreviated to their shortest unambiguous"
+ " form.\n\n");
+ if_print_debug (
+ "Use the 'debug' or '#debug' command in a game, typed at the usual"
+ " game prompt, to return to the debugger.\n");
+ return;
+ }
+
+ /* Command-specific help. */
+ switch (topic)
+ {
+ case DEBUG_HELP:
+ if_print_debug (
+ "Give the name of the command you want help on, for example 'help"
+ " continue'.\n");
+ break;
+
+ case DEBUG_CONTINUE:
+ if_print_debug (
+ "Leave the debugger and resume the game. Use the 'debug' or '#debug'"
+ " command in a game, typed at the usual game prompt, to return to the"
+ " debugger.\n");
+ break;
+
+ case DEBUG_STEP:
+ if_print_debug (
+ "Run one game turn, then re-enter the debugger. Useful for games that"
+ " intercept empty input lines, which otherwise catch the 'debug'"
+ " command before SCARE can get to it.\n");
+ break;
+
+ case DEBUG_QUIT:
+ if_print_debug (
+ "Exit the interpreter main loop. Equivalent to a confirmed 'quit'"
+ " from within the game itself, this ends the interpreter session.\n");
+ break;
+
+ case DEBUG_BUFFER:
+ if_print_debug (
+ "Print the current text that the game has buffered for output. The"
+ " debugger catches games before they have printed their turn output"
+ " -- this is the text that will be filtered and printed on exiting the"
+ " debugger.\n");
+ break;
+
+ case DEBUG_RESOURCES:
+ if_print_debug (
+ "Print any resources currently active, and any requested by the game"
+ " on the current turn. The requested resources will become the active"
+ " ones on exiting the debugger.\n");
+ break;
+
+ case DEBUG_RANDOM:
+ if_print_debug (
+ "If no seed is given, report the current random number generator"
+ " setting. Otherwise, seed the random number generator with the value"
+ " given. This is useful for persuading games with random sections to"
+ " behave predictably. A new seed value of zero is invalid.\n");
+ break;
+
+ case DEBUG_GAME:
+ if_print_debug (
+ "Print general game information, including the number of rooms,"
+ " objects, events, tasks, and variables that the game defines\n");
+ break;
+
+ case DEBUG_PLAYER:
+ if_print_debug (
+ "Print out the current player room and position, and any parent object"
+ " of the player character.\n");
+ break;
+
+ case DEBUG_OLDPLAYER:
+ if_print_debug (
+ "Print out the player room and position from the previous turn, and"
+ " any parent object of the player character.\n");
+ break;
+
+ case DEBUG_ROOMS:
+ if_print_debug (
+ "Print out the name and contents of rooms in the range. If no range,"
+ " print details of the room containing the player.\n");
+ break;
+
+ case DEBUG_OLDROOMS:
+ if_print_debug (
+ "Print out the name and contents of rooms in the range for the"
+ " previous turn. If no range, print details of the room that"
+ " contained the player on the previous turn.\n");
+ break;
+
+ case DEBUG_OBJECTS:
+ if_print_debug (
+ "Print out details of all objects in the range. If no range, print"
+ " details of objects in the room containing the player, and visible to"
+ " the player.\n");
+ break;
+
+ case DEBUG_OLDOBJECTS:
+ if_print_debug (
+ "Print out details of all objects in the range for the previous turn."
+ " If no range, print details of objects in the room that contained"
+ " the player, and were visible to the player.\n");
+ break;
+
+ case DEBUG_NPCS:
+ if_print_debug (
+ "Print out details of all NPCs in the range. If no range, print"
+ " details of only NPCs in the room containing the player.\n");
+ break;
+
+ case DEBUG_OLDNPCS:
+ if_print_debug (
+ "Print out details of all NPCs in the range for the previous turn."
+ " If no range, print details of only NPCs in the room that contained"
+ " the player.\n");
+ break;
+
+ case DEBUG_EVENTS:
+ if_print_debug (
+ "Print out details of all events in the range. If no range, print"
+ " details of only events currently running.\n");
+ break;
+
+ case DEBUG_OLDEVENTS:
+ if_print_debug (
+ "Print out details of all events in the range for the previous turn."
+ " If no range, print details of only events running on the previous"
+ " turn.\n");
+ break;
+
+ case DEBUG_TASKS:
+ if_print_debug (
+ "Print out details of all tasks in the range. If no range, print"
+ " details of only tasks that are runnable, for the current state of"
+ " the game.\n");
+ break;
+
+ case DEBUG_OLDTASKS:
+ if_print_debug (
+ "Print out details of all tasks in the range for the previous turn."
+ " If no range, print details of only tasks that were runnable, for"
+ " the previous state of the game.\n");
+ break;
+
+ case DEBUG_VARIABLES:
+ if_print_debug (
+ "Print out the names, types, and values of all game variables in the"
+ " range. If no range, print details of all variables (equivalent to"
+ " 'variables *').\n");
+ break;
+
+ case DEBUG_OLDVARIABLES:
+ if_print_debug (
+ "Print out the names, types, and values at the previous turn of all"
+ " game variables in the range. If no range, print details of all"
+ " variables (equivalent to 'variables *').\n");
+ break;
+
+ case DEBUG_WATCHPLAYER:
+ if_print_debug (
+ "If no range is given, list any watchpoint on player movement. If"
+ " range '0' is given, set a watchpoint on player movement. Other"
+ " usages of 'watchplayer' behave as if no range is given.\n");
+ break;
+
+ case DEBUG_WATCHOBJECTS:
+ if_print_debug (
+ "Set watchpoints on all objects in the range. If no range, list out"
+ " object watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHNPCS:
+ if_print_debug (
+ "Set watchpoints on all NPCs in the range. If no range, list out NPC"
+ " watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHEVENTS:
+ if_print_debug (
+ "Set watchpoints on all events in the range. If no range, list out"
+ " event watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHTASKS:
+ if_print_debug (
+ "Set watchpoints on all tasks in the range. If no range, list out"
+ " task watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHVARIABLES:
+ if_print_debug (
+ "Set watchpoints on all game variables in the range. If no range,"
+ " list variable watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARPLAYER:
+ if_print_debug (
+ "Clear any watchpoint set on player movements.\n");
+ break;
+
+ case DEBUG_CLEAROBJECTS:
+ if_print_debug (
+ "Clear watchpoints on all objects in the range. If no range, list"
+ " out object watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARNPCS:
+ if_print_debug (
+ "Clear watchpoints on all NPCs in the range. If no range, list out"
+ " NPC watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEAREVENTS:
+ if_print_debug (
+ "Clear watchpoints on all events in the range. If no range, list out"
+ " event watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARTASKS:
+ if_print_debug (
+ "Clear watchpoints on all tasks in the range. If no range, list out"
+ " task watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARVARIABLES:
+ if_print_debug (
+ "Clear watchpoints on all game variables in the range. If no range,"
+ " list variable watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHALL:
+ if_print_debug (
+ "Print out a list of all all watchpoints set for all the classes of"
+ " item on which watchpoints can be used.\n");
+ break;
+
+ case DEBUG_CLEARALL:
+ if_print_debug (
+ "Clear all watchpoints set, on all classes of item on which"
+ " watchpoints can be used.\n");
+ break;
+
+ default:
+ if_print_debug (
+ "Sorry, there is no help available on that at the moment.\n");
+ break;
+ }
+}
+
+
+/*
+ * debug_print_quoted()
+ * debug_print_player()
+ * debug_print_room()
+ * debug_print_object()
+ * debug_print_npc()
+ * debug_print_event()
+ * debug_print_task()
+ * debug_print_variable()
+ *
+ * Low level output helpers.
+ */
+static void
+debug_print_quoted (const sc_char *string)
+{
+ if_print_debug_character ('"');
+ if_print_debug (string);
+ if_print_debug_character ('"');
+}
+
+static void
+debug_print_player (sc_gameref_t game)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[2];
+ const sc_char *playername;
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "PlayerName";
+ playername = prop_get_string (bundle, "S<-ss", vt_key);
+ if_print_debug ("Player ");
+ debug_print_quoted (playername);
+}
+
+static void
+debug_print_room (sc_gameref_t game, sc_int room)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_char buffer[32];
+ const sc_char *name;
+
+ if_print_debug ("Room ");
+ if (room < 0 || room >= gs_room_count (game))
+ {
+ sprintf (buffer, "%ld ", room);
+ if_print_debug (buffer);
+ if_print_debug ("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Rooms";
+ vt_key[1].integer = room;
+ vt_key[2].string = "Short";
+ name = prop_get_string (bundle, "S<-sis", vt_key);
+ sprintf (buffer, "%ld ", room);
+ if_print_debug (buffer);
+ debug_print_quoted (name);
+}
+
+static void
+debug_print_object (sc_gameref_t game, sc_int object)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_bool bstatic;
+ sc_char buffer[32];
+ const sc_char *prefix, *name;
+
+ if (object < 0 || object >= gs_object_count (game))
+ {
+ if_print_debug ("Object ");
+ sprintf (buffer, "%ld ", object);
+ if_print_debug (buffer);
+ if_print_debug ("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ bstatic = prop_get_boolean (bundle, "B<-sis", vt_key);
+ vt_key[2].string = "Prefix";
+ prefix = prop_get_string (bundle, "S<-sis", vt_key);
+ vt_key[2].string = "Short";
+ name = prop_get_string (bundle, "S<-sis", vt_key);
+ if (bstatic)
+ if_print_debug ("Static ");
+ else
+ if_print_debug ("Dynamic ");
+ sprintf (buffer, "%ld ", object);
+ if_print_debug (buffer);
+ debug_print_quoted (prefix);
+ if_print_debug_character (' ');
+ debug_print_quoted (name);
+}
+
+static void
+debug_print_npc (sc_gameref_t game, sc_int npc)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_char buffer[32];
+ const sc_char *prefix, *name;
+
+ if_print_debug ("NPC ");
+ if (npc < 0 || npc >= gs_npc_count (game))
+ {
+ sprintf (buffer, "%ld ", npc);
+ if_print_debug (buffer);
+ if_print_debug ("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "NPCs";
+ vt_key[1].integer = npc;
+ vt_key[2].string = "Prefix";
+ prefix = prop_get_string (bundle, "S<-sis", vt_key);
+ vt_key[2].string = "Name";
+ name = prop_get_string (bundle, "S<-sis", vt_key);
+ sprintf (buffer, "%ld ", npc);
+ if_print_debug (buffer);
+ debug_print_quoted (prefix);
+ if_print_debug_character (' ');
+ debug_print_quoted (name);
+}
+
+static void
+debug_print_event (sc_gameref_t game, sc_int event)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_char buffer[32];
+ const sc_char *name;
+
+ if_print_debug ("Event ");
+ if (event < 0 || event >= gs_event_count (game))
+ {
+ sprintf (buffer, "%ld ", event);
+ if_print_debug (buffer);
+ if_print_debug ("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Short";
+ name = prop_get_string (bundle, "S<-sis", vt_key);
+ sprintf (buffer, "%ld ", event);
+ if_print_debug (buffer);
+ debug_print_quoted (name);
+}
+
+static void
+debug_print_task (sc_gameref_t game, sc_int task)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[4];
+ sc_char buffer[32];
+ const sc_char *command;
+
+ if_print_debug ("Task ");
+ if (task < 0 || task >= gs_task_count (game))
+ {
+ sprintf (buffer, "%ld ", task);
+ if_print_debug (buffer);
+ if_print_debug ("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Tasks";
+ vt_key[1].integer = task;
+ vt_key[2].string = "Command";
+ vt_key[3].integer = 0;
+ command = prop_get_string (bundle, "S<-sisi", vt_key);
+ sprintf (buffer, "%ld ", task);
+ if_print_debug (buffer);
+ debug_print_quoted (command);
+}
+
+static void
+debug_print_variable (sc_gameref_t game, sc_int variable)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ const sc_var_setref_t vars = gs_get_vars (game);
+ sc_vartype_t vt_key[3], vt_rvalue;
+ sc_char buffer[32];
+ sc_int var_type;
+ const sc_char *name;
+
+ if (variable < 0 || variable >= debug_variable_count (game))
+ {
+ if_print_debug ("Variable ");
+ sprintf (buffer, "%ld ", variable);
+ if_print_debug (buffer);
+ if_print_debug ("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Variables";
+ vt_key[1].integer = variable;
+ vt_key[2].string = "Name";
+ name = prop_get_string (bundle, "S<-sis", vt_key);
+
+ if (var_get (vars, name, &var_type, &vt_rvalue))
+ {
+ switch (var_type)
+ {
+ case VAR_INTEGER:
+ if_print_debug ("Integer ");
+ break;
+ case VAR_STRING:
+ if_print_debug ("String ");
+ break;
+ default:
+ if_print_debug ("[Invalid type] ");
+ break;
+ }
+ }
+ else
+ if_print_debug ("[Invalid variable] ");
+ sprintf (buffer, "%ld ", variable);
+ if_print_debug (buffer);
+ debug_print_quoted (name);
+}
+
+
+/*
+ * debug_game()
+ *
+ * Display overall game details.
+ */
+static void
+debug_game (sc_gameref_t game, sc_command_type_t type)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+ sc_vartype_t vt_key[2];
+ const sc_char *version, *gamename, *compiledate, *gameauthor;
+ sc_int perspective, waitturns;
+ sc_bool has_sound, has_graphics, has_battle;
+ sc_char buffer[32];
+ assert (debug_is_valid (debug));
+
+ if (type != COMMAND_QUERY)
+ {
+ if_print_debug ("The Game command takes no arguments.\n");
+ return;
+ }
+
+ if_print_debug ("Game ");
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "GameName";
+ gamename = prop_get_string (bundle, "S<-ss", vt_key);
+ debug_print_quoted (gamename);
+ if_print_debug_character ('\n');
+
+ if_print_debug (" Compiled ");
+ vt_key[0].string = "CompileDate";
+ compiledate = prop_get_string (bundle, "S<-s", vt_key);
+ debug_print_quoted (compiledate);
+
+ if_print_debug (", Author ");
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "GameAuthor";
+ gameauthor = prop_get_string (bundle, "S<-ss", vt_key);
+ debug_print_quoted (gameauthor);
+ if_print_debug_character ('\n');
+
+ vt_key[0].string = "VersionString";
+ version = prop_get_string (bundle, "S<-s", vt_key);
+ if_print_debug (" Version ");
+ if_print_debug (version);
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "Perspective";
+ perspective = prop_get_integer (bundle, "I<-ss", vt_key);
+ switch (perspective)
+ {
+ case 0:
+ if_print_debug (", First person");
+ break;
+ case 1:
+ if_print_debug (", Second person");
+ break;
+ case 2:
+ if_print_debug (", Third person");
+ break;
+ default:
+ if_print_debug (", [Unknown perspective]");
+ break;
+ }
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "WaitTurns";
+ waitturns = prop_get_integer (bundle, "I<-ss", vt_key);
+ if_print_debug (", Waitturns ");
+ sprintf (buffer, "%ld", waitturns);
+ if_print_debug (buffer);
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "Sound";
+ has_sound = prop_get_boolean (bundle, "B<-ss", vt_key);
+ vt_key[1].string = "Graphics";
+ has_graphics = prop_get_boolean (bundle, "B<-ss", vt_key);
+ if (has_sound)
+ if_print_debug (", Sound");
+ if (has_graphics)
+ if_print_debug (", Graphics");
+ if_print_debug_character ('\n');
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "BattleSystem";
+ has_battle = prop_get_boolean (bundle, "B<-ss", vt_key);
+ if (has_battle)
+ if_print_debug (" Battle system\n");
+
+ if_print_debug (" Room count ");
+ sprintf (buffer, "%ld", gs_room_count (game));
+ if_print_debug (buffer);
+
+ if_print_debug (", Object count ");
+ sprintf (buffer, "%ld", gs_object_count (game));
+ if_print_debug (buffer);
+
+ if_print_debug (", NPC count ");
+ sprintf (buffer, "%ld", gs_npc_count (game));
+ if_print_debug (buffer);
+ if_print_debug_character ('\n');
+
+ if_print_debug (" Event count ");
+ sprintf (buffer, "%ld", gs_event_count (game));
+ if_print_debug (buffer);
+
+ if_print_debug (", Task count ");
+ sprintf (buffer, "%ld", gs_task_count (game));
+ if_print_debug (buffer);
+
+ if_print_debug (", Variable count ");
+ sprintf (buffer, "%ld", debug_variable_count (game));
+ if_print_debug (buffer);
+ if_print_debug_character ('\n');
+
+ if (game->is_running)
+ if_print_debug (" Running");
+ else
+ if_print_debug (" Not running");
+ if (game->has_completed)
+ if_print_debug (", Completed");
+ else
+ if_print_debug (", Not completed");
+ if (game->verbose)
+ if_print_debug (", Verbose");
+ else
+ if_print_debug (", Not verbose");
+ if (game->bold_room_names)
+ if_print_debug (", Bold");
+ else
+ if_print_debug (", Not bold");
+ if (game->undo_available)
+ if_print_debug (", Undo");
+ else
+ if_print_debug (", No undo");
+ if_print_debug_character ('\n');
+
+ if_print_debug (" Score ");
+ sprintf (buffer, "%ld", game->score);
+ if_print_debug (buffer);
+ if_print_debug (", Turns ");
+ sprintf (buffer, "%ld", game->turns);
+ if_print_debug (buffer);
+ if_print_debug (", Seconds ");
+ sprintf (buffer, "%lu", debug->elapsed_seconds);
+ if_print_debug (buffer);
+ if_print_debug_character ('\n');
+}
+
+
+/*
+ * debug_player()
+ *
+ * Print a few brief details about the player status.
+ */
+static void
+debug_player (sc_gameref_t game,
+ sc_command_t command, sc_command_type_t type)
+{
+ if (type != COMMAND_QUERY)
+ {
+ if_print_debug ("The Player command takes no arguments.\n");
+ return;
+ }
+
+ if (command == DEBUG_OLDPLAYER)
+ {
+ if (!game->undo_available)
+ {
+ if_print_debug ("There is no previous game state to examine.\n");
+ return;
+ }
+
+ game = game->undo;
+ assert (gs_is_game_valid (game));
+ }
+
+ debug_print_player (game);
+ if_print_debug_character ('\n');
+
+ if (gs_playerroom (game) == -1)
+ if_print_debug (" Hidden!\n");
+ else
+ {
+ if_print_debug (" In ");
+ debug_print_room (game, gs_playerroom (game));
+ if_print_debug_character ('\n');
+ }
+
+ switch (gs_playerposition (game))
+ {
+ case 0:
+ if_print_debug (" Standing\n");
+ break;
+ case 1:
+ if_print_debug (" Sitting\n");
+ break;
+ case 2:
+ if_print_debug (" Lying\n");
+ break;
+ default:
+ if_print_debug (" [Invalid position]\n");
+ break;
+ }
+
+ if (gs_playerparent (game) != -1)
+ {
+ if_print_debug (" Parent is ");
+ debug_print_object (game, gs_playerparent (game));
+ if_print_debug_character ('\n');
+ }
+}
+
+
+/*
+ * debug_normalize_arguments()
+ *
+ * Normalize a set of arguments parsed from a debugger command line, for
+ * debug commands that take ranges.
+ */
+static sc_bool
+debug_normalize_arguments (sc_command_type_t type,
+ sc_int *arg1, sc_int *arg2, sc_int limit)
+{
+ sc_int low = 0, high = 0;
+
+ /* Set range low and high depending on the command type. */
+ switch (type)
+ {
+ case COMMAND_QUERY:
+ case COMMAND_ALL:
+ low = 0;
+ high = limit - 1;
+ break;
+ case COMMAND_ONE:
+ low = *arg1;
+ high = *arg1;
+ break;
+ case COMMAND_RANGE:
+ low = *arg1;
+ high = *arg2;
+ break;
+ default:
+ sc_fatal ("debug_normalize_arguments: bad command type\n");
+ }
+
+ /* If range is valid, copy out and return TRUE. */
+ if (low >= 0 && low < limit && high >= 0 && high < limit && high >= low)
+ {
+ *arg1 = low;
+ *arg2 = high;
+ return TRUE;
+ }
+
+ /* Input range is invalid. */
+ return FALSE;
+}
+
+
+/*
+ * debug_filter_room()
+ * debug_dump_room()
+ *
+ * Print details of rooms and their direct contents.
+ */
+static sc_bool
+debug_filter_room (sc_gameref_t game, sc_int room)
+{
+ return room == gs_playerroom (game);
+}
+
+static void
+debug_dump_room (sc_gameref_t game, sc_int room)
+{
+ sc_int object, npc;
+
+ debug_print_room (game, room);
+ if_print_debug_character ('\n');
+
+ if (gs_room_seen (game, room))
+ if_print_debug (" Visited\n");
+ else
+ if_print_debug (" Not visited\n");
+
+ if (gs_playerroom (game) == room)
+ {
+ if_print_debug (" ");
+ debug_print_player (game);
+ if_print_debug_character ('\n');
+ }
+
+ for (object = 0; object < gs_object_count (game); object++)
+ {
+ if (obj_indirectly_in_room (game, object, room))
+ {
+ if_print_debug (" ");
+ debug_print_object (game, object);
+ if_print_debug_character ('\n');
+ }
+ }
+
+ for (npc = 0; npc < gs_npc_count (game); npc++)
+ {
+ if (npc_in_room (game, npc, room))
+ {
+ if_print_debug (" ");
+ debug_print_npc (game, npc);
+ if_print_debug_character ('\n');
+ }
+ }
+}
+
+
+/*
+ * debug_filter_object()
+ * debug_dump_object()
+ *
+ * Print the changeable details of game objects.
+ */
+static sc_bool
+debug_filter_object (sc_gameref_t game, sc_int object)
+{
+ return obj_indirectly_in_room (game, object, gs_playerroom (game));
+}
+
+static void
+debug_dump_object (sc_gameref_t game, sc_int object)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_int openness;
+ sc_vartype_t vt_key[3];
+ sc_bool bstatic, is_statussed;
+ sc_int position, parent;
+
+ debug_print_object (game, object);
+ if_print_debug_character ('\n');
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ bstatic = prop_get_boolean (bundle, "B<-sis", vt_key);
+
+ if (gs_object_seen (game, object))
+ if_print_debug (" Seen");
+ else
+ if_print_debug (" Not seen");
+ if (bstatic)
+ {
+ if (gs_object_static_unmoved (game, object))
+ if_print_debug (", Not relocated");
+ else
+ if_print_debug (", Relocated");
+ }
+ else
+ {
+ vt_key[2].string = "OnlyWhenNotMoved";
+ if (prop_get_integer (bundle, "I<-sis", vt_key) == 1)
+ {
+ if (gs_object_unmoved (game, object))
+ if_print_debug (", Not moved");
+ else
+ if_print_debug (", Moved");
+ }
+ }
+ openness = gs_object_openness (game, object);
+ switch (openness)
+ {
+ case OBJ_OPEN:
+ if_print_debug (", Open");
+ break;
+ case OBJ_CLOSED:
+ if_print_debug (", Closed");
+ break;
+ case OBJ_LOCKED:
+ if_print_debug (", Locked");
+ break;
+ }
+ if_print_debug_character ('\n');
+
+ position = gs_object_position (game, object);
+ parent = gs_object_parent (game, object);
+ switch (position)
+ {
+ case OBJ_HIDDEN:
+ if (bstatic)
+ if_print_debug (" Static default\n");
+ else
+ if_print_debug (" Hidden\n");
+ break;
+ case OBJ_HELD_PLAYER:
+ if_print_debug (" Held by ");
+ debug_print_player (game);
+ if_print_debug_character ('\n');
+ break;
+ case OBJ_HELD_NPC:
+ if_print_debug (" Held by ");
+ debug_print_npc (game, parent);
+ if_print_debug_character ('\n');
+ break;
+ case OBJ_WORN_PLAYER:
+ if_print_debug (" Worn by ");
+ debug_print_player (game);
+ if_print_debug_character ('\n');
+ break;
+ case OBJ_WORN_NPC:
+ if_print_debug (" Worn by ");
+ debug_print_npc (game, parent);
+ if_print_debug_character ('\n');
+ break;
+ case OBJ_PART_NPC:
+ if_print_debug (" Part of ");
+ if (parent == -1)
+ debug_print_player (game);
+ else
+ debug_print_npc (game, parent);
+ if_print_debug_character ('\n');
+ break;
+ case OBJ_ON_OBJECT:
+ if_print_debug (" On ");
+ debug_print_object (game, parent);
+ if_print_debug_character ('\n');
+ break;
+ case OBJ_IN_OBJECT:
+ if_print_debug (" Inside ");
+ debug_print_object (game, parent);
+ if_print_debug_character ('\n');
+ break;
+ default:
+ if_print_debug (" In ");
+ debug_print_room (game, position - 1);
+ if_print_debug_character ('\n');
+ break;
+ }
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "CurrentState";
+ is_statussed = prop_get_integer (bundle, "I<-sis", vt_key) != 0;
+ if (is_statussed)
+ {
+ sc_char buffer[32];
+ const sc_char *states;
+
+ if_print_debug (" State ");
+ sprintf (buffer, "%ld", gs_object_state (game, object));
+ if_print_debug (buffer);
+
+ vt_key[2].string = "States";
+ states = prop_get_string (bundle, "S<-sis", vt_key);
+ if_print_debug (" of ");
+ debug_print_quoted (states);
+ if_print_debug_character ('\n');
+ }
+}
+
+
+/*
+ * debug_filter_npc()
+ * debug_dump_npc()
+ *
+ * Print stuff about NPCs.
+ */
+static sc_bool
+debug_filter_npc (sc_gameref_t game, sc_int npc)
+{
+ return npc_in_room (game, npc, gs_playerroom (game));
+}
+
+static void
+debug_dump_npc (sc_gameref_t game, sc_int npc)
+{
+ debug_print_npc (game, npc);
+ if_print_debug_character ('\n');
+
+ if (gs_npc_seen (game, npc))
+ if_print_debug (" Seen\n");
+ else
+ if_print_debug (" Not seen\n");
+
+ if (gs_npc_location (game, npc) - 1 == -1)
+ if_print_debug (" Hidden\n");
+ else
+ {
+ if_print_debug (" In ");
+ debug_print_room (game, gs_npc_location (game, npc) - 1);
+ if_print_debug_character ('\n');
+ }
+
+ switch (gs_npc_position (game, npc))
+ {
+ case 0:
+ if_print_debug (" Standing\n");
+ break;
+ case 1:
+ if_print_debug (" Sitting\n");
+ break;
+ case 2:
+ if_print_debug (" Lying\n");
+ break;
+ default:
+ if_print_debug (" [Invalid position]\n");
+ break;
+ }
+
+ if (gs_npc_parent (game, npc) != -1)
+ {
+ if_print_debug (" Parent is ");
+ debug_print_object (game, gs_npc_parent (game, npc));
+ if_print_debug_character ('\n');
+ }
+
+ if (gs_npc_walkstep_count (game, npc) > 0)
+ {
+ sc_char buffer[32];
+ sc_int walk;
+
+ if_print_debug (" Walkstep count ");
+ sprintf (buffer, "%ld", gs_npc_walkstep_count (game, npc));
+ if_print_debug (buffer);
+ if_print_debug (", Walks { ");
+ for (walk = 0; walk < gs_npc_walkstep_count (game, npc); walk++)
+ {
+ sprintf (buffer, "%ld", gs_npc_walkstep (game, npc, walk));
+ if_print_debug (buffer);
+ if_print_debug_character (' ');
+ }
+ if_print_debug ("}.\n");
+ }
+}
+
+
+/*
+ * debug_filter_event()
+ * debug_dump_event()
+ *
+ * Print stuff about events.
+ */
+static sc_bool
+debug_filter_event (sc_gameref_t game, sc_int event)
+{
+ return gs_event_state (game, event) == ES_RUNNING;
+}
+
+static void
+debug_dump_event (sc_gameref_t game, sc_int event)
+{
+ sc_char buffer[32];
+
+ debug_print_event (game, event);
+ if_print_debug_character ('\n');
+
+ switch (gs_event_state (game, event))
+ {
+ case ES_WAITING:
+ if_print_debug (" Waiting\n");
+ break;
+ case ES_RUNNING:
+ if_print_debug (" Running\n");
+ break;
+ case ES_AWAITING:
+ if_print_debug (" Awaiting\n");
+ break;
+ case ES_FINISHED:
+ if_print_debug (" Finished\n");
+ break;
+ case ES_PAUSED:
+ if_print_debug (" Paused\n");
+ break;
+ default:
+ if_print_debug (" [Invalid state]\n");
+ break;
+ }
+
+ if_print_debug (" Time ");
+ sprintf (buffer, "%ld\n", gs_event_time (game, event));
+ if_print_debug (buffer);
+}
+
+
+/*
+ * debug_filter_task()
+ * debug_dump_task()
+ *
+ * Print stuff about tasks.
+ */
+static sc_bool
+debug_filter_task (sc_gameref_t game, sc_int task)
+{
+ return task_can_run_task (game, task);
+}
+
+static void
+debug_dump_task (sc_gameref_t game, sc_int task)
+{
+ debug_print_task (game, task);
+ if_print_debug_character ('\n');
+
+ if (task_can_run_task (game, task))
+ if_print_debug (" Runnable");
+ else
+ if_print_debug (" Not runnable");
+ if (gs_task_done (game, task))
+ if_print_debug (", Done");
+ else
+ if_print_debug (", Not done");
+ if (gs_task_scored (game, task))
+ if_print_debug (", Scored\n");
+ else
+ if_print_debug (", Not scored\n");
+}
+
+
+/*
+ * debug_dump_variable()
+ *
+ * Print stuff about variables.
+ */
+static void
+debug_dump_variable (sc_gameref_t game, sc_int variable)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ const sc_var_setref_t vars = gs_get_vars (game);
+ sc_vartype_t vt_key[3], vt_rvalue;
+ const sc_char *name;
+ sc_int var_type;
+
+ debug_print_variable (game, variable);
+ if_print_debug_character ('\n');
+
+ vt_key[0].string = "Variables";
+ vt_key[1].integer = variable;
+ vt_key[2].string = "Name";
+ name = prop_get_string (bundle, "S<-sis", vt_key);
+
+ if_print_debug (" Value = ");
+ if (var_get (vars, name, &var_type, &vt_rvalue))
+ {
+ switch (var_type)
+ {
+ case VAR_INTEGER:
+ {
+ sc_char buffer[32];
+
+ sprintf (buffer, "%ld", vt_rvalue.integer);
+ if_print_debug (buffer);
+ break;
+ }
+ case VAR_STRING:
+ debug_print_quoted (vt_rvalue.string);
+ break;
+ default:
+ if_print_debug ("[Unknown]");
+ break;
+ }
+ }
+ else
+ if_print_debug ("[Unknown]");
+ if_print_debug_character ('\n');
+}
+
+
+/*
+ * debug_dump_common()
+ *
+ * Common handler for iterating dumps of classes.
+ */
+static void
+debug_dump_common (sc_gameref_t game, sc_command_t command,
+ sc_command_type_t type, sc_int arg1, sc_int arg2)
+{
+ sc_int low = arg1, high = arg2;
+ sc_int limit, index_;
+ const sc_char *class_;
+ sc_bool (*filter_function) (sc_gameref_t, sc_int);
+ void (*dumper_function) (sc_gameref_t, sc_int);
+ sc_bool printed = FALSE;
+
+ /* Initialize variables to avoid gcc warnings. */
+ limit = 0;
+ class_ = NULL;
+ filter_function = NULL;
+ dumper_function = NULL;
+
+ /* Switch to undo game on relevant commands. */
+ switch (command)
+ {
+ case DEBUG_OLDROOMS:
+ case DEBUG_OLDOBJECTS:
+ case DEBUG_OLDNPCS:
+ case DEBUG_OLDEVENTS:
+ case DEBUG_OLDTASKS:
+ case DEBUG_OLDVARIABLES:
+ if (!game->undo_available)
+ {
+ if_print_debug ("There is no previous game state to examine.\n");
+ return;
+ }
+
+ game = game->undo;
+ assert (gs_is_game_valid (game));
+ break;
+
+ default:
+ break;
+ }
+
+ /* Demultiplex dump command. */
+ switch (command)
+ {
+ case DEBUG_ROOMS:
+ case DEBUG_OLDROOMS:
+ class_ = "Room";
+ filter_function = debug_filter_room;
+ dumper_function = debug_dump_room;
+ limit = gs_room_count (game);
+ break;
+ case DEBUG_OBJECTS:
+ case DEBUG_OLDOBJECTS:
+ class_ = "Object";
+ filter_function = debug_filter_object;
+ dumper_function = debug_dump_object;
+ limit = gs_object_count (game);
+ break;
+ case DEBUG_NPCS:
+ case DEBUG_OLDNPCS:
+ class_ = "NPC";
+ filter_function = debug_filter_npc;
+ dumper_function = debug_dump_npc;
+ limit = gs_npc_count (game);
+ break;
+ case DEBUG_EVENTS:
+ case DEBUG_OLDEVENTS:
+ class_ = "Event";
+ filter_function = debug_filter_event;
+ dumper_function = debug_dump_event;
+ limit = gs_event_count (game);
+ break;
+ case DEBUG_TASKS:
+ case DEBUG_OLDTASKS:
+ class_ = "Task";
+ filter_function = debug_filter_task;
+ dumper_function = debug_dump_task;
+ limit = gs_task_count (game);
+ break;
+ case DEBUG_VARIABLES:
+ case DEBUG_OLDVARIABLES:
+ class_ = "Variable";
+ filter_function = NULL;
+ dumper_function = debug_dump_variable;
+ limit = debug_variable_count (game);
+ break;
+ default:
+ sc_fatal ("debug_dump_common: invalid command\n");
+ }
+
+ /* Normalize to this limit. */
+ if (!debug_normalize_arguments (type, &low, &high, limit))
+ {
+ if (limit == 0)
+ {
+ if_print_debug ("There is nothing of type ");
+ debug_print_quoted (class_);
+ if_print_debug (" to print.\n");
+ }
+ else
+ {
+ if_print_debug ("Invalid item or range for ");
+ debug_print_quoted (class_);
+ if (limit == 1)
+ if_print_debug ("; only 0 is valid.\n");
+ else
+ {
+ sc_char buffer[32];
+
+ if_print_debug ("; valid values are 0 to ");
+ sprintf (buffer, "%ld", limit - 1);
+ if_print_debug (buffer);
+ if_print_debug (".\n");
+ }
+ }
+ return;
+ }
+
+ /* Print each item of the class, filtering on query commands. */
+ for (index_ = low; index_ <= high; index_++)
+ {
+ if (type == COMMAND_QUERY
+ && filter_function && !filter_function (game, index_))
+ continue;
+
+ if (printed)
+ if_print_debug_character ('\n');
+ dumper_function (game, index_);
+ printed = TRUE;
+ }
+ if (!printed)
+ {
+ if_print_debug ("Nothing of type ");
+ debug_print_quoted (class_);
+ if_print_debug (" is relevant.\nTry \"");
+ if_print_debug (class_);
+ if_print_debug (" *\" to show all items of this type.\n");
+ }
+}
+
+
+/*
+ * debug_buffer()
+ *
+ * Print the current raw printfilter contents.
+ */
+static void
+debug_buffer (sc_gameref_t game, sc_command_type_t type)
+{
+ const sc_filterref_t filter = gs_get_filter (game);
+ const sc_char *buffer;
+
+ if (type != COMMAND_QUERY)
+ {
+ if_print_debug ("The Buffer command takes no arguments.\n");
+ return;
+ }
+
+ buffer = pf_get_buffer (filter);
+ if (buffer)
+ if_print_debug (buffer);
+ else
+ if_print_debug ("There is no game text buffered.\n");
+}
+
+
+/*
+ * debug_print_resource()
+ *
+ * Helper for debug_resources().
+ */
+static void
+debug_print_resource (const sc_resource_t *resource)
+{
+ sc_char buffer[32];
+
+ debug_print_quoted (resource->name);
+ if_print_debug (", offset ");
+ sprintf (buffer, "%ld", resource->offset);
+ if_print_debug (buffer);
+ if_print_debug (", length ");
+ sprintf (buffer, "%ld", resource->length);
+ if_print_debug (buffer);
+}
+
+
+/*
+ * debug_resources()
+ *
+ * Print any active and requested resources.
+ */
+static void
+debug_resources (sc_gameref_t game, sc_command_type_t type)
+{
+ sc_bool printed = FALSE;
+
+ if (type != COMMAND_QUERY)
+ {
+ if_print_debug ("The Resources command takes no arguments.\n");
+ return;
+ }
+
+ if (game->stop_sound)
+ {
+ if_print_debug ("Sound stop");
+ if (strlen (game->requested_sound.name) > 0)
+ if_print_debug (" before new sound");
+ if_print_debug (" requested");
+ if (game->sound_active)
+ if_print_debug (", sound active");
+ if_print_debug (".\n");
+ printed = TRUE;
+ }
+ if (!res_compare_resource (&game->requested_sound,
+ &game->playing_sound))
+ {
+ if_print_debug ("Requested Sound ");
+ debug_print_resource (&game->requested_sound);
+ if_print_debug (".\n");
+ printed = TRUE;
+ }
+ if (!res_compare_resource (&game->requested_graphic,
+ &game->displayed_graphic))
+ {
+ if_print_debug ("Requested Graphic ");
+ debug_print_resource (&game->requested_graphic);
+ if_print_debug (".\n");
+ printed = TRUE;
+ }
+
+ if (strlen (game->playing_sound.name) > 0)
+ {
+ if_print_debug ("Playing Sound ");
+ debug_print_resource (&game->playing_sound);
+ if_print_debug (".\n");
+ printed = TRUE;
+ }
+ if (strlen (game->displayed_graphic.name) > 0)
+ {
+ if_print_debug ("Displaying Graphic ");
+ debug_print_resource (&game->displayed_graphic);
+ if_print_debug (".\n");
+ printed = TRUE;
+ }
+
+ if (!printed)
+ if_print_debug ("There is no game resource activity.\n");
+}
+
+
+/*
+ * debug_random()
+ *
+ * Report the PRNG in use, and seed the random number generator to the
+ * given value.
+ */
+static void
+debug_random (sc_command_type_t type, sc_int new_seed)
+{
+ const sc_char *random_type;
+ sc_char buffer[32];
+
+ if (type != COMMAND_ONE && type != COMMAND_QUERY)
+ {
+ if_print_debug ("The Random command takes either one argument or"
+ " no arguments.\n");
+ return;
+ }
+
+ random_type = sc_is_congruential_random () ? "congruential" : "platform";
+
+ if (type == COMMAND_QUERY)
+ {
+ if_print_debug ("The ");
+ if_print_debug (random_type);
+ if_print_debug (" random number generator is selected.\n");
+ return;
+ }
+
+ if (new_seed == 0)
+ {
+ if_print_debug ("The seed value may not be zero.\n");
+ return;
+ }
+
+ sc_seed_random (new_seed);
+
+ if_print_debug ("Set seed ");
+ sprintf (buffer, "%ld", new_seed);
+ if_print_debug (buffer);
+ if_print_debug (" for the ");
+ if_print_debug (random_type);
+ if_print_debug (" random number generator.\n");
+}
+
+
+/*
+ * debug_watchpoint_common()
+ *
+ * Common handler for setting and clearing watchpoints.
+ */
+static void
+debug_watchpoint_common (sc_gameref_t game, sc_command_t command,
+ sc_command_type_t type, sc_int arg1, sc_int arg2)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+ sc_int low = arg1, high = arg2;
+ sc_int limit, index_;
+ const sc_char *class_;
+ sc_bool *watchpoints, action;
+ sc_char buffer[32];
+ assert (debug_is_valid (debug));
+
+ /* Initialize variables to avoid gcc warnings. */
+ limit = 0;
+ class_ = NULL;
+ watchpoints = NULL;
+ action = FALSE;
+
+ /* Set action to TRUE or FALSE, for setting/clearing watchpoints. */
+ switch (command)
+ {
+ case DEBUG_WATCHPLAYER:
+ case DEBUG_WATCHOBJECTS:
+ case DEBUG_WATCHNPCS:
+ case DEBUG_WATCHEVENTS:
+ case DEBUG_WATCHTASKS:
+ case DEBUG_WATCHVARIABLES:
+ action = TRUE;
+ break;
+ case DEBUG_CLEARPLAYER:
+ case DEBUG_CLEAROBJECTS:
+ case DEBUG_CLEARNPCS:
+ case DEBUG_CLEAREVENTS:
+ case DEBUG_CLEARTASKS:
+ case DEBUG_CLEARVARIABLES:
+ action = FALSE;
+ break;
+ default:
+ sc_fatal ("debug_watchpoint_common: invalid command\n");
+ }
+
+ /* Handle player watchpoint setting. */
+ if (command == DEBUG_WATCHPLAYER || command == DEBUG_CLEARPLAYER)
+ {
+ if (command == DEBUG_CLEARPLAYER)
+ {
+ debug->watch_player = action;
+ if_print_debug ("Cleared Player watchpoint.\n");
+ }
+ else if (type == COMMAND_ONE && arg1 == 0)
+ {
+ debug->watch_player = action;
+ if_print_debug ("Set Player watchpoint.\n");
+ }
+ else
+ {
+ if (debug->watch_player)
+ if_print_debug ("Player watchpoint is set.\n");
+ else
+ if_print_debug ("No Player watchpoint is set; to set one, use"
+ " \"Watchplayer 0\".\n");
+ }
+ return;
+ }
+
+ /* Demultiplex watchpoint command. */
+ switch (command)
+ {
+ case DEBUG_WATCHOBJECTS:
+ case DEBUG_CLEAROBJECTS:
+ class_ = "Object";
+ watchpoints = debug->watch_objects;
+ limit = gs_object_count (game);
+ break;
+ case DEBUG_WATCHNPCS:
+ case DEBUG_CLEARNPCS:
+ class_ = "NPC";
+ watchpoints = debug->watch_npcs;
+ limit = gs_npc_count (game);
+ break;
+ case DEBUG_WATCHEVENTS:
+ case DEBUG_CLEAREVENTS:
+ class_ = "Event";
+ watchpoints = debug->watch_events;
+ limit = gs_event_count (game);
+ break;
+ case DEBUG_WATCHTASKS:
+ case DEBUG_CLEARTASKS:
+ class_ = "Task";
+ watchpoints = debug->watch_tasks;
+ limit = gs_task_count (game);
+ break;
+ case DEBUG_WATCHVARIABLES:
+ case DEBUG_CLEARVARIABLES:
+ class_ = "Variable";
+ watchpoints = debug->watch_variables;
+ limit = debug_variable_count (game);
+ break;
+ default:
+ sc_fatal ("debug_watchpoint_common: invalid command\n");
+ }
+
+ /* Normalize to this limit. */
+ if (!debug_normalize_arguments (type, &low, &high, limit))
+ {
+ if (limit == 0)
+ {
+ if_print_debug ("There is nothing of type ");
+ debug_print_quoted (class_);
+ if_print_debug (" to watch.\n");
+ }
+ else
+ {
+ if_print_debug ("Invalid item or range for ");
+ debug_print_quoted (class_);
+ if (limit == 1)
+ if_print_debug ("; only 0 is valid.\n");
+ else
+ {
+ if_print_debug ("; valid values are 0 to ");
+ sprintf (buffer, "%ld", limit - 1);
+ if_print_debug (buffer);
+ if_print_debug (".\n");
+ }
+ }
+ return;
+ }
+
+ /* On query, search the array for set flags, and print out. */
+ if (type == COMMAND_QUERY)
+ {
+ sc_bool printed = FALSE;
+
+ /* Scan for set watchpoints, and list each found. */
+ for (index_ = low; index_ <= high; index_++)
+ {
+ if (watchpoints[index_])
+ {
+ if (!printed)
+ {
+ if_print_debug ("Watchpoints are set for ");
+ if_print_debug (class_);
+ if_print_debug (" { ");
+ }
+ sprintf (buffer, "%ld", index_);
+ if_print_debug (buffer);
+ if_print_debug_character (' ');
+ printed = TRUE;
+ }
+ }
+ if (printed)
+ if_print_debug ("}.\n");
+ else
+ {
+ if_print_debug ("No ");
+ if_print_debug (class_);
+ if_print_debug (" watchpoints are set.\n");
+ }
+ return;
+ }
+
+ /*
+ * For non-queries, set watchpoint flags as defined in action for
+ * the range determined, and print confirmation.
+ */
+ for (index_ = low; index_ <= high; index_++)
+ watchpoints[index_] = action;
+
+ if (action)
+ if_print_debug ("Set ");
+ else
+ if_print_debug ("Cleared ");
+ sprintf (buffer, "%ld ", high - low + 1);
+ if_print_debug (buffer);
+ if_print_debug (class_);
+ if (high == low)
+ if_print_debug (" watchpoint.\n");
+ else
+ if_print_debug (" watchpoints.\n");
+}
+
+
+/*
+ * debug_watchall_common()
+ *
+ * Common handler to list out and clear all set watchpoints at a stroke.
+ */
+static void
+debug_watchall_common (sc_gameref_t game,
+ sc_command_t command, sc_command_type_t type)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+ assert (debug_is_valid (debug));
+
+ if (type != COMMAND_QUERY)
+ {
+ if (command == DEBUG_WATCHALL)
+ if_print_debug ("The Watchall command takes no arguments.\n");
+ else
+ if_print_debug ("The Clearall command takes no arguments.\n");
+ return;
+ }
+
+ /* Query all set watchpoints using common watchpoint handler... */
+ if (command == DEBUG_WATCHALL)
+ {
+ debug_watchpoint_common (game,
+ DEBUG_WATCHPLAYER, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common (game,
+ DEBUG_WATCHOBJECTS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common (game,
+ DEBUG_WATCHNPCS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common (game,
+ DEBUG_WATCHEVENTS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common (game,
+ DEBUG_WATCHTASKS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common (game,
+ DEBUG_WATCHVARIABLES, COMMAND_QUERY, 0, 0);
+ return;
+ }
+
+ /* ...but reset all the fast way, with memset(). */
+ assert (command == DEBUG_CLEARALL);
+ debug->watch_player = FALSE;
+ memset (debug->watch_objects, FALSE,
+ gs_object_count (game) * sizeof (*debug->watch_objects));
+ memset (debug->watch_npcs, FALSE,
+ gs_npc_count (game) * sizeof (*debug->watch_npcs));
+ memset (debug->watch_events, FALSE,
+ gs_event_count (game) * sizeof (*debug->watch_events));
+ memset (debug->watch_tasks, FALSE,
+ gs_task_count (game) * sizeof (*debug->watch_tasks));
+ memset (debug->watch_variables, FALSE,
+ debug_variable_count (game) * sizeof (*debug->watch_variables));
+ if_print_debug ("Cleared all watchpoints.\n");
+}
+
+
+/*
+ * debug_compare_object()
+ *
+ * Compare two objects, and return TRUE if the same.
+ */
+static sc_bool
+debug_compare_object (sc_gameref_t from, sc_gameref_t with, sc_int object)
+{
+ const sc_objectstate_t *from_object = from->objects + object;
+ const sc_objectstate_t *with_object = with->objects + object;
+
+ return from_object->unmoved == with_object->unmoved
+ && from_object->static_unmoved == with_object->static_unmoved
+ && from_object->position == with_object->position
+ && from_object->parent == with_object->parent
+ && from_object->openness == with_object->openness
+ && from_object->state == with_object->state
+ && from_object->seen == with_object->seen;
+}
+
+
+/*
+ * debug_compare_npc()
+ *
+ * Compare two NPCs, and return TRUE if the same.
+ */
+static sc_bool
+debug_compare_npc (sc_gameref_t from, sc_gameref_t with, sc_int npc)
+{
+ const sc_npcstate_t *from_npc = from->npcs + npc;
+ const sc_npcstate_t *with_npc = with->npcs + npc;
+
+ if (from_npc->walkstep_count != with_npc->walkstep_count)
+ sc_fatal ("debug_compare_npc: walkstep count error\n");
+
+ return from_npc->location == with_npc->location
+ && from_npc->position == with_npc->position
+ && from_npc->parent == with_npc->parent
+ && from_npc->seen == with_npc->seen
+ && memcmp (from_npc->walksteps, with_npc->walksteps,
+ from_npc->walkstep_count
+ * sizeof (*from_npc->walksteps)) == 0;
+}
+
+
+/*
+ * debug_compare_event()
+ *
+ * Compare two events, and return TRUE if the same.
+ */
+static sc_bool
+debug_compare_event (sc_gameref_t from, sc_gameref_t with, sc_int event)
+{
+ const sc_eventstate_t *from_event = from->events + event;
+ const sc_eventstate_t *with_event = with->events + event;
+
+ return from_event->state == with_event->state
+ && from_event->time == with_event->time;
+}
+
+
+/*
+ * debug_compare_task()
+ *
+ * Compare two tasks, and return TRUE if the same.
+ */
+static sc_bool
+debug_compare_task (sc_gameref_t from, sc_gameref_t with, sc_int task)
+{
+ const sc_taskstate_t *from_task = from->tasks + task;
+ const sc_taskstate_t *with_task = with->tasks + task;
+
+ return from_task->done == with_task->done
+ && from_task->scored == with_task->scored;
+}
+
+
+/*
+ * debug_compare_variable()
+ *
+ * Compare two variables, and return TRUE if the same.
+ */
+static sc_bool
+debug_compare_variable (sc_gameref_t from, sc_gameref_t with, sc_int variable)
+{
+ const sc_prop_setref_t bundle = from->bundle;
+ const sc_var_setref_t from_var = from->vars;
+ const sc_var_setref_t with_var = with->vars;
+ sc_vartype_t vt_key[3], vt_rvalue, vt_rvalue2;
+ const sc_char *name;
+ sc_int var_type, var_type2;
+ sc_bool equal = FALSE;
+
+ if (from->bundle != with->bundle)
+ sc_fatal ("debug_compare_variable: property sharing malfunction\n");
+
+ vt_key[0].string = "Variables";
+ vt_key[1].integer = variable;
+ vt_key[2].string = "Name";
+ name = prop_get_string (bundle, "S<-sis", vt_key);
+
+ if (!var_get (from_var, name, &var_type, &vt_rvalue)
+ || !var_get (with_var, name, &var_type2, &vt_rvalue2))
+ sc_fatal ("debug_compare_variable: can't find variable %s\n", name);
+ else if (var_type != var_type2)
+ sc_fatal ("debug_compare_variable: variable type mismatch %s\n", name);
+
+ switch (var_type)
+ {
+ case VAR_INTEGER:
+ equal = (vt_rvalue.integer == vt_rvalue2.integer);
+ break;
+ case VAR_STRING:
+ equal = !strcmp (vt_rvalue.string, vt_rvalue2.string);
+ break;
+ default:
+ sc_fatal ("debug_compare_variable:"
+ " invalid variable type, %ld\n", var_type);
+ }
+
+ return equal;
+}
+
+
+/*
+ * debug_check_class()
+ *
+ * Central handler for checking watchpoints. Compares a number of items
+ * of a class using the comparison function given, where indicated by a
+ * watchpoints flags array. Prints entries that differ, and returns TRUE
+ * if any differed.
+ */
+static sc_bool
+debug_check_class (sc_gameref_t from, sc_gameref_t with,
+ const sc_char *class_, sc_int class_count,
+ const sc_bool *watchpoints,
+ sc_bool (*const compare_function)
+ (sc_gameref_t, sc_gameref_t, sc_int))
+{
+ sc_int index_;
+ sc_bool triggered = FALSE;
+
+ /*
+ * Scan the watchpoints array for set watchpoints, comparing classes
+ * where the watchpoint flag is set.
+ */
+ for (index_ = 0; index_ < class_count; index_++)
+ {
+ if (!watchpoints[index_])
+ continue;
+
+ if (!compare_function (from, with, index_))
+ {
+ sc_char buffer[32];
+
+ if (!triggered)
+ {
+ if_print_debug ("--- ");
+ if_print_debug (class_);
+ if_print_debug (" watchpoint triggered { ");
+ }
+ sprintf (buffer, "%ld ", index_);
+ if_print_debug (buffer);
+ triggered = TRUE;
+ }
+ }
+ if (triggered)
+ if_print_debug ("}.\n");
+
+ /* Return TRUE if anything differed. */
+ return triggered;
+}
+
+
+/*
+ * debug_check_watchpoints()
+ *
+ * Checks the game against the undo game for all set watchpoints. Returns
+ * TRUE if any triggered, FALSE if none (or if the undo game isn't available,
+ * in which case no check is possible).
+ */
+static sc_bool
+debug_check_watchpoints (sc_gameref_t game)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+ const sc_gameref_t undo = game->undo;
+ sc_bool triggered;
+ assert (debug_is_valid (debug) && gs_is_game_valid (undo));
+
+ /* If no undo is present, no check is possible. */
+ if (!game->undo_available)
+ return FALSE;
+
+ /* Check first for player watchpoint. */
+ triggered = FALSE;
+ if (debug->watch_player)
+ {
+ if (gs_playerroom (game) != gs_playerroom (undo)
+ || gs_playerposition (game) != gs_playerposition (undo)
+ || gs_playerparent (game) != gs_playerparent (undo))
+ {
+ if_print_debug ("--- Player watchpoint triggered.\n");
+ triggered |= TRUE;
+ }
+ }
+
+ /* Now check other classes of watchpoint. */
+ triggered |= debug_check_class (game, undo,
+ "Object", gs_object_count (game),
+ debug->watch_objects, debug_compare_object);
+ triggered |= debug_check_class (game, undo,
+ "NPC", gs_npc_count (game),
+ debug->watch_npcs, debug_compare_npc);
+ triggered |= debug_check_class (game, undo,
+ "Event", gs_event_count (game),
+ debug->watch_events, debug_compare_event);
+ triggered |= debug_check_class (game, undo,
+ "Task", gs_task_count (game),
+ debug->watch_tasks, debug_compare_task);
+ triggered |= debug_check_class (game, undo,
+ "Variable", debug_variable_count (game),
+ debug->watch_variables,
+ debug_compare_variable);
+
+ return triggered;
+}
+
+
+/*
+ * debug_parse_command()
+ *
+ * Given a debugging command string, try to parse it and return the
+ * appropriate command and its arguments. Returns DEBUG_NONE if the parse
+ * fails.
+ */
+static sc_command_t
+debug_parse_command (const sc_char *command_string,
+ sc_command_type_t *type,
+ sc_int *arg1, sc_int *arg2, sc_command_t *help_topic)
+{
+ sc_command_t return_command;
+ sc_command_type_t return_type;
+ sc_int val1, val2, converted, matches;
+ sc_char *help, *string, junk, wildcard;
+ sc_bool is_help, is_parsed, is_wildcard;
+ const sc_strings_t *entry;
+
+ /* Allocate temporary strings long enough to take a copy of the input. */
+ string = (sc_char *)sc_malloc (strlen (command_string) + 1);
+ help = (sc_char *)sc_malloc (strlen (command_string) + 1);
+
+ /*
+ * Parse the input line, in a very simplistic fashion. The argument count
+ * is one less than sscanf converts.
+ */
+ is_parsed = is_wildcard = is_help = FALSE;
+ val1 = val2 = 0;
+ converted = sscanf (command_string, " %s %s %c", help, string, &junk);
+ if (converted == 2 && sc_strcasecmp (help, "help") == 0)
+ {
+ is_help = TRUE;
+ is_parsed = TRUE;
+ }
+ sc_free (help);
+ if (!is_parsed)
+ {
+ converted = sscanf (command_string,
+ " %s %ld to %ld %c", string, &val1, &val2, &junk);
+ if (converted != 3)
+ converted = sscanf (command_string,
+ " %s %ld - %ld %c", string, &val1, &val2, &junk);
+ if (converted != 3)
+ converted = sscanf (command_string,
+ " %s %ld .. %ld %c", string, &val1, &val2, &junk);
+ if (converted != 3)
+ converted = sscanf (command_string,
+ " %s %ld %ld %c", string, &val1, &val2, &junk);
+ is_parsed |= converted == 3;
+ }
+ if (!is_parsed)
+ {
+ converted = sscanf (command_string,
+ " %s %ld %c", string, &val1, &junk);
+ is_parsed |= converted == 2;
+ }
+ if (!is_parsed)
+ {
+ converted = sscanf (command_string,
+ " %s %c %c", string, &wildcard, &junk);
+ if (converted == 2 && wildcard == '*')
+ {
+ is_wildcard = TRUE;
+ is_parsed = TRUE;
+ }
+ else
+ is_parsed |= converted == 1;
+ }
+ if (!is_parsed)
+ {
+ if_print_debug ("Invalid debug command.");
+ if_print_debug (" Type 'help' for a list of valid commands.\n");
+ sc_free (string);
+ return DEBUG_NONE;
+ }
+
+ /* Decide on a command type based on the parse. */
+ if (is_wildcard)
+ return_type = COMMAND_ALL;
+ else if (converted == 3)
+ return_type = COMMAND_RANGE;
+ else if (converted == 2)
+ return_type = COMMAND_ONE;
+ else
+ return_type = COMMAND_QUERY;
+
+ /*
+ * Find the first unambiguous command matching the string. If none,
+ * return DEBUG_NONE.
+ */
+ matches = 0;
+ return_command = DEBUG_NONE;
+ for (entry = DEBUG_COMMANDS; entry->command_string; entry++)
+ {
+ if (sc_strncasecmp (string, entry->command_string, strlen (string)) == 0)
+ {
+ matches++;
+ return_command = entry->command;
+ }
+ }
+ if (matches != 1)
+ {
+ if (matches > 1)
+ if_print_debug ("Ambiguous debug command.");
+ else
+ if_print_debug ("Unrecognized debug command.");
+ if_print_debug (" Type 'help' for a list of valid commands.\n");
+ sc_free (string);
+ return DEBUG_NONE;
+ }
+
+ /* Done with temporary command parse area. */
+ sc_free (string);
+
+ /*
+ * Return the command type, arguments, and the debugging command. For help
+ * <topic>, the command is help, with the command on which help requested
+ * in *help_topic. All clear, then?
+ */
+ *type = return_type;
+ *arg1 = val1;
+ *arg2 = val2;
+ *help_topic = is_help ? return_command : DEBUG_NONE;
+ return is_help ? DEBUG_HELP : return_command;
+}
+
+
+/*
+ * debug_dispatch()
+ *
+ * Dispatch a debugging command to the appropriate handler.
+ */
+static void
+debug_dispatch (sc_gameref_t game,
+ sc_command_t command, sc_command_type_t type,
+ sc_int arg1, sc_int arg2, sc_command_t help_topic)
+{
+ /* Demultiplex debugging command, and call handlers. */
+ switch (command)
+ {
+ case DEBUG_HELP:
+ debug_help (help_topic);
+ break;
+ case DEBUG_BUFFER:
+ debug_buffer (game, type);
+ break;
+ case DEBUG_RESOURCES:
+ debug_resources (game, type);
+ break;
+ case DEBUG_RANDOM:
+ debug_random (type, arg1);
+ break;
+ case DEBUG_GAME:
+ debug_game (game, type);
+ break;
+ case DEBUG_PLAYER:
+ case DEBUG_OLDPLAYER:
+ debug_player (game, command, type);
+ break;
+ case DEBUG_ROOMS:
+ case DEBUG_OBJECTS:
+ case DEBUG_NPCS:
+ case DEBUG_EVENTS:
+ case DEBUG_TASKS:
+ case DEBUG_VARIABLES:
+ case DEBUG_OLDROOMS:
+ case DEBUG_OLDOBJECTS:
+ case DEBUG_OLDNPCS:
+ case DEBUG_OLDEVENTS:
+ case DEBUG_OLDTASKS:
+ case DEBUG_OLDVARIABLES:
+ debug_dump_common (game, command, type, arg1, arg2);
+ break;
+ case DEBUG_WATCHPLAYER:
+ case DEBUG_WATCHOBJECTS:
+ case DEBUG_WATCHNPCS:
+ case DEBUG_WATCHEVENTS:
+ case DEBUG_WATCHTASKS:
+ case DEBUG_WATCHVARIABLES:
+ case DEBUG_CLEARPLAYER:
+ case DEBUG_CLEAROBJECTS:
+ case DEBUG_CLEARNPCS:
+ case DEBUG_CLEAREVENTS:
+ case DEBUG_CLEARTASKS:
+ case DEBUG_CLEARVARIABLES:
+ debug_watchpoint_common (game, command, type, arg1, arg2);
+ break;
+ case DEBUG_WATCHALL:
+ case DEBUG_CLEARALL:
+ debug_watchall_common (game, command, type);
+ break;
+ case DEBUG_NONE:
+ break;
+ default:
+ sc_fatal ("debug_dispatch: invalid debug command\n");
+ }
+}
+
+
+/*
+ * debug_dialog()
+ *
+ * Create a small debugging dialog with the user.
+ */
+static void
+debug_dialog (sc_gameref_t game)
+{
+ const sc_filterref_t filter = gs_get_filter (game);
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+ const sc_var_setref_t vars = gs_get_vars (game);
+ assert (debug_is_valid (debug));
+
+ /*
+ * Note elapsed seconds, so time stands still while debugging, and clear
+ * any pending game quit left over from prior dialogs (just in case).
+ */
+ debug->elapsed_seconds = var_get_elapsed_seconds (vars);
+ debug->quit_pending = FALSE;
+
+ /* Handle debug commands until debugger quit or game quit. */
+ while (TRUE)
+ {
+ sc_char buffer[DEBUG_BUFFER_SIZE];
+ sc_command_t command, help_topic;
+ sc_command_type_t type;
+ sc_int arg1, arg2;
+
+ /* Get a debugging command string from the user. */
+ do
+ {
+ if_read_debug (buffer, sizeof (buffer));
+ }
+ while (sc_strempty (buffer));
+
+ /* Parse the command read, and handle dialog exit commands. */
+ command = debug_parse_command (buffer,
+ &type, &arg1, &arg2, &help_topic);
+ if (command == DEBUG_CONTINUE || command == DEBUG_STEP)
+ {
+ if (!game->is_running)
+ {
+ if_print_debug ("The game is no longer running.\n");
+ continue;
+ }
+
+ debug->single_step = (command == DEBUG_STEP);
+ break;
+ }
+ else if (command == DEBUG_QUIT)
+ {
+ /*
+ * If the game is not running, we can't halt it, and we don't need
+ * to confirm the quit (either the player "quit" or the game
+ * completed), so leave the dialog loop.
+ */
+ if (!game->is_running)
+ break;
+
+ /*
+ * The game is still running, so confirm quit by requiring a repeat,
+ * or if this is the confirmation, force the game to a halt.
+ */
+ if (!debug->quit_pending)
+ {
+ if_print_debug ("Use 'quit' again to confirm, or another"
+ " debugger command to cancel.\n");
+ debug->quit_pending = TRUE;
+ continue;
+ }
+
+ /* Drop printfilter contents and quit the game. */
+ pf_empty (filter);
+ run_quit (game);
+
+ /* Just in case... */
+ if_print_debug ("Unable to quit from the game. Sorry.\n");
+ continue;
+ }
+
+ /* Dispatch the remaining debugging commands, and clear quit flag. */
+ debug_dispatch (game, command, type, arg1, arg2, help_topic);
+ debug->quit_pending = FALSE;
+ }
+
+ /* Restart time, and clear any pending game quit. */
+ var_set_elapsed_seconds (vars, debug->elapsed_seconds);
+ debug->quit_pending = FALSE;
+}
+
+
+/*
+ * debug_run_command()
+ *
+ * Handle a single debugging command line from the outside world. Returns
+ * TRUE if valid, FALSE if invalid (parse failed, not understood).
+ */
+sc_bool
+debug_run_command (sc_gameref_t game, const sc_char *debug_command)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+ sc_command_t command, help_topic;
+ sc_command_type_t type;
+ sc_int arg1, arg2;
+
+ /* If debugging disallowed (not initialized), refuse the call. */
+ if (debug)
+ {
+ /*
+ * Parse the command string passed in, and return FALSE if the parse
+ * fails, or if it returns DEBUG_CONTINUE, DEBUG_STEP, or DEBUG_QUIT,
+ * none of which make any sense in this context.
+ */
+ command = debug_parse_command (debug_command,
+ &type, &arg1, &arg2, &help_topic);
+ if (command == DEBUG_NONE
+ || command == DEBUG_CONTINUE || command == DEBUG_STEP
+ || command == DEBUG_QUIT)
+ return FALSE;
+
+ /* Dispatch the remaining debugging commands, return successfully. */
+ debug_dispatch (game, command, type, arg1, arg2, help_topic);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * debug_cmd_debugger()
+ *
+ * Called by the run main loop on user "debug" command request. Prints
+ * a polite refusal if debugging is not enabled, otherwise runs a debugging
+ * dialog. Uses if_print_string() as this isn't debug output.
+ */
+sc_bool
+debug_cmd_debugger (sc_gameref_t game)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug)
+ debug_dialog (game);
+ else
+ if_print_string ("SCARE's game debugger is not enabled. Sorry.\n");
+
+ /*
+ * Set as administrative command, so as not to consume a game turn, and
+ * return successfully.
+ */
+ game->is_admin = TRUE;
+ return TRUE;
+}
+
+
+/*
+ * debug_game_started()
+ * debug_game_ended()
+ *
+ * The first is called on entry to the game main loop, and gives us a chance
+ * to look at things before any turns are run, and to set watchpoints to
+ * catch things in games that use catch-all command tasks on startup (The PK
+ * Girl, for example).
+ *
+ * The second is called on exit from the game, and may make a final sweep for
+ * watchpoints and offer the debug dialog one last time.
+ */
+void
+debug_game_started (sc_gameref_t game)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug)
+ {
+ /* Starting a new game, or a restore or undo of an old one? */
+ if (!gs_room_seen (game, gs_playerroom (game)))
+ {
+ /*
+ * It's a new game starting or restarting. Print a banner, and
+ * run the debugger dialog.
+ */
+ if_print_debug ("\n--- SCARE " SCARE_VERSION SCARE_PATCH_LEVEL
+ " Game Debugger\n"
+ "--- Type 'help' for a list of commands.\n");
+ debug_dialog (game);
+ }
+ else
+ {
+ /*
+ * It's a restore or undo through memos, so run the dialog only if
+ * single-stepping; no need to check watchpoints for this case as
+ * none can be set -- no undo.
+ */
+ if (debug->single_step)
+ debug_dialog (game);
+ }
+ }
+}
+
+void
+debug_game_ended (sc_gameref_t game)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug)
+ {
+ /*
+ * Using our carnal knowledge of the run main loop, we know here that
+ * if the loop exited with do_restart or do_restore, we'll get a call to
+ * debug_game_start() when the loop restarts. So in this case, ignore
+ * the call (even if single stepping).
+ */
+ if (game->do_restart || game->do_restore)
+ return;
+
+ /*
+ * Check for any final watchpoints, and print a message describing why
+ * we're here. Suppress the check for watchpoints if the user exited
+ * the game, as it'll only be a repeat of any found last turn update.
+ */
+ if (!game->is_running)
+ {
+ if (game->has_completed)
+ {
+ debug_check_watchpoints (game);
+ if_print_debug ("\n--- The game has completed.\n");
+ }
+ else
+ if_print_debug ("\n--- The game has exited.\n");
+ }
+ else
+ {
+ debug_check_watchpoints (game);
+ if_print_debug ("\n--- The game is still running!\n");
+ }
+
+ /* Run a final dialog. */
+ debug_dialog (game);
+ }
+}
+
+
+/*
+ * debug_turn_update()
+ *
+ * Called after each turn by the main game loop. Checks for any set
+ * watchpoints, and triggers a debug dialog when any fire.
+ */
+void
+debug_turn_update (sc_gameref_t game)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug)
+ {
+ /*
+ * Again using carnal knowledge of the run main loop, if we're in
+ * mid-wait, ignore the call. Also, ignore the call if the game is
+ * no longer running, as we'll see a debug_game_ended() call come
+ * along to handle that.
+ */
+ if (game->waitcounter > 0 || !game->is_running)
+ return;
+
+ /*
+ * Run debugger dialog if any watchpoints triggered, or if single
+ * stepping (even if none triggered).
+ */
+ if (debug_check_watchpoints (game) || debug->single_step)
+ debug_dialog (game);
+ }
+}
+
+
+/*
+ * debug_set_enabled()
+ * debug_get_enabled()
+ *
+ * Enable/disable debugging, and return debugging status. Debugging is
+ * enabled when there is a debugger reference in the game, and disabled
+ * when it's NULL -- that's the flag. To avoid lugging about all the
+ * watchpoint memory with a game, debugger data is allocated on enabling,
+ * and free'd on disabling; as a result, any set watchpoints are lost on
+ * disabling.
+ */
+void
+debug_set_enabled (sc_gameref_t game, sc_bool enable)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+
+ /*
+ * If enabling and not already enabled, or disabling and not already
+ * disabled, either initialize or finalize..
+ */
+ if ((enable && !debug) || (!enable && debug))
+ {
+ /* Initialize or finalize debugging, as appropriate. */
+ if (enable)
+ debug_initialize (game);
+ else
+ debug_finalize (game);
+ }
+}
+
+sc_bool
+debug_get_enabled (sc_gameref_t game)
+{
+ const sc_debuggerref_t debug = debug_get_debugger (game);
+
+ return debug != NULL;
+}
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/adrift/scevents.cpp b/engines/glk/adrift/scevents.cpp
new file mode 100644
index 0000000..18d95b1
--- /dev/null
+++ b/engines/glk/adrift/scevents.cpp
@@ -0,0 +1,855 @@
+/* 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/adrift/scare.h"
+#include "glk/adrift/scprotos.h"
+#include "glk/adrift/scgamest.h"
+
+namespace Glk {
+namespace Adrift {
+
+/*
+ * Module notes:
+ *
+ * o Event pause and resume tasks need more testing.
+ */
+
+/* Trace flag, set before running. */
+static sc_bool evt_trace = FALSE;
+
+
+/*
+ * evt_any_task_in_state()
+ *
+ * Return TRUE if any task at all matches the given completion state.
+ */
+static sc_bool
+evt_any_task_in_state (sc_gameref_t game, sc_bool state)
+{
+ sc_int task;
+
+ /* Scan tasks for any whose completion matches input. */
+ for (task = 0; task < gs_task_count (game); task++)
+ {
+ if (gs_task_done (game, task) == state)
+ return TRUE;
+ }
+
+ /* No tasks matched. */
+ return FALSE;
+}
+
+
+/*
+ * evt_can_see_event()
+ *
+ * Return TRUE if player is in the right room for event text.
+ */
+sc_bool
+evt_can_see_event (sc_gameref_t game, sc_int event)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[5];
+ sc_int type;
+
+ /* Check room list for the event and return it. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Where";
+ vt_key[3].string = "Type";
+ type = prop_get_integer (bundle, "I<-siss", vt_key);
+ switch (type)
+ {
+ case ROOMLIST_NO_ROOMS:
+ return FALSE;
+ case ROOMLIST_ALL_ROOMS:
+ return TRUE;
+
+ case ROOMLIST_ONE_ROOM:
+ vt_key[3].string = "Room";
+ return prop_get_integer (bundle, "I<-siss", vt_key)
+ == gs_playerroom (game);
+
+ case ROOMLIST_SOME_ROOMS:
+ vt_key[3].string = "Rooms";
+ vt_key[4].integer = gs_playerroom (game);
+ return prop_get_boolean (bundle, "B<-sissi", vt_key);
+
+ default:
+ sc_fatal ("evt_can_see_event: invalid type, %ld\n", type);
+ return FALSE;
+ }
+}
+
+
+/*
+ * evt_move_object()
+ *
+ * Move an object from within an event.
+ */
+static void
+evt_move_object (sc_gameref_t game, sc_int object, sc_int destination)
+{
+ /* Ignore negative values of object. */
+ if (object >= 0)
+ {
+ if (evt_trace)
+ {
+ sc_trace ("Event: moving object %ld to room %ld\n",
+ object, destination);
+ }
+
+ /* Move object depending on destination. */
+ switch (destination)
+ {
+ case -1: /* Hidden. */
+ gs_object_make_hidden (game, object);
+ break;
+
+ case 0: /* Held by player. */
+ gs_object_player_get (game, object);
+ break;
+
+ case 1: /* Same room as player. */
+ gs_object_to_room (game, object, gs_playerroom (game));
+ break;
+
+ default:
+ if (destination < gs_room_count (game) + 2)
+ gs_object_to_room (game, object, destination - 2);
+ else
+ {
+ sc_int roomgroup, room;
+
+ roomgroup = destination - gs_room_count (game) - 2;
+ room = lib_random_roomgroup_member (game, roomgroup);
+ gs_object_to_room (game, object, room);
+ }
+ break;
+ }
+
+ /*
+ * If static, mark as no longer unmoved.
+ *
+ * TODO Is this the only place static objects can be moved? And just
+ * how static is a static object if it's moveable, anyway?
+ */
+ if (obj_is_static (game, object))
+ gs_set_object_static_unmoved (game, object, FALSE);
+ }
+}
+
+
+/*
+ * evt_fixup_v390_v380_immediate_restart()
+ *
+ * Versions 3.9 and 3.8 differ from version 4.0 on immediate restart; they
+ * "miss" the event start actions and move one step into the event without
+ * comment. It's arguable if this is a feature or a bug; nevertheless, we
+ * can do the same thing here, though it's ugly.
+ */
+static sc_bool
+evt_fixup_v390_v380_immediate_restart (sc_gameref_t game, sc_int event)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_int version;
+
+ vt_key[0].string = "Version";
+ version = prop_get_integer (bundle, "I<-s", vt_key);
+ if (version < TAF_VERSION_400)
+ {
+ sc_int time1, time2;
+
+ if (evt_trace)
+ sc_trace ("Event: applying 3.9/3.8 restart fixup\n");
+
+ /* Set to running state. */
+ gs_set_event_state (game, event, ES_RUNNING);
+
+ /* Set up event time to be one less than a proper start. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Time1";
+ time1 = prop_get_integer (bundle, "I<-sis", vt_key);
+ vt_key[2].string = "Time2";
+ time2 = prop_get_integer (bundle, "I<-sis", vt_key);
+ gs_set_event_time (game, event, sc_randomint (time1, time2) - 1);
+ }
+
+ /* Return TRUE if we applied the fixup. */
+ return version < TAF_VERSION_400;
+}
+
+
+/*
+ * evt_start_event()
+ *
+ * Change an event from WAITING to RUNNING.
+ */
+static void
+evt_start_event (sc_gameref_t game, sc_int event)
+{
+ const sc_filterref_t filter = gs_get_filter (game);
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[4];
+ sc_int time1, time2, obj1, obj1dest;
+
+ if (evt_trace)
+ sc_trace ("Event: starting event %ld\n", event);
+
+ /* If event is visible, print its start text. */
+ if (evt_can_see_event (game, event))
+ {
+ const sc_char *starttext;
+
+ /* Get and print start text. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "StartText";
+ starttext = prop_get_string (bundle, "S<-sis", vt_key);
+ if (!sc_strempty (starttext))
+ {
+ pf_buffer_string (filter, starttext);
+ pf_buffer_character (filter, '\n');
+ }
+
+ /* Handle any associated resource. */
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 0;
+ res_handle_resource (game, "sisi", vt_key);
+ }
+
+ /* Move event object to destination. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Obj1";
+ obj1 = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ vt_key[2].string = "Obj1Dest";
+ obj1dest = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ evt_move_object (game, obj1, obj1dest);
+
+ /* Set the event's state and time. */
+ gs_set_event_state (game, event, ES_RUNNING);
+
+ vt_key[2].string = "Time1";
+ time1 = prop_get_integer (bundle, "I<-sis", vt_key);
+ vt_key[2].string = "Time2";
+ time2 = prop_get_integer (bundle, "I<-sis", vt_key);
+ gs_set_event_time (game, event, sc_randomint (time1, time2));
+
+ if (evt_trace)
+ sc_trace ("Event: start event handling done, %ld\n", event);
+}
+
+
+/*
+ * evt_get_starter_type()
+ *
+ * Return the starter type for an event.
+ */
+static sc_int
+evt_get_starter_type (sc_gameref_t game, sc_int event)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_int startertype;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "StarterType";
+ startertype = prop_get_integer (bundle, "I<-sis", vt_key);
+
+ return startertype;
+}
+
+
+/*
+ * evt_finish_event()
+ *
+ * Move an event to FINISHED, or restart it.
+ */
+static void
+evt_finish_event (sc_gameref_t game, sc_int event)
+{
+ const sc_filterref_t filter = gs_get_filter (game);
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[4];
+ sc_int obj2, obj2dest, obj3, obj3dest;
+ sc_int task, startertype, restarttype;
+ sc_bool taskdir;
+
+ if (evt_trace)
+ sc_trace ("Event: finishing event %ld\n", event);
+
+ /* Set up invariant parts of the key. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ /* If event is visible, print its finish text. */
+ if (evt_can_see_event (game, event))
+ {
+ const sc_char *finishtext;
+
+ /* Get and print finish text. */
+ vt_key[2].string = "FinishText";
+ finishtext = prop_get_string (bundle, "S<-sis", vt_key);
+ if (!sc_strempty (finishtext))
+ {
+ pf_buffer_string (filter, finishtext);
+ pf_buffer_character (filter, '\n');
+ }
+
+ /* Handle any associated resource. */
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 4;
+ res_handle_resource (game, "sisi", vt_key);
+ }
+
+ /* Move event objects to destination. */
+ vt_key[2].string = "Obj2";
+ obj2 = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ vt_key[2].string = "Obj2Dest";
+ obj2dest = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ evt_move_object (game, obj2, obj2dest);
+
+ vt_key[2].string = "Obj3";
+ obj3 = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ vt_key[2].string = "Obj3Dest";
+ obj3dest = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ evt_move_object (game, obj3, obj3dest);
+
+ /* See if there is an affected task. */
+ vt_key[2].string = "TaskAffected";
+ task = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ if (task >= 0)
+ {
+ vt_key[2].string = "TaskFinished";
+ taskdir = !prop_get_boolean (bundle, "B<-sis", vt_key);
+ if (task_can_run_task_directional (game, task, taskdir))
+ {
+ if (evt_trace)
+ {
+ sc_trace ("Event: event running task %ld, %s\n",
+ task, taskdir ? "forwards" : "backwards");
+ }
+
+ task_run_task (game, task, taskdir);
+ }
+ else
+ {
+ if (evt_trace)
+ sc_trace ("Event: event can't run task %ld\n", task);
+ }
+ }
+
+ /* Handle possible restart. */
+ vt_key[2].string = "RestartType";
+ restarttype = prop_get_integer (bundle, "I<-sis", vt_key);
+ switch (restarttype)
+ {
+ case 0: /* Don't restart. */
+ startertype = evt_get_starter_type (game, event);
+ switch (startertype)
+ {
+ case 1: /* Immediate. */
+ case 2: /* Random delay. */
+ case 3: /* After task. */
+ gs_set_event_state (game, event, ES_FINISHED);
+ gs_set_event_time (game, event, 0);
+ break;
+
+ default:
+ sc_fatal ("evt_finish_event:"
+ " unknown value for starter type, %ld\n", startertype);
+ }
+ break;
+
+ case 1: /* Restart immediately. */
+ if (evt_fixup_v390_v380_immediate_restart (game, event))
+ break;
+ else
+ evt_start_event (game, event);
+ break;
+
+ case 2: /* Restart after delay. */
+ startertype = evt_get_starter_type (game, event);
+ switch (startertype)
+ {
+ case 1: /* Immediate. */
+ if (evt_fixup_v390_v380_immediate_restart (game, event))
+ break;
+ else
+ evt_start_event (game, event);
+ break;
+
+ case 2: /* Random delay. */
+ {
+ sc_int start, end;
+
+ gs_set_event_state (game, event, ES_WAITING);
+ vt_key[2].string = "StartTime";
+ start = prop_get_integer (bundle, "I<-sis", vt_key);
+ vt_key[2].string = "EndTime";
+ end = prop_get_integer (bundle, "I<-sis", vt_key);
+ gs_set_event_time (game, event, sc_randomint (start, end));
+ break;
+ }
+
+ case 3: /* After task. */
+ gs_set_event_state (game, event, ES_AWAITING);
+ gs_set_event_time (game, event, 0);
+ break;
+
+ default:
+ sc_fatal ("evt_finish_event: unknown StarterType\n");
+ }
+ break;
+
+ default:
+ sc_fatal ("evt_finish_event: unknown RestartType\n");
+ }
+
+ if (evt_trace)
+ sc_trace ("Event: finish event handling done, %ld\n", event);
+}
+
+
+/*
+ * evt_has_starter_task()
+ * evt_starter_task_is_complete()
+ * evt_pauser_task_is_complete()
+ * evt_resumer_task_is_complete()
+ *
+ * Return the status of start, pause and resume states of an event.
+ */
+static sc_bool
+evt_has_starter_task (sc_gameref_t game, sc_int event)
+{
+ sc_int startertype;
+
+ startertype = evt_get_starter_type (game, event);
+ return startertype == 3;
+}
+
+static sc_bool
+evt_starter_task_is_complete (sc_gameref_t game, sc_int event)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_int task;
+ sc_bool start;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "TaskNum";
+ task = prop_get_integer (bundle, "I<-sis", vt_key);
+
+ start = FALSE;
+ if (task == 0)
+ {
+ if (evt_any_task_in_state (game, TRUE))
+ start = TRUE;
+ }
+ else if (task > 0)
+ {
+ if (gs_task_done (game, task - 1))
+ start = TRUE;
+ }
+
+ return start;
+}
+
+static sc_bool
+evt_pauser_task_is_complete (sc_gameref_t game, sc_int event)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_int pausetask;
+ sc_bool completed, pause;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ vt_key[2].string = "PauseTask";
+ pausetask = prop_get_integer (bundle, "I<-sis", vt_key);
+ vt_key[2].string = "PauserCompleted";
+ completed = !prop_get_boolean (bundle, "B<-sis", vt_key);
+
+ pause = FALSE;
+ if (pausetask == 1)
+ {
+ if (evt_any_task_in_state (game, completed))
+ pause = TRUE;
+ }
+ else if (pausetask > 1)
+ {
+ if (completed == gs_task_done (game, pausetask - 2))
+ pause = TRUE;
+ }
+
+ return pause;
+}
+
+static sc_bool
+evt_resumer_task_is_complete (sc_gameref_t game, sc_int event)
+{
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[3];
+ sc_int resumetask;
+ sc_bool completed, resume;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ vt_key[2].string = "ResumeTask";
+ resumetask = prop_get_integer (bundle, "I<-sis", vt_key);
+ vt_key[2].string = "ResumerCompleted";
+ completed = !prop_get_boolean (bundle, "B<-sis", vt_key);
+
+ resume = FALSE;
+ if (resumetask == 1)
+ {
+ if (evt_any_task_in_state (game, completed))
+ resume = TRUE;
+ }
+ else if (resumetask > 1)
+ {
+ if (completed == gs_task_done (game, resumetask - 2))
+ resume = TRUE;
+ }
+
+ return resume;
+}
+
+
+/*
+ * evt_handle_preftime_notifications()
+ *
+ * Print messages and handle resources for the event where we're in mid-event
+ * and getting close to some number of turns from its end.
+ */
+static void
+evt_handle_preftime_notifications (sc_gameref_t game, sc_int event)
+{
+ const sc_filterref_t filter = gs_get_filter (game);
+ const sc_prop_setref_t bundle = gs_get_bundle (game);
+ sc_vartype_t vt_key[4];
+ sc_int preftime1, preftime2;
+ const sc_char *preftext;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ vt_key[2].string = "PrefTime1";
+ preftime1 = prop_get_integer (bundle, "I<-sis", vt_key);
+ if (preftime1 == gs_event_time (game, event))
+ {
+ vt_key[2].string = "PrefText1";
+ preftext = prop_get_string (bundle, "S<-sis", vt_key);
+ if (!sc_strempty (preftext))
+ {
+ pf_buffer_string (filter, preftext);
+ pf_buffer_character (filter, '\n');
+ }
+
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 2;
+ res_handle_resource (game, "sisi", vt_key);
+ }
+
+ vt_key[2].string = "PrefTime2";
+ preftime2 = prop_get_integer (bundle, "I<-sis", vt_key);
+ if (preftime2 == gs_event_time (game, event))
+ {
+ vt_key[2].string = "PrefText2";
+ preftext = prop_get_string (bundle, "S<-sis", vt_key);
+ if (!sc_strempty (preftext))
+ {
+ pf_buffer_string (filter, preftext);
+ pf_buffer_character (filter, '\n');
+ }
+
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 3;
+ res_handle_resource (game, "sisi", vt_key);
+ }
+}
+
+
+/*
+ * evt_tick_event()
+ *
+ * Attempt to advance an event by one turn.
+ */
+static void
+evt_tick_event (sc_gameref_t game, sc_int event)
+{
+ if (evt_trace)
+ {
+ sc_trace ("Event: ticking event %ld: state %ld, time %ld\n", event,
+ gs_event_state (game, event), gs_event_time (game, event));
+ }
+
+ /* Handle call based on current event state. */
+ switch (gs_event_state (game, event))
+ {
+ case ES_WAITING:
+ {
+ if (evt_trace)
+ sc_trace ("Event: ticking waiting event %ld\n", event);
+
+ /*
+ * Because we also tick an event that goes from waiting to running,
+ * events started here will tick through RUNNING too, and have their
+ * time decremented. To get around this, so that the timer for one-
+ * shot events doesn't look one lower than it should after this
+ * transition, we need to set the initial time for events that start
+ * as soon as the game starts to one greater than that set by
+ * evt_start_time(). Here's the hack to do that; if the event starts
+ * immediately, its time will already be zero, even before decrement,
+ * which is how we tell which events to apply this hack to.
+ *
+ * TODO This seems to work, but also seems very dodgy.
+ */
+ if (gs_event_time (game, event) == 0)
+ {
+ evt_start_event (game, event);
+
+ /* If the event time was set to zero, finish immediately. */
+ if (gs_event_time (game, event) <= 0)
+ evt_finish_event (game, event);
+ else
+ gs_set_event_time (game, event, gs_event_time (game, event) + 1);
+ break;
+ }
+
+ /*
+ * Decrement the event's time, and if it goes to zero, start running
+ * the event.
+ */
+ gs_decrement_event_time (game, event);
+
+ if (gs_event_time (game, event) <= 0)
+ {
+ evt_start_event (game, event);
+
+ /* If the event time was set to zero, finish immediately. */
+ if (gs_event_time (game, event) <= 0)
+ evt_finish_event (game, event);
+ }
+ }
+ break;
+
+ case ES_RUNNING:
+ {
+ if (evt_trace)
+ sc_trace ("Event: ticking running event %ld\n", event);
+
+ /*
+ * Re-check the starter task; if it's no longer completed, we need
+ * to set the event back to waiting on task.
+ */
+ if (evt_has_starter_task (game, event))
+ {
+ if (!evt_starter_task_is_complete (game, event))
+ {
+ if (evt_trace)
+ sc_trace ("Event: starter task not complete\n");
+
+ gs_set_event_state (game, event, ES_AWAITING);
+ gs_set_event_time (game, event, 0);
+ break;
+ }
+ }
+
+ /* If the pauser has completed, but resumer not, pause this event. */
+ if (evt_pauser_task_is_complete (game, event)
+ && !evt_resumer_task_is_complete (game, event))
+ {
+ if (evt_trace)
+ sc_trace ("Event: pause complete\n");
+
+ gs_set_event_state (game, event, ES_PAUSED);
+ break;
+ }
+
+ /*
+ * Decrement the event's time, and print any notifications for a set
+ * number of turns from the event end.
+ */
+ gs_decrement_event_time (game, event);
+
+ if (evt_can_see_event (game, event))
+ evt_handle_preftime_notifications (game, event);
+
+ /* If the time goes to zero, finish running the event. */
+ if (gs_event_time (game, event) <= 0)
+ evt_finish_event (game, event);
+ }
+ break;
+
+ case ES_AWAITING:
+ {
+ if (evt_trace)
+ sc_trace ("Event: ticking awaiting event %ld\n", event);
+
+ /*
+ * Check the starter task. If it's completed, start running the
+ * event.
+ */
+ if (evt_starter_task_is_complete (game, event))
+ {
+ evt_start_event (game, event);
+
+ /* If the event time was set to zero, finish immediately. */
+ if (gs_event_time (game, event) <= 0)
+ evt_finish_event (game, event);
+ else
+ {
+ /*
+ * If the pauser has completed, but resumer not, immediately
+ * also pause this event.
+ */
+ if (evt_pauser_task_is_complete (game, event)
+ && !evt_resumer_task_is_complete (game, event))
+ {
+ if (evt_trace)
+ sc_trace ("Event: pause complete, immediate pause\n");
+
+ gs_set_event_state (game, event, ES_PAUSED);
+ }
+ }
+ }
+ }
+ break;
+
+ case ES_FINISHED:
+ {
+ if (evt_trace)
+ sc_trace ("Event: ticking finished event %ld\n", event);
+
+ /*
+ * Check the starter task; if it's not completed, we need to set the
+ * event back to waiting on task.
+ *
+ * A completed event needs to go back to waiting on its task, but we
+ * don't want to set it there as soon as the event finishes. We need
+ * to wait for the starter task to first become undone, otherwise the
+ * event just cycles endlessly, and they don't in Adrift itself. Here
+ * is where we wait for starter tasks to become undone.
+ */
+ if (evt_has_starter_task (game, event))
+ {
+ if (!evt_starter_task_is_complete (game, event))
+ {
+ if (evt_trace)
+ sc_trace ("Event: starter task not complete\n");
+
+ gs_set_event_state (game, event, ES_AWAITING);
+ gs_set_event_time (game, event, 0);
+ break;
+ }
+ }
+ }
+ break;
+
+ case ES_PAUSED:
+ {
+ if (evt_trace)
+ sc_trace ("Event: ticking paused event %ld\n", event);
+
+ /* If the resumer has completed, resume this event. */
+ if (evt_resumer_task_is_complete (game, event))
+ {
+ if (evt_trace)
+ sc_trace ("Event: resume complete\n");
+
+ gs_set_event_state (game, event, ES_RUNNING);
+ break;
+ }
+ }
+ break;
+
+ default:
+ sc_fatal ("evt_tick: invalid event state\n");
+ }
+
+ if (evt_trace)
+ {
+ sc_trace ("Event: after ticking event %ld: state %ld, time %ld\n", event,
+ gs_event_state (game, event), gs_event_time (game, event));
+ }
+}
+
+
+/*
+ * evt_tick_events()
+ *
+ * Attempt to advance each event by one turn.
+ */
+void
+evt_tick_events (sc_gameref_t game)
+{
+ sc_int event;
+
+ /*
+ * Tick all events. If an event transitions into a running state from a
+ * paused or waiting state, tick that event again.
+ */
+ for (event = 0; event < gs_event_count (game); event++)
+ {
+ sc_int prior_state, state;
+
+ /* Note current state, and tick event forwards. */
+ prior_state = gs_event_state (game, event);
+ evt_tick_event (game, event);
+
+ /*
+ * If the event went from paused or waiting to running, tick again.
+ * This looks dodgy, and probably is, but it does keep timers correct
+ * by only re-ticking events that have transitioned from non-running
+ * states to a running one, and not already-running events. This is
+ * in effect just adding a bit of turn processing to a tick that would
+ * otherwise change state alone; a bit of laziness, in other words.
+ */
+ state = gs_event_state (game, event);
+ if (state == ES_RUNNING
+ && (prior_state == ES_PAUSED || prior_state == ES_WAITING))
+ evt_tick_event (game, event);
+ }
+}
+
+
+/*
+ * evt_debug_trace()
+ *
+ * Set event tracing on/off.
+ */
+void
+evt_debug_trace (sc_bool flag)
+{
+ evt_trace = flag;
+}
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/adrift/scexpr.cpp b/engines/glk/adrift/scexpr.cpp
new file mode 100644
index 0000000..ed33860
--- /dev/null
+++ b/engines/glk/adrift/scexpr.cpp
@@ -0,0 +1,1677 @@
+/* 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/adrift/scare.h"
+#include "glk/adrift/scprotos.h"
+
+namespace Glk {
+namespace Adrift {
+
+/*
+ * Module notes:
+ *
+ * o The tokenizer doesn't differentiate between "&", "&&", and "and", but "&"
+ * is context sensitive -- either a logical and for numerics, or concaten-
+ * ation for strings. As a result, "&&" and "and" also work as string
+ * concatenators when used in string expressions. It may not be to spec,
+ * but we'll call this a "feature".
+ */
+
+/* Assorted definitions and constants. */
+enum { MAX_NESTING_DEPTH = 32 };
+static const sc_char NUL = '\0';
+static const sc_char PERCENT = '%';
+static const sc_char SINGLE_QUOTE = '\'';
+static const sc_char DOUBLE_QUOTE = '"';
+
+
+/*
+ * Tokens. Single character tokens are represented by their ascii value
+ * (0-255), others by values above 255. -1 represents a null token. Because
+ * '&' and '+' are context sensitive, the pseudo-token TOK_CONCATENATE
+ * serves to indicate string concatenation -- it's never returned by the
+ * tokenizer.
+ */
+enum
+{ TOK_NONE = -1,
+ TOK_ADD = '+', TOK_SUBTRACT = '-', TOK_MULTIPLY = '*', TOK_DIVIDE = '/',
+ TOK_AND = '&', TOK_OR = '|',
+ TOK_LPAREN = '(', TOK_RPAREN = ')', TOK_COMMA = ',', TOK_POWER = '^',
+ TOK_EQUAL = '=', TOK_GREATER = '>', TOK_LESS = '<',
+
+ TOK_IDENT = 256,
+ TOK_INTEGER, TOK_STRING, TOK_VARIABLE, TOK_UMINUS, TOK_UPLUS,
+ TOK_MOD, TOK_NOT_EQUAL, TOK_GREATER_EQ, TOK_LESS_EQ, TOK_IF,
+ TOK_MIN, TOK_MAX, TOK_EITHER, TOK_RANDOM, TOK_INSTR, TOK_LEN, TOK_VAL,
+ TOK_ABS, TOK_UPPER, TOK_LOWER, TOK_PROPER, TOK_RIGHT, TOK_LEFT, TOK_MID,
+ TOK_STR, TOK_CONCATENATE,
+ TOK_EOS
+};
+
+/*
+ * Small tables tying multicharacter tokens strings to tokens. At present,
+ * the string lengths for names are not used.
+ */
+typedef struct
+{
+ const sc_char *const name;
+ const sc_int length;
+ const sc_int token;
+} sc_expr_multichar_t;
+
+static const sc_expr_multichar_t FUNCTION_TOKENS[] = {
+ {"either", 6, TOK_EITHER},
+ {"proper", 6, TOK_PROPER}, {"pcase", 5, TOK_PROPER}, {"instr", 5, TOK_INSTR},
+ {"upper", 5, TOK_UPPER}, {"ucase", 5, TOK_UPPER},
+ {"lower", 5, TOK_LOWER}, {"lcase", 5, TOK_LOWER},
+ {"right", 5, TOK_RIGHT}, {"left", 4, TOK_LEFT},
+ {"rand", 4, TOK_RANDOM}, {"max", 3, TOK_MAX}, {"min", 3, TOK_MIN},
+ {"mod", 3, TOK_MOD}, {"abs", 3, TOK_ABS}, {"len", 3, TOK_LEN},
+ {"val", 3, TOK_VAL}, {"and", 3, TOK_AND}, {"mid", 3, TOK_MID},
+ {"str", 3, TOK_STR}, {"or", 2, TOK_OR}, {"if", 2, TOK_IF},
+ {NULL, 0, TOK_NONE}
+};
+static const sc_expr_multichar_t OPERATOR_TOKENS[] = {
+ {"&&", 2, TOK_AND}, {"||", 2, TOK_OR},
+ {"==", 2, TOK_EQUAL}, {"!=", 2, TOK_NOT_EQUAL},
+ {"<>", 2, TOK_NOT_EQUAL}, {">=", 2, TOK_GREATER_EQ}, {"<=", 2, TOK_LESS_EQ},
+ {NULL, 0, TOK_NONE}
+};
+
+
+/*
+ * expr_multichar_search()
+ *
+ * Multicharacter token table search, returns the matching token, or
+ * TOK_NONE if no match.
+ */
+static sc_int
+expr_multichar_search (const sc_char *name, const sc_expr_multichar_t *table)
+{
+ const sc_expr_multichar_t *entry;
+
+ /* Scan the table for a case-independent full string match. */
+ for (entry = table; entry->name; entry++)
+ {
+ if (sc_strcasecmp (name, entry->name) == 0)
+ break;
+ }
+
+ /* Return the token matched, or TOK_NONE. */
+ return entry->name ? entry->token : TOK_NONE;
+}
+
+
+/* Tokenizer variables. */
+static const sc_char *expr_expression = NULL;
+static sc_int expr_index = 0;
+static sc_vartype_t expr_token_value;
+static sc_char *expr_temporary = NULL;
+static sc_int expr_current_token = TOK_NONE;
+
+/*
+ * expr_tokenize_start()
+ * expr_tokenize_end()
+ *
+ * Start and wrap up expression string tokenization.
+ */
+static void
+expr_tokenize_start (const sc_char *expression)
+{
+ static sc_bool initialized = FALSE;
+
+ /* On first call only, verify the string lengths in the tables. */
+ if (!initialized)
+ {
+ const sc_expr_multichar_t *entry;
+
+ /* Compare table lengths with string lengths. */
+ for (entry = FUNCTION_TOKENS; entry->name; entry++)
+ {
+ if (entry->length != (sc_int) strlen (entry->name))
+ {
+ sc_fatal ("expr_tokenize_start:"
+ " token string length is wrong for \"%s\"\n",
+ entry->name);
+ }
+ }
+
+ for (entry = OPERATOR_TOKENS; entry->name; entry++)
+ {
+ if (entry->length != (sc_int) strlen (entry->name))
+ {
+ sc_fatal ("expr_tokenize_start:"
+ " operator string length is wrong for \"%s\"\n",
+ entry->name);
+ }
+ }
+
+ initialized = TRUE;
+ }
+
+ /* Save expression, and restart index. */
+ expr_expression = expression;
+ expr_index = 0;
+
+ /* Allocate a temporary token value/literals string. */
+ assert (!expr_temporary);
+ expr_temporary = (sc_char *)sc_malloc (strlen (expression) + 1);
+
+ /* Reset last token to none. */
+ expr_current_token = TOK_NONE;
+}
+
+static void
+expr_tokenize_end (void)
+{
+ /* Deallocate temporary strings, clear expression. */
+ sc_free (expr_temporary);
+ expr_temporary = NULL;
+ expr_expression = NULL;
+ expr_index = 0;
+ expr_current_token = TOK_NONE;
+}
+
+
+/*
+ * expr_next_token_unadjusted()
+ * expr_next_token()
+ *
+ * Return the next token from the current expression. The initial token may
+ * be adjusted into a unary +/- depending on the value of the previous token.
+ */
+static sc_int
+expr_next_token_unadjusted (sc_vartype_t *token_value)
+{
+ sc_int c;
+ assert (expr_expression);
+
+ /* Skip any and all leading whitespace. */
+ do
+ {
+ c = expr_expression[expr_index++];
+ }
+ while (sc_isspace (c) && c != NUL);
+
+ /* Return EOS if at expression end. */
+ if (c == NUL)
+ {
+ expr_index--;
+ return TOK_EOS;
+ }
+
+ /*
+ * Identify and return numerics. We deal only with unsigned numbers here;
+ * the unary +/- tokens take care of any integer sign issues.
+ */
+ else if (sc_isdigit (c))
+ {
+ sc_int value;
+
+ sscanf (expr_expression + expr_index - 1, "%ld", &value);
+
+ while (sc_isdigit (c) && c != NUL)
+ c = expr_expression[expr_index++];
+ expr_index--;
+
+ token_value->integer = value;
+ return TOK_INTEGER;
+ }
+
+ /* Identify and return variable references. */
+ else if (c == PERCENT)
+ {
+ sc_int index_;
+
+ /* Copy variable name. */
+ c = expr_expression[expr_index++];
+ for (index_ = 0; c != PERCENT && c != NUL;)
+ {
+ expr_temporary[index_++] = c;
+ c = expr_expression[expr_index++];
+ }
+ expr_temporary[index_++] = NUL;
+
+ if (c == NUL)
+ {
+ sc_error ("expr_next_token_unadjusted:"
+ " warning: unterminated variable name\n");
+ expr_index--;
+ }
+
+ /* Return a variable name. */
+ token_value->string = expr_temporary;
+ return TOK_VARIABLE;
+ }
+
+ /* Identify and return string literals. */
+ else if (c == DOUBLE_QUOTE || c == SINGLE_QUOTE)
+ {
+ sc_int index_;
+ sc_char quote;
+
+ /* Copy maximal string literal. */
+ quote = c;
+ c = expr_expression[expr_index++];
+ for (index_ = 0; c != quote && c != NUL;)
+ {
+ expr_temporary[index_++] = c;
+ c = expr_expression[expr_index++];
+ }
+ expr_temporary[index_++] = NUL;
+
+ if (c == NUL)
+ {
+ sc_error ("expr_next_token_unadjusted:"
+ " warning: unterminated string literal\n");
+ expr_index--;
+ }
+
+ /* Return string literal. */
+ token_value->string = expr_temporary;
+ return TOK_STRING;
+ }
+
+ /* Identify ids and other multicharacter tokens. */
+ else if (sc_isalpha (c))
+ {
+ sc_int index_, token;
+
+ /*
+ * Copy maximal alphabetical string. While an ident would normally
+ * be alpha followed by zero or more alnum, for Adrift purposes we
+ * use only alpha -- all idents should really be "functions", and
+ * in particular we want to see "mod7" as "mod" and 7 separately.
+ */
+ for (index_ = 0; sc_isalpha (c) && c != NUL;)
+ {
+ expr_temporary[index_++] = c;
+ c = expr_expression[expr_index++];
+ }
+ expr_index--;
+ expr_temporary[index_++] = NUL;
+
+ /*
+ * Check for a function name, and if known, return that, otherwise
+ * return a bare id.
+ */
+ token = expr_multichar_search (expr_temporary, FUNCTION_TOKENS);
+ if (token == TOK_NONE)
+ {
+ token_value->string = expr_temporary;
+ return TOK_IDENT;
+ }
+ else
+ return token;
+ }
+
+ /*
+ * Last chance check for two-character (multichar) operators, and if none
+ * then return a single-character token.
+ */
+ else
+ {
+ sc_char operator_[3];
+ sc_int token;
+
+ /*
+ * Build a two-character string. If we happen to be at the last
+ * expression character, we'll pick up the expression NUL into
+ * operator_[1], so no need to special case end of expression here.
+ */
+ operator_[0] = c;
+ operator_[1] = expr_expression[expr_index];
+ operator_[2] = NUL;
+
+ /* Search for this two-character operator. */
+ if (operator_[0] != NUL && operator_[1] != NUL)
+ {
+ token = expr_multichar_search (operator_, OPERATOR_TOKENS);
+ if (token != TOK_NONE)
+ {
+ /* Matched, so advance expression index and return this token. */
+ expr_index++;
+ return token;
+ }
+ }
+
+ /*
+ * No match, or at last expression character; return a single character
+ * token.
+ */
+ return c;
+ }
+}
+
+static sc_int
+expr_next_token (void)
+{
+ sc_int token;
+ sc_vartype_t token_value;
+
+ /*
+ * Get the basic next token. We may adjust it later for unary minus/plus
+ * depending on what it is, and the prior token.
+ */
+ token_value.voidp = NULL;
+ token = expr_next_token_unadjusted (&token_value);
+
+ /* Special handling for unary minus/plus signs. */
+ if (token == TOK_SUBTRACT || token == TOK_ADD)
+ {
+ /*
+ * Unary minus/plus if prior token was an operator or a comparison, left
+ * parenthesis, or comma, or if there was no prior token.
+ */
+ switch (expr_current_token)
+ {
+ case TOK_MOD:
+ case TOK_POWER:
+ case TOK_ADD:
+ case TOK_SUBTRACT:
+ case TOK_MULTIPLY:
+ case TOK_DIVIDE:
+ case TOK_AND:
+ case TOK_OR:
+ case TOK_EQUAL:
+ case TOK_GREATER:
+ case TOK_LESS:
+ case TOK_NOT_EQUAL:
+ case TOK_GREATER_EQ:
+ case TOK_LESS_EQ:
+ case TOK_LPAREN:
+ case TOK_COMMA:
+ case TOK_NONE:
+ token = (token == TOK_SUBTRACT) ? TOK_UMINUS : TOK_UPLUS;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Set current token to the one just found, and return it. */
+ expr_current_token = token;
+ expr_token_value = token_value;
+ return token;
+}
+
+
+/*
+ * expr_current_token_value()
+ *
+ * Return the token value of the current token. Undefined if the current
+ * token is not numeric, an id, or a variable.
+ */
+static void
+expr_current_token_value (sc_vartype_t *value)
+{
+ /* Quick check that the value is a valid one. */
+ switch (expr_current_token)
+ {
+ case TOK_INTEGER:
+ case TOK_STRING:
+ case TOK_VARIABLE:
+ case TOK_IDENT:
+ break;
+
+ default:
+ sc_fatal ("expr_current_token_value:"
+ " taking undefined token value, %ld\n", expr_current_token);
+ }
+
+ /* Return value. */
+ *value = expr_token_value;
+}
+
+
+/*
+ * Evaluation values stack, uses a variable type so it can contain both
+ * integers and strings, and flags strings for possible garbage collection
+ * on parse errors.
+ */
+typedef struct
+{
+ sc_bool is_collectible;
+ sc_vartype_t value;
+} sc_stack_t;
+static sc_stack_t expr_eval_stack[MAX_NESTING_DEPTH];
+static sc_int expr_eval_stack_index = 0;
+
+/* Variables set to reference for %...% values. */
+static sc_var_setref_t expr_varset = NULL;
+
+/*
+ * expr_eval_start()
+ *
+ * Reset the evaluation stack to an empty state, and register the variables
+ * set to use when referencing %...% variables.
+ */
+static void
+expr_eval_start (sc_var_setref_t vars)
+{
+ expr_eval_stack_index = 0;
+ expr_varset = vars;
+}
+
+
+/*
+ * expr_eval_garbage_collect()
+ *
+ * In case of parse error, empty out and free all collectible malloced
+ * strings left in the evaluation array.
+ */
+static void
+expr_eval_garbage_collect (void)
+{
+ sc_int index_;
+
+ /*
+ * Find and free all collectible strings still in the stack. We have to
+ * free through mutable string rather than const string.
+ */
+ for (index_ = 0; index_ < expr_eval_stack_index; index_++)
+ {
+ if (expr_eval_stack[index_].is_collectible)
+ sc_free (expr_eval_stack[index_].value.mutable_string);
+ }
+
+ /* Reset the stack index, for clarity and neatness. */
+ expr_eval_stack_index = 0;
+}
+
+
+/*
+ * expr_eval_push_integer()
+ * expr_eval_push_string()
+ * expr_eval_push_alloced_string()
+ *
+ * Push a value onto the values stack. Strings are malloc'ed and copied,
+ * and the copy is placed onto the stack, unless _alloced_string() is used;
+ * for this case, the input string is assumed to be already malloc'ed, and
+ * the caller should not subsequently free the string.
+ */
+static void
+expr_eval_push_integer (sc_int value)
+{
+ if (expr_eval_stack_index >= MAX_NESTING_DEPTH)
+ sc_fatal ("expr_eval_push_integer: stack overflow\n");
+
+ expr_eval_stack[expr_eval_stack_index].is_collectible = FALSE;
+ expr_eval_stack[expr_eval_stack_index++].value.integer = value;
+}
+
+static void
+expr_eval_push_string (const sc_char *value)
+{
+ sc_char *value_copy;
+
+ if (expr_eval_stack_index >= MAX_NESTING_DEPTH)
+ sc_fatal ("expr_eval_push_string: stack overflow\n");
+
+ /* Push a copy of value. */
+ value_copy = (sc_char *)sc_malloc (strlen (value) + 1);
+ strcpy (value_copy, value);
+ expr_eval_stack[expr_eval_stack_index].is_collectible = TRUE;
+ expr_eval_stack[expr_eval_stack_index++].value.mutable_string = value_copy;
+}
+
+static void
+expr_eval_push_alloced_string (sc_char *value)
+{
+ if (expr_eval_stack_index >= MAX_NESTING_DEPTH)
+ sc_fatal ("expr_eval_push_alloced_string: stack overflow\n");
+
+ expr_eval_stack[expr_eval_stack_index].is_collectible = TRUE;
+ expr_eval_stack[expr_eval_stack_index++].value.mutable_string = value;
+}
+
+
+/*
+ * expr_eval_pop_integer()
+ * expr_eval_pop_string()
+ *
+ * Pop values off the values stack. Returned strings are malloc'ed copies,
+ * and the caller is responsible for freeing them.
+ */
+static sc_int
+expr_eval_pop_integer (void)
+{
+ if (expr_eval_stack_index == 0)
+ sc_fatal ("expr_eval_pop_integer: stack underflow\n");
+
+ assert (!expr_eval_stack[expr_eval_stack_index - 1].is_collectible);
+ return expr_eval_stack[--expr_eval_stack_index].value.integer;
+}
+
+static sc_char *
+expr_eval_pop_string (void)
+{
+ if (expr_eval_stack_index == 0)
+ sc_fatal ("expr_eval_pop_string: stack underflow\n");
+
+ /* Returns mutable string rather than const string. */
+ assert (expr_eval_stack[expr_eval_stack_index - 1].is_collectible);
+ return expr_eval_stack[--expr_eval_stack_index].value.mutable_string;
+}
+
+
+/*
+ * expr_eval_result()
+ *
+ * Return the top of the values stack as the expression result.
+ */
+static void
+expr_eval_result (sc_vartype_t *vt_rvalue)
+{
+ if (expr_eval_stack_index != 1)
+ sc_fatal ("expr_eval_result: values stack not completed\n");
+
+ /* Clear down stack and return the top value. */
+ expr_eval_stack_index = 0;
+ *vt_rvalue = expr_eval_stack[0].value;
+}
+
+
+/*
+ * expr_eval_abs()
+ *
+ * Return the absolute value of the given sc_int. Replacement for labs(),
+ * avoids tying sc_int to long types too closely.
+ */
+static sc_int
+expr_eval_abs (sc_int value)
+{
+ return value < 0 ? -value : value;
+}
+
+
+/* Parse error jump buffer. */
+static jmp_buf expr_parse_error;
+
+/*
+ * expr_eval_action()
+ *
+ * Evaluate the effect of a token into the values stack.
+ */
+static void
+expr_eval_action (sc_int token)
+{
+ sc_vartype_t token_value;
+
+ switch (token)
+ {
+ /* Handle tokens representing stack pushes. */
+ case TOK_INTEGER:
+ expr_current_token_value (&token_value);
+ expr_eval_push_integer (token_value.integer);
+ break;
+
+ case TOK_STRING:
+ expr_current_token_value (&token_value);
+ expr_eval_push_string (token_value.string);
+ break;
+
+ case TOK_VARIABLE:
+ {
+ sc_vartype_t vt_rvalue;
+ sc_int type;
+
+ expr_current_token_value (&token_value);
+ if (!var_get (expr_varset, token_value.string, &type, &vt_rvalue))
+ {
+ sc_error ("expr_eval_action:"
+ " undefined variable, %s\n", token_value.string);
+ longjmp (expr_parse_error, 1);
+ }
+ switch (type)
+ {
+ case VAR_INTEGER:
+ expr_eval_push_integer (vt_rvalue.integer);
+ break;
+
+ case VAR_STRING:
+ expr_eval_push_string (vt_rvalue.string);
+ break;
+
+ default:
+ sc_fatal ("expr_eval_action: bad variable type\n");
+ }
+ break;
+ }
+
+ /* Handle tokens representing functions returning numeric. */
+ case TOK_IF:
+ {
+ sc_int test, val1, val2;
+
+ /* Pop the test and alternatives, and push back result. */
+ val2 = expr_eval_pop_integer ();
+ val1 = expr_eval_pop_integer ();
+ test = expr_eval_pop_integer ();
+ expr_eval_push_integer (test ? val1 : val2);
+ break;
+ }
+
+ case TOK_MAX:
+ case TOK_MIN:
+ {
+ sc_int argument_count, index_, result;
+
+ /* Get argument count off the top of the stack. */
+ argument_count = expr_eval_pop_integer ();
+ assert (argument_count > 0);
+
+ /* Find the max or min of these stacked values. */
+ result = expr_eval_pop_integer ();
+ for (index_ = 1; index_ < argument_count; index_++)
+ {
+ sc_int next;
+
+ next = expr_eval_pop_integer ();
+ switch (token)
+ {
+ case TOK_MAX:
+ result = (next > result) ? next : result;
+ break;
+
+ case TOK_MIN:
+ result = (next < result) ? next : result;
+ break;
+
+ default:
+ sc_fatal ("expr_eval_action: bad token, %ld\n", token);
+ }
+ }
+
+ /* Push back the result. */
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ case TOK_EITHER:
+ {
+ sc_int argument_count, pick, index_;
+ sc_int result = 0;
+
+ /* Get argument count off the top of the stack. */
+ argument_count = expr_eval_pop_integer ();
+ assert (argument_count > 0);
+
+ /*
+ * Pick one of the top N items at random, then unstack all N and
+ * push back the value of the one picked.
+ */
+ pick = sc_rand () % argument_count;
+ for (index_ = 0; index_ < argument_count; index_++)
+ {
+ sc_int val;
+
+ val = expr_eval_pop_integer ();
+ if (index_ == pick)
+ result = val;
+ }
+
+ /* Push back the result. */
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ case TOK_INSTR:
+ {
+ sc_char *val1, *val2, *search;
+ sc_int result;
+
+ /* Extract the two values to work on. */
+ val2 = expr_eval_pop_string ();
+ val1 = expr_eval_pop_string ();
+
+ /*
+ * Search for the second in the first. The result is the character
+ * position, starting at 1, or 0 if not found. Then free the popped
+ * strings, and push back the result.
+ */
+ search = (val1[0] != NUL) ? strstr (val1, val2) : NULL;
+ result = (!search) ? 0 : search - val1 + 1;
+ sc_free (val1);
+ sc_free (val2);
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ case TOK_LEN:
+ {
+ sc_char *val;
+ sc_int result;
+
+ /* Pop the top string, and push back its length. */
+ val = expr_eval_pop_string ();
+ result = strlen (val);
+ sc_free (val);
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ case TOK_VAL:
+ {
+ sc_char *val;
+ sc_int result = 0;
+
+ /*
+ * Extract the string at stack top, and try to convert, returning
+ * zero if conversion fails. Free the popped string, and push back
+ * the result.
+ */
+ val = expr_eval_pop_string ();
+ sscanf (val, "%ld", &result);
+ sc_free (val);
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ /* Handle tokens representing unary numeric operations. */
+ case TOK_UMINUS:
+ expr_eval_push_integer (-(expr_eval_pop_integer ()));
+ break;
+
+ case TOK_UPLUS:
+ break;
+
+ case TOK_ABS:
+ expr_eval_push_integer (expr_eval_abs (expr_eval_pop_integer ()));
+ break;
+
+ /* Handle tokens representing most binary numeric operations. */
+ case TOK_ADD:
+ case TOK_SUBTRACT:
+ case TOK_MULTIPLY:
+ case TOK_AND:
+ case TOK_OR:
+ case TOK_EQUAL:
+ case TOK_GREATER:
+ case TOK_LESS:
+ case TOK_NOT_EQUAL:
+ case TOK_GREATER_EQ:
+ case TOK_LESS_EQ:
+ case TOK_RANDOM:
+ {
+ sc_int val1, val2, result = 0;
+
+ /* Extract the two values to work on. */
+ val2 = expr_eval_pop_integer ();
+ val1 = expr_eval_pop_integer ();
+
+ /* Generate the result value. */
+ switch (token)
+ {
+ case TOK_ADD:
+ result = val1 + val2;
+ break;
+ case TOK_SUBTRACT:
+ result = val1 - val2;
+ break;
+ case TOK_MULTIPLY:
+ result = val1 * val2;
+ break;
+ case TOK_AND:
+ result = val1 && val2;
+ break;
+ case TOK_OR:
+ result = val1 || val2;
+ break;
+ case TOK_EQUAL:
+ result = val1 == val2;
+ break;
+ case TOK_GREATER:
+ result = val1 > val2;
+ break;
+ case TOK_LESS:
+ result = val1 < val2;
+ break;
+ case TOK_NOT_EQUAL:
+ result = val1 != val2;
+ break;
+ case TOK_GREATER_EQ:
+ result = val1 >= val2;
+ break;
+ case TOK_LESS_EQ:
+ result = val1 <= val2;
+ break;
+ case TOK_RANDOM:
+ result = sc_randomint (val1, val2);
+ break;
+ default:
+ sc_fatal ("expr_eval_action: bad token, %ld\n", token);
+ }
+
+ /* Put result back at top of stack. */
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ /* Handle division and modulus separately; they're "eccentric". */
+ case TOK_DIVIDE:
+ case TOK_MOD:
+ {
+ sc_int val1, val2, x, y, result = 0;
+
+ /* Extract the two values to work on, complain about division by 0. */
+ val2 = expr_eval_pop_integer ();
+ val1 = expr_eval_pop_integer ();
+ if (val2 == 0)
+ {
+ sc_error ("expr_eval_action: attempt to divide by zero\n");
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ /*
+ * ANSI/ISO C only defines integer division for positive values.
+ * Negative values usually work consistently across platforms, but are
+ * not guaranteed. For maximum portability, then, here we'll work
+ * carefully with positive integers only.
+ */
+ x = expr_eval_abs (val1);
+ y = expr_eval_abs (val2);
+
+ /* Generate the result value. */
+ switch (token)
+ {
+ case TOK_DIVIDE:
+ /*
+ * Adrift's division apparently works by dividing using floating
+ * point, then applying (asymmetrical) rounding, so we have to do
+ * the same here.
+ */
+ result = ((val1 < 0) == (val2 < 0))
+ ? ((x / y) + (((x % y) * 2 >= y) ? 1 : 0))
+ : -((x / y) + (((x % y) * 2 > y) ? 1 : 0));
+ break;
+
+ case TOK_MOD:
+ /*
+ * Adrift also breaks numerical consistency by defining mod in a
+ * conventional (non-rounded), way, so that A=(AdivB)*B+AmodB
+ * does not hold.
+ */
+ result = (val1 < 0) ? -(x % y) : (x % y);
+ break;
+
+ default:
+ sc_fatal ("expr_eval_action: bad token, %ld\n", token);
+ }
+
+ /* Put result back at top of stack. */
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ /* Handle power individually, to avoid needing a maths library. */
+ case TOK_POWER:
+ {
+ sc_int val1, val2, result;
+
+ /* Extract the two values to work on. */
+ val2 = expr_eval_pop_integer ();
+ val1 = expr_eval_pop_integer ();
+
+ /* Handle negative and zero power values first, as special cases. */
+ if (val2 == 0)
+ result = 1;
+ else if (val2 < 0)
+ {
+ if (val1 == 0)
+ {
+ sc_error ("expr_eval_action: attempt to divide by zero\n");
+ result = 0;
+ }
+ else if (val1 == 1)
+ result = val1;
+ else if (val1 == -1)
+ result = (-val2 & 1) ? val1 : -val1;
+ else
+ result = 0;
+ }
+ else
+ {
+ /* Raise to positive powers using the Russian Peasant algorithm. */
+ while ((val2 & 1) == 0)
+ {
+ val1 = val1 * val1;
+ val2 >>= 1;
+ }
+
+ result = val1;
+ val2 >>= 1;
+ while (val2 > 0)
+ {
+ val1 = val1 * val1;
+ if (val2 & 1)
+ result = result * val1;
+ val2 >>= 1;
+ }
+ }
+
+ /* Put result back at top of stack. */
+ expr_eval_push_integer (result);
+ break;
+ }
+
+ /* Handle tokens representing functions returning string. */
+ case TOK_LEFT:
+ case TOK_RIGHT:
+ {
+ sc_char *text;
+ sc_int length;
+
+ /*
+ * Extract the text and length. If length is longer than text, or
+ * negative, do nothing.
+ */
+ length = expr_eval_pop_integer ();
+ text = expr_eval_pop_string ();
+ if (length < 0 || length >= (sc_int) strlen (text))
+ {
+ expr_eval_push_alloced_string (text);
+ break;
+ }
+
+ /*
+ * Take the left or right segment -- for left, the operation is a
+ * simple truncation; for right, it's a memmove.
+ */
+ switch (token)
+ {
+ case TOK_LEFT:
+ text[length] = NUL;
+ break;
+
+ case TOK_RIGHT:
+ memmove (text, text + strlen (text) - length, length + 1);
+ break;
+
+ default:
+ sc_fatal ("expr_eval_action: bad token, %ld\n", token);
+ }
+
+ /* Put result back at top of stack. */
+ expr_eval_push_alloced_string (text);
+ break;
+ }
+
+ case TOK_MID:
+ {
+ sc_char *text;
+ sc_int length, start, limit;
+
+ /*
+ * Extract the text, start, and length, re-basing start from 1 to 0,
+ * and calculate the limit on characters available for the move.
+ */
+ length = expr_eval_pop_integer ();
+ start = expr_eval_pop_integer () - 1;
+ text = expr_eval_pop_string ();
+ limit = strlen (text);
+
+ /*
+ * Clamp ranges that roam outside the available text -- start less
+ * than 0 to 0, and greater than len(text) to len(text), and length
+ * less than 0 to 0, and off string end to string end.
+ */
+ if (start < 0)
+ start = 0;
+ else if (start > limit)
+ start = limit;
+ if (length < 0)
+ length = 0;
+ else if (length > limit - start)
+ length = limit - start;
+
+ /* Move substring, terminate, and put back at top of stack. */
+ memmove (text, text + start, length + 1);
+ text[length] = NUL;
+ expr_eval_push_alloced_string (text);
+ break;
+ }
+
+ case TOK_STR:
+ {
+ sc_int val;
+ sc_char buffer[32];
+
+ /*
+ * Extract the value, convert it, and push back the resulting string.
+ * The leading space on positive values matches the Runner.
+ */
+ val = expr_eval_pop_integer ();
+ sprintf (buffer, "% ld", val);
+ expr_eval_push_string (buffer);
+ break;
+ }
+
+
+ /* Handle tokens representing unary string operations. */
+ case TOK_UPPER:
+ case TOK_LOWER:
+ case TOK_PROPER:
+ {
+ sc_char *text;
+ sc_int index_;
+
+ /* Extract the value to work on. */
+ text = expr_eval_pop_string ();
+
+ /* Convert the entire string in place -- it's malloc'ed. */
+ for (index_ = 0; text[index_] != NUL; index_++)
+ {
+ switch (token)
+ {
+ case TOK_UPPER:
+ text[index_] = sc_toupper (text[index_]);
+ break;
+
+ case TOK_LOWER:
+ text[index_] = sc_tolower (text[index_]);
+ break;
+
+ case TOK_PROPER:
+ if (index_ == 0 || sc_isspace (text[index_ - 1]))
+ text[index_] = sc_toupper (text[index_]);
+ else
+ text[index_] = sc_tolower (text[index_]);
+ break;
+
+ default:
+ sc_fatal ("expr_eval_action: bad token, %ld\n", token);
+ }
+ }
+
+ /* Put result back at top of stack. */
+ expr_eval_push_alloced_string (text);
+ break;
+ }
+
+ /* Handle token representing binary string operation. */
+ case TOK_CONCATENATE:
+ {
+ sc_char *text1, *text2;
+
+ /* Extract the two texts to work on. */
+ text2 = expr_eval_pop_string ();
+ text1 = expr_eval_pop_string ();
+
+ /*
+ * Resize text1 to be long enough for both, and concatenate, then
+ * free text2, and push back the concatenation.
+ */
+ text1 = (sc_char *)sc_realloc (text1, strlen (text1) + strlen (text2) + 1);
+ strcat (text1, text2);
+ sc_free (text2);
+ expr_eval_push_alloced_string (text1);
+ break;
+ }
+
+ default:
+ sc_fatal ("expr_eval_action: bad token, %ld\n", token);
+ }
+}
+
+
+/* Predictive parser lookahead token. */
+static sc_int expr_parse_lookahead = TOK_NONE;
+
+/* Forward declaration of factor parsers and string expression parser. */
+static void expr_parse_numeric_factor (void);
+static void expr_parse_string_factor (void);
+static void expr_parse_string_expr (void);
+
+/*
+ * expr_parse_match()
+ *
+ * Match a token to the lookahead, then advance lookahead.
+ */
+static void
+expr_parse_match (sc_int token)
+{
+ if (expr_parse_lookahead == token)
+ expr_parse_lookahead = expr_next_token ();
+ else
+ {
+ /* Syntax error. */
+ sc_error ("expr_parse_match: syntax error,"
+ " expected %ld, got %ld\n", expr_parse_lookahead, token);
+ longjmp (expr_parse_error, 1);
+ }
+}
+
+
+/*
+ * Numeric operator precedence table. Operators are in order of precedence,
+ * with the highest being a factor. Each precedence entry permits several
+ * listed tokens. The end of the table (highest precedence) is marked by
+ * a list with no operators (although in practice we need to put a TOK_NONE
+ * in here since some C compilers won't accept { } as an empty initializer).
+ */
+typedef struct
+{
+ const sc_int token_count;
+ const sc_int tokens[6];
+} sc_precedence_entry_t;
+#if 0
+/*
+ * Conventional (BASIC, C) precedence table for the parser. Exponentiation
+ * has the highest precedence, then multiplicative operations, additive,
+ * comparisons, and boolean combiners.
+ */
+static const sc_precedence_entry_t PRECEDENCE_TABLE[] = {
+ {1, {TOK_OR}},
+ {1, {TOK_AND}},
+ {2, {TOK_EQUAL, TOK_NOT_EQUAL}},
+ {4, {TOK_GREATER, TOK_LESS, TOK_GREATER_EQ, TOK_LESS_EQ}},
+ {2, {TOK_ADD, TOK_SUBTRACT}},
+ {3, {TOK_MULTIPLY, TOK_DIVIDE, TOK_MOD}},
+ {1, {TOK_POWER}},
+ {0, {TOK_NONE}}
+};
+#else
+/*
+ * Adrift-like precedence table for the parser. Exponentiation and modulus
+ * operations seem to be implemented at the same level as addition and
+ * subtraction, and boolean 'and' and 'or' have equal precedence.
+ */
+static const sc_precedence_entry_t PRECEDENCE_TABLE[] = {
+ {2, {TOK_OR, TOK_AND}},
+ {6, {TOK_EQUAL, TOK_NOT_EQUAL,
+ TOK_GREATER, TOK_LESS, TOK_GREATER_EQ, TOK_LESS_EQ}},
+ {4, {TOK_ADD, TOK_SUBTRACT, TOK_POWER, TOK_MOD}},
+ {2, {TOK_MULTIPLY, TOK_DIVIDE}},
+ {0, {TOK_NONE}}
+};
+#endif
+
+
+/*
+ * expr_parse_contains_token()
+ *
+ * Helper for expr_parse_numeric_element(). Search the token list for the
+ * entry passed in, and return TRUE if it contains the given token.
+ */
+static int
+expr_parse_contains_token (const sc_precedence_entry_t *entry, sc_int token)
+{
+ sc_bool is_matched;
+ sc_int index_;
+
+ /* Search the entry's token list for the token passed in. */
+ is_matched = FALSE;
+ for (index_ = 0; index_ < entry->token_count; index_++)
+ {
+ if (entry->tokens[index_] == token)
+ {
+ is_matched = TRUE;
+ break;
+ }
+ }
+
+ return is_matched;
+}
+
+
+/*
+ * expr_parse_numeric_element()
+ *
+ * Parse numeric expression elements. This function uses the precedence table
+ * to match tokens, then decide whether, and how, to recurse into itself, or
+ * whether to parse a highest-precedence factor.
+ */
+static void
+expr_parse_numeric_element (sc_int precedence)
+{
+ const sc_precedence_entry_t *entry;
+
+ /* See if the level passed in has listed tokens. */
+ entry = PRECEDENCE_TABLE + precedence;
+ if (entry->token_count == 0)
+ {
+ /* Precedence levels that hit the table end are factors. */
+ expr_parse_numeric_factor ();
+ return;
+ }
+
+ /*
+ * Parse initial higher-precedence factor, then others that associate
+ * with the given level.
+ */
+ expr_parse_numeric_element (precedence + 1);
+ while (expr_parse_contains_token (entry, expr_parse_lookahead))
+ {
+ sc_int token;
+
+ /* Note token and match, parse next level, then action this token. */
+ token = expr_parse_lookahead;
+ expr_parse_match (token);
+ expr_parse_numeric_element (precedence + 1);
+ expr_eval_action (token);
+ }
+}
+
+
+/*
+ * expr_parse_numeric_expr()
+ *
+ * Parse a complete numeric (sub-)expression.
+ */
+static void
+expr_parse_numeric_expr (void)
+{
+ /* Call the parser of the lowest precedence operators. */
+ expr_parse_numeric_element (0);
+}
+
+
+/*
+ * expr_parse_numeric_factor()
+ *
+ * Parse a numeric expression factor.
+ */
+static void
+expr_parse_numeric_factor (void)
+{
+ /* Handle factors based on lookahead token. */
+ switch (expr_parse_lookahead)
+ {
+ /* Handle straightforward factors first. */
+ case TOK_LPAREN:
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_RPAREN);
+ break;
+
+ case TOK_UMINUS:
+ expr_parse_match (TOK_UMINUS);
+ expr_parse_numeric_factor ();
+ expr_eval_action (TOK_UMINUS);
+ break;
+
+ case TOK_UPLUS:
+ expr_parse_match (TOK_UPLUS);
+ expr_parse_numeric_factor ();
+ break;
+
+ case TOK_INTEGER:
+ expr_eval_action (TOK_INTEGER);
+ expr_parse_match (TOK_INTEGER);
+ break;
+
+ case TOK_VARIABLE:
+ {
+ sc_vartype_t token_value, vt_rvalue;
+ sc_int type;
+
+ expr_current_token_value (&token_value);
+ if (!var_get (expr_varset, token_value.string, &type, &vt_rvalue))
+ {
+ sc_error ("expr_parse_numeric_factor:"
+ " undefined variable, %s\n", token_value.string);
+ longjmp (expr_parse_error, 1);
+ }
+ if (type != VAR_INTEGER)
+ {
+ sc_error ("expr_parse_numeric_factor:"
+ " string variable in numeric context, %s\n",
+ token_value.string);
+ longjmp (expr_parse_error, 1);
+ }
+ expr_eval_action (TOK_VARIABLE);
+ expr_parse_match (TOK_VARIABLE);
+ break;
+ }
+
+ /* Handle functions as factors. */
+ case TOK_ABS:
+ /* Parse as "abs (val)". */
+ expr_parse_match (TOK_ABS);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_ABS);
+ break;
+
+ case TOK_IF:
+ /* Parse as "if (boolean, val1, val2)". */
+ expr_parse_match (TOK_IF);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_COMMA);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_COMMA);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_IF);
+ break;
+
+ case TOK_RANDOM:
+ /* Parse as "random (low, high)". */
+ expr_parse_match (TOK_RANDOM);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_COMMA);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_RANDOM);
+ break;
+
+ case TOK_MAX:
+ case TOK_MIN:
+ case TOK_EITHER:
+ /* Parse as "<func> (val1[,val2[,val3...]]])". */
+ {
+ sc_int token, argument_count;
+
+ /* Match up the function name and opening parenthesis. */
+ token = expr_parse_lookahead;
+ expr_parse_match (token);
+ expr_parse_match (TOK_LPAREN);
+
+ /* Count variable number of arguments as they are stacked. */
+ expr_parse_numeric_expr ();
+ argument_count = 1;
+ while (expr_parse_lookahead == TOK_COMMA)
+ {
+ expr_parse_match (TOK_COMMA);
+ expr_parse_numeric_expr ();
+ argument_count++;
+ }
+ expr_parse_match (TOK_RPAREN);
+
+ /* Push additional value -- the count of arguments. */
+ expr_eval_push_integer (argument_count);
+ expr_eval_action (token);
+ break;
+ }
+
+ case TOK_INSTR:
+ /* Parse as "instr (val1, val2)". */
+ expr_parse_match (TOK_INSTR);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_COMMA);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_INSTR);
+ break;
+
+ case TOK_LEN:
+ /* Parse as "len (val)". */
+ expr_parse_match (TOK_LEN);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_LEN);
+ break;
+
+ case TOK_VAL:
+ /* Parse as "val (val)". */
+ expr_parse_match (TOK_VAL);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_VAL);
+ break;
+
+ case TOK_IDENT:
+ /* Unrecognized function-type token. */
+ sc_error ("expr_parse_numeric_factor: syntax error, unknown ident\n");
+ longjmp (expr_parse_error, 1);
+
+ default:
+ /* Syntax error. */
+ sc_error ("expr_parse_numeric_factor:"
+ " syntax error, unexpected token, %ld\n", expr_parse_lookahead);
+ longjmp (expr_parse_error, 1);
+ }
+}
+
+
+/*
+ * expr_parse_string_expr()
+ *
+ * Parse a complete string (sub-)expression.
+ */
+static void
+expr_parse_string_expr (void)
+{
+ /*
+ * Parse a string factor, then all repeated concatenations. Because the '+'
+ * and '&' are context sensitive, we have to invent/translate them into the
+ * otherwise unused TOK_CONCATENATE for evaluation.
+ */
+ expr_parse_string_factor ();
+ while (expr_parse_lookahead == TOK_AND || expr_parse_lookahead == TOK_ADD)
+ {
+ expr_parse_match (expr_parse_lookahead);
+ expr_parse_string_factor ();
+ expr_eval_action (TOK_CONCATENATE);
+ }
+}
+
+
+/*
+ * expr_parse_string_factor()
+ *
+ * Parse a string expression factor.
+ */
+static void
+expr_parse_string_factor (void)
+{
+ /* Handle factors based on lookahead token. */
+ switch (expr_parse_lookahead)
+ {
+ /* Handle straightforward factors first. */
+ case TOK_LPAREN:
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_RPAREN);
+ break;
+
+ case TOK_STRING:
+ expr_eval_action (TOK_STRING);
+ expr_parse_match (TOK_STRING);
+ break;
+
+ case TOK_VARIABLE:
+ {
+ sc_vartype_t token_value, vt_rvalue;
+ sc_int type;
+
+ expr_current_token_value (&token_value);
+ if (!var_get (expr_varset, token_value.string, &type, &vt_rvalue))
+ {
+ sc_error ("expr_parse_string_factor:"
+ " undefined variable, %s\n", token_value.string);
+ longjmp (expr_parse_error, 1);
+ }
+ if (type != VAR_STRING)
+ {
+ sc_error ("expr_parse_string_factor:"
+ " numeric variable in string context, %s\n",
+ token_value.string);
+ longjmp (expr_parse_error, 1);
+ }
+ expr_eval_action (TOK_VARIABLE);
+ expr_parse_match (TOK_VARIABLE);
+ break;
+ }
+
+ /* Handle functions as factors. */
+ case TOK_UPPER:
+ case TOK_LOWER:
+ case TOK_PROPER:
+ /* Parse as "<func> (text)". */
+ {
+ sc_int token;
+
+ token = expr_parse_lookahead;
+ expr_parse_match (token);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (token);
+ break;
+ }
+
+ case TOK_LEFT:
+ case TOK_RIGHT:
+ /* Parse as "<func> (text,length)". */
+ {
+ sc_int token;
+
+ token = expr_parse_lookahead;
+ expr_parse_match (token);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_COMMA);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (token);
+ break;
+ }
+
+ case TOK_MID:
+ /* Parse as "mid (text,start,length)". */
+ expr_parse_match (TOK_MID);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_string_expr ();
+ expr_parse_match (TOK_COMMA);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_COMMA);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_MID);
+ break;
+
+ case TOK_STR:
+ /* Parse as "str (val)". */
+ expr_parse_match (TOK_STR);
+ expr_parse_match (TOK_LPAREN);
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_RPAREN);
+ expr_eval_action (TOK_STR);
+ break;
+
+ case TOK_IDENT:
+ /* Unrecognized function-type token. */
+ sc_error ("expr_parse_string_factor: syntax error, unknown ident\n");
+ longjmp (expr_parse_error, 1);
+
+ default:
+ /* Syntax error. */
+ sc_error ("expr_parse_string_factor:"
+ " syntax error, unexpected token, %ld\n", expr_parse_lookahead);
+ longjmp (expr_parse_error, 1);
+ }
+}
+
+
+/*
+ * expr_evaluate_expression()
+ *
+ * Parse a string expression into a runtime values stack. Return the
+ * value of the expression.
+ */
+static sc_bool
+expr_evaluate_expression (const sc_char *expression, sc_var_setref_t vars,
+ sc_int assign_type, sc_vartype_t *vt_rvalue)
+{
+ assert (assign_type == VAR_INTEGER || assign_type == VAR_STRING);
+
+ /* Reset values stack and start tokenizer. */
+ expr_eval_start (vars);
+ expr_tokenize_start (expression);
+
+ /* Try parsing an expression, and catch errors. */
+ if (setjmp (expr_parse_error) == 0)
+ {
+ /* Parse an expression, and ensure it ends at string end. */
+ expr_parse_lookahead = expr_next_token ();
+ if (assign_type == VAR_STRING)
+ expr_parse_string_expr ();
+ else
+ expr_parse_numeric_expr ();
+ expr_parse_match (TOK_EOS);
+ }
+ else
+ {
+ /* Parse error -- clean up tokenizer, collect garbage, and fail. */
+ expr_tokenize_end ();
+ expr_eval_garbage_collect ();
+ return FALSE;
+ }
+
+ /* Clean up tokenizer and return successfully with result. */
+ expr_tokenize_end ();
+ expr_eval_result (vt_rvalue);
+ return TRUE;
+}
+
+
+/*
+ * expr_eval_numeric_expression()
+ * expr_eval_string_expression()
+ *
+ * Public interfaces to expression evaluation. Evaluate an expression, and
+ * assign the result to either a numeric or a string. For string expressions,
+ * the return value is malloc'ed, and the caller is responsible for freeing
+ * it.
+ */
+sc_bool
+expr_eval_numeric_expression (const sc_char *expression,
+ sc_var_setref_t vars, sc_int *rvalue)
+{
+ sc_vartype_t vt_rvalue;
+ sc_bool status;
+ assert (expression && vars && rvalue);
+
+ /* Evaluate numeric expression, and return value if valid. */
+ status = expr_evaluate_expression (expression, vars, VAR_INTEGER, &vt_rvalue);
+ if (status)
+ *rvalue = vt_rvalue.integer;
+ return status;
+}
+
+sc_bool
+expr_eval_string_expression (const sc_char *expression,
+ sc_var_setref_t vars, sc_char **rvalue)
+{
+ sc_vartype_t vt_rvalue;
+ sc_bool status;
+ assert (expression && vars && rvalue);
+
+ /* Evaluate string expression, and return value if valid. */
+ status = expr_evaluate_expression (expression, vars, VAR_STRING, &vt_rvalue);
+ if (status)
+ *rvalue = vt_rvalue.mutable_string;
+ return status;
+}
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/adrift/scgamest.cpp b/engines/glk/adrift/scgamest.cpp
new file mode 100644
index 0000000..2d9d78f
--- /dev/null
+++ b/engines/glk/adrift/scgamest.cpp
@@ -0,0 +1,1195 @@
+/* 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/adrift/scare.h"
+#include "glk/adrift/scprotos.h"
+#include "glk/adrift/scgamest.h"
+
+namespace Glk {
+namespace Adrift {
+
+/* Assorted definitions and constants. */
+static const sc_uint GAME_MAGIC = 0x35aed26e;
+
+/*
+ * gs_move_player_to_room()
+ * gs_player_in_room()
+ *
+ * Move the player to a given room, and check presence in a given room.
+ */
+void
+gs_move_player_to_room (sc_gameref_t game, sc_int room)
+{
+ assert(gs_is_game_valid (game));
+
+ if (room < 0)
+ {
+ sc_fatal ("gs_move_player_to_room: invalid room, %ld\n", room);
+ return;
+ }
+ else if (room < game->room_count)
+ game->playerroom = room;
+ else
+ game->playerroom = lib_random_roomgroup_member (game,
+ room - game->room_count);
+
+ game->playerparent = -1;
+ game->playerposition = 0;
+}
+
+sc_bool
+gs_player_in_room (sc_gameref_t game, sc_int room)
+{
+ assert(gs_is_game_valid (game));
+ return game->playerroom == room;
+}
+
+
+/*
+ * gs_in_range()
+ *
+ * Helper for event, room, object, and npc range assertions.
+ */
+static sc_bool
+gs_in_range (sc_int value, sc_int limit)
+{
+ return value >= 0 && value < limit;
+}
+
+
+/*
+ * gs_*()
+ *
+ * Game accessors and mutators.
+ */
+sc_var_setref_t
+gs_get_vars (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->vars;
+}
+
+sc_prop_setref_t
+gs_get_bundle (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->bundle;
+}
+
+sc_filterref_t
+gs_get_filter (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->filter;
+}
+
+sc_memo_setref_t
+gs_get_memento (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->memento;
+}
+
+
+/*
+ * Game accessors and mutators for the player.
+ */
+void
+gs_set_playerroom (sc_gameref_t gs, sc_int room)
+{
+ assert(gs_is_game_valid (gs));
+ gs->playerroom = room;
+}
+
+void
+gs_set_playerposition (sc_gameref_t gs, sc_int position)
+{
+ assert(gs_is_game_valid (gs));
+ gs->playerposition = position;
+}
+
+void
+gs_set_playerparent (sc_gameref_t gs, sc_int parent)
+{
+ assert(gs_is_game_valid (gs));
+ gs->playerparent = parent;
+}
+
+sc_int
+gs_playerroom (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->playerroom;
+}
+
+sc_int
+gs_playerposition (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->playerposition;
+}
+
+sc_int
+gs_playerparent (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->playerparent;
+}
+
+
+/*
+ * Game accessors and mutators for events.
+ */
+sc_int
+gs_event_count (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->event_count;
+}
+
+void
+gs_set_event_state (sc_gameref_t gs, sc_int event, sc_int state)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (event, gs->event_count));
+ gs->events[event].state = state;
+}
+
+void
+gs_set_event_time (sc_gameref_t gs, sc_int event, sc_int etime)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (event, gs->event_count));
+ gs->events[event].time = etime;
+}
+
+sc_int
+gs_event_state (sc_gameref_t gs, sc_int event)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (event, gs->event_count));
+ return gs->events[event].state;
+}
+
+sc_int
+gs_event_time (sc_gameref_t gs, sc_int event)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (event, gs->event_count));
+ return gs->events[event].time;
+}
+
+void
+gs_decrement_event_time (sc_gameref_t gs, sc_int event)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (event, gs->event_count));
+ gs->events[event].time--;
+}
+
+
+/*
+ * Game accessors and mutators for rooms.
+ */
+sc_int
+gs_room_count (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->room_count;
+}
+
+void
+gs_set_room_seen (sc_gameref_t gs, sc_int room, sc_bool seen)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (room, gs->room_count));
+ gs->rooms[room].visited = seen;
+}
+
+sc_bool
+gs_room_seen (sc_gameref_t gs, sc_int room)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (room, gs->room_count));
+ return gs->rooms[room].visited;
+}
+
+
+/*
+ * Game accessors and mutators for tasks.
+ */
+sc_int
+gs_task_count (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->task_count;
+}
+
+void
+gs_set_task_done (sc_gameref_t gs, sc_int task, sc_bool done)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (task, gs->task_count));
+ gs->tasks[task].done = done;
+}
+
+void
+gs_set_task_scored (sc_gameref_t gs, sc_int task, sc_bool scored)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (task, gs->task_count));
+ gs->tasks[task].scored = scored;
+}
+
+sc_bool
+gs_task_done (sc_gameref_t gs, sc_int task)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (task, gs->task_count));
+ return gs->tasks[task].done;
+}
+
+sc_bool
+gs_task_scored (sc_gameref_t gs, sc_int task)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (task, gs->task_count));
+ return gs->tasks[task].scored;
+}
+
+
+/*
+ * Game accessors and mutators for objects.
+ */
+sc_int
+gs_object_count (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->object_count;
+}
+
+void
+gs_set_object_openness (sc_gameref_t gs, sc_int object, sc_int openness)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].openness = openness;
+}
+
+void
+gs_set_object_state (sc_gameref_t gs, sc_int object, sc_int state)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].state = state;
+}
+
+void
+gs_set_object_seen (sc_gameref_t gs, sc_int object, sc_bool seen)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].seen = seen;
+}
+
+void
+gs_set_object_unmoved (sc_gameref_t gs, sc_int object, sc_bool unmoved)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].unmoved = unmoved;
+}
+
+void
+gs_set_object_static_unmoved (sc_gameref_t gs, sc_int object, sc_bool unmoved)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].static_unmoved = unmoved;
+}
+
+sc_int
+gs_object_openness (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ return gs->objects[object].openness;
+}
+
+sc_int
+gs_object_state (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ return gs->objects[object].state;
+}
+
+sc_bool
+gs_object_seen (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ return gs->objects[object].seen;
+}
+
+sc_bool
+gs_object_unmoved (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ return gs->objects[object].unmoved;
+}
+
+sc_bool
+gs_object_static_unmoved (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ return gs->objects[object].static_unmoved;
+}
+
+sc_int
+gs_object_position (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ return gs->objects[object].position;
+}
+
+sc_int
+gs_object_parent (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ return gs->objects[object].parent;
+}
+
+static void
+gs_object_move_onto_unchecked (sc_gameref_t gs, sc_int object, sc_int onto)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = OBJ_ON_OBJECT;
+ gs->objects[object].parent = onto;
+}
+
+static void
+gs_object_move_into_unchecked (sc_gameref_t gs, sc_int object, sc_int into)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = OBJ_IN_OBJECT;
+ gs->objects[object].parent = into;
+}
+
+static void
+gs_object_make_hidden_unchecked (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = OBJ_HIDDEN;
+ gs->objects[object].parent = -1;
+}
+
+static void
+gs_object_player_get_unchecked (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = OBJ_HELD_PLAYER;
+ gs->objects[object].parent = -1;
+}
+
+static void
+gs_object_npc_get_unchecked (sc_gameref_t gs, sc_int object, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = OBJ_HELD_NPC;
+ gs->objects[object].parent = npc;
+}
+
+static void
+gs_object_player_wear_unchecked (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = OBJ_WORN_PLAYER;
+ gs->objects[object].parent = 0;
+}
+
+static void
+gs_object_npc_wear_unchecked (sc_gameref_t gs, sc_int object, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = OBJ_WORN_NPC;
+ gs->objects[object].parent = npc;
+}
+
+static void
+gs_object_to_room_unchecked (sc_gameref_t gs, sc_int object, sc_int room)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ gs->objects[object].position = room + 1;
+ gs->objects[object].parent = -1;
+}
+
+void
+gs_object_move_onto (sc_gameref_t gs, sc_int object, sc_int onto)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != OBJ_ON_OBJECT
+ || gs->objects[object].parent != onto)
+ {
+ gs_object_move_onto_unchecked (gs, object, onto);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+void
+gs_object_move_into (sc_gameref_t gs, sc_int object, sc_int into)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != OBJ_IN_OBJECT
+ || gs->objects[object].parent != into)
+ {
+ gs_object_move_into_unchecked (gs, object, into);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+void
+gs_object_make_hidden (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != OBJ_HIDDEN)
+ {
+ gs_object_make_hidden_unchecked (gs, object);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+void
+gs_object_player_get (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != OBJ_HELD_PLAYER)
+ {
+ gs_object_player_get_unchecked (gs, object);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+void
+gs_object_npc_get (sc_gameref_t gs, sc_int object, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != OBJ_HELD_NPC
+ || gs->objects[object].parent != npc)
+ {
+ gs_object_npc_get_unchecked (gs, object, npc);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+void
+gs_object_player_wear (sc_gameref_t gs, sc_int object)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != OBJ_WORN_PLAYER)
+ {
+ gs_object_player_wear_unchecked (gs, object);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+void
+gs_object_npc_wear (sc_gameref_t gs, sc_int object, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != OBJ_WORN_NPC
+ || gs->objects[object].parent != npc)
+ {
+ gs_object_npc_wear_unchecked (gs, object, npc);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+void
+gs_object_to_room (sc_gameref_t gs, sc_int object, sc_int room)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (object, gs->object_count));
+ if (gs->objects[object].position != room + 1)
+ {
+ gs_object_to_room_unchecked (gs, object, room);
+ gs->objects[object].unmoved = FALSE;
+ }
+}
+
+
+/*
+ * Game accessors and mutators for NPCs.
+ */
+sc_int
+gs_npc_count (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ return gs->npc_count;
+}
+
+void
+gs_set_npc_location (sc_gameref_t gs, sc_int npc, sc_int location)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ gs->npcs[npc].location = location;
+}
+
+sc_int
+gs_npc_location (sc_gameref_t gs, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ return gs->npcs[npc].location;
+}
+
+void
+gs_set_npc_position (sc_gameref_t gs, sc_int npc, sc_int position)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ gs->npcs[npc].position = position;
+}
+
+sc_int
+gs_npc_position (sc_gameref_t gs, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ return gs->npcs[npc].position;
+}
+
+void
+gs_set_npc_parent (sc_gameref_t gs, sc_int npc, sc_int parent)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ gs->npcs[npc].parent = parent;
+}
+
+sc_int
+gs_npc_parent (sc_gameref_t gs, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ return gs->npcs[npc].parent;
+}
+
+void
+gs_set_npc_seen (sc_gameref_t gs, sc_int npc, sc_bool seen)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ gs->npcs[npc].seen = seen;
+}
+
+sc_bool
+gs_npc_seen (sc_gameref_t gs, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ return gs->npcs[npc].seen;
+}
+
+sc_int
+gs_npc_walkstep_count (sc_gameref_t gs, sc_int npc)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count));
+ return gs->npcs[npc].walkstep_count;
+}
+
+void
+gs_set_npc_walkstep (sc_gameref_t gs,
+ sc_int npc, sc_int walk, sc_int walkstep)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count)
+ && gs_in_range (walk, gs->npcs[npc].walkstep_count));
+ gs->npcs[npc].walksteps[walk] = walkstep;
+}
+
+sc_int
+gs_npc_walkstep (sc_gameref_t gs, sc_int npc, sc_int walk)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count)
+ && gs_in_range (walk, gs->npcs[npc].walkstep_count));
+ return gs->npcs[npc].walksteps[walk];
+}
+
+void
+gs_decrement_npc_walkstep (sc_gameref_t gs, sc_int npc, sc_int walk)
+{
+ assert(gs_is_game_valid (gs) && gs_in_range (npc, gs->npc_count)
+ && gs_in_range (walk, gs->npcs[npc].walkstep_count));
+ gs->npcs[npc].walksteps[walk]--;
+}
+
+
+/*
+ * Convenience functions for bulk clearance of references.
+ */
+void
+gs_clear_npc_references (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ memset (gs->npc_references,
+ FALSE, gs->npc_count * sizeof (*gs->npc_references));
+}
+
+void
+gs_clear_object_references (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ memset (gs->object_references,
+ FALSE, gs->object_count * sizeof (*gs->object_references));
+}
+
+void
+gs_set_multiple_references (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ memset (gs->multiple_references,
+ TRUE, gs->object_count * sizeof (*gs->multiple_references));
+}
+
+void
+gs_clear_multiple_references (sc_gameref_t gs)
+{
+ assert(gs_is_game_valid (gs));
+ memset (gs->multiple_references,
+ FALSE, gs->object_count * sizeof (*gs->multiple_references));
+}
+
+
+/*
+ * gs_create()
+ *
+ * Create and initialize a game state.
+ */
+sc_gameref_t
+gs_create (sc_var_setref_t vars,
+ sc_prop_setref_t bundle, sc_filterref_t filter)
+{
+ sc_gameref_t game;
+ sc_vartype_t vt_key[4];
+ sc_int index_, bytes;
+ assert(vars && bundle && filter);
+
+ /* Create the initial state structure. */
+ game = (sc_gameref_t)sc_malloc (sizeof (*game));
+ game->magic = GAME_MAGIC;
+
+ /* Store the variables, properties bundle, and filter references. */
+ game->vars = vars;
+ game->bundle = bundle;
+ game->filter = filter;
+
+ /* Set memento to NULL for now; it's added later. */
+ game->memento = NULL;
+
+ /* Initialize for no debugger. */
+ game->debugger = NULL;
+
+ /* Initialize the undo buffers to NULL for now. */
+ game->temporary = NULL;
+ game->undo = NULL;
+ game->undo_available = FALSE;
+
+ /* Create rooms state array. */
+ vt_key[0].string = "Rooms";
+ game->room_count = prop_get_child_count (bundle, "I<-s", vt_key);
+ game->rooms = (sc_roomstate_t *)sc_malloc (game->room_count * sizeof (*game->rooms));
+
+ /* Set up initial rooms states. */
+ for (index_ = 0; index_ < game->room_count; index_++)
+ gs_set_room_seen (game, index_, FALSE);
+
+ /* Create objects state array. */
+ vt_key[0].string = "Objects";
+ game->object_count = prop_get_child_count (bundle, "I<-s", vt_key);
+ game->objects = (sc_objectstate_t *)sc_malloc (game->object_count * sizeof (*game->objects));
+
+ /* Set up initial object states. */
+ for (index_ = 0; index_ < game->object_count; index_++)
+ {
+ const sc_char *inroomdesc;
+ sc_bool is_static, unmoved;
+
+ vt_key[1].integer = index_;
+
+ vt_key[2].string = "Static";
+ is_static = prop_get_boolean (bundle, "B<-sis", vt_key);
+ if (is_static)
+ {
+ sc_int type;
+
+ vt_key[2].string = "Where";
+ vt_key[3].string = "Type";
+ type = prop_get_integer (bundle, "I<-siss", vt_key);
+ if (type == ROOMLIST_NPC_PART)
+ {
+ sc_int parent;
+
+ game->objects[index_].position = OBJ_PART_NPC;
+
+ vt_key[2].string = "Parent";
+ parent = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
+ game->objects[index_].parent = parent;
+ }
+ else
+ gs_object_make_hidden_unchecked (game, index_);
+ }
+ else
+ {
+ sc_int initialparent, initialposition;
+
+ vt_key[2].string = "Parent";
+ initialparent = prop_get_integer (bundle, "I<-sis", vt_key);
+ vt_key[2].string = "InitialPosition";
+ initialposition = prop_get_integer (bundle, "I<-sis", vt_key);
+ switch (initialposition)
+ {
+ case 0: /* Hidden. */
+ gs_object_make_hidden_unchecked (game, index_);
+ break;
+
+ case 1: /* Held. */
+ if (initialparent == 0) /* By player. */
+ gs_object_player_get_unchecked (game, index_);
+ else /* By NPC. */
+ gs_object_npc_get_unchecked (game, index_, initialparent - 1);
+ break;
+
+ case 2: /* In container. */
+ gs_object_move_into_unchecked (game, index_,
+ obj_container_object (game, initialparent));
+ break;
+
+ case 3: /* On surface. */
+ gs_object_move_onto_unchecked (game, index_,
+ obj_surface_object (game, initialparent));
+ break;
+
+ default: /* In room, or worn by player/NPC. */
+ if (initialposition >= 4
+ && initialposition < 4 + game->room_count)
+ {
+ gs_object_to_room_unchecked (game,
+ index_, initialposition - 4);
+ }
+ else if (initialposition == 4 + game->room_count)
+ {
+ if (initialparent == 0)
+ gs_object_player_wear_unchecked (game, index_);
+ else
+ gs_object_npc_wear_unchecked (game,
+ index_, initialparent - 1);
+ }
+ else
+ {
+ sc_error ("gs_create: object in out of bounds room, %ld\n",
+ initialposition - 4 - game->room_count);
+ gs_object_to_room_unchecked (game, index_, -2);
+ }
+ }
+ }
+
+ vt_key[2].string = "CurrentState";
+ gs_set_object_state (game, index_,
+ prop_get_integer (bundle, "I<-sis", vt_key));
+
+ vt_key[2].string = "Openable";
+ gs_set_object_openness (game, index_,
+ prop_get_integer (bundle, "I<-sis", vt_key));
+
+ gs_set_object_seen (game, index_, FALSE);
+
+ vt_key[2].string = "InRoomDesc";
+ inroomdesc = prop_get_string (bundle, "S<-sis", vt_key);
+ if (!sc_strempty (inroomdesc))
+ {
+ vt_key[2].string = "OnlyWhenNotMoved";
+ if (prop_get_integer (bundle, "I<-sis", vt_key) == 1)
+ unmoved = TRUE;
+ else
+ unmoved = FALSE;
+ }
+ else
+ unmoved = FALSE;
+ gs_set_object_unmoved (game, index_, unmoved);
Commit: 58c71a23db7933e5e9a4b9daeda362cc29ced36c
https://github.com/scummvm/scummvm/commit/58c71a23db7933e5e9a4b9daeda362cc29ced36c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Fixes to startup code
Changed paths:
engines/glk/adrift/os_glk.cpp
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index 98f4f34..cc7471e 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -3319,8 +3319,8 @@ void glk_main() {
/*---------------------------------------------------------------------*/
/* Glk linkage relevant only to the UNIX platform */
/*---------------------------------------------------------------------*/
-#ifdef UNUSED
+#ifdef TODO
/*
* Glk arguments for UNIX versions of the Glk interpreter.
*/
@@ -3341,7 +3341,12 @@ glkunix_argumentlist_t glkunix_arguments[] = {
(char *) "filename game to run"},
{nullptr, glkunix_arg_End, nullptr}
};
+#endif
+struct glkunix_startup_t {
+ int argc;
+ char **argv;
+};
/*
* glkunix_startup_code()
@@ -3352,9 +3357,7 @@ glkunix_argumentlist_t glkunix_arguments[] = {
* to build a game from the stream. On error, set the message in
* gsc_game_message; the core gsc_main() will report it when it's called.
*/
-int
-glkunix_startup_code (glkunix_startup_t * data)
-{
+int glkunix_startup_code(glkunix_startup_t *data) {
int argc = data->argc;
sc_char **argv = data->argv;
int argv_index;
@@ -3367,8 +3370,8 @@ glkunix_startup_code (glkunix_startup_t * data)
gsc_startup_called = TRUE;
#ifdef GARGLK
- garg_vm->glk_set_program_name("SCARE " SCARE_VERSION);
- garg_vm->glk_set_program_info("SCARE " SCARE_VERSION
+ g_vm->garglk_set_program_name("SCARE " SCARE_VERSION);
+ g_vm->garglk_set_program_info("SCARE " SCARE_VERSION
" by Simon Baldwin and Mark J. Tilford");
#endif
@@ -3420,7 +3423,7 @@ glkunix_startup_code (glkunix_startup_t * data)
}
/* Open a stream to the TAF file, complain if this fails. */
- game_stream = glkunix_stream_open_pathname (argv[argv_index], FALSE, 0);
+ game_stream = g_vm->glk_stream_open_file(g_vm->glk_fileref_create_by_name(filemode_Read, argv[argv_index]), filemode_Read);
if (!game_stream)
{
gsc_game = nullptr;
@@ -3436,7 +3439,7 @@ glkunix_startup_code (glkunix_startup_t * data)
*/
if (restore_from)
{
- restore_stream = glkunix_stream_open_pathname (restore_from, FALSE, 0);
+ restore_stream =g_vm->glk_stream_open_file(g_vm->glk_fileref_create_by_name(filemode_Read, restore_from), filemode_Read);
if (!restore_stream)
{
g_vm->glk_stream_close (game_stream, nullptr);
@@ -3451,13 +3454,14 @@ glkunix_startup_code (glkunix_startup_t * data)
restore_stream = nullptr;
/* Set SCARE trace flags and other general setup from the environment. */
- if (getenv ("SC_TRACE_FLAGS"))
- trace_flags = strtoul (getenv ("SC_TRACE_FLAGS"), nullptr, 0);
- else
+ if (false /*getenv ("SC_TRACE_FLAGS") */) {
+ //trace_flags = strtoul (getenv ("SC_TRACE_FLAGS"), nullptr, 0);
+ } else {
trace_flags = 0;
- enable_debugger = (getenv ("SC_DEBUGGER_ENABLED") != nullptr);
- stable_random = (getenv ("SC_STABLE_RANDOM_ENABLED") != nullptr);
- locale = getenv ("SC_LOCALE");
+ }
+ enable_debugger = false; // (getenv("SC_DEBUGGER_ENABLED") != nullptr);
+ stable_random = false; // (getenv("SC_STABLE_RANDOM_ENABLED") != nullptr);
+ locale = nullptr; // getenv("SC_LOCALE");
#ifdef LINUX_GRAPHICS
/* Note the path to the game file for graphics extraction. */
@@ -3468,7 +3472,6 @@ glkunix_startup_code (glkunix_startup_t * data)
return gsc_startup_code (game_stream, restore_stream, trace_flags,
enable_debugger, stable_random, locale);
}
-#endif /* __unix */
/*---------------------------------------------------------------------*/
Commit: b87d5ef16243bfbdd8f87c7558c6b73fb5842de2
https://github.com/scummvm/scummvm/commit/b87d5ef16243bfbdd8f87c7558c6b73fb5842de2
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Adding detection entries
Changed paths:
A engines/glk/adrift/detection.cpp
A engines/glk/adrift/detection.h
A engines/glk/adrift/detection_tables.h
engines/glk/detection.cpp
engines/glk/module.mk
diff --git a/engines/glk/adrift/detection.cpp b/engines/glk/adrift/detection.cpp
new file mode 100644
index 0000000..fc76a08
--- /dev/null
+++ b/engines/glk/adrift/detection.cpp
@@ -0,0 +1,98 @@
+/* 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/adrift/detection.h"
+#include "glk/adrift/detection_tables.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/md5.h"
+#include "engines/game.h"
+
+namespace Glk {
+namespace Adrift {
+
+void AdriftMetaEngine::getSupportedGames(PlainGameList &games) {
+ for (const PlainGameDescriptor *pd = ADRIFT_GAME_LIST; pd->gameId; ++pd) {
+ games.push_back(*pd);
+ }
+}
+
+GameDescriptor AdriftMetaEngine::findGame(const char *gameId) {
+ for (const PlainGameDescriptor *pd = ADRIFT_GAME_LIST; pd->gameId; ++pd) {
+ if (!strcmp(gameId, pd->gameId))
+ return *pd;
+ }
+
+ return PlainGameDescriptor();
+}
+
+bool AdriftMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
+ const char *const EXTENSIONS[] = { ".taf", nullptr };
+
+ // Loop through the files of the folder
+ for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+ // Check for a recognised filename
+ if (file->isDirectory())
+ continue;
+ Common::String filename = file->getName();
+ bool hasExt = false;
+ for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
+ hasExt = filename.hasSuffixIgnoreCase(*ext);
+ if (!hasExt)
+ continue;
+
+ // Open up the file and calculate the md5
+ Common::File gameFile;
+ if (!gameFile.open(*file))
+ continue;
+
+ Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
+ size_t filesize = gameFile.size();
+ gameFile.close();
+
+ // Check for known games
+ const AdriftGameDescription *p = ADRIFT_GAMES;
+ while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
+ ++p;
+
+ if (!p->_gameId) {
+ const PlainGameDescriptor &desc = ADRIFT_GAME_LIST[0];
+ gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
+ } else {
+ PlainGameDescriptor gameDesc = findGame(p->_gameId);
+ gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
+ }
+ }
+
+ return !gameList.empty();
+}
+
+void AdriftMetaEngine::detectClashes(Common::StringMap &map) {
+ for (const PlainGameDescriptor *pd = ADRIFT_GAME_LIST; pd->gameId; ++pd) {
+ if (map.contains(pd->gameId))
+ error("Duplicate game Id found - %s", pd->gameId);
+ map[pd->gameId] = "";
+ }
+}
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/adrift/detection.h b/engines/glk/adrift/detection.h
new file mode 100644
index 0000000..f58d3cf
--- /dev/null
+++ b/engines/glk/adrift/detection.h
@@ -0,0 +1,63 @@
+/* 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_ADRIFT_DETECTION
+#define GLK_ADRIFT_DETECTION
+
+#include "common/fs.h"
+#include "common/hash-str.h"
+#include "engines/game.h"
+#include "glk/detection.h"
+
+namespace Glk {
+namespace Adrift {
+
+/**
+ * Meta engine for Adrift interpreter
+ */
+class AdriftMetaEngine {
+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 Adrift
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/adrift/detection_tables.h b/engines/glk/adrift/detection_tables.h
new file mode 100644
index 0000000..bbb98de
--- /dev/null
+++ b/engines/glk/adrift/detection_tables.h
@@ -0,0 +1,273 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "engines/game.h"
+#include "common/gui_options.h"
+#include "common/language.h"
+
+namespace Glk {
+namespace Adrift {
+
+/**
+ * Game description
+ */
+struct AdriftGameDescription {
+ const char *const _gameId;
+ const char *const _extra;
+ const char *const _md5;
+ size_t _filesize;
+ Common::Language _language;
+};
+
+const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
+ { "Adrift", "Adrift IF Game" },
+
+ { "3monkeys", "Three Monkeys, One Cage" },
+ { "akron", "Akron" },
+ { "albridgemanor", "Albridge Manor" },
+ { "asdfa", "A Short Damn Fantasy Adventure" },
+ { "awalkatdusk", "A Walk At Dusk" },
+ { "bariscebik", "Bariscebik" },
+ { "barneysproblem", "Barney's Problem" },
+ { "beanstalk", "Beanstalk the and Jack" },
+ { "beerisntenough", "WHen Beer Isn't Enough" },
+ { "buriedalive", "Buried Alive" },
+ { "caveofwonders", "Cave of Wondors" },
+ { "cbn1", "The Revenge Of Clueless Bob Newbie!" },
+ { "cbn2", "The Revenge Of Clueless Bob Newbie, Part 2" },
+ { "chooseyourown", "Choose Your Own..." },
+ { "circusmenagerie", "Menagerie!" },
+ { "cityInfear", "City In Fear" },
+ { "coloromcadrift", "Color of Milk COffee" },
+ { "compendiumendgame", "The WOodfish Compendium: The Game to End All Games" },
+ { "compendiumforum", "The WOodfish Compendium: Forum" },
+ { "compendiumforum2", "The WOodfish Compendium: Forum2" },
+ { "compendiumimagi", "The WOodfish Compendium: ImagiDroids" },
+ { "compendiumsaffire", "The WOodfish Compendium: Saffire " },
+ { "compendiumtopaz", "The WOodfish Compendium: Topaz" },
+ { "cowboyblues", "Cowboy Blues" },
+ { "crawlersdelight", "Crawler's Delight" },
+ { "crimeadventure", "Crime Adventure" },
+ { "cursed", "Cursed" },
+ { "cursedhints", "Cursed - Hints" },
+ { "cyber1", "Cyber Warp 1" },
+ { "cyber2", "Cyber Warp 2" },
+ { "darkness", "Darkness" },
+ { "dayattheoffice", "A Day at the Office" },
+ { "deadreckoningadrift", "Dead Reckoning" },
+ { "dontgoadrift", "Don't Go" },
+ { "doortoutopia", "The Door to Utopia" },
+ { "drwhovortexlust", "Doctor Who and The Vortex of Lust" },
+ { "dragonshrine", "The Curse of DragonShrine" },
+ { "edithscats", "Edith's Cats" },
+ { "enc1", "Encounter 1 : Tim's Mom" },
+ { "enc2", "Encounter 2 : The Study Group" },
+ { "escapetofreedom", "Escape to Freedom" },
+ { "etnyadrift", "Escape to New York" },
+ { "farfromhome", "Far From Home" },
+ { "frustratedinterviewee", "Frustrated Interviewee" },
+ { "gammagals", "The Gamma Gals" },
+ { "ghosttownadrift", "Ghost Town" },
+ { "gmylm", "Give Me Your Lunch Money" },
+ { "goblinhunt", "Goblin Hunt" },
+ { "goldilocksadrift", "Goldilocks is a FOX!" },
+ { "halloweenhijinks", "Halloween Hijinks" },
+ { "houseofthedamned", "House of the Damned" },
+ { "hhofhh", "The Haunted House of Hideous Horror" },
+ { "hcw", "How to Conquer the World" },
+ { "jgrim", "Jonathan Grimshaw: Space Tourist" },
+ { "jimpond", "Jim Pond 1" },
+ { "lairofthevampire", "Lair of the Vampire" },
+ { "legacyofaprincess", "Legacy of a Princess" },
+ { "longjourneyhome", "The Long Journey Home" },
+ { "lostadrift", "Lost" },
+ { "magicshow", "The Magic Show" },
+ { "maroonedadrift", "Marooned" },
+ { "ml256", "Makers Local and the Transdimensional Margarita Blender" },
+ { "monsterage", "Monster Age: Trials of Dustorn" },
+ { "monsters", "Monsters" },
+ { "murdererhadleft", "What The Murderer Had Left" },
+ { "mustescape", "Must Escape!" },
+ { "darkhavenmystery", "The Mystery Of The Darkhaven Caves" },
+ { "neighboursfromhell", "Neighbours From Hell" },
+ { "onnafa", "Oh No, Not Another Fantasy Adventure" },
+ { "overtheedge", "Over the Edge" },
+ { "paintadrift", "Paint!!!" },
+ { "pathwayadrift", "Pathway to Destruction" },
+ { "percytheviking", "The Saga Of Percy The Viking" },
+ { "pestilence", "Pestilence" },
+ { "phonebooth", "Pick Up the Phone Booth and Cry" },
+ { "towerprincess", "The Princess in the Tower" },
+ { "professorvonwitt", "Professor von Witt's Fabulous Flying Machine" },
+ { "provenance", "Provenance" },
+ { "rachelbadday", "Rachel has a bad day" },
+ { "readinginmayadrift", "A Reading in May" },
+ { "sceneofthecrime", "Scene of the Crime" },
+ { "selmaswill", "Selma's Will" },
+ { "seymoursstoopidquest", "Seymour's Stoopid Quest" },
+ { "shardsofmemory", "Shards of Memory" },
+ { "sommerilse", "Sommeril Special Edition" },
+ { "stowaway", "Stowaway" },
+ { "takeone", "Take One" },
+ { "target", "Target" },
+ { "thepkgirl", "The PK Girl" },
+ { "viewisbetter", "The View Is Better Here" },
+ { "thelasthour", "The Last Hour" },
+ { "ticket", "Ticket to No Where" },
+ { "hellinahamper", "To Hell in a Hamper" },
+ { "toomuchexercise", "Too Much Exercise" },
+ { "topaz", "Topaz" },
+ { "twilight", "The Twilight" },
+ { "unauthorizedtermination", "Unauthorised Termination" },
+ { "unfortunately", "Back To Life... Unfortunately" },
+ { "unravelinggod", "Unraveling God" },
+ { "vague", "Vague" },
+ { "veteranknowledge" , "Veteran Knowledge" },
+ { "waxworx", "Wax Worx" },
+ { "campwindylake", "Camp Windy Lake" },
+ { "woodsaredark", "The Woods Are Dark" },
+ { "worstgame", "The Worst Game In The World... Ever!!!" },
+ { "wrecked", "Wrecked" },
+ { "xycanthus", "Doomed Xycanthus" },
+ { "yadfa", "Yet Another Damn Fantasy Adventure" },
+ { "yonastoundingcastle", "Yon Astounding Castle! of some sort" },
+
+ { nullptr, nullptr }
+};
+
+const AdriftGameDescription ADRIFT_GAMES[] = {
+ DT_ENTRY0("3monkeys", "dec34c282511b1eadfe231dbbb49f625", 79286),
+ DT_ENTRY0("akron", "2461ceeef3ef1eac15a2051a549b4402", 22258),
+ DT_ENTRY0("albridgemanor", "268003e454c4ade042d593af8397a490", 31353),
+ DT_ENTRY0("asdfa", "06173b47b4e88c0a494d2263666ad375", 27733),
+ DT_ENTRY0("awalkatdusk", "f2e8aca65a17d41804709ee5a420ef36", 20725),
+ DT_ENTRY0("bariscebik", "d63d310e2b2fe4ab7ea6bc74c136b8e0", 14634),
+ DT_ENTRY0("barneysproblem", "3fe45352a6c0d7bb0bdbf4f9c08afba7", 66055),
+ DT_ENTRY0("beanstalk", "fc9c17c355894948dc2e72c66e8d9963", 9837),
+ DT_ENTRY0("beerisntenough", "98248a8e65a36f6d0fb98111255a85dc", 14070),
+ DT_ENTRY0("buriedalive", "9e9a71babf3012461205dc7aa2cd2a3f", 11808),
+ DT_ENTRY0("caveofwonders", "f55f4e63886eb09e1f89bea547574919", 85471),
+ DT_ENTRY0("cbn1", "9e27ab68a1f37f5f7591b362c4888526", 7577),
+ DT_ENTRY0("cbn2", "983eacedabebf7bbd8fed72ed399bba4", 6137),
+ DT_ENTRY0("chooseyourown", "774ae5ba4fea61da0898069df4ed1c81", 54869),
+ DT_ENTRY0("circusmenagerie", "3814400e3abb3e6340f055d5ec883c46", 117017),
+ DT_ENTRY0("cityInfear", "a6f625f184fa848ee6746e9aa6c94915", 248088),
+ DT_ENTRY0("coloromcadrift", "6b8d8f115a89c99f785156a9b5802bc2", 12681),
+ DT_ENTRY0("compendiumendgame", "ad76afa2fcdb8c9e2272a115cce6bd4f", 4092),
+ DT_ENTRY0("compendiumforum1", "273b73bf6262f603bee198238bc02196", 9128),
+ DT_ENTRY0("compendiumforum2", "b4af4a085707f221dbabd2906e411d29", 11172),
+ DT_ENTRY0("compendiumimagi", "3cfd6a4dd7ce552afdc52d0923e079cd", 9273),
+ DT_ENTRY0("compendiumsaffire", "d8a0413cdb908ba2ac400fe6a880d954", 7486),
+ DT_ENTRY0("compendiumtopaz", "5f91c9cd4391b6e44c2c052698d01118", 4866),
+ DT_ENTRY0("cowboyblues", "23eabfd5db63ded776dd0323d2abe7ea", 111835),
+ DT_ENTRY0("crawlersdelight", "9da704541689f95b3636ad729cfda5f4", 18705),
+ DT_ENTRY0("crimeadventure", "965eafa4579caa3bb8382a07b5e1771e", 15073),
+ DT_ENTRY0("cursed", "62d2e05e62f1137b25a61bbb46154729", 487990),
+ DT_ENTRY0("cursed_hints", "4ad13bf274af97ebbfe47c4a852b3a46", 36793),
+ DT_ENTRY0("cyber1", "b53f7a302edad4d9e2a3310dc1c66e72", 1786),
+ DT_ENTRY0("cyber2", "535c161818ee238e112b1d00bd082b26", 3384),
+ DT_ENTRY0("darkness", "f02a5be2f9a2fd59ef10f3d16157ee27", 25238),
+ DT_ENTRY0("dayattheoffice", "2d908b5448c6fd2dbc98a7f9d2dda9df", 13824),
+ DT_ENTRY0("deadreckoningadrift", "c49f787df29d6a73e77a0a33386614d3", 82279),
+ DT_ENTRY0("dontgoadrift", "f192abcc4e1f04787a7f1fde2ad05385", 13789),
+ DT_ENTRY0("doortoutopia", "9e727b8ad5b9c62d712d4a302083f6d8", 15432),
+ DT_ENTRY0("drwhovortexlust", "e2b76d720096fb6427927456fc80c5a2", 166913),
+ DT_ENTRY0("dragonshrine", "604250027cfd8cfd1fb0d231085e40e5", 636932),
+ DT_ENTRY0("edithscats", "0c6bbf3d292a427182458bd5332f2348", 18316),
+ DT_ENTRY0("enc1", "d297f4376e5ba5b05985ca12a60d8671", 101668),
+ DT_ENTRY0("enc2", "4bd8ebd78a0a227510f62f2074e60ee5", 120335),
+ DT_ENTRY0("escapetofreedom", "a7edcb289eb8177a143a96912ec55393", 18171),
+ DT_ENTRY0("etnyadrift", "990c0e2390d197ebcae1109e5534c433", 59583),
+ DT_ENTRY0("farfromhome", "b84df75a6ff647006f1f2783bde114f7", 42118),
+ DT_ENTRY0("frustratedinterviewee", "86dcc06a9edcd967183d5448165fd92e", 50578),
+ DT_ENTRY0("gammagals", "db813e61ded3e7f642d437ef1e77d0b3", 277834),
+ DT_ENTRY0("ghosttownadrift", "60c11a24853dec5e6a292914c6b4f7f2", 30205645),
+ DT_ENTRY0("gmylm", "67b61f16ca39d8abc9eb770385ef0e50", 15194757),
+ DT_ENTRY0("goblinhunt", "5e36c63feebf77cfba30757042a9fafa", 10891),
+ DT_ENTRY0("goldilocksadrift", "12e596065ae94d3f86a67acb4de2aae7", 56539),
+ DT_ENTRY0("halloweenhijinks", "14694f7b9cef4baeb0f958500119d2ff", 68052),
+ DT_ENTRY0("houseofthedamned", "3b25e7d9e1fd6ff2206ab0555c19e899", 35974),
+ DT_ENTRY0("hhofhh", "cff22c2f2af619ac56e075e95385e600", 6541),
+ DT_ENTRY0("hcw", "327dfec3d8f0b63ff5b05a552ee946ca", 82659),
+ DT_ENTRY0("jgrim", "f9c1b2064edeed5675a3466baeebdefd", 96713),
+ DT_ENTRY0("jimpond", "eef1aed7efbd36283b7d39b1514b3933", 50551),
+ DT_ENTRY0("lairofthevampire", "33dce0c1c3f9ed2beded0bab931e8d78", 133689),
+ DT_ENTRY0("legacyofaprincess", "9db58796cc772b662743e9a65ae1a876", 37003),
+ DT_ENTRY0("longjourneyhome", "c16c9e02c4a3248b25cb4f6c1ada0646", 59124),
+ DT_ENTRY0("lostadrift", "904b80ebf94df890ad7c26e454b6a612", 42596),
+ DT_ENTRY0("magicshow", "29fd03636eec8ffdaea26251a6f2444c", 104201),
+ DT_ENTRY0("maroonedadrift", "5e3e0435c98a0a915a98d5b1b080522c", 50516),
+ DT_ENTRY0("ml256", "68862c0031f1497e32ce26e0654bb07f", 32397),
+ DT_ENTRY0("monsterage", "00b8e89e5e7421a0ea017707466efe17", 16486),
+ DT_ENTRY0("monsters", "fde7be359d37c9229fec77244fc38a54", 17168),
+ DT_ENTRY0("murdererhadleft", "f95c63f90f28061a15dbe3bdf0cd4048", 13425),
+ DT_ENTRY0("mustescape", "e58fd08918fa3d5a38f424f79595fb4e", 17497),
+ DT_ENTRY0("darkhavenmystery", "1027e9e3dba08e0fd2796e0e934be855", 27826),
+ DT_ENTRY0("neighboursfromhell", "686d8c0995aa085fb056c6a5bd402911", 13520),
+ DT_ENTRY0("onnafa", "da4c0cc6fe34a08047de54abc66de038", 167339),
+ DT_ENTRY0("overtheedge", "9c7bfb9252ac80597ef125c95d58a54b", 14771),
+ DT_ENTRY1("overtheedge", "Gargoyle", "a6bb780b231c31a9e01455d0424acdca", 14937),
+ DT_ENTRY0("paintadrift", "1183921d034d3614ec277e18d9112b69", 76493),
+ DT_ENTRY0("pathwayadrift", "bcf1f61393c1b8123a98ee4879ffd8a6", 20896),
+ DT_ENTRY0("percytheviking", "e995d3a23005914eb92836f141ebe1c4", 5965),
+ DT_ENTRY0("pestilence", "2d5ff3fe2d866150689749087d5cee3d", 29021),
+ DT_ENTRY0("phonebooth", "25f4977d7b8df28322df945809826f43", 1372),
+ DT_ENTRY0("towerprincess", "d745a3f2c4dc40fb10f25d1539a2a1e7", 7181),
+ DT_ENTRY0("professorvonwitt", "570e7d90fa42a199ee0cba44a3c95d6b", 31253),
+ DT_ENTRY0("provenance", "49ebc8ad4f681eb727c8a2c90c3c6dd7", 532278),
+ DT_ENTRY0("rachelbadday", "8940ad383d78b2ba5d1fa9738bf1ea98", 98539),
+ DT_ENTRY0("readinginmayadrift", "ba8a12e79520234e31622f141c99cafd", 13434),
+ DT_ENTRY0("sceneofthecrime", "a8a094b145523c622e65ab6897727f2d", 68054),
+ DT_ENTRY0("selmaswill", "23b7fb4bf976135b8be2740e1fbfb83b", 19559),
+ DT_ENTRY0("seymoursstoopidquest", "61f4e155b958c1c652f12ed4216ee10d", 12623),
+ DT_ENTRY0("shardsofmemory", "9b75834354aed4b148d4ec2b8cdd66ae", 118604),
+ DT_ENTRY0("sommerilse", "1870db33af741482bb5d93ab54200e7c", 22839),
+ DT_ENTRY0("stowaway", "6877c3079978ecf74e72b792005fca32", 14231),
+ DT_ENTRY0("takeone", "114caad9308b7adf9e15267a11f12632", 9547),
+ DT_ENTRY0("target", "c6bbbae5ea3f6407a55435cb4e0c20c3", 43024),
+ DT_ENTRY0("thepkgirl", "c9282cf8f91ebfe5a93b136f56d7a1aa", 1645515),
+ DT_ENTRY0("viewisbetter", "9334adc4ccd03ceb1684ee56fdb07ab9", 7720),
+ DT_ENTRY0("thelasthour", "786d39eb223a64fe836f87b032b60ae1", 10658),
+ DT_ENTRY0("ticket", "8c549a6bdc6a5a4895412516be8dce25", 65502),
+ DT_ENTRY0("hellinahamper", "810247344fddc9a812bf6283b4826093", 80183),
+ DT_ENTRY0("toomuchexercise", "aebb58d94f632c4232bee72b9a1b5e25", 6248),
+ DT_ENTRY0("topaz", "0777a97e473b41ae04ab825556748e8d", 5980),
+ DT_ENTRY0("twilight", "ab5ddd461c1fb2065d26fcfdf4baa5aa", 71377),
+ DT_ENTRY0("unauthorizedtermination", "a7bba6890fe2945bb192c67e395516ac", 107335),
+ DT_ENTRY0("unfortunately", "8493ffd877273ef95c88c8f433126473", 55438),
+ DT_ENTRY0("unravelinggod", "2d43577a756ddc6b561f447e67270ac4", 45000),
+ DT_ENTRY0("vague", "0f5ef8616c668b9c3de078a77b26a512", 122681),
+ DT_ENTRY0("veteranknowledge", "409d3d59cb767dc8b812e16db78b2e47", 52248),
+ DT_ENTRY0("waxworx", "a10a1e404ae77fd968b4427a13bd7034", 38414),
+ DT_ENTRY0("campwindylake", "33ea1f1fea9998472e9c352ea6e1c1d8", 114698),
+ DT_ENTRY0("woodsaredark", "4acae86746292076b90fa6fa73ea76d0", 71216),
+ DT_ENTRY0("worstgame", "8789e209419529ac22d2be4774620c78", 9858),
+ DT_ENTRY0("wrecked", "b1c6c4ef73025fbbe99b612a72e3186a", 88550),
+ DT_ENTRY0("xycanthus", "5637cb8221087c5cca094b13138655c3", 116322),
+ DT_ENTRY0("yadfa", "5ee5906fc4b889d126cdfd83bd883a43", 77880),
+ DT_ENTRY0("yonastoundingcastle", "baf2c0423903a3104f67d3a19bde43df", 2320881),
+
+ DT_END_MARKER
+};
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index 3037fe9..0345e8f 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -23,6 +23,8 @@
#include "glk/glk.h"
#include "glk/detection.h"
#include "glk/quetzal.h"
+#include "glk/adrift/detection.h"
+#include "glk/adrift/adrift.h"
#include "glk/advsys/detection.h"
#include "glk/advsys/advsys.h"
#include "glk/alan2/detection.h"
@@ -155,6 +157,7 @@ Common::Error GlkMetaEngine::createInstance(OSystem *syst, Engine **engine) cons
else if ((*engine = create<Glk::Hugo::HugoMetaEngine, Glk::Hugo::Hugo>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Scott::ScottMetaEngine, Glk::Scott::Scott>(syst, gameDesc)) != nullptr) {}
#ifndef RELEASE_BUILD
+ else if ((*engine = create<Glk::Adrift::AdriftMetaEngine, Glk::Adrift::Adrift>(syst, gameDesc)) != nullptr) {}
else if ((*engine = create<Glk::Magnetic::MagneticMetaEngine, Glk::Magnetic::Magnetic>(syst, gameDesc)) != nullptr) {}
else if ((td = Glk::TADS::TADSMetaEngine::findGame(gameDesc._gameId.c_str()))._description) {
if (td._options & Glk::TADS::OPTION_TADS3)
@@ -202,6 +205,7 @@ PlainGameList GlkMetaEngine::getSupportedGames() const {
Glk::Hugo::HugoMetaEngine::getSupportedGames(list);
Glk::Scott::ScottMetaEngine::getSupportedGames(list);
#ifndef RELEASE_BUILD
+ Glk::Adrift::AdriftMetaEngine::getSupportedGames(list);
Glk::Magnetic::MagneticMetaEngine::getSupportedGames(list);
Glk::TADS::TADSMetaEngine::getSupportedGames(list);
#endif
@@ -232,6 +236,9 @@ PlainGameDescriptor GlkMetaEngine::findGame(const char *gameId) const {
if (gd._description) return gd;
#ifndef RELEASE_BUILD
+ gd = Glk::Adrift::AdriftMetaEngine::findGame(gameId);
+ if (gd._description) return gd;
+
gd = Glk::Magnetic::MagneticMetaEngine::findGame(gameId);
if (gd._description) return gd;
@@ -255,6 +262,7 @@ DetectedGames GlkMetaEngine::detectGames(const Common::FSList &fslist) const {
Glk::Scott::ScottMetaEngine::detectGames(fslist, detectedGames);
#ifndef RELEASE_BUILD
+ Glk::Adrift::AdriftMetaEngine::detectGames(fslist, detectedGames);
Glk::Magnetic::MagneticMetaEngine::detectGames(fslist, detectedGames);
Glk::TADS::TADSMetaEngine::detectGames(fslist, detectedGames);
#endif
@@ -273,6 +281,7 @@ void GlkMetaEngine::detectClashes() const {
Glk::Scott::ScottMetaEngine::detectClashes(map);
#ifndef RELEASE_BUILD
+ Glk::Adrift::AdriftMetaEngine::detectClashes(map);
Glk::Magnetic::MagneticMetaEngine::detectClashes(map);
Glk::TADS::TADSMetaEngine::detectClashes(map);
#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index a0e8428..bc65355 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -28,6 +28,7 @@ MODULE_OBJS := \
window_text_buffer.o \
window_text_grid.o \
adrift/adrift.o \
+ adrift/detection.o \
adrift/os_glk.o \
adrift/scdebug.o \
adrift/scevents.o \
Commit: 146199f29bc5e2b278e3d02c906922aaa68870b3
https://github.com/scummvm/scummvm/commit/146199f29bc5e2b278e3d02c906922aaa68870b3
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Adding Blorb support
Changed paths:
engines/glk/adrift/detection.cpp
engines/glk/adrift/detection_tables.h
engines/glk/blorb.cpp
engines/glk/blorb.h
diff --git a/engines/glk/adrift/detection.cpp b/engines/glk/adrift/detection.cpp
index fc76a08..fc41ac0 100644
--- a/engines/glk/adrift/detection.cpp
+++ b/engines/glk/adrift/detection.cpp
@@ -22,6 +22,7 @@
#include "glk/adrift/detection.h"
#include "glk/adrift/detection_tables.h"
+#include "glk/blorb.h"
#include "common/debug.h"
#include "common/file.h"
#include "common/md5.h"
@@ -46,17 +47,13 @@ GameDescriptor AdriftMetaEngine::findGame(const char *gameId) {
}
bool AdriftMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
- const char *const EXTENSIONS[] = { ".taf", nullptr };
-
// Loop through the files of the folder
for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
// Check for a recognised filename
if (file->isDirectory())
continue;
Common::String filename = file->getName();
- bool hasExt = false;
- for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
- hasExt = filename.hasSuffixIgnoreCase(*ext);
+ bool hasExt = Blorb::hasBlorbExt(filename) || filename.hasSuffixIgnoreCase(".taf");
if (!hasExt)
continue;
@@ -67,8 +64,13 @@ bool AdriftMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
size_t filesize = gameFile.size();
+ gameFile.seek(0);
+ bool isBlorb = Blorb::isBlorb(gameFile, ID_ADRI);
gameFile.close();
+ if (!isBlorb && Blorb::hasBlorbExt(filename))
+ continue;
+
// Check for known games
const AdriftGameDescription *p = ADRIFT_GAMES;
while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
diff --git a/engines/glk/adrift/detection_tables.h b/engines/glk/adrift/detection_tables.h
index bbb98de..0df9388 100644
--- a/engines/glk/adrift/detection_tables.h
+++ b/engines/glk/adrift/detection_tables.h
@@ -41,6 +41,7 @@ struct AdriftGameDescription {
const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "Adrift", "Adrift IF Game" },
+ // English Games
{ "3monkeys", "Three Monkeys, One Cage" },
{ "akron", "Akron" },
{ "albridgemanor", "Albridge Manor" },
@@ -151,10 +152,23 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "yadfa", "Yet Another Damn Fantasy Adventure" },
{ "yonastoundingcastle", "Yon Astounding Castle! of some sort" },
+ // English Blorb Games
+ { "advbackyard", "An Adventurer's Backyard" },
+ { "allthroughthenight", "All Through the Night" },
+ { "darkhour", "The Dark Hour" },
+ { "jacarandajim", "Jacaranda Jim" },
+ { "jacd", "Just Another Christmas Day" },
+ { "noblecrook1", "Noble Crook, episode 1" },
+ { "noblecrook2", "Noble Crook, episode 2" },
+ { "noblecrook3", "Noble Crook, episode 3" },
+ { "noblecrook4", "Noble Crook, episode 4" },
+ { "sonofcamelot", "Son of Camelot" },
+
{ nullptr, nullptr }
};
const AdriftGameDescription ADRIFT_GAMES[] = {
+ // English Games
DT_ENTRY0("3monkeys", "dec34c282511b1eadfe231dbbb49f625", 79286),
DT_ENTRY0("akron", "2461ceeef3ef1eac15a2051a549b4402", 22258),
DT_ENTRY0("albridgemanor", "268003e454c4ade042d593af8397a490", 31353),
@@ -266,6 +280,18 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("yadfa", "5ee5906fc4b889d126cdfd83bd883a43", 77880),
DT_ENTRY0("yonastoundingcastle", "baf2c0423903a3104f67d3a19bde43df", 2320881),
+ // English Blorb Games
+ DT_ENTRY0("advbackyard", "73b1171283ffa2b3cf6fb72a0ec31a35", 48990),
+ DT_ENTRY0("allthroughthenight", "89dcb84d74f70945780ed9e719401301", 36345976),
+ DT_ENTRY0("darkhour", "75bc2ac4d561ad2a2143bd90a19d1b46", 35184),
+ DT_ENTRY0("jacarandajim", "78e0de68825eea88995d7490adb6c062", 79146),
+ DT_ENTRY0("jacd", "28ae6ee45f1d2980765d3e9645f0b269", 54256),
+ DT_ENTRY0("noblecrook1", "334c706261ab79b783403ad3315980fd", 23966),
+ DT_ENTRY0("noblecrook2", "9d460ed691ad1b45d5d7c19f1ebf61d9", 22446),
+ DT_ENTRY0("noblecrook3", "c9d4a1ba7d5c1625f2d4cad0f067275a", 22088),
+ DT_ENTRY0("noblecrook4", "cb26241f8dba982bb0cd357ebd8fac45", 20606),
+ DT_ENTRY0("sonofcamelot", "7b3e9e45edc75202b3f586d0ca8dddde", 474380),
+
DT_END_MARKER
};
diff --git a/engines/glk/blorb.cpp b/engines/glk/blorb.cpp
index 36360c3..4678c1d 100644
--- a/engines/glk/blorb.cpp
+++ b/engines/glk/blorb.cpp
@@ -143,6 +143,7 @@ Common::ErrorCode Blorb::load() {
} else if (ce._type == ID_Exec) {
if (
+ (_interpType == INTERPRETER_ADRIFT && ce._id == ID_ADRI) ||
(_interpType == INTERPRETER_FROTZ && ce._id == ID_ZCOD) ||
(_interpType == INTERPRETER_GLULXE && ce._id == ID_GLUL) ||
(_interpType == INTERPRETER_TADS2 && ce._id == ID_TAD2) ||
diff --git a/engines/glk/blorb.h b/engines/glk/blorb.h
index 6076428..cfb5897 100644
--- a/engines/glk/blorb.h
+++ b/engines/glk/blorb.h
@@ -57,6 +57,7 @@ enum {
ID_AUTH = MKTAG('A', 'U', 'T', 'H'),
ID_ANNO = MKTAG('A', 'N', 'N', 'O'),
+ ID_ADRI = MKTAG('A', 'D', 'R', 'I'),
ID_ZCOD = MKTAG('Z', 'C', 'O', 'D'),
ID_GLUL = MKTAG('G', 'L', 'U', 'L'),
ID_TAD2 = MKTAG('T', 'A', 'D', '2'),
Commit: 7fe81a7f2fd2be606626bc2dd1f31c1df6ca6163
https://github.com/scummvm/scummvm/commit/7fe81a7f2fd2be606626bc2dd1f31c1df6ca6163
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Added Italian detection
Changed paths:
engines/glk/adrift/detection.cpp
engines/glk/adrift/detection_tables.h
engines/glk/detection.cpp
engines/glk/detection.h
diff --git a/engines/glk/adrift/detection.cpp b/engines/glk/adrift/detection.cpp
index fc41ac0..7623fdf 100644
--- a/engines/glk/adrift/detection.cpp
+++ b/engines/glk/adrift/detection.cpp
@@ -81,7 +81,7 @@ bool AdriftMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
} else {
PlainGameDescriptor gameDesc = findGame(p->_gameId);
- gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
+ gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, p->_extra, filename, p->_language));
}
}
diff --git a/engines/glk/adrift/detection_tables.h b/engines/glk/adrift/detection_tables.h
index 0df9388..a507e49 100644
--- a/engines/glk/adrift/detection_tables.h
+++ b/engines/glk/adrift/detection_tables.h
@@ -69,7 +69,6 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "crawlersdelight", "Crawler's Delight" },
{ "crimeadventure", "Crime Adventure" },
{ "cursed", "Cursed" },
- { "cursedhints", "Cursed - Hints" },
{ "cyber1", "Cyber Warp 1" },
{ "cyber2", "Cyber Warp 2" },
{ "darkness", "Darkness" },
@@ -164,6 +163,9 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "noblecrook4", "Noble Crook, episode 4" },
{ "sonofcamelot", "Son of Camelot" },
+ // Italian Games
+ { "ilgolem", "Il Golem" },
+
{ nullptr, nullptr }
};
@@ -196,7 +198,7 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("crawlersdelight", "9da704541689f95b3636ad729cfda5f4", 18705),
DT_ENTRY0("crimeadventure", "965eafa4579caa3bb8382a07b5e1771e", 15073),
DT_ENTRY0("cursed", "62d2e05e62f1137b25a61bbb46154729", 487990),
- DT_ENTRY0("cursed_hints", "4ad13bf274af97ebbfe47c4a852b3a46", 36793),
+ DT_ENTRY1("cursed", "Hints", "4ad13bf274af97ebbfe47c4a852b3a46", 36793),
DT_ENTRY0("cyber1", "b53f7a302edad4d9e2a3310dc1c66e72", 1786),
DT_ENTRY0("cyber2", "535c161818ee238e112b1d00bd082b26", 3384),
DT_ENTRY0("darkness", "f02a5be2f9a2fd59ef10f3d16157ee27", 25238),
@@ -292,6 +294,9 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("noblecrook4", "cb26241f8dba982bb0cd357ebd8fac45", 20606),
DT_ENTRY0("sonofcamelot", "7b3e9e45edc75202b3f586d0ca8dddde", 474380),
+ // Italian Games
+ DT_ENTRYL0("ilgolem", Common::IT_ITA, "7ab97545be9c30457d0c9e748ab7885f", 6372213),
+
DT_END_MARKER
};
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index 0345e8f..cce1ec1 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -70,6 +70,13 @@ GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common:
addExtraEntry("filename", filename);
}
+GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const char *extra,
+ const Common::String &filename, Common::Language lang) :
+ DetectedGame(id, desc, lang, Common::kPlatformUnknown, extra) {
+ setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
+ addExtraEntry("filename", filename);
+}
+
GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common::String &filename,
const Common::String &md5, size_t filesize) :
DetectedGame(id, desc, Common::UNK_LANG, Common::kPlatformUnknown) {
diff --git a/engines/glk/detection.h b/engines/glk/detection.h
index f3ed374..d262e43 100644
--- a/engines/glk/detection.h
+++ b/engines/glk/detection.h
@@ -112,6 +112,8 @@ public:
Common::Language lang);
GlkDetectedGame(const char *id, const char *desc, const Common::String &filename,
const Common::String &md5, size_t filesize);
+ GlkDetectedGame(const char *id, const char *desc, const char *extra, const Common::String &filename,
+ Common::Language lang);
};
/**
Commit: 58917059aefdfd689c570d85b33664462bfba44d
https://github.com/scummvm/scummvm/commit/58917059aefdfd689c570d85b33664462bfba44d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Adding competition detection entries
Changed paths:
engines/glk/adrift/detection_tables.h
diff --git a/engines/glk/adrift/detection_tables.h b/engines/glk/adrift/detection_tables.h
index a507e49..052f506 100644
--- a/engines/glk/adrift/detection_tables.h
+++ b/engines/glk/adrift/detection_tables.h
@@ -51,10 +51,7 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "barneysproblem", "Barney's Problem" },
{ "beanstalk", "Beanstalk the and Jack" },
{ "beerisntenough", "WHen Beer Isn't Enough" },
- { "buriedalive", "Buried Alive" },
{ "caveofwonders", "Cave of Wondors" },
- { "cbn1", "The Revenge Of Clueless Bob Newbie!" },
- { "cbn2", "The Revenge Of Clueless Bob Newbie, Part 2" },
{ "chooseyourown", "Choose Your Own..." },
{ "circusmenagerie", "Menagerie!" },
{ "cityInfear", "City In Fear" },
@@ -77,7 +74,6 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "dontgoadrift", "Don't Go" },
{ "doortoutopia", "The Door to Utopia" },
{ "drwhovortexlust", "Doctor Who and The Vortex of Lust" },
- { "dragonshrine", "The Curse of DragonShrine" },
{ "edithscats", "Edith's Cats" },
{ "enc1", "Encounter 1 : Tim's Mom" },
{ "enc2", "Encounter 2 : The Study Group" },
@@ -88,11 +84,9 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "gammagals", "The Gamma Gals" },
{ "ghosttownadrift", "Ghost Town" },
{ "gmylm", "Give Me Your Lunch Money" },
- { "goblinhunt", "Goblin Hunt" },
{ "goldilocksadrift", "Goldilocks is a FOX!" },
{ "halloweenhijinks", "Halloween Hijinks" },
{ "houseofthedamned", "House of the Damned" },
- { "hhofhh", "The Haunted House of Hideous Horror" },
{ "hcw", "How to Conquer the World" },
{ "jgrim", "Jonathan Grimshaw: Space Tourist" },
{ "jimpond", "Jim Pond 1" },
@@ -111,12 +105,9 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "neighboursfromhell", "Neighbours From Hell" },
{ "onnafa", "Oh No, Not Another Fantasy Adventure" },
{ "overtheedge", "Over the Edge" },
- { "paintadrift", "Paint!!!" },
{ "pathwayadrift", "Pathway to Destruction" },
- { "percytheviking", "The Saga Of Percy The Viking" },
{ "pestilence", "Pestilence" },
{ "phonebooth", "Pick Up the Phone Booth and Cry" },
- { "towerprincess", "The Princess in the Tower" },
{ "professorvonwitt", "Professor von Witt's Fabulous Flying Machine" },
{ "provenance", "Provenance" },
{ "rachelbadday", "Rachel has a bad day" },
@@ -124,8 +115,7 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "sceneofthecrime", "Scene of the Crime" },
{ "selmaswill", "Selma's Will" },
{ "seymoursstoopidquest", "Seymour's Stoopid Quest" },
- { "shardsofmemory", "Shards of Memory" },
- { "sommerilse", "Sommeril Special Edition" },
+ { "sommeril", "Sommeril" },
{ "stowaway", "Stowaway" },
{ "takeone", "Take One" },
{ "target", "Target" },
@@ -166,6 +156,96 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
// Italian Games
{ "ilgolem", "Il Golem" },
+ // Three Hour Games Competition: July 2004
+ { "3hgjailbreakbob", "Jailbreak Bob" },
+ { "3hgbriefcase", "Briefcase" },
+ { "3hgtheannihilationofthink", " Annihilation of Think.com" },
+ { "3hgshadricktravels", "Shadrick's Travels" },
+ { "3hglostsouls", "Lost Souls" },
+ { "3hgtheamulet", "Amulet" },
+ { "3hgzombiecow", "Zombie Cow" },
+
+ // Three Hour Games Competition: November 2004
+ { "3hgsandl", " Snakes and Ladders" },
+ { "3hgconfession", "The Murder of Jack Morely" },
+ { "3hgveteran", " Veteran Experience" },
+ { "3hgburiedalive", " Buried Alive" },
+ { "3hgzac", "Zombies are Cool" },
+ { "3hgtogetyou", "We are coming to get you!" },
+
+ // Game of the Year Competition: December 2004
+ { "goyshardsofmemory", " Shards of Memory" },
+ { "goyshadricksunderground", "Shadrack's Underground Adventure" },
+ { "goypaint", "Paint!!!" },
+ { "goydragonshrine", "The Curse of DragonShrine" },
+ { "goydarkness", "Darkness" },
+
+ // ADRIFT Intro Comp 2005
+ { "aicmurdermansion", "Murder Mansion" },
+ { "aicoutline", "Outline" },
+ { "aicsrs", "Silk Road Secrets: Samarkand to Lop Nor" },
+ { "aicescape", "Must Escape!" },
+ { "aicfinalquestion", "The Final Question" },
+ { "aicrift", "Rift" },
+ { "aicp2p", " Point 2 Point" },
+ { "aiczacksmackfoot", "Zack Smackfoot" },
+
+ // ADRIFT Mini-Competition Summer 2003
+ { "amcthorn", "Thorn" },
+ { "amcneighbours", "Neighbours From Hell" },
+ { "amcmonsters", "Monsters" },
+ { "amcdiarystrip", "Diary of a Stripper" },
+
+ // ADRIFT One-Hour Game Competition 1
+ { "1hgamonkeytoomany", "" },
+ { "1hgprincess1", "The Green Princess" },
+ { "1hg1hrgame", "TODO" },
+ { "1hgendgame", "The Game To End All Games" },
+ { "1hgchicken", "The Evil Chicken of Doom!" },
+ { "1hghauntedhouse", "The Haunted House of Hideous Horror" },
+ { "1hgfrog", "TODO" },
+ { "1hgmicrobewillie", "Microbe Willie vs. The Rat" },
+ { "1hgjasonvssalm", "Jason vs. Salm" },
+
+ // ADRIFT One-Hour Game Competition 2
+ { "1hgpercy", "The Saga of Percy the Viking" },
+ { "1hgforum", "Forum" },
+ { "1hgdfu", "Dance Fever USA" },
+
+ // ADRIFT One-Hour Game Competition 3
+ { "1hgforum2", "Forum 2" },
+ { "1hgcrm", "That Crazy Radioactive Monkey!" },
+ { "1hgasdfa", "A Short Damn Fantasy Adventure" },
+ { "1hgdemonhunter", "Apprentice of the Demonhunter" },
+ { "1hgcbn1", "The Revenge of Clueless Bob Newbie!" },
+ { "1hgcbn2", "The Revenge of Clueless Bob Newbie Part 2: This Time it's Personal" },
+ { "1hgticktick", "TODO" },
+ { "1hgpyramid", " The Pyramid of Hamaratum" },
+ { "1hgquesti", "Quest for Flesh" },
+ { "1hgshore", "The Farthest Shore" },
+ { "1hgsaffire", "Saffire" },
+ { "1hgecod2", " The Curse of the Revenge of the Ghost of the Evil Chicken of Doom... Returns!" },
+ { "1hgimagination", " Just My Imagination-Musings of a Child" },
+
+ // ADRIFT One-Hour Game Competition 4
+ { "1hgcah", "Cruel and Hilarious Punishment!" },
+ { "1hgarghsgreatescape", "Argh's Great Escape" },
+ { "1hgshreddem", "Shred 'em" },
+ { "1hgagent4f", "Agent 4-F From Mars" },
+ { "1hgecod3", "An Evening with the Evil Chicken of Doom" },
+ { "1hgtrabula", " Get Treasure for Trabula" },
+ { "1hgwoof", "Woof" },
+ { "1hgundefined", "Undefined" },
+ { "1hgadriftmaze", "Adrift Maze" },
+ { "1hgicecream", "Ice Cream" },
+ { "1hgwreckage", "SE: Wreckage" },
+ { "1hgspam", "SPAM" },
+ { "1hgvagabond", "Vagabond" },
+ { "1hgthecatinthetree", "The Cat in the Tree" },
+ { "1hgtopaz", "Topaz" },
+ { "1hggoblinhunt", "Goblin Hunt" },
+
+
{ nullptr, nullptr }
};
@@ -180,10 +260,7 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("barneysproblem", "3fe45352a6c0d7bb0bdbf4f9c08afba7", 66055),
DT_ENTRY0("beanstalk", "fc9c17c355894948dc2e72c66e8d9963", 9837),
DT_ENTRY0("beerisntenough", "98248a8e65a36f6d0fb98111255a85dc", 14070),
- DT_ENTRY0("buriedalive", "9e9a71babf3012461205dc7aa2cd2a3f", 11808),
DT_ENTRY0("caveofwonders", "f55f4e63886eb09e1f89bea547574919", 85471),
- DT_ENTRY0("cbn1", "9e27ab68a1f37f5f7591b362c4888526", 7577),
- DT_ENTRY0("cbn2", "983eacedabebf7bbd8fed72ed399bba4", 6137),
DT_ENTRY0("chooseyourown", "774ae5ba4fea61da0898069df4ed1c81", 54869),
DT_ENTRY0("circusmenagerie", "3814400e3abb3e6340f055d5ec883c46", 117017),
DT_ENTRY0("cityInfear", "a6f625f184fa848ee6746e9aa6c94915", 248088),
@@ -201,13 +278,13 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY1("cursed", "Hints", "4ad13bf274af97ebbfe47c4a852b3a46", 36793),
DT_ENTRY0("cyber1", "b53f7a302edad4d9e2a3310dc1c66e72", 1786),
DT_ENTRY0("cyber2", "535c161818ee238e112b1d00bd082b26", 3384),
+ DT_ENTRY0("darkness", "af7b3452fdb40f121f2a6be2fa81e4f8", 25203),
DT_ENTRY0("darkness", "f02a5be2f9a2fd59ef10f3d16157ee27", 25238),
DT_ENTRY0("dayattheoffice", "2d908b5448c6fd2dbc98a7f9d2dda9df", 13824),
DT_ENTRY0("deadreckoningadrift", "c49f787df29d6a73e77a0a33386614d3", 82279),
DT_ENTRY0("dontgoadrift", "f192abcc4e1f04787a7f1fde2ad05385", 13789),
DT_ENTRY0("doortoutopia", "9e727b8ad5b9c62d712d4a302083f6d8", 15432),
DT_ENTRY0("drwhovortexlust", "e2b76d720096fb6427927456fc80c5a2", 166913),
- DT_ENTRY0("dragonshrine", "604250027cfd8cfd1fb0d231085e40e5", 636932),
DT_ENTRY0("edithscats", "0c6bbf3d292a427182458bd5332f2348", 18316),
DT_ENTRY0("enc1", "d297f4376e5ba5b05985ca12a60d8671", 101668),
DT_ENTRY0("enc2", "4bd8ebd78a0a227510f62f2074e60ee5", 120335),
@@ -218,11 +295,9 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("gammagals", "db813e61ded3e7f642d437ef1e77d0b3", 277834),
DT_ENTRY0("ghosttownadrift", "60c11a24853dec5e6a292914c6b4f7f2", 30205645),
DT_ENTRY0("gmylm", "67b61f16ca39d8abc9eb770385ef0e50", 15194757),
- DT_ENTRY0("goblinhunt", "5e36c63feebf77cfba30757042a9fafa", 10891),
DT_ENTRY0("goldilocksadrift", "12e596065ae94d3f86a67acb4de2aae7", 56539),
DT_ENTRY0("halloweenhijinks", "14694f7b9cef4baeb0f958500119d2ff", 68052),
DT_ENTRY0("houseofthedamned", "3b25e7d9e1fd6ff2206ab0555c19e899", 35974),
- DT_ENTRY0("hhofhh", "cff22c2f2af619ac56e075e95385e600", 6541),
DT_ENTRY0("hcw", "327dfec3d8f0b63ff5b05a552ee946ca", 82659),
DT_ENTRY0("jgrim", "f9c1b2064edeed5675a3466baeebdefd", 96713),
DT_ENTRY0("jimpond", "eef1aed7efbd36283b7d39b1514b3933", 50551),
@@ -242,12 +317,9 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("onnafa", "da4c0cc6fe34a08047de54abc66de038", 167339),
DT_ENTRY0("overtheedge", "9c7bfb9252ac80597ef125c95d58a54b", 14771),
DT_ENTRY1("overtheedge", "Gargoyle", "a6bb780b231c31a9e01455d0424acdca", 14937),
- DT_ENTRY0("paintadrift", "1183921d034d3614ec277e18d9112b69", 76493),
DT_ENTRY0("pathwayadrift", "bcf1f61393c1b8123a98ee4879ffd8a6", 20896),
- DT_ENTRY0("percytheviking", "e995d3a23005914eb92836f141ebe1c4", 5965),
DT_ENTRY0("pestilence", "2d5ff3fe2d866150689749087d5cee3d", 29021),
DT_ENTRY0("phonebooth", "25f4977d7b8df28322df945809826f43", 1372),
- DT_ENTRY0("towerprincess", "d745a3f2c4dc40fb10f25d1539a2a1e7", 7181),
DT_ENTRY0("professorvonwitt", "570e7d90fa42a199ee0cba44a3c95d6b", 31253),
DT_ENTRY0("provenance", "49ebc8ad4f681eb727c8a2c90c3c6dd7", 532278),
DT_ENTRY0("rachelbadday", "8940ad383d78b2ba5d1fa9738bf1ea98", 98539),
@@ -255,8 +327,7 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("sceneofthecrime", "a8a094b145523c622e65ab6897727f2d", 68054),
DT_ENTRY0("selmaswill", "23b7fb4bf976135b8be2740e1fbfb83b", 19559),
DT_ENTRY0("seymoursstoopidquest", "61f4e155b958c1c652f12ed4216ee10d", 12623),
- DT_ENTRY0("shardsofmemory", "9b75834354aed4b148d4ec2b8cdd66ae", 118604),
- DT_ENTRY0("sommerilse", "1870db33af741482bb5d93ab54200e7c", 22839),
+ DT_ENTRY1("sommeril", "Special Edition", "1870db33af741482bb5d93ab54200e7c", 22839),
DT_ENTRY0("stowaway", "6877c3079978ecf74e72b792005fca32", 14231),
DT_ENTRY0("takeone", "114caad9308b7adf9e15267a11f12632", 9547),
DT_ENTRY0("target", "c6bbbae5ea3f6407a55435cb4e0c20c3", 43024),
@@ -297,6 +368,101 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
// Italian Games
DT_ENTRYL0("ilgolem", Common::IT_ITA, "7ab97545be9c30457d0c9e748ab7885f", 6372213),
+ // Three Hour Games Competition: July 2004
+ DT_ENTRY0("3hgjailbreakbob", "c2e909cf2ddda863d2eb613c8273ee37", 31064),
+ DT_ENTRY0("3hgbriefcase", "f1c899773faf027d9cbb50078a6667c3", 10872),
+ DT_ENTRY0("3hgtheannihilationofthink", "22743eceafe94bf60ab5a3e43241883e", 6303),
+ DT_ENTRY0("3hgshadricktravels", "33036e2b4c11a36d28e6532051e9f05b", 7456),
+ DT_ENTRY0("3hglostsouls", "3083e21a3bd6766ea5fdf3166e8bd4d8", 16695),
+ DT_ENTRY0("3hgtheamulet", "7c08e1f03763ad757dc39f5df37a28b7", 5585),
+ DT_ENTRY0("3hgzombiecow", "f0fe890f9679b158f9a22ed9f78179e6", 5193),
+
+ // Three Hour Games Competition: November 2004
+ DT_ENTRY0("3hgsandl", "73a1e0b4451690e76d306136ec30754b", 27995),
+ DT_ENTRY0("3hgconfession", "718faa6f6e72fcd4b95ebcb1601be7bd", 203757),
+ DT_ENTRY0("3hgveteran", "65d5fc95b59f24e0e4997f62bf592ba3", 12043),
+ DT_ENTRY0("3hgburiedalive", "9e9a71babf3012461205dc7aa2cd2a3f", 11808),
+ DT_ENTRY0("3hgzac", "85d95b8a6a962222d15724d42740f378", 13692),
+ DT_ENTRY0("3hgtogetyou", "388b5596945067ed3b92e6282e670825", 4496),
+
+ // Game of the Year Competition: December 2004
+ DT_ENTRY0("goyshardsofmemory", "7e9cb5002fa22a25000b3478c826413d", 118610),
+ DT_ENTRY0("goyshardsofmemory", "9b75834354aed4b148d4ec2b8cdd66ae", 118604),
+ DT_ENTRY0("goyshadricksunderground", "a9e1e59b37976c6c0fcc6aee69978afe", 113385),
+ DT_ENTRY0("waxworx", "94aaf6625541238867b079bfe475f146", 38471),
+ DT_ENTRY0("goypaint", "1183921d034d3614ec277e18d9112b69", 76493),
+ DT_ENTRY0("goydragonshrine", "604250027cfd8cfd1fb0d231085e40e5", 636932),
+ DT_ENTRY0("goydarkness", "6047363499d5eb666c341139d0eb532a", 24847),
+
+ // ADRIFT Intro Comp 2005
+ DT_ENTRY0("aicmurdermansion", "07367e1f546f80e64b44923f474f5906", 6793),
+ DT_ENTRY0("aicoutline", "b86de4feca73e0ea49c324a2181b8b8f", 5724),
+ DT_ENTRY0("aicsrs", "f1243c19976246c2c319fba5be6f9d13", 157833),
+ DT_ENTRY0("aicescape", "c5a13fa9059ebc2904eea95e1c6b790a", 3964),
+ DT_ENTRY0("aicfinalquestion", "1f1ede210336b6b8bd8e28eda2d00e0c", 15555),
+ DT_ENTRY0("aicrift", "b4dc3233be12767837bd596789379473", 2606),
+ DT_ENTRY0("aicp2p", "3b3386f5f0f844c3a9eb47ba2596135a", 6491),
+ DT_ENTRY0("aiczacksmackfoot", "a8d2d303c6e5f698d40714c3d5e241e2", 6374),
+
+ // ADRIFT Mini-Competition Summer 2003
+ DT_ENTRY0("amcthorn", "0d02030e9ac6563cda759a20ae1fc06b", 13887),
+ DT_ENTRY0("amcneighbours", "afdf85651706a4568762565b2c24aa8d", 13333),
+ DT_ENTRY0("amcmonsters", "02a042f7277dfc9789bd6ffee1e8db08", 9628),
+ DT_ENTRY0("amcdiarystrip", "0e04238a2b49220c284ce9c8723abd77", 43334),
+
+ // ADRIFT One-Hour Game Competition 1
+ DT_ENTRY0("1hgamonkeytoomany", "c9d719261d0f760f95685899aa80bbf5", 5016),
+ DT_ENTRY0("1hgprincess1", "d745a3f2c4dc40fb10f25d1539a2a1e7", 7181),
+ DT_ENTRY0("1hg1hrgame", "63e9594bf2b4e7cf5bf75dd9cc1353dc", 2978),
+ DT_ENTRY0("1hgendgame", "6036e5654786f841ca59f8f7e95276be", 4063),
+ DT_ENTRY0("1hgchicken", "40f0f52f2eeb029516bca3e01e6ceac0", 5249),
+ DT_ENTRY0("1hghauntedhouse", "cff22c2f2af619ac56e075e95385e600", 6541),
+ DT_ENTRY0("1hgfrog", "3a8f3a0a6b4efd4787e6d338e4b31cea", 2089),
+ DT_ENTRY0("1hgmicrobewillie", "14fe6ac0db4943fc9951610f5d0e0428", 3538),
+ DT_ENTRY0("1hgjasonvssalm", "70d60774dc777918645d7f3359f534cf", 2947),
+
+ // ADRIFT One-Hour Game Competition 2
+ DT_ENTRY0("1hgpercy", "e995d3a23005914eb92836f141ebe1c4", 5965),
+ DT_ENTRY0("1hgforum", "4df8a13d8823aca26207fb459e98dd8b", 9005),
+ DT_ENTRY0("1hgdfu", "e70e0bdfd9ffa0f20c2bc682eeb2f1ab", 16443),
+
+ // ADRIFT One-Hour Game Competition 3
+ DT_ENTRY0("1hgforum2", "5a534ac4e39a319022d145094c46930a", 11185),
+ DT_ENTRY0("1hgcrm", "d97d1ff8f01a61fb477b76df65c77795", 15432),
+ DT_ENTRY0("1hgasdfa", "fccb2fb890d554263d5f55bc02220ab8", 6440),
+ DT_ENTRY0("1hgdemonhunter", "ca37aaf35fb15a40a7f5f8caa1475112", 4169),
+ DT_ENTRY0("1hgcbn1", "9e27ab68a1f37f5f7591b362c4888526", 7577),
+ DT_ENTRY0("1hgcbn2", "983eacedabebf7bbd8fed72ed399bba4", 6137),
+ DT_ENTRY0("1hgticktick", "5b952d75e3e46a71334419c78dc6ff51", 2055),
+ DT_ENTRY0("1hgpyramid", "a198f4ca146fed3094bf5fd70d2eefdd", 1953),
+ DT_ENTRY0("1hgquesti", "c7d6058e8172ff5d4a974fe159aa9cb7", 2544),
+ DT_ENTRY0("1hgshore", "ef0b6074e47f55b7dff868e5dbd0c0cf", 4354),
+ DT_ENTRY0("1hgsaffire", "d3eb89cf10d11a42df2df8f7bdb1505a", 7489),
+ DT_ENTRY0("1hgecod2", "ff55438090db248964fd8944f3a2da9f", 17584),
+ DT_ENTRY0("1hgimagination", "91923aeec3b7a8c55a15bc6dd240f7fb", 3257),
+
+ // ADRIFT One-Hour Game Competition 4
+ DT_ENTRY0("1hgcah", "1945c5584b775b22c9b329915629eb44", 9808),
+ DT_ENTRY0("1hgarghsgreatescape", "0de27ef52495de415637d78e393c612f", 3608),
+ DT_ENTRY0("1hgshreddem", "426885b0a8a9aade134307fad1693512", 1209),
+ DT_ENTRY0("1hgagent4f", "407cc79b128aefdae4fdabb4d7a661e4", 3703),
+ DT_ENTRY0("1hgecod3", "bd783057274a626868b052915bad2a2c", 10870),
+ DT_ENTRY0("1hgtrabula", "54fd39f8d86b4e1726970073342057da", 2224),
+ DT_ENTRY0("1hgwoof", "f66cbdcf9f7c6a3b30b0c7ca95bdea46", 1712),
+ DT_ENTRY0("1hgundefined", "cf5172b53c8e3ef3a8739a31b78cccc2", 2920),
+ DT_ENTRY0("1hgadriftmaze", "017d681d45402c2d75ae70c28d2b467f", 2224),
+ DT_ENTRY0("1hgicecream", "f68b7ec0959459cd1ee3c741660010c6", 5039),
+ DT_ENTRY0("1hgwreckage", "822b988245ff40c6f490edc046921fcf", 4487),
+ DT_ENTRY0("1hgspam", "2ffc74d57936add0cdc06d83924f0f15", 2807),
+ DT_ENTRY0("1hgvagabond", "ae8545f6506fe3a49e27c96721196dce", 4762),
+ DT_ENTRY0("1hgthecatinthetree", "f67640c2ed3b621272ebbea06a5fd467", 6174),
+ DT_ENTRY0("1hgtopaz", "7d4beb159bf3876f761bbac911395d05", 4839),
+ DT_ENTRY0("1hggoblinhunt", "5e36c63feebf77cfba30757042a9fafa", 10891),
+
+ // InsideADRIFT Spring Competition 2004
+ DT_ENTRY0("waxworx", "4fa14c7944506f4e0142cb865738d0b0", 37542),
+ DT_ENTRY0("sommeril", "9e8ee4cbd4ecab3ab51c702f4e0277e1", 400940),
+
DT_END_MARKER
};
Commit: ebc12d193b9d6d3fce1119b52393cd3acbdb2b2f
https://github.com/scummvm/scummvm/commit/ebc12d193b9d6d3fce1119b52393cd3acbdb2b2f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Added remaining detection entries
Changed paths:
engines/glk/adrift/detection_tables.h
diff --git a/engines/glk/adrift/detection_tables.h b/engines/glk/adrift/detection_tables.h
index 052f506..c824905 100644
--- a/engines/glk/adrift/detection_tables.h
+++ b/engines/glk/adrift/detection_tables.h
@@ -52,16 +52,15 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "beanstalk", "Beanstalk the and Jack" },
{ "beerisntenough", "WHen Beer Isn't Enough" },
{ "caveofwonders", "Cave of Wondors" },
- { "chooseyourown", "Choose Your Own..." },
{ "circusmenagerie", "Menagerie!" },
{ "cityInfear", "City In Fear" },
{ "coloromcadrift", "Color of Milk COffee" },
- { "compendiumendgame", "The WOodfish Compendium: The Game to End All Games" },
- { "compendiumforum", "The WOodfish Compendium: Forum" },
- { "compendiumforum2", "The WOodfish Compendium: Forum2" },
- { "compendiumimagi", "The WOodfish Compendium: ImagiDroids" },
- { "compendiumsaffire", "The WOodfish Compendium: Saffire " },
- { "compendiumtopaz", "The WOodfish Compendium: Topaz" },
+ { "compendiumendgame", "The Woodfish Compendium: The Game to End All Games" },
+ { "compendiumforum", "The Woodfish Compendium: Forum" },
+ { "compendiumforum2", "The Woodfish Compendium: Forum2" },
+ { "compendiumimagi", "The Woodfish Compendium: ImagiDroids" },
+ { "compendiumsaffire", "The Woodfish Compendium: Saffire " },
+ { "compendiumtopaz", "The Woodfish Compendium: Topaz" },
{ "cowboyblues", "Cowboy Blues" },
{ "crawlersdelight", "Crawler's Delight" },
{ "crimeadventure", "Crime Adventure" },
@@ -101,7 +100,6 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "monsters", "Monsters" },
{ "murdererhadleft", "What The Murderer Had Left" },
{ "mustescape", "Must Escape!" },
- { "darkhavenmystery", "The Mystery Of The Darkhaven Caves" },
{ "neighboursfromhell", "Neighbours From Hell" },
{ "onnafa", "Oh No, Not Another Fantasy Adventure" },
{ "overtheedge", "Over the Edge" },
@@ -122,7 +120,6 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "thepkgirl", "The PK Girl" },
{ "viewisbetter", "The View Is Better Here" },
{ "thelasthour", "The Last Hour" },
- { "ticket", "Ticket to No Where" },
{ "hellinahamper", "To Hell in a Hamper" },
{ "toomuchexercise", "Too Much Exercise" },
{ "topaz", "Topaz" },
@@ -175,7 +172,6 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
// Game of the Year Competition: December 2004
{ "goyshardsofmemory", " Shards of Memory" },
- { "goyshadricksunderground", "Shadrack's Underground Adventure" },
{ "goypaint", "Paint!!!" },
{ "goydragonshrine", "The Curse of DragonShrine" },
{ "goydarkness", "Darkness" },
@@ -245,6 +241,20 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "1hgtopaz", "Topaz" },
{ "1hggoblinhunt", "Goblin Hunt" },
+ // InsideADRIFT Summer Competition 2004
+ { "chooseyourown", "Choose Your Own..." },
+ { "darkhavenmystery", "The Mystery Of The Darkhaven Caves" },
+ { "shadricksunderground", "Shadrack's Underground Adventure" },
+ { "tickettonowhere", "Ticket to No Where" },
+ { "tearsofatoughman", "Tears of a tough man" },
+ { "theadriftproject", "The ADRIFT Project" },
+
+ // InsideADRIFT Spring Competition 2005
+ { "iadcseaside", "A Day At The Seaside" },
+ { "iadcfrustrated", "Frustrated Interviewee" },
+ { "iadchub", "The House Husband" },
+ { "iadcprivateeye", "Private Eye" },
+ { "iadcblood", "Fire in the Blood" },
{ nullptr, nullptr }
};
@@ -261,7 +271,6 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("beanstalk", "fc9c17c355894948dc2e72c66e8d9963", 9837),
DT_ENTRY0("beerisntenough", "98248a8e65a36f6d0fb98111255a85dc", 14070),
DT_ENTRY0("caveofwonders", "f55f4e63886eb09e1f89bea547574919", 85471),
- DT_ENTRY0("chooseyourown", "774ae5ba4fea61da0898069df4ed1c81", 54869),
DT_ENTRY0("circusmenagerie", "3814400e3abb3e6340f055d5ec883c46", 117017),
DT_ENTRY0("cityInfear", "a6f625f184fa848ee6746e9aa6c94915", 248088),
DT_ENTRY0("coloromcadrift", "6b8d8f115a89c99f785156a9b5802bc2", 12681),
@@ -312,7 +321,6 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("monsters", "fde7be359d37c9229fec77244fc38a54", 17168),
DT_ENTRY0("murdererhadleft", "f95c63f90f28061a15dbe3bdf0cd4048", 13425),
DT_ENTRY0("mustescape", "e58fd08918fa3d5a38f424f79595fb4e", 17497),
- DT_ENTRY0("darkhavenmystery", "1027e9e3dba08e0fd2796e0e934be855", 27826),
DT_ENTRY0("neighboursfromhell", "686d8c0995aa085fb056c6a5bd402911", 13520),
DT_ENTRY0("onnafa", "da4c0cc6fe34a08047de54abc66de038", 167339),
DT_ENTRY0("overtheedge", "9c7bfb9252ac80597ef125c95d58a54b", 14771),
@@ -334,7 +342,7 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("thepkgirl", "c9282cf8f91ebfe5a93b136f56d7a1aa", 1645515),
DT_ENTRY0("viewisbetter", "9334adc4ccd03ceb1684ee56fdb07ab9", 7720),
DT_ENTRY0("thelasthour", "786d39eb223a64fe836f87b032b60ae1", 10658),
- DT_ENTRY0("ticket", "8c549a6bdc6a5a4895412516be8dce25", 65502),
+ DT_ENTRY0("tickettonowhere", "8c549a6bdc6a5a4895412516be8dce25", 65502),
DT_ENTRY0("hellinahamper", "810247344fddc9a812bf6283b4826093", 80183),
DT_ENTRY0("toomuchexercise", "aebb58d94f632c4232bee72b9a1b5e25", 6248),
DT_ENTRY0("topaz", "0777a97e473b41ae04ab825556748e8d", 5980),
@@ -364,6 +372,13 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("noblecrook3", "c9d4a1ba7d5c1625f2d4cad0f067275a", 22088),
DT_ENTRY0("noblecrook4", "cb26241f8dba982bb0cd357ebd8fac45", 20606),
DT_ENTRY0("sonofcamelot", "7b3e9e45edc75202b3f586d0ca8dddde", 474380),
+ DT_ENTRY0("spacedetective1", "170517dae3a195f37d876f5645637953", 34044),
+ DT_ENTRY0("spacedetective2", "1e12b19d8777173cbf9866b3dd2fc2f0", 32632),
+ DT_ENTRY0("spacedetective3", "fc9fb75830d7f59bf932896152b1e759", 30560),
+ DT_ENTRY0("spacedetective4", "86fbcf204c6b0982ef2394a60bb8df3e", 32184),
+ DT_ENTRY0("spacedetective5", "f1bf863cce436a5ef17e64237803571a", 32676),
+ DT_ENTRY0("spacedetective6", "6035c865f7a4831e4539b7a2ff2ab711", 31922),
+ DT_ENTRY0("spacedetective7", "2044086edd9b2288ff2279b3824dfcef", 30066),
// Italian Games
DT_ENTRYL0("ilgolem", Common::IT_ITA, "7ab97545be9c30457d0c9e748ab7885f", 6372213),
@@ -388,7 +403,6 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
// Game of the Year Competition: December 2004
DT_ENTRY0("goyshardsofmemory", "7e9cb5002fa22a25000b3478c826413d", 118610),
DT_ENTRY0("goyshardsofmemory", "9b75834354aed4b148d4ec2b8cdd66ae", 118604),
- DT_ENTRY0("goyshadricksunderground", "a9e1e59b37976c6c0fcc6aee69978afe", 113385),
DT_ENTRY0("waxworx", "94aaf6625541238867b079bfe475f146", 38471),
DT_ENTRY0("goypaint", "1183921d034d3614ec277e18d9112b69", 76493),
DT_ENTRY0("goydragonshrine", "604250027cfd8cfd1fb0d231085e40e5", 636932),
@@ -463,6 +477,21 @@ const AdriftGameDescription ADRIFT_GAMES[] = {
DT_ENTRY0("waxworx", "4fa14c7944506f4e0142cb865738d0b0", 37542),
DT_ENTRY0("sommeril", "9e8ee4cbd4ecab3ab51c702f4e0277e1", 400940),
+ // InsideADRIFT Summer Competition 2004
+ DT_ENTRY0("chooseyourown", "774ae5ba4fea61da0898069df4ed1c81", 54869),
+ DT_ENTRY0("darkhavenmystery", "1027e9e3dba08e0fd2796e0e934be855", 27826),
+ DT_ENTRY0("shadricksunderground", "a9e1e59b37976c6c0fcc6aee69978afe", 113385),
+ DT_ENTRY0("tickettonowhere", "a69b0fa1b33d8e0ab6504d37615e6a3c", 65083),
+ DT_ENTRY0("tearsofatoughman", "b440d0b4b18a93537803750f31e838b7", 9436),
+ DT_ENTRY0("theadriftproject", "18a4db8af27fd98751504ee3e45089e3", 231594),
+
+ // InsideADRIFT Spring Competition 2005
+ DT_ENTRY0("iadcseaside", "271c64455f4abb3dee35c3902e5cdfc1", 279480),
+ DT_ENTRY0("iadcfrustrated", "1c218d4fcbbfa11271fb4d0003df7a6a", 210267),
+ DT_ENTRY0("iadchub", "c3224b3d6c55997056ea195ba4ebb60a", 24610),
+ DT_ENTRY0("iadcprivateeye", "3076b9f11acf2b1e377a31cd1a11c323", 236323),
+ DT_ENTRY0("iadcblood", "775404faa0d7973c1df537bd423a45d3", 100201),
+
DT_END_MARKER
};
Commit: f560ccb5bd17a26f232dacd08714836c33dce0bc
https://github.com/scummvm/scummvm/commit/f560ccb5bd17a26f232dacd08714836c33dce0bc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:26-07:00
Commit Message:
GLK: ADRIFT: Hooking up game code to skeleton engine class
Changed paths:
A engines/glk/adrift/os_glk.h
engines/glk/adrift/adrift.cpp
engines/glk/adrift/os_glk.cpp
diff --git a/engines/glk/adrift/adrift.cpp b/engines/glk/adrift/adrift.cpp
index 4f02b40..8ae56df 100644
--- a/engines/glk/adrift/adrift.cpp
+++ b/engines/glk/adrift/adrift.cpp
@@ -21,6 +21,7 @@
*/
#include "glk/adrift/adrift.h"
+#include "glk/adrift/os_glk.h"
namespace Glk {
namespace Adrift {
@@ -32,16 +33,8 @@ Adrift::Adrift(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst,
}
void Adrift::runGame() {
- // TODO: run
-
- deinitialize();
-}
-
-bool Adrift::initialize() {
- return true;
-}
-
-void Adrift::deinitialize() {
+ if (winglk_startup_code(&_gameFile))
+ glk_main();
}
Common::Error Adrift::readSaveData(Common::SeekableReadStream *rs) {
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index cc7471e..d973f7c 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -2961,13 +2961,11 @@ static char *gsc_game_message = nullptr;
* buffer with TAF or TAS file data from a Glk stream, and returns the byte
* count.
*/
-static sc_int
-gsc_callback (void *opaque, sc_byte *buffer, sc_int length)
-{
- strid_t stream = (strid_t) opaque;
- assert (stream);
+static sc_int gsc_callback(void *opaque, sc_byte *buffer, sc_int length) {
+ Common::SeekableReadStream *stream = (Common::SeekableReadStream *)opaque;
+ assert(stream);
- return g_vm->glk_get_buffer_stream (stream, (char *) buffer, length);
+ return stream->read(buffer, length);
}
@@ -3053,117 +3051,117 @@ gsc_get_ending_option()
* does the real work of running the game.
*/
static int
-gsc_startup_code (strid_t game_stream, strid_t restore_stream,
- sc_uint trace_flags, sc_bool enable_debugger,
- sc_bool stable_random, const sc_char *locale)
-{
- winid_t window;
- assert (game_stream);
-
- /* Open a temporary Glk main window. */
- window = g_vm->glk_window_open (0, 0, 0, wintype_TextBuffer, 0);
- if (window)
- {
- /* Clear and initialize the temporary window. */
- g_vm->glk_window_clear (window);
- g_vm->glk_set_window (window);
- g_vm->glk_set_style (style_Normal);
-
- /*
- * Display a brief loading game message; here we have to use a timeout
- * to ensure that the text is flushed to Glk.
- */
- g_vm->glk_put_string ("Loading game...\n");
- if (g_vm->glk_gestalt (gestalt_Timer, 0))
- {
- event_t event;
-
- g_vm->glk_request_timer_events (GSC_LOADING_TIMEOUT);
- do
- {
- g_vm->glk_select (&event);
- }
- while (event.type != evtype_Timer);
- g_vm->glk_request_timer_events (0);
- }
- }
-
- /* If the Glk libarary does not support unicode, disable it. */
- if (!gsc_has_unicode || !g_vm->glk_gestalt (gestalt_Unicode, 0))
- gsc_unicode_enabled = FALSE;
-
- /*
- * If a locale was requested, set it in the core interpreter now. This
- * locale will preempt any auto-detected one found from inspecting the
- * game on creation. After game creation, the Glk locale is synchronized
- * to the core interpreter's locale.
- */
- if (locale)
- sc_set_locale (locale);
-
- /*
- * Set tracing flags, then try to create a SCARE game reference from the
- * TAF file. Since we need this in our call from g_vm->glk_main, we have to keep
- * it in a module static variable. If we can't open the TAF file, then
- * we'll set the pointer to nullptr, and complain about it later in main.
- * Passing the message string around like this is a nuisance...
- */
- sc_set_trace_flags (trace_flags);
- gsc_game = sc_game_from_callback (gsc_callback, game_stream);
- if (!gsc_game)
- {
- gsc_game = nullptr;
- gsc_game_message = "Unable to load an Adrift game from the"
- " requested file.";
- }
- else
- gsc_game_message = nullptr;
- g_vm->glk_stream_close (game_stream, nullptr);
-
- /*
- * If the game was created successfully and there is a restore stream, try
- * to immediately restore the game from that stream.
- */
- if (gsc_game && restore_stream)
- {
- if (!sc_load_game_from_callback (gsc_game, gsc_callback, restore_stream))
- {
- sc_free_game (gsc_game);
- gsc_game = nullptr;
- gsc_game_message = "Unable to restore this Adrift game from the"
- " requested file.";
- }
- else
- gsc_game_message = nullptr;
- }
- if (restore_stream)
- g_vm->glk_stream_close (restore_stream, nullptr);
-
- /* If successful, set game debugging and synchronize to the core's locale. */
- if (gsc_game)
- {
- sc_set_game_debugger_enabled (gsc_game, enable_debugger);
- gsc_set_locale (sc_get_locale ());
- }
-
- /* Set portable and predictable random number generation if requested. */
- if (stable_random)
- {
- sc_set_portable_random (TRUE);
- sc_reseed_random_sequence (1);
- }
-
- /* Close the temporary window. */
- if (window)
- g_vm->glk_window_close (window, nullptr);
-
- /* Set title of game */
+gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream,
+ sc_uint trace_flags, sc_bool enable_debugger,
+ sc_bool stable_random, const sc_char *locale)
+{
+ winid_t window;
+ assert(game_stream);
+
+ /* Open a temporary Glk main window. */
+ window = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
+ if (window)
+ {
+ /* Clear and initialize the temporary window. */
+ g_vm->glk_window_clear(window);
+ g_vm->glk_set_window(window);
+ g_vm->glk_set_style(style_Normal);
+
+ /*
+ * Display a brief loading game message; here we have to use a timeout
+ * to ensure that the text is flushed to Glk.
+ */
+ g_vm->glk_put_string("Loading game...\n");
+ if (g_vm->glk_gestalt(gestalt_Timer, 0)) {
+ event_t event;
+
+ g_vm->glk_request_timer_events(GSC_LOADING_TIMEOUT);
+ do {
+ g_vm->glk_select(&event);
+ } while (!g_vm->shouldQuit() && event.type != evtype_Timer);
+ g_vm->glk_request_timer_events(0);
+ }
+
+ if (g_vm->shouldQuit())
+ return false;
+ }
+
+ /* If the Glk libarary does not support unicode, disable it. */
+ if (!gsc_has_unicode || !g_vm->glk_gestalt(gestalt_Unicode, 0))
+ gsc_unicode_enabled = FALSE;
+
+ /*
+ * If a locale was requested, set it in the core interpreter now. This
+ * locale will preempt any auto-detected one found from inspecting the
+ * game on creation. After game creation, the Glk locale is synchronized
+ * to the core interpreter's locale.
+ */
+ if (locale)
+ sc_set_locale(locale);
+
+ /*
+ * Set tracing flags, then try to create a SCARE game reference from the
+ * TAF file. Since we need this in our call from g_vm->glk_main, we have to keep
+ * it in a module static variable. If we can't open the TAF file, then
+ * we'll set the pointer to nullptr, and complain about it later in main.
+ * Passing the message string around like this is a nuisance...
+ */
+ sc_set_trace_flags(trace_flags);
+ gsc_game = sc_game_from_callback(gsc_callback, game_stream);
+ if (!gsc_game)
+ {
+ gsc_game = nullptr;
+ gsc_game_message = "Unable to load an Adrift game from the"
+ " requested file.";
+ }
+ else
+ gsc_game_message = nullptr;
+ delete game_stream;
+
+ /*
+ * If the game was created successfully and there is a restore stream, try
+ * to immediately restore the game from that stream.
+ */
+ if (gsc_game && restore_stream)
+ {
+ if (!sc_load_game_from_callback(gsc_game, gsc_callback, restore_stream))
+ {
+ sc_free_game(gsc_game);
+ gsc_game = nullptr;
+ gsc_game_message = "Unable to restore this Adrift game from the"
+ " requested file.";
+ }
+ else
+ gsc_game_message = nullptr;
+ }
+ if (restore_stream)
+ g_vm->glk_stream_close(restore_stream, nullptr);
+
+ /* If successful, set game debugging and synchronize to the core's locale. */
+ if (gsc_game)
+ {
+ sc_set_game_debugger_enabled(gsc_game, enable_debugger);
+ gsc_set_locale(sc_get_locale());
+ }
+
+ /* Set portable and predictable random number generation if requested. */
+ if (stable_random)
+ {
+ sc_set_portable_random(TRUE);
+ sc_reseed_random_sequence(1);
+ }
+
+ /* Close the temporary window. */
+ if (window)
+ g_vm->glk_window_close(window, nullptr);
+
+ /* Set title of game */
#ifdef GARGLK
- g_vm->garglk_set_story_name(sc_get_game_name(gsc_game));
+ g_vm->garglk_set_story_name(sc_get_game_name(gsc_game));
#endif
- /* Game set up, perhaps successfully. */
- return TRUE;
+ /* Game set up, perhaps successfully. */
+ return TRUE;
}
static void
@@ -3302,17 +3300,17 @@ static int gsc_startup_called = FALSE,
gsc_main_called = FALSE;
/*
- * g_vm->glk_main()
+ * glk_main()
*
* Main entry point for Glk. Here, all startup is done, and we call our
* function to run the game, or to report errors if gsc_game_message is set.
*/
void glk_main() {
- assert (gsc_startup_called && !gsc_main_called);
- gsc_main_called = TRUE;
+ assert(gsc_startup_called && !gsc_main_called);
+ gsc_main_called = TRUE;
- /* Call the generic interpreter main function. */
- gsc_main ();
+ /* Call the generic interpreter main function. */
+ gsc_main();
}
@@ -3343,226 +3341,27 @@ glkunix_argumentlist_t glkunix_arguments[] = {
};
#endif
-struct glkunix_startup_t {
- int argc;
- char **argv;
-};
-
-/*
- * glkunix_startup_code()
- *
- * Startup entry point for UNIX versions of Glk interpreter. Glk will call
- * glkunix_startup_code() to pass in arguments. On startup, parse arguments
- * and open a Glk stream to the game, then call the generic gsc_startup_code()
- * to build a game from the stream. On error, set the message in
- * gsc_game_message; the core gsc_main() will report it when it's called.
- */
-int glkunix_startup_code(glkunix_startup_t *data) {
- int argc = data->argc;
- sc_char **argv = data->argv;
- int argv_index;
- sc_char *restore_from;
- const sc_char *locale;
- strid_t game_stream, restore_stream;
- sc_uint trace_flags;
- sc_bool enable_debugger, stable_random;
- assert (!gsc_startup_called);
- gsc_startup_called = TRUE;
-
-#ifdef GARGLK
- g_vm->garglk_set_program_name("SCARE " SCARE_VERSION);
- g_vm->garglk_set_program_info("SCARE " SCARE_VERSION
- " by Simon Baldwin and Mark J. Tilford");
-#endif
-
- /* Handle command line arguments. */
- restore_from = nullptr;
- for (argv_index = 1;
- argv_index < argc && argv[argv_index][0] == '-'; argv_index++)
- {
- if (strcmp (argv[argv_index], "-nc") == 0)
- {
- gsc_commands_enabled = FALSE;
- continue;
- }
- if (strcmp (argv[argv_index], "-na") == 0)
- {
- gsc_abbreviations_enabled = FALSE;
- continue;
- }
- if (strcmp (argv[argv_index], "-nu") == 0)
- {
- gsc_unicode_enabled = FALSE;
- continue;
- }
-#ifdef LINUX_GRAPHICS
- if (strcmp (argv[argv_index], "-ng") == 0)
- {
- gsclinux_graphics_enabled = FALSE;
- continue;
- }
-#endif
- if (strcmp (argv[argv_index], "-r") == 0)
- {
- restore_from = argv[++argv_index];
- continue;
- }
- return FALSE;
- }
-
- /* On invalid usage, set a complaint message and return. */
- if (argv_index != argc - 1)
- {
- gsc_game = nullptr;
- if (argv_index < argc - 1)
- gsc_game_message = "More than one game file"
- " was given on the command line.";
- else
- gsc_game_message = "No game file was given on the command line.";
- return TRUE;
- }
-
- /* Open a stream to the TAF file, complain if this fails. */
- game_stream = g_vm->glk_stream_open_file(g_vm->glk_fileref_create_by_name(filemode_Read, argv[argv_index]), filemode_Read);
- if (!game_stream)
- {
- gsc_game = nullptr;
- gsc_game_message = "Unable to open the requested game file.";
- return TRUE;
- }
- else
- gsc_game_message = nullptr;
-
- /*
- * If a restore requested, open a stream to the TAF (TAS) file, and
- * again, complain if this fails.
- */
- if (restore_from)
- {
- restore_stream =g_vm->glk_stream_open_file(g_vm->glk_fileref_create_by_name(filemode_Read, restore_from), filemode_Read);
- if (!restore_stream)
- {
- g_vm->glk_stream_close (game_stream, nullptr);
- gsc_game = nullptr;
- gsc_game_message = "Unable to open the requested restore file.";
- return TRUE;
- }
- else
- gsc_game_message = nullptr;
- }
- else
- restore_stream = nullptr;
-
- /* Set SCARE trace flags and other general setup from the environment. */
- if (false /*getenv ("SC_TRACE_FLAGS") */) {
- //trace_flags = strtoul (getenv ("SC_TRACE_FLAGS"), nullptr, 0);
- } else {
- trace_flags = 0;
- }
- enable_debugger = false; // (getenv("SC_DEBUGGER_ENABLED") != nullptr);
- stable_random = false; // (getenv("SC_STABLE_RANDOM_ENABLED") != nullptr);
- locale = nullptr; // getenv("SC_LOCALE");
-
-#ifdef LINUX_GRAPHICS
- /* Note the path to the game file for graphics extraction. */
- gsclinux_game_file = argv[argv_index];
-#endif
-
- /* Use the generic startup code to complete startup. */
- return gsc_startup_code (game_stream, restore_stream, trace_flags,
- enable_debugger, stable_random, locale);
-}
-
-
-/*---------------------------------------------------------------------*/
-/* Glk linkage relevant only to the Windows platform */
-/*---------------------------------------------------------------------*/
-#ifdef _WIN32
-
-#include <windows.h>
-
-#include "WinGlk.h"
-#include "resource.h"
-
-/* Windows constants and external definitions. */
-static const unsigned int GSCWIN_glk_INIT_VERSION = 0x601;
-extern int InitGlk (unsigned int iVersion);
-
/*
- * WinMain()
- *
- * Entry point for all Glk applications.
- */
-int WINAPI
-WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow)
-{
- /* Attempt to initialize both the Glk library and SCARE. */
- if (!(InitGlk (GSCWIN_glk_INIT_VERSION) && wing_vm->glk_startup_code (lpCmdLine)))
- return 0;
-
- /* Run the application; no return from this routine. */
- g_vm->glk_main ();
- g_vm->glk_exit ();
- return 0;
-}
-
-
-/*
- * wing_vm->glk_startup_code()
+ * winglk_startup_code()
*
* Startup entry point for Windows versions of Glk interpreter.
*/
-int
-wing_vm->glk_startup_code (const char *cmdline)
-{
- const char *filename, *locale;
- frefid_t fileref;
- strid_t game_stream;
- sc_uint trace_flags;
- sc_bool enable_debugger, stable_random;
- assert (!gsc_startup_called);
- gsc_startup_called = TRUE;
-
- /* Set up application and window. */
- wing_vm->glk_app_set_name ("Scare");
- wing_vm->glk_set_menu_name ("&Scare");
- wing_vm->glk_window_set_title ("Scare Adrift Interpreter");
- wing_vm->glk_set_about_text ("Windows Scare 1.3.10");
- wing_vm->glk_set_gui (IDI_SCARE);
-
- /* Open a stream to the game. */
- filename = wing_vm->glk_get_initial_filename (cmdline,
- "Select an Adrift game to run",
- "Adrift Files (.taf)|*.taf;All Files (*.*)|*.*||");
- if (!filename)
- return 0;
-
- fileref = wing_vm->glk_fileref_create_by_name (fileusage_BinaryMode
- | fileusage_Data,
- (char *) filename, 0, 0);
- if (!fileref)
- return 0;
+bool winglk_startup_code(Common::SeekableReadStream *gameFile) {
+ const char *locale;
+ sc_uint trace_flags;
+ sc_bool enable_debugger, stable_random;
+ assert(!gsc_startup_called);
+ gsc_startup_called = TRUE;
- game_stream = g_vm->glk_stream_open_file (fileref, filemode_Read, 0);
- g_vm->glk_fileref_destroy (fileref);
- if (!game_stream)
- return 0;
-
- /* Set trace, debugger, and portable random flags. */
- if (getenv ("SC_TRACE_FLAGS"))
- trace_flags = strtoul (getenv ("SC_TRACE_FLAGS"), nullptr, 0);
- else
- trace_flags = 0;
- enable_debugger = (getenv ("SC_DEBUGGER_ENABLED") != nullptr);
- stable_random = (getenv ("SC_STABLE_RANDOM_ENABLED") != nullptr);
- locale = getenv ("SC_LOCALE");
+ assert(gameFile);
+ trace_flags = 0;
+ enable_debugger = gDebugLevel > 0;
+ stable_random = gDebugLevel > 0;
+ locale = nullptr;
- /* Use the generic startup code to complete startup. */
- return gsc_startup_code (game_stream, nullptr, trace_flags,
- enable_debugger, stable_random, locale);
+ // Use the generic startup code to complete startup
+ return gsc_startup_code(gameFile, nullptr, trace_flags, enable_debugger, stable_random, locale);
}
-#endif /* _WIN32 */
} // End of namespace Adrift
} // End of namespace Glk
diff --git a/engines/glk/adrift/os_glk.h b/engines/glk/adrift/os_glk.h
new file mode 100644
index 0000000..0bc2681
--- /dev/null
+++ b/engines/glk/adrift/os_glk.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 ADRIFT_OS_GLK_H
+#define ADRIFT_OS_GLK_H
+
+#include "common/scummsys.h"
+#include "glk/adrift/scare.h"
+
+namespace Glk {
+namespace Adrift {
+
+extern bool winglk_startup_code(Common::SeekableReadStream *gameFile);
+extern void glk_main();
+
+} // End of namespace Adrift
+} // End of namespace Glk
+
+#endif
Commit: 855b75f6dfd602879b7153e576124749d8c47c92
https://github.com/scummvm/scummvm/commit/855b75f6dfd602879b7153e576124749d8c47c92
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Flag loading game message as translatable
Changed paths:
engines/glk/adrift/os_glk.cpp
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index d973f7c..41409cb 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -27,6 +27,7 @@
#include "glk/streams.h"
#include "glk/windows.h"
#include "common/textconsole.h"
+#include "common/translation.h"
namespace Glk {
namespace Adrift {
@@ -3071,7 +3072,7 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream
* Display a brief loading game message; here we have to use a timeout
* to ensure that the text is flushed to Glk.
*/
- g_vm->glk_put_string("Loading game...\n");
+ g_vm->glk_put_string(_("Loading game...\n"));
if (g_vm->glk_gestalt(gestalt_Timer, 0)) {
event_t event;
Commit: c03b7a50eafe3c6a559c55746ec88d5a37885e9a
https://github.com/scummvm/scummvm/commit/c03b7a50eafe3c6a559c55746ec88d5a37885e9a
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Implement zlib decompression
Changed paths:
common/zlib.cpp
common/zlib.h
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/sctaffil.cpp
diff --git a/common/zlib.cpp b/common/zlib.cpp
index 6afffb1..e4a3d47 100644
--- a/common/zlib.cpp
+++ b/common/zlib.cpp
@@ -141,6 +141,79 @@ bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcL
return true;
}
+bool inflateZlibHeaderless(Common::WriteStream *dst, Common::SeekableReadStream *src) {
+ byte *inBuffer, *outBuffer;
+ z_stream stream;
+ int status;
+
+ // Allocate buffers
+ inBuffer = new byte[kTempBufSize];
+ outBuffer = new byte[kTempBufSize];
+
+ /* Initialize Zlib inflation functions. */
+ stream.next_out = outBuffer;
+ stream.avail_out = kTempBufSize;
+ stream.next_in = inBuffer;
+ stream.avail_in = 0;
+
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ status = inflateInit(&stream);
+ if (status != Z_OK) {
+ delete[] inBuffer;
+ delete[] outBuffer;
+ return false;
+ }
+
+ // Inflate the input buffers. */
+ for (;;) {
+ int inBytes, outBytes;
+
+ /* If the input buffer is empty, try to obtain more data. */
+ if (stream.avail_in == 0) {
+ inBytes = src->read(inBuffer, kTempBufSize);
+ stream.next_in = inBuffer;
+ stream.avail_in = inBytes;
+ }
+
+ // Decompress as much stream data as we can. */
+ status = inflate(&stream, Z_SYNC_FLUSH);
+ if (status != Z_STREAM_END && status != Z_OK) {
+ delete[] inBuffer;
+ delete[] outBuffer;
+ return false;
+ }
+ outBytes = kTempBufSize - stream.avail_out;
+
+ // See if decompressed data is available. */
+ if (outBytes > 0) {
+ // Add data from the buffer to the output
+ int consumed = dst->write(outBuffer, outBytes);
+
+ // Move unused buffer data to buffer start
+ memmove(outBuffer, outBuffer + consumed, kTempBufSize - consumed);
+
+ // Reset inflation stream for available space
+ stream.next_out = outBuffer + outBytes - consumed;
+ stream.avail_out += consumed;
+ }
+
+ // If at inflation stream end and output is empty, leave loop
+ if (status == Z_STREAM_END && stream.avail_out == kTempBufSize)
+ break;
+ }
+
+ // End inflation buffers
+ status = inflateEnd(&stream);
+ delete[] inBuffer;
+ delete[] outBuffer;
+
+ // Return result
+ return (status == Z_OK);
+}
+
#ifndef RELEASE_BUILD
static bool _shownBackwardSeekingWarning = false;
#endif
diff --git a/common/zlib.h b/common/zlib.h
index eb05483..a172399 100644
--- a/common/zlib.h
+++ b/common/zlib.h
@@ -96,6 +96,18 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen,
*/
bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen);
+/**
+ * Wrapper around zlib's inflate functions. This function is used by Glk to
+ * decompress TAF 4.0 files, which are headerless Zlib compressed streams with a
+ * custom header
+ *
+ * @param dst the destination stream to write decompressed data out to
+ * @param src the Source stream
+ *
+ * @return true on success (Z_OK or Z_STREAM_END), false otherwise.
+ */
+bool inflateZlibHeaderless(Common::WriteStream *dst, Common::SeekableReadStream *src);
+
#endif
/**
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index 41409cb..243aca6 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -3112,12 +3112,10 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream
if (!gsc_game)
{
gsc_game = nullptr;
- gsc_game_message = "Unable to load an Adrift game from the"
- " requested file.";
+ gsc_game_message = "Unable to load an Adrift game from the requested file.";
}
else
gsc_game_message = nullptr;
- delete game_stream;
/*
* If the game was created successfully and there is a restore stream, try
@@ -3129,8 +3127,7 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream
{
sc_free_game(gsc_game);
gsc_game = nullptr;
- gsc_game_message = "Unable to restore this Adrift game from the"
- " requested file.";
+ gsc_game_message = "Unable to restore this Adrift game from the requested file.";
}
else
gsc_game_message = nullptr;
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index 6f0ebae..6868580 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -23,6 +23,20 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
#include "common/textconsole.h"
+#include "common/zlib.h"
+#include "common/memstream.h"
+
+#if defined(USE_ZLIB)
+ #ifdef __SYMBIAN32__
+ #include <zlib\zlib.h>
+ #else
+ #include <zlib.h>
+ #endif
+
+ #if ZLIB_VERNUM < 0x1204
+ #error Version 1.2.0.4 or newer of zlib is required for this code
+ #endif
+#endif
namespace Glk {
namespace Adrift {
@@ -426,130 +440,35 @@ taf_unobfuscate (sc_tafref_t taf, sc_read_callbackref_t callback,
return TRUE;
}
+#define BUFFER_SIZE 16384
/*
* taf_decompress()
*
- * Decompress a version 4.0 TAF file from data read by repeated calls to the
- * callback() function. Callback() should return the count of bytes placed
- * in the buffer, 0 if no more (end of file). Assumes that the file has been
- * read past the header.
+ * Decompress a version 4.0 TAF
*/
static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
- void *opaque, sc_bool is_gamefile)
-{
- error("TODO: decompress");
-#ifdef TODO
- sc_byte *in_buffer, *out_buffer;
-// z_stream stream;
- sc_int status;
- sc_bool is_first_block;
-
- /*
- * Malloc buffers, done this way rather than as stack variables for systems
- * such as PalmOS that may have limited stacks.
- */
- in_buffer = sc_malloc (IN_BUFFER_SIZE);
- out_buffer = sc_malloc (OUT_BUFFER_SIZE);
-
- /* Initialize Zlib inflation functions. */
- stream.next_out = out_buffer;
- stream.avail_out = OUT_BUFFER_SIZE;
- stream.next_in = in_buffer;
- stream.avail_in = 0;
-
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- status = inflateInit (&stream);
- if (status != Z_OK)
- {
- sc_error ("taf_decompress: inflateInit: error %ld\n", status);
- sc_free (in_buffer);
- sc_free (out_buffer);
- return FALSE;
- }
-
- /*
- * Attempts to restore non-savefiles can arrive here, because there's no
- * up-front header check, like the one for TAF files, applied to them. The
- * first we see of the problem is when the first inflate() fails, so it's
- * handy to use a flag here to block the error report for such cases.
- */
- is_first_block = TRUE;
-
- /* Inflate the input buffers. */
- while (TRUE)
- {
- sc_int in_bytes, out_bytes;
-
- /* If the input buffer is empty, try to obtain more data. */
- if (stream.avail_in == 0)
- {
- in_bytes = callback (opaque, in_buffer, IN_BUFFER_SIZE);
- stream.next_in = in_buffer;
- stream.avail_in = in_bytes;
- }
-
- /* Decompress as much stream data as we can. */
- status = inflate (&stream, Z_SYNC_FLUSH);
- if (status != Z_STREAM_END && status != Z_OK)
- {
- if (is_gamefile || !is_first_block)
- sc_error ("taf_decompress: inflate: error %ld\n", status);
- sc_free (in_buffer);
- sc_free (out_buffer);
- return FALSE;
- }
- out_bytes = OUT_BUFFER_SIZE - stream.avail_out;
-
- /* See if decompressed data is available. */
- if (out_bytes > 0)
- {
- sc_int consumed;
-
- /* Add lines from this buffer to the TAF. */
- consumed = taf_append_buffer (taf, out_buffer, out_bytes);
-
- /* Move unused buffer data to buffer start. */
- memmove (out_buffer,
- out_buffer + consumed, OUT_BUFFER_SIZE - consumed);
-
- /* Reset inflation stream for available space. */
- stream.next_out = out_buffer + out_bytes - consumed;
- stream.avail_out += consumed;
- }
-
- /* Enable full error reporting for non-gamefiles. */
- is_first_block = FALSE;
-
- /* If at inflation stream end and output is empty, leave loop. */
- if (status == Z_STREAM_END && stream.avail_out == OUT_BUFFER_SIZE)
- break;
- }
-
- /*
- * Decompression completed, note the total bytes read for use when locating
- * resources later on in the file. For what it's worth, this value is only
- * used in version 4.0 games.
- */
- taf->total_in_bytes = stream.total_in;
- if (is_gamefile)
- taf->total_in_bytes += VERSION_HEADER_SIZE + V400_HEADER_EXTRA;
-
- /* End inflation. */
- status = inflateEnd (&stream);
- if (status != Z_OK)
- sc_error ("taf_decompress: warning: inflateEnd: error %ld\n", status);
-
- if (taf->is_unterminated)
- sc_fatal ("taf_decompress: unterminated final data slab\n");
-
- /* Return successfully. */
- sc_free (in_buffer);
- sc_free (out_buffer);
- return TRUE;
+ void *opaque, sc_bool is_gamefile) {
+#if USE_ZLIB
+ Common::SeekableReadStream *src = (Common::SeekableReadStream *)opaque;
+ assert(src);
+ Common::MemoryWriteStreamDynamic dest(DisposeAfterUse::YES);
+
+ if (!Common::inflateZlibHeaderless(&dest, src))
+ return false;
+
+ // Iterate through pushing data out to the taf file
+ const byte *pTemp = dest.getData();
+ int bytesRemaining = dest.size();
+
+ while (bytesRemaining > 0) {
+ int consumed = taf_append_buffer(taf, pTemp, bytesRemaining);
+ bytesRemaining -= consumed;
+ }
+
+ return true;
+#else
+ return true;
#endif
}
Commit: 068375e48c2acb9c0e187ff259dde7ad7d1c241f
https://github.com/scummvm/scummvm/commit/068375e48c2acb9c0e187ff259dde7ad7d1c241f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Fix exiting game out of debug prompt
Changed paths:
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/scdebug.cpp
engines/glk/adrift/scinterf.cpp
engines/glk/adrift/scrunner.cpp
engines/glk/adrift/sctaffil.cpp
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index 243aca6..1244b48 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -2841,6 +2841,10 @@ gsc_event_wait_2 (glui32 wait_type_1, glui32 wait_type_2, event_t * event)
do
{
g_vm->glk_select (event);
+ if (g_vm->shouldQuit()) {
+ g_vm->glk_cancel_line_event(gsc_main_window, event);
+ return;
+ }
switch (event->type)
{
diff --git a/engines/glk/adrift/scdebug.cpp b/engines/glk/adrift/scdebug.cpp
index e2472cc..3852d16 100644
--- a/engines/glk/adrift/scdebug.cpp
+++ b/engines/glk/adrift/scdebug.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "glk/adrift/scare.h"
+#include "glk/adrift/adrift.h"
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
@@ -2429,6 +2429,9 @@ debug_dialog (sc_gameref_t game)
do
{
if_read_debug (buffer, sizeof (buffer));
+
+ if (g_vm->shouldQuit())
+ return;
}
while (sc_strempty (buffer));
diff --git a/engines/glk/adrift/scinterf.cpp b/engines/glk/adrift/scinterf.cpp
index 044c4d8..cc8e123 100644
--- a/engines/glk/adrift/scinterf.cpp
+++ b/engines/glk/adrift/scinterf.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "glk/adrift/scare.h"
+#include "glk/adrift/adrift.h"
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
#include "common/file.h"
@@ -215,6 +215,8 @@ if_read_line_common (sc_char *buffer, sc_int length,
memset (buffer, NUL, length);
is_line_available = read_line_function (buffer, length);
+ if (g_vm->shouldQuit())
+ return;
}
while (!is_line_available);
diff --git a/engines/glk/adrift/scrunner.cpp b/engines/glk/adrift/scrunner.cpp
index 872a7648..ab6bfd8 100644
--- a/engines/glk/adrift/scrunner.cpp
+++ b/engines/glk/adrift/scrunner.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "glk/adrift/scare.h"
+#include "glk/adrift/adrift.h"
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
@@ -1377,6 +1377,7 @@ run_main_loop (sc_gameref_t game)
* Game loop, exits either when a command parser handler sets the game
* running flag to FALSE, or by call to run_quit().
*/
+ game->is_running &= !g_vm->shouldQuit();
while (game->is_running)
{
sc_bool status;
@@ -1449,7 +1450,9 @@ run_main_loop (sc_gameref_t game)
debug_turn_update (game);
}
}
- }
+
+ game->is_running &= !g_vm->shouldQuit();
+ }
/*
* Final status update, for games that vary it on completion, then notify
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index 6868580..c8a25ed 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -453,6 +453,7 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
Common::SeekableReadStream *src = (Common::SeekableReadStream *)opaque;
assert(src);
Common::MemoryWriteStreamDynamic dest(DisposeAfterUse::YES);
+ size_t startingPos = src->pos();
if (!Common::inflateZlibHeaderless(&dest, src))
return false;
@@ -466,6 +467,8 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
bytesRemaining -= consumed;
}
+ taf->total_in_bytes = src->pos() - startingPos;
+
return true;
#else
return true;
Commit: fc410a88a0e8840f7d3cf3522ac4a33460bed761
https://github.com/scummvm/scummvm/commit/fc410a88a0e8840f7d3cf3522ac4a33460bed761
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Method renaming
Changed paths:
engines/glk/adrift/adrift.cpp
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/os_glk.h
diff --git a/engines/glk/adrift/adrift.cpp b/engines/glk/adrift/adrift.cpp
index 8ae56df..9ba4e1c 100644
--- a/engines/glk/adrift/adrift.cpp
+++ b/engines/glk/adrift/adrift.cpp
@@ -33,8 +33,8 @@ Adrift::Adrift(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst,
}
void Adrift::runGame() {
- if (winglk_startup_code(&_gameFile))
- glk_main();
+ if (adrift_startup_code(&_gameFile))
+ adrift_main();
}
Common::Error Adrift::readSaveData(Common::SeekableReadStream *rs) {
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index 1244b48..3325380 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -3302,12 +3302,12 @@ static int gsc_startup_called = FALSE,
gsc_main_called = FALSE;
/*
- * glk_main()
+ * adrift_main()
*
* Main entry point for Glk. Here, all startup is done, and we call our
* function to run the game, or to report errors if gsc_game_message is set.
*/
-void glk_main() {
+void adrift_main() {
assert(gsc_startup_called && !gsc_main_called);
gsc_main_called = TRUE;
@@ -3320,7 +3320,7 @@ void glk_main() {
/* Glk linkage relevant only to the UNIX platform */
/*---------------------------------------------------------------------*/
-#ifdef TODO
+#ifdef UNUSED
/*
* Glk arguments for UNIX versions of the Glk interpreter.
*/
@@ -3348,7 +3348,7 @@ glkunix_argumentlist_t glkunix_arguments[] = {
*
* Startup entry point for Windows versions of Glk interpreter.
*/
-bool winglk_startup_code(Common::SeekableReadStream *gameFile) {
+bool adrift_startup_code(Common::SeekableReadStream *gameFile) {
const char *locale;
sc_uint trace_flags;
sc_bool enable_debugger, stable_random;
diff --git a/engines/glk/adrift/os_glk.h b/engines/glk/adrift/os_glk.h
index 0bc2681..52c7d89 100644
--- a/engines/glk/adrift/os_glk.h
+++ b/engines/glk/adrift/os_glk.h
@@ -29,8 +29,8 @@
namespace Glk {
namespace Adrift {
-extern bool winglk_startup_code(Common::SeekableReadStream *gameFile);
-extern void glk_main();
+extern bool adrift_startup_code(Common::SeekableReadStream *gameFile);
+extern void adrift_main();
} // End of namespace Adrift
} // End of namespace Glk
Commit: ac9b8fd43d75aca937a32e581e06019833776248
https://github.com/scummvm/scummvm/commit/ac9b8fd43d75aca937a32e581e06019833776248
Author: dreammaster (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Formatting
Changed paths:
engines/glk/adrift/detection_tables.h
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/scare.h
engines/glk/adrift/scdebug.cpp
engines/glk/adrift/scevents.cpp
engines/glk/adrift/scexpr.cpp
engines/glk/adrift/scgamest.cpp
engines/glk/adrift/scgamest.h
engines/glk/adrift/scinterf.cpp
engines/glk/adrift/sclibrar.cpp
engines/glk/adrift/sclocale.cpp
engines/glk/adrift/scmemos.cpp
engines/glk/adrift/scnpcs.cpp
engines/glk/adrift/scobjcts.cpp
engines/glk/adrift/scparser.cpp
engines/glk/adrift/scprintf.cpp
engines/glk/adrift/scprops.cpp
engines/glk/adrift/scprotos.h
engines/glk/adrift/scresour.cpp
engines/glk/adrift/screstrs.cpp
engines/glk/adrift/scrunner.cpp
engines/glk/adrift/scserial.cpp
engines/glk/adrift/sctaffil.cpp
engines/glk/adrift/sctafpar.cpp
engines/glk/adrift/sctasks.cpp
engines/glk/adrift/scutils.cpp
engines/glk/adrift/scvars.cpp
engines/glk/adrift/sxfile.cpp
engines/glk/adrift/sxglob.cpp
engines/glk/adrift/sxmain.cpp
engines/glk/adrift/sxprotos.h
engines/glk/adrift/sxscript.cpp
engines/glk/adrift/sxstubs.cpp
engines/glk/adrift/sxtester.cpp
engines/glk/adrift/sxutils.cpp
diff --git a/engines/glk/adrift/detection_tables.h b/engines/glk/adrift/detection_tables.h
index c824905..3f0bbde 100644
--- a/engines/glk/adrift/detection_tables.h
+++ b/engines/glk/adrift/detection_tables.h
@@ -190,7 +190,7 @@ const PlainGameDescriptor ADRIFT_GAME_LIST[] = {
{ "amcthorn", "Thorn" },
{ "amcneighbours", "Neighbours From Hell" },
{ "amcmonsters", "Monsters" },
- { "amcdiarystrip", "Diary of a Stripper" },
+ { "amcdiarystrip", "Diary of a Stripper" },
// ADRIFT One-Hour Game Competition 1
{ "1hgamonkeytoomany", "" },
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index 3325380..37ac07f 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -89,9 +89,9 @@ static const sc_int GSC_CONF_SUBTLE_HINT = INT_MAX,
GSC_CONF_CONTINUE_HINTS = INT_MAX - 2;
/* Forward declaration of event wait functions, and a short delay. */
-static void gsc_event_wait_2 (glui32 wait_type_1,
- glui32 wait_type_2, event_t *event);
-static void gsc_event_wait (glui32 wait_type, event_t *event);
+static void gsc_event_wait_2(glui32 wait_type_1,
+ glui32 wait_type_2, event_t *event);
+static void gsc_event_wait(glui32 wait_type, event_t *event);
static void gsc_short_delay();
@@ -106,29 +106,28 @@ static void gsc_short_delay();
* abort() or otherwise handle the error.
*/
static void
-gsc_fatal (const char *string)
-{
- /*
- * If the failure happens too early for us to have a window, print
- * the message to stderr.
- */
- if (!gsc_main_window) {
- error("\n\nINTERNAL ERROR: %s\n", string);
- }
+gsc_fatal(const char *string) {
+ /*
+ * If the failure happens too early for us to have a window, print
+ * the message to stderr.
+ */
+ if (!gsc_main_window) {
+ error("\n\nINTERNAL ERROR: %s\n", string);
+ }
- /* Cancel all possible pending window input events. */
- g_vm->glk_cancel_line_event (gsc_main_window, nullptr);
- g_vm->glk_cancel_char_event (gsc_main_window);
+ /* Cancel all possible pending window input events. */
+ g_vm->glk_cancel_line_event(gsc_main_window, nullptr);
+ g_vm->glk_cancel_char_event(gsc_main_window);
- /* Print a message indicating the error, and exit. */
- g_vm->glk_set_window (gsc_main_window);
- g_vm->glk_set_style (style_Normal);
- g_vm->glk_put_string ("\n\nINTERNAL ERROR: ");
- g_vm->glk_put_string ((char *) string);
+ /* Print a message indicating the error, and exit. */
+ g_vm->glk_set_window(gsc_main_window);
+ g_vm->glk_set_style(style_Normal);
+ g_vm->glk_put_string("\n\nINTERNAL ERROR: ");
+ g_vm->glk_put_string((char *) string);
- g_vm->glk_put_string ("\n\nPlease record the details of this error, try to"
- " note down everything you did to cause it, and email"
- " this information to simon_baldwin at yahoo.com.\n\n");
+ g_vm->glk_put_string("\n\nPlease record the details of this error, try to"
+ " note down everything you did to cause it, and email"
+ " this information to simon_baldwin at yahoo.com.\n\n");
}
@@ -138,18 +137,16 @@ gsc_fatal (const char *string)
* Non-failing malloc; call gsc_fatal and exit if memory allocation fails.
*/
static void *
-gsc_malloc (size_t size)
-{
- void *pointer;
+gsc_malloc(size_t size) {
+ void *pointer;
- pointer = malloc (size > 0 ? size : 1);
- if (!pointer)
- {
- gsc_fatal ("GLK: Out of system memory");
- g_vm->glk_exit ();
- }
+ pointer = malloc(size > 0 ? size : 1);
+ if (!pointer) {
+ gsc_fatal("GLK: Out of system memory");
+ g_vm->glk_exit();
+ }
- return pointer;
+ return pointer;
}
@@ -170,8 +167,8 @@ static const glui32 GSC_ISO_8859_EQUIVALENCE = 256;
*/
enum { GSC_TABLE_SIZE = 256 };
typedef struct {
- const glui32 unicode[GSC_TABLE_SIZE];
- const sc_char *const ascii[GSC_TABLE_SIZE];
+ const glui32 unicode[GSC_TABLE_SIZE];
+ const sc_char *const ascii[GSC_TABLE_SIZE];
} gsc_codepages_t;
/*
@@ -179,9 +176,9 @@ typedef struct {
* an alternate. The latter is intended for monospaced output.
*/
typedef struct {
- const sc_char *const name;
- const gsc_codepages_t main;
- const gsc_codepages_t alternate;
+ const sc_char *const name;
+ const gsc_codepages_t main;
+ const gsc_codepages_t alternate;
} gsc_locale_t;
@@ -195,117 +192,127 @@ typedef struct {
* character that might be recognizable as what it's trying to emulate.
*/
static const gsc_locale_t GSC_LATIN1_LOCALE = {
- "Latin1",
- /* cp1252 to unicode. */
-{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
- 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
- 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
- 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
- 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
- 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
- 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
- 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
- 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
- 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
- 0x007e, 0x0000, 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020,
- 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
- 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc,
- 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178, 0x00a0, 0x00a1,
- 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa,
- 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
- 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc,
- 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5,
- 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
- 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0,
- 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9,
- 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
- 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
- 0x00fc, 0x00fd, 0x00fe, 0x00ff },
- /* cp1252 to ascii. */
- { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
- "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
- "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
- "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
- "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
- "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
- "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
- "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
- "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
- "x", "y", "z", "{", "|", "}", "~", nullptr, "E", nullptr, ",",
- "f", ",,", "...", "+", "#", "^", "%", "S", "<", "OE", nullptr,
- "Z", nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", "~",
- "[TM]","s", ">", "oe", nullptr, "z", "Y", " ", "!", "c", "GBP",
- "*", "Y", "|", "S", "\"", "(C)", "a", "<<", "-", "-", "(R)",
- "-", "o", "+/-", "2", "3", "'", "u", "P", "*", ",", "1",
- "o", ">>", "1/4", "1/2", "3/4", "?", "A", "A", "A", "A", "A",
- "A", "AE", "C", "E", "E", "E", "E", "I", "I", "I", "I",
- "D", "N", "O", "O", "O", "O", "O", "x", "O", "U", "U",
- "U", "U", "Y", "p", "ss", "a", "a", "a", "a", "a", "a",
- "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "d",
- "n", "o", "o", "o", "o", "o", "/", "o", "u", "u", "u",
- "u", "y", "P", "y" } },
- /* cp850 to unicode. */
-{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
- 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
- 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
- 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
- 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
- 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
- 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
- 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
- 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
- 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
- 0x007e, 0x0000, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5,
- 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
- 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff,
- 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, 0x00e1, 0x00ed,
- 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae, 0x00ac,
- 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502,
- 0x2524, 0x00c1, 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d,
- 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c,
- 0x00e3, 0x00c3, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c,
- 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce,
- 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, 0x00d3,
- 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, 0x00de, 0x00da,
- 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1, 0x2017,
- 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, 0x00b0, 0x00a8, 0x00b7, 0x00b9,
- 0x00b3, 0x00b2, 0x25a0, 0x00a0 },
- /* cp850 to ascii. */
- { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
- "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
- "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
- "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
- "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
- "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
- "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
- "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
- "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
- "x", "y", "z", "{", "|", "}", "~", nullptr, "C", "u", "e",
- "a", "a", "a", "a", "c", "e", "e", "e", "i", "i", "i",
- "A", "A", "E", "ae", "AE", "o", "o", "o", "u", "u", "y",
- "O", "U", "o", "GBP", "O", "x", "f", "a", "i", "o", "u",
- "n", "N", "a", "o", "?", "(R)", "-", "1/2", "1/4", "i", "<<",
- ">>", "#", "#", "#", "|", "+", "A", "A", "A", "(C)", "+",
- "|", "+", "+", "c", "Y", "+", "+", "+", "+", "+", "-",
- "+", "a", "A", "+", "+", "+", "+", "+", "=", "+", "*",
- "d", "D", "E", "E", "E", "i", "I", "I", "I", "+", "+",
- ".", ".", "|", "I", ".", "O", "ss", "O", "O", "o", "O",
- "u", "p", "P", "U", "U", "U", "y", "Y", "-", "'", "-",
- "+/-", "=", "3/4", "P", "S", "/", ",", "deg", "\"", "*", "1",
- "3", "2", ".", " " } }
+ "Latin1",
+ /* cp1252 to unicode. */
+ { {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020,
+ 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
+ 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc,
+ 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178, 0x00a0, 0x00a1,
+ 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa,
+ 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
+ 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc,
+ 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5,
+ 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
+ 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0,
+ 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9,
+ 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
+ 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
+ 0x00fc, 0x00fd, 0x00fe, 0x00ff
+ },
+ /* cp1252 to ascii. */
+ {
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, "E", nullptr, ",",
+ "f", ",,", "...", "+", "#", "^", "%", "S", "<", "OE", nullptr,
+ "Z", nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", "~",
+ "[TM]", "s", ">", "oe", nullptr, "z", "Y", " ", "!", "c", "GBP",
+ "*", "Y", "|", "S", "\"", "(C)", "a", "<<", "-", "-", "(R)",
+ "-", "o", "+/-", "2", "3", "'", "u", "P", "*", ",", "1",
+ "o", ">>", "1/4", "1/2", "3/4", "?", "A", "A", "A", "A", "A",
+ "A", "AE", "C", "E", "E", "E", "E", "I", "I", "I", "I",
+ "D", "N", "O", "O", "O", "O", "O", "x", "O", "U", "U",
+ "U", "U", "Y", "p", "ss", "a", "a", "a", "a", "a", "a",
+ "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "d",
+ "n", "o", "o", "o", "o", "o", "/", "o", "u", "u", "u",
+ "u", "y", "P", "y"
+ }
+ },
+ /* cp850 to unicode. */
+ { {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5,
+ 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
+ 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff,
+ 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, 0x00e1, 0x00ed,
+ 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae, 0x00ac,
+ 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502,
+ 0x2524, 0x00c1, 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d,
+ 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c,
+ 0x00e3, 0x00c3, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c,
+ 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce,
+ 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, 0x00d3,
+ 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, 0x00de, 0x00da,
+ 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1, 0x2017,
+ 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, 0x00b0, 0x00a8, 0x00b7, 0x00b9,
+ 0x00b3, 0x00b2, 0x25a0, 0x00a0
+ },
+ /* cp850 to ascii. */
+ {
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, "C", "u", "e",
+ "a", "a", "a", "a", "c", "e", "e", "e", "i", "i", "i",
+ "A", "A", "E", "ae", "AE", "o", "o", "o", "u", "u", "y",
+ "O", "U", "o", "GBP", "O", "x", "f", "a", "i", "o", "u",
+ "n", "N", "a", "o", "?", "(R)", "-", "1/2", "1/4", "i", "<<",
+ ">>", "#", "#", "#", "|", "+", "A", "A", "A", "(C)", "+",
+ "|", "+", "+", "c", "Y", "+", "+", "+", "+", "+", "-",
+ "+", "a", "A", "+", "+", "+", "+", "+", "=", "+", "*",
+ "d", "D", "E", "E", "E", "i", "I", "I", "I", "+", "+",
+ ".", ".", "|", "I", ".", "O", "ss", "O", "O", "o", "O",
+ "u", "p", "P", "U", "U", "U", "y", "Y", "-", "'", "-",
+ "+/-", "=", "3/4", "P", "S", "/", ",", "deg", "\"", "*", "1",
+ "3", "2", ".", " "
+ }
+ }
};
@@ -321,117 +328,127 @@ static const gsc_locale_t GSC_LATIN1_LOCALE = {
* the general appearance and shape of the character being emulated is used.
*/
static const gsc_locale_t GSC_CYRILLIC_LOCALE = {
- "Cyrillic",
- /* cp1251 to unicode. */
-{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
- 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
- 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
- 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
- 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
- 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
- 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
- 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
- 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
- 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
- 0x007e, 0x0000, 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020,
- 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
- 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000,
- 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, 0x00a0, 0x040e,
- 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404,
- 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, 0x00b0, 0x00b1, 0x0406, 0x0456,
- 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458,
- 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
- 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
- 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430,
- 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439,
- 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442,
- 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b,
- 0x044c, 0x044d, 0x044e, 0x044f },
- /* cp1251 to gost 16876-71 ascii. */
- { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
- "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
- "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
- "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
- "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
- "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
- "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
- "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
- "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
- "x", "y", "z", "{", "|", "}", "~", nullptr, nullptr, nullptr, ",",
- nullptr, ",,", "...", "+", "#", "E", "%", nullptr, "<", nullptr, nullptr,
- nullptr, nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", nullptr,
- "[TM]",nullptr, ">", nullptr, nullptr, nullptr, nullptr, " ", nullptr, nullptr, nullptr,
- "*", "G", "|", "S", "Jo", "(C)", "Je", "<<", "-", "-", "(R)",
- "Ji", "o", "+/-", "I", "i", "g", "u", "P", "*", "jo", nullptr,
- "je", ">>", "j", "S", "s", "ji", "A", "B", "V", "G", "D",
- "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N", "O", "P",
- "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh", "Shh", "\"",
- "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g", "d", "e",
- "zh", "z", "i", "jj", "k", "l", "m", "n", "o", "p", "r",
- "s", "t", "u", "f", "kh", "c", "ch", "sh", "shh", "\"", "y",
- "'", "eh", "ju", "ja" } },
- /* cp866 to unicode. */
-{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
- 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
- 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
- 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
- 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
- 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
- 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
- 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
- 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
- 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
- 0x007e, 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416,
- 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
- 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431,
- 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a,
- 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x2591, 0x2592, 0x2593, 0x2502,
- 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d,
- 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c,
- 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c,
- 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
- 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x0440,
- 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449,
- 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0401, 0x0451, 0x0404,
- 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, 0x00b0, 0x2022, 0x00b7, 0x221a,
- 0x2116, 0x00a4, 0x25a0, 0x00a0 },
- /* cp866 to gost 16876-71 ascii. */
- { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
- "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
- "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
- "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
- "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
- "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
- "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
- "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
- "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
- "x", "y", "z", "{", "|", "}", "~", nullptr, "A", "B", "V",
- "G", "D", "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N",
- "O", "P", "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh",
- "Shh", "\"", "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g",
- "d", "e", "zh", "z", "i", "jj", "k", "l", "m", "n", "o",
- "p", "#", "#", "#", "|", "+", "+", "+", "+", "+", "+",
- "|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "-",
- "+", "+", "+", "+", "+", "+", "+", "+", "|", "+", "+",
- "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+",
- "+", ".", ".", ".", ".", "r", "s", "t", "u", "f", "kh",
- "c", "ch", "sh", "shh", "\"", "y", "'", "eh", "ju", "ja", "Jo",
- "jo", "Je", "je", "Ji", "ji", nullptr, nullptr, "deg", "*", "*", nullptr,
- nullptr, "*", ".", " " } }
+ "Cyrillic",
+ /* cp1251 to unicode. */
+ { {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020,
+ 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
+ 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000,
+ 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, 0x00a0, 0x040e,
+ 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404,
+ 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, 0x00b0, 0x00b1, 0x0406, 0x0456,
+ 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458,
+ 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
+ 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430,
+ 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439,
+ 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442,
+ 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b,
+ 0x044c, 0x044d, 0x044e, 0x044f
+ },
+ /* cp1251 to gost 16876-71 ascii. */
+ {
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, nullptr, nullptr, ",",
+ nullptr, ",,", "...", "+", "#", "E", "%", nullptr, "<", nullptr, nullptr,
+ nullptr, nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", nullptr,
+ "[TM]", nullptr, ">", nullptr, nullptr, nullptr, nullptr, " ", nullptr, nullptr, nullptr,
+ "*", "G", "|", "S", "Jo", "(C)", "Je", "<<", "-", "-", "(R)",
+ "Ji", "o", "+/-", "I", "i", "g", "u", "P", "*", "jo", nullptr,
+ "je", ">>", "j", "S", "s", "ji", "A", "B", "V", "G", "D",
+ "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N", "O", "P",
+ "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh", "Shh", "\"",
+ "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g", "d", "e",
+ "zh", "z", "i", "jj", "k", "l", "m", "n", "o", "p", "r",
+ "s", "t", "u", "f", "kh", "c", "ch", "sh", "shh", "\"", "y",
+ "'", "eh", "ju", "ja"
+ }
+ },
+ /* cp866 to unicode. */
+ { {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
+ 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
+ 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
+ 0x007e, 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416,
+ 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
+ 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431,
+ 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a,
+ 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x2591, 0x2592, 0x2593, 0x2502,
+ 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d,
+ 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c,
+ 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c,
+ 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
+ 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x0440,
+ 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449,
+ 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0401, 0x0451, 0x0404,
+ 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, 0x00b0, 0x2022, 0x00b7, 0x221a,
+ 0x2116, 0x00a4, 0x25a0, 0x00a0
+ },
+ /* cp866 to gost 16876-71 ascii. */
+ {
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
+ "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
+ "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a",
+ "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
+ "x", "y", "z", "{", "|", "}", "~", nullptr, "A", "B", "V",
+ "G", "D", "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N",
+ "O", "P", "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh",
+ "Shh", "\"", "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g",
+ "d", "e", "zh", "z", "i", "jj", "k", "l", "m", "n", "o",
+ "p", "#", "#", "#", "|", "+", "+", "+", "+", "+", "+",
+ "|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "-",
+ "+", "+", "+", "+", "+", "+", "+", "+", "|", "+", "+",
+ "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+",
+ "+", ".", ".", ".", ".", "r", "s", "t", "u", "f", "kh",
+ "c", "ch", "sh", "shh", "\"", "y", "'", "eh", "ju", "ja", "Jo",
+ "jo", "Je", "je", "Ji", "ji", nullptr, nullptr, "deg", "*", "*", nullptr,
+ nullptr, "*", ".", " "
+ }
+ }
};
@@ -447,24 +464,22 @@ static const sc_bool gsc_has_unicode = FALSE;
/* Gestalt selector and stubs for non-unicode capable libraries. */
static const glui32 gestalt_Unicode = 15;
-static void glk_put_char_uni (glui32 ch)
-{
- glui32 unused;
- unused = ch;
- gsc_fatal ("GLK: Stub unicode function called");
+static void glk_put_char_uni(glui32 ch) {
+ glui32 unused;
+ unused = ch;
+ gsc_fatal("GLK: Stub unicode function called");
}
-static void glk_request_line_event_uni (winid_t win,
- glui32 *buf, glui32 maxlen, glui32 initlen)
-{
- winid_t unused1;
- glui32 *unused2;
- glui32 unused3, unused4;
- unused1 = win;
- unused2 = buf;
- unused3 = maxlen;
- unused4 = initlen;
- gsc_fatal ("GLK: Stub unicode function called");
+static void glk_request_line_event_uni(winid_t win,
+ glui32 *buf, glui32 maxlen, glui32 initlen) {
+ winid_t unused1;
+ glui32 *unused2;
+ glui32 unused3, unused4;
+ unused1 = win;
+ unused2 = buf;
+ unused3 = maxlen;
+ unused4 = initlen;
+ gsc_fatal("GLK: Stub unicode function called");
}
#endif
@@ -480,9 +495,9 @@ static const glui32 GSC_MIN_PRINTABLE = ' ',
/* List of pointers to supported and available locales, nullptr terminated. */
static const gsc_locale_t *const GSC_AVAILABLE_LOCALES[] = {
- &GSC_LATIN1_LOCALE,
- &GSC_CYRILLIC_LOCALE,
- nullptr
+ &GSC_LATIN1_LOCALE,
+ &GSC_CYRILLIC_LOCALE,
+ nullptr
};
/*
@@ -499,30 +514,27 @@ static const gsc_locale_t *const gsc_fallback_locale = &GSC_LATIN1_LOCALE;
* Set a locale explicitly from the name passed in.
*/
static void
-gsc_set_locale (const sc_char *name)
-{
- const gsc_locale_t *matched = nullptr;
- const gsc_locale_t *const *iterator;
- assert (name);
+gsc_set_locale(const sc_char *name) {
+ const gsc_locale_t *matched = nullptr;
+ const gsc_locale_t *const *iterator;
+ assert(name);
- /*
- * Search locales for a matching name, abbreviated if necessary. Stop on
- * the first match found.
- */
- for (iterator = GSC_AVAILABLE_LOCALES; *iterator; iterator++)
- {
- const gsc_locale_t *const locale = *iterator;
+ /*
+ * Search locales for a matching name, abbreviated if necessary. Stop on
+ * the first match found.
+ */
+ for (iterator = GSC_AVAILABLE_LOCALES; *iterator; iterator++) {
+ const gsc_locale_t *const locale = *iterator;
- if (sc_strncasecmp (name, locale->name, strlen (name)) == 0)
- {
- matched = locale;
- break;
- }
- }
+ if (sc_strncasecmp(name, locale->name, strlen(name)) == 0) {
+ matched = locale;
+ break;
+ }
+ }
- /* If matched, set the global locale. */
- if (matched)
- gsc_locale = matched;
+ /* If matched, set the global locale. */
+ if (matched)
+ gsc_locale = matched;
}
@@ -533,24 +545,22 @@ gsc_set_locale (const sc_char *name)
* having to write transcripts as ascii.
*/
static void
-gsc_put_char_uni (glui32 unicode, const char *ascii)
-{
- /* If there is an transcript stream, temporarily disconnect it. */
- if (gsc_transcript_stream)
- g_vm->glk_window_set_echo_stream (gsc_main_window, nullptr);
+gsc_put_char_uni(glui32 unicode, const char *ascii) {
+ /* If there is an transcript stream, temporarily disconnect it. */
+ if (gsc_transcript_stream)
+ g_vm->glk_window_set_echo_stream(gsc_main_window, nullptr);
- g_vm->glk_put_char_uni (unicode);
+ g_vm->glk_put_char_uni(unicode);
- /* Print ascii to the transcript, then reattach it. */
- if (gsc_transcript_stream)
- {
- if (ascii)
- g_vm->glk_put_string_stream (gsc_transcript_stream, (char *) ascii);
- else
- g_vm->glk_put_char_stream (gsc_transcript_stream, '?');
+ /* Print ascii to the transcript, then reattach it. */
+ if (gsc_transcript_stream) {
+ if (ascii)
+ g_vm->glk_put_string_stream(gsc_transcript_stream, (char *) ascii);
+ else
+ g_vm->glk_put_char_stream(gsc_transcript_stream, '?');
- g_vm->glk_window_set_echo_stream (gsc_main_window, gsc_transcript_stream);
- }
+ g_vm->glk_window_set_echo_stream(gsc_main_window, gsc_transcript_stream);
+ }
}
@@ -561,86 +571,79 @@ gsc_put_char_uni (glui32 unicode, const char *ascii)
* main or the alternate codepage depending on the flag passed in.
*/
static void
-gsc_put_char_locale (sc_char ch,
- const gsc_locale_t *locale, sc_bool is_alternate)
-{
- const gsc_codepages_t *codepage;
- unsigned char character;
- glui32 unicode;
- const char *ascii;
-
- /*
- * Select either the main or the alternate codepage for this locale, and
- * retrieve the unicode and ascii representations of the character.
- */
- codepage = is_alternate ? &locale->alternate : &locale->main;
- character = (unsigned char) ch;
- unicode = codepage->unicode[character];
- ascii = codepage->ascii[character];
-
- /*
- * If a unicode representation exists, use for either iso 8859-1 or, if
- * possible, direct unicode output.
- */
- if (unicode > 0)
- {
- /*
- * If unicode is in the range 1-255, this value is directly equivalent
- * to the iso 8859-1 representation; otherwise the character has no
- * direct iso 8859-1 glyph.
- */
- if (unicode < GSC_ISO_8859_EQUIVALENCE)
- {
- /*
- * If the iso 8859-1 character is one that this Glk library will
- * print exactly, print and return. We add a check here for the
- * guaranteed printable characters, since some Glk libraries don't
- * return the correct values for gestalt_CharOutput for these.
- */
- if (unicode == '\n'
- || (unicode >= GSC_MIN_PRINTABLE && unicode <= GSC_MAX_PRINTABLE)
- || g_vm->glk_gestalt (gestalt_CharOutput,
- unicode) == gestalt_CharOutput_ExactPrint)
- {
- g_vm->glk_put_char ((unsigned char) unicode);
- return;
- }
- }
-
- /*
- * If no usable iso 8859-1 representation, see if unicode is enabled and
- * if the Glk library can print the character exactly. If yes, output
- * the character that way.
- *
- * TODO Using unicode output currently disrupts transcript output. Any
- * echo stream connected for a transcript here will be a text rather than
- * a unicode stream, so probably won't output the character correctly.
- * For now, if there's a transcript, we try to write ascii output.
- */
- if (gsc_unicode_enabled)
- {
- if (g_vm->glk_gestalt (gestalt_CharOutput,
- unicode) == gestalt_CharOutput_ExactPrint)
- {
- gsc_put_char_uni (unicode, ascii);
- return;
- }
- }
- }
-
- /*
- * No success with iso 8859-1 or unicode, so try for an ascii substitute.
- * Substitute strings use only 7-bit ascii, and so all are safe to print
- * directly with Glk.
- */
- if (ascii)
- {
- g_vm->glk_put_string ((char *) ascii);
- return;
- }
-
- /* No apparent way to output this character, so print a '?'. */
- g_vm->glk_put_char ('?');
+gsc_put_char_locale(sc_char ch,
+ const gsc_locale_t *locale, sc_bool is_alternate) {
+ const gsc_codepages_t *codepage;
+ unsigned char character;
+ glui32 unicode;
+ const char *ascii;
+
+ /*
+ * Select either the main or the alternate codepage for this locale, and
+ * retrieve the unicode and ascii representations of the character.
+ */
+ codepage = is_alternate ? &locale->alternate : &locale->main;
+ character = (unsigned char) ch;
+ unicode = codepage->unicode[character];
+ ascii = codepage->ascii[character];
+
+ /*
+ * If a unicode representation exists, use for either iso 8859-1 or, if
+ * possible, direct unicode output.
+ */
+ if (unicode > 0) {
+ /*
+ * If unicode is in the range 1-255, this value is directly equivalent
+ * to the iso 8859-1 representation; otherwise the character has no
+ * direct iso 8859-1 glyph.
+ */
+ if (unicode < GSC_ISO_8859_EQUIVALENCE) {
+ /*
+ * If the iso 8859-1 character is one that this Glk library will
+ * print exactly, print and return. We add a check here for the
+ * guaranteed printable characters, since some Glk libraries don't
+ * return the correct values for gestalt_CharOutput for these.
+ */
+ if (unicode == '\n'
+ || (unicode >= GSC_MIN_PRINTABLE && unicode <= GSC_MAX_PRINTABLE)
+ || g_vm->glk_gestalt(gestalt_CharOutput,
+ unicode) == gestalt_CharOutput_ExactPrint) {
+ g_vm->glk_put_char((unsigned char) unicode);
+ return;
+ }
+ }
+
+ /*
+ * If no usable iso 8859-1 representation, see if unicode is enabled and
+ * if the Glk library can print the character exactly. If yes, output
+ * the character that way.
+ *
+ * TODO Using unicode output currently disrupts transcript output. Any
+ * echo stream connected for a transcript here will be a text rather than
+ * a unicode stream, so probably won't output the character correctly.
+ * For now, if there's a transcript, we try to write ascii output.
+ */
+ if (gsc_unicode_enabled) {
+ if (g_vm->glk_gestalt(gestalt_CharOutput,
+ unicode) == gestalt_CharOutput_ExactPrint) {
+ gsc_put_char_uni(unicode, ascii);
+ return;
+ }
+ }
+ }
+
+ /*
+ * No success with iso 8859-1 or unicode, so try for an ascii substitute.
+ * Substitute strings use only 7-bit ascii, and so all are safe to print
+ * directly with Glk.
+ */
+ if (ascii) {
+ g_vm->glk_put_string((char *) ascii);
+ return;
+ }
+
+ /* No apparent way to output this character, so print a '?'. */
+ g_vm->glk_put_char('?');
}
@@ -655,55 +658,49 @@ gsc_put_char_locale (sc_char ch,
* Public functions for writing using the current or fallback locale.
*/
static void
-gsc_put_char (const sc_char character)
-{
- const gsc_locale_t *locale;
+gsc_put_char(const sc_char character) {
+ const gsc_locale_t *locale;
- locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
- gsc_put_char_locale (character, locale, FALSE);
+ locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
+ gsc_put_char_locale(character, locale, FALSE);
}
static void
-gsc_put_char_alternate (const sc_char character)
-{
- const gsc_locale_t *locale;
+gsc_put_char_alternate(const sc_char character) {
+ const gsc_locale_t *locale;
- locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
- gsc_put_char_locale (character, locale, TRUE);
+ locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
+ gsc_put_char_locale(character, locale, TRUE);
}
static void
-gsc_put_buffer_using (const sc_char *buffer,
- sc_int length, void (*putchar_function) (sc_char))
-{
- sc_int index_;
+gsc_put_buffer_using(const sc_char *buffer,
+ sc_int length, void (*putchar_function)(sc_char)) {
+ sc_int index_;
- for (index_ = 0; index_ < length; index_++)
- putchar_function (buffer[index_]);
+ for (index_ = 0; index_ < length; index_++)
+ putchar_function(buffer[index_]);
}
static void
-gsc_put_buffer (const sc_char *buffer, sc_int length)
-{
- assert (buffer);
+gsc_put_buffer(const sc_char *buffer, sc_int length) {
+ assert(buffer);
- gsc_put_buffer_using (buffer, length, gsc_put_char);
+ gsc_put_buffer_using(buffer, length, gsc_put_char);
}
static void
-gsc_put_string (const sc_char *string)
-{
- assert (string);
+gsc_put_string(const sc_char *string) {
+ assert(string);
- gsc_put_buffer_using (string, strlen (string), gsc_put_char);
+ gsc_put_buffer_using(string, strlen(string), gsc_put_char);
}
static void
-gsc_put_string_alternate (const sc_char *string)
-{
- assert (string);
+gsc_put_string_alternate(const sc_char *string) {
+ assert(string);
- gsc_put_buffer_using (string, strlen (string), gsc_put_char_alternate);
+ gsc_put_buffer_using(string, strlen(string), gsc_put_char_alternate);
}
@@ -716,36 +713,33 @@ gsc_put_string_alternate (const sc_char *string)
* available.
*/
static sc_char
-gsc_unicode_to_locale (glui32 unicode, const gsc_locale_t *locale)
-{
- const gsc_codepages_t *codepage;
- sc_int character;
+gsc_unicode_to_locale(glui32 unicode, const gsc_locale_t *locale) {
+ const gsc_codepages_t *codepage;
+ sc_int character;
- /* Always use the main codepage for input. */
- codepage = &locale->main;
+ /* Always use the main codepage for input. */
+ codepage = &locale->main;
- /*
- * Search the unicode table sequentially for the input character. This is
- * inefficient, but because game input is usually not copious, excusable.
- */
- for (character = 0; character < GSC_TABLE_SIZE; character++)
- {
- if (codepage->unicode[character] == unicode)
- break;
- }
+ /*
+ * Search the unicode table sequentially for the input character. This is
+ * inefficient, but because game input is usually not copious, excusable.
+ */
+ for (character = 0; character < GSC_TABLE_SIZE; character++) {
+ if (codepage->unicode[character] == unicode)
+ break;
+ }
- /* Return the character translation, or '?' if none. */
- return character < GSC_TABLE_SIZE ? (sc_char) character : '?';
+ /* Return the character translation, or '?' if none. */
+ return character < GSC_TABLE_SIZE ? (sc_char) character : '?';
}
static void
-gsc_unicode_buffer_to_locale (const glui32 *unicode, sc_int length,
- sc_char *buffer, const gsc_locale_t *locale)
-{
- sc_int index_;
+gsc_unicode_buffer_to_locale(const glui32 *unicode, sc_int length,
+ sc_char *buffer, const gsc_locale_t *locale) {
+ sc_int index_;
- for (index_ = 0; index_ < length; index_++)
- buffer[index_] = gsc_unicode_to_locale (unicode[index_], locale);
+ for (index_ = 0; index_ < length; index_++)
+ buffer[index_] = gsc_unicode_to_locale(unicode[index_], locale);
}
@@ -756,41 +750,39 @@ gsc_unicode_buffer_to_locale (const glui32 *unicode, sc_int length,
* of characters placed in the buffer.
*/
static sc_int
-gsc_read_line_locale (sc_char *buffer,
- sc_int length, const gsc_locale_t *locale)
-{
- event_t event;
+gsc_read_line_locale(sc_char *buffer,
+ sc_int length, const gsc_locale_t *locale) {
+ event_t event;
- /*
- * If we have unicode, we have to use it to ensure that characters not in
- * the Latin1 locale are properly translated.
- */
- if (gsc_unicode_enabled)
- {
- glui32 *unicode;
+ /*
+ * If we have unicode, we have to use it to ensure that characters not in
+ * the Latin1 locale are properly translated.
+ */
+ if (gsc_unicode_enabled) {
+ glui32 *unicode;
- /*
- * Allocate a unicode buffer long enough to hold all the characters,
- * then read in a unicode line.
- */
- unicode = (glui32 *)gsc_malloc (length * sizeof (*unicode));
- g_vm->glk_request_line_event_uni (gsc_main_window, unicode, length, 0);
- gsc_event_wait (evtype_LineInput, &event);
+ /*
+ * Allocate a unicode buffer long enough to hold all the characters,
+ * then read in a unicode line.
+ */
+ unicode = (glui32 *)gsc_malloc(length * sizeof(*unicode));
+ g_vm->glk_request_line_event_uni(gsc_main_window, unicode, length, 0);
+ gsc_event_wait(evtype_LineInput, &event);
- /* Convert the unicode buffer out, then free it. */
- gsc_unicode_buffer_to_locale (unicode, event.val1, buffer, locale);
- free (unicode);
+ /* Convert the unicode buffer out, then free it. */
+ gsc_unicode_buffer_to_locale(unicode, event.val1, buffer, locale);
+ free(unicode);
- /* Return the count of characters placed in the buffer. */
- return event.val1;
- }
+ /* Return the count of characters placed in the buffer. */
+ return event.val1;
+ }
- /* No success with unicode, so fall back to standard line input. */
- g_vm->glk_request_line_event (gsc_main_window, buffer, length, 0);
- gsc_event_wait (evtype_LineInput, &event);
+ /* No success with unicode, so fall back to standard line input. */
+ g_vm->glk_request_line_event(gsc_main_window, buffer, length, 0);
+ gsc_event_wait(evtype_LineInput, &event);
- /* Return the count of characters placed in the buffer. */
- return event.val1;
+ /* Return the count of characters placed in the buffer. */
+ return event.val1;
}
@@ -800,12 +792,11 @@ gsc_read_line_locale (sc_char *buffer,
* Public function for reading using the current or fallback locale.
*/
static sc_int
-gsc_read_line (sc_char *buffer, sc_int length)
-{
- const gsc_locale_t *locale;
+gsc_read_line(sc_char *buffer, sc_int length) {
+ const gsc_locale_t *locale;
- locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
- return gsc_read_line_locale (buffer, length, locale);
+ locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
+ return gsc_read_line_locale(buffer, length, locale);
}
@@ -834,22 +825,19 @@ static const sc_char *const GSC_WHITESPACE = "\t\n\v\f\r ";
* other than whitespace.
*/
static sc_bool
-gsc_is_string_usable (const sc_char *string)
-{
- /* If non-null, scan for any non-space character. */
- if (string)
- {
- sc_int index_;
-
- for (index_ = 0; string[index_] != '\0'; index_++)
- {
- if (!strchr (GSC_WHITESPACE, string[index_]))
- return TRUE;
- }
- }
+gsc_is_string_usable(const sc_char *string) {
+ /* If non-null, scan for any non-space character. */
+ if (string) {
+ sc_int index_;
+
+ for (index_ = 0; string[index_] != '\0'; index_++) {
+ if (!strchr(GSC_WHITESPACE, string[index_]))
+ return TRUE;
+ }
+ }
- /* nullptr, or no characters other than whitespace. */
- return FALSE;
+ /* nullptr, or no characters other than whitespace. */
+ return FALSE;
}
@@ -860,69 +848,62 @@ gsc_is_string_usable (const sc_char *string)
* Glk libraries.
*/
static void
-gsc_status_update()
-{
- glui32 width, height;
- uint index;
- assert (gsc_status_window);
-
- g_vm->glk_window_get_size (gsc_status_window, &width, &height);
- if (height > 0)
- {
- const sc_char *room;
-
- g_vm->glk_window_clear (gsc_status_window);
- g_vm->glk_window_move_cursor (gsc_status_window, 0, 0);
- g_vm->glk_set_window (gsc_status_window);
-
- g_vm->glk_set_style(style_User1);
- for (index = 0; index < width; index++)
- g_vm->glk_put_char (' ');
- g_vm->glk_window_move_cursor (gsc_status_window, 0, 0);
-
- /* See if the game is indicating any current player room. */
- room = sc_get_game_room (gsc_game);
- if (!gsc_is_string_usable (room))
- {
- /*
- * Player location is indeterminate, so print out a generic status,
- * showing the game name and author.
- */
- g_vm->glk_window_move_cursor (gsc_status_window, 1, 0);
- gsc_put_string (sc_get_game_name (gsc_game));
- g_vm->glk_put_string (" | ");
- gsc_put_string (sc_get_game_author (gsc_game));
- }
- else
- {
- const sc_char *status;
- char score[64];
-
- /* Print the player location. */
- g_vm->glk_window_move_cursor (gsc_status_window, 1, 0);
- gsc_put_string (room);
-
- /* Get the game's status line, or if none, format score. */
- status = sc_get_game_status_line (gsc_game);
- if (!gsc_is_string_usable (status))
- {
- sprintf (score, "Score: %ld", sc_get_game_score (gsc_game));
- status = score;
- }
-
- /* Print the status line or score at window right, if it fits. */
- if (width > strlen (status) + GSC_STATUS_SLOP + 1)
- {
- glui32 position;
-
- position = width - strlen (status) - GSC_STATUS_SLOP;
- g_vm->glk_window_move_cursor (gsc_status_window, position - 1, 0);
- gsc_put_string (status);
- }
- }
-
- g_vm->glk_set_window (gsc_main_window);
- }
+gsc_status_update() {
+ glui32 width, height;
+ uint index;
+ assert(gsc_status_window);
+
+ g_vm->glk_window_get_size(gsc_status_window, &width, &height);
+ if (height > 0) {
+ const sc_char *room;
+
+ g_vm->glk_window_clear(gsc_status_window);
+ g_vm->glk_window_move_cursor(gsc_status_window, 0, 0);
+ g_vm->glk_set_window(gsc_status_window);
+
+ g_vm->glk_set_style(style_User1);
+ for (index = 0; index < width; index++)
+ g_vm->glk_put_char(' ');
+ g_vm->glk_window_move_cursor(gsc_status_window, 0, 0);
+
+ /* See if the game is indicating any current player room. */
+ room = sc_get_game_room(gsc_game);
+ if (!gsc_is_string_usable(room)) {
+ /*
+ * Player location is indeterminate, so print out a generic status,
+ * showing the game name and author.
+ */
+ g_vm->glk_window_move_cursor(gsc_status_window, 1, 0);
+ gsc_put_string(sc_get_game_name(gsc_game));
+ g_vm->glk_put_string(" | ");
+ gsc_put_string(sc_get_game_author(gsc_game));
+ } else {
+ const sc_char *status;
+ char score[64];
+
+ /* Print the player location. */
+ g_vm->glk_window_move_cursor(gsc_status_window, 1, 0);
+ gsc_put_string(room);
+
+ /* Get the game's status line, or if none, format score. */
+ status = sc_get_game_status_line(gsc_game);
+ if (!gsc_is_string_usable(status)) {
+ sprintf(score, "Score: %ld", sc_get_game_score(gsc_game));
+ status = score;
+ }
+
+ /* Print the status line or score at window right, if it fits. */
+ if (width > strlen(status) + GSC_STATUS_SLOP + 1) {
+ glui32 position;
+
+ position = width - strlen(status) - GSC_STATUS_SLOP;
+ g_vm->glk_window_move_cursor(gsc_status_window, position - 1, 0);
+ gsc_put_string(status);
+ }
+ }
+
+ g_vm->glk_set_window(gsc_main_window);
+ }
}
@@ -933,15 +914,14 @@ gsc_status_update()
* available length.
*/
static void
-gsc_status_safe_strcat (char *dest, size_t length, const char *src)
-{
- size_t available, src_length;
+gsc_status_safe_strcat(char *dest, size_t length, const char *src) {
+ size_t available, src_length;
- /* Append only as many characters as will fit. */
- src_length = strlen (src);
- available = length - strlen (dest) - 1;
- if (available > 0)
- strncat (dest, src, src_length < available ? src_length : available);
+ /* Append only as many characters as will fit. */
+ src_length = strlen(src);
+ available = length - strlen(dest) - 1;
+ if (available > 0)
+ strncat(dest, src, src_length < available ? src_length : available);
}
@@ -953,48 +933,44 @@ gsc_status_safe_strcat (char *dest, size_t length, const char *src)
* windowing Glk libraries.
*/
static void
-gsc_status_print()
-{
- static char current_status[GSC_STATUS_BUFFER_LENGTH + 1];
-
- const sc_char *room;
-
- /* Do nothing if the game isn't indicating any current player room. */
- room = sc_get_game_room (gsc_game);
- if (gsc_is_string_usable (room))
- {
- char buffer[GSC_STATUS_BUFFER_LENGTH + 1];
- const sc_char *status;
- char score[64];
-
- /* Make an attempt at a status line, starting with player location. */
- strcpy (buffer, "");
- gsc_status_safe_strcat (buffer, sizeof (buffer), room);
-
- /* Get the game's status line, or if none, format score. */
- status = sc_get_game_status_line (gsc_game);
- if (!gsc_is_string_usable (status))
- {
- sprintf (score, "Score: %ld", sc_get_game_score (gsc_game));
- status = score;
- }
+gsc_status_print() {
+ static char current_status[GSC_STATUS_BUFFER_LENGTH + 1];
+
+ const sc_char *room;
+
+ /* Do nothing if the game isn't indicating any current player room. */
+ room = sc_get_game_room(gsc_game);
+ if (gsc_is_string_usable(room)) {
+ char buffer[GSC_STATUS_BUFFER_LENGTH + 1];
+ const sc_char *status;
+ char score[64];
+
+ /* Make an attempt at a status line, starting with player location. */
+ strcpy(buffer, "");
+ gsc_status_safe_strcat(buffer, sizeof(buffer), room);
+
+ /* Get the game's status line, or if none, format score. */
+ status = sc_get_game_status_line(gsc_game);
+ if (!gsc_is_string_usable(status)) {
+ sprintf(score, "Score: %ld", sc_get_game_score(gsc_game));
+ status = score;
+ }
- /* Append the status line or score. */
- gsc_status_safe_strcat (buffer, sizeof (buffer), " | ");
- gsc_status_safe_strcat (buffer, sizeof (buffer), status);
+ /* Append the status line or score. */
+ gsc_status_safe_strcat(buffer, sizeof(buffer), " | ");
+ gsc_status_safe_strcat(buffer, sizeof(buffer), status);
- /* If this matches the current saved status line, do nothing more. */
- if (strcmp (buffer, current_status) != 0)
- {
- /* Bracket, and output the status line buffer. */
- g_vm->glk_put_string ("[ ");
- gsc_put_string (buffer);
- g_vm->glk_put_string (" ]\n");
+ /* If this matches the current saved status line, do nothing more. */
+ if (strcmp(buffer, current_status) != 0) {
+ /* Bracket, and output the status line buffer. */
+ g_vm->glk_put_string("[ ");
+ gsc_put_string(buffer);
+ g_vm->glk_put_string(" ]\n");
- /* Save the details of the printed status buffer. */
- strcpy (current_status, buffer);
- }
- }
+ /* Save the details of the printed status buffer. */
+ strcpy(current_status, buffer);
+ }
+ }
}
@@ -1005,12 +981,11 @@ gsc_status_print()
* or prints the status line to the main window.
*/
static void
-gsc_status_notify()
-{
- if (gsc_status_window)
- gsc_status_update ();
- else
- gsc_status_print ();
+gsc_status_notify() {
+ if (gsc_status_window)
+ gsc_status_update();
+ else
+ gsc_status_print();
}
@@ -1022,27 +997,25 @@ gsc_status_notify()
* arrange events.
*/
static void
-gsc_status_redraw()
-{
- if (gsc_status_window)
- {
- winid_t parent;
-
- /*
- * Rearrange the status window, without changing its actual arrangement
- * in any way. This is a hack to work round incorrect window repainting
- * in Xglk; it forces a complete repaint of affected windows on Glk
- * window resize and arrange events, and works in part because Xglk
- * doesn't check for actual arrangement changes in any way before
- * invalidating its windows. The hack should be harmless to Glk
- * libraries other than Xglk, moreover, we're careful to activate it
- * only on resize and arrange events.
- */
- parent = g_vm->glk_window_get_parent (gsc_status_window);
- g_vm->glk_window_set_arrangement (parent,
- winmethod_Above | winmethod_Fixed, 1, nullptr);
- gsc_status_update ();
- }
+gsc_status_redraw() {
+ if (gsc_status_window) {
+ winid_t parent;
+
+ /*
+ * Rearrange the status window, without changing its actual arrangement
+ * in any way. This is a hack to work round incorrect window repainting
+ * in Xglk; it forces a complete repaint of affected windows on Glk
+ * window resize and arrange events, and works in part because Xglk
+ * doesn't check for actual arrangement changes in any way before
+ * invalidating its windows. The hack should be harmless to Glk
+ * libraries other than Xglk, moreover, we're careful to activate it
+ * only on resize and arrange events.
+ */
+ parent = g_vm->glk_window_get_parent(gsc_status_window);
+ g_vm->glk_window_set_arrangement(parent,
+ winmethod_Above | winmethod_Fixed, 1, nullptr);
+ gsc_status_update();
+ }
}
@@ -1059,8 +1032,8 @@ static int gsc_help_requested = FALSE,
/* Font descriptor type, encapsulating size and monospaced boolean. */
typedef struct {
- sc_bool is_monospaced;
- sc_int size;
+ sc_bool is_monospaced;
+ sc_int size;
} gsc_font_size_t;
/* Font stack and attributes for nesting tags. */
@@ -1098,29 +1071,25 @@ static const glui32 GSC_CANCEL_WAIT_1 = ' ',
* help from the interpreter unless silenced.
*/
static void
-gsc_output_register_help_request()
-{
- gsc_help_requested = TRUE;
+gsc_output_register_help_request() {
+ gsc_help_requested = TRUE;
}
static void
-gsc_output_silence_help_hints()
-{
- gsc_help_hints_silenced = TRUE;
+gsc_output_silence_help_hints() {
+ gsc_help_hints_silenced = TRUE;
}
static void
-gsc_output_provide_help_hint()
-{
- if (gsc_help_requested && !gsc_help_hints_silenced)
- {
- g_vm->glk_set_style (style_Emphasized);
- g_vm->glk_put_string ("[Try 'glk help' for help on special interpreter"
- " commands]\n");
+gsc_output_provide_help_hint() {
+ if (gsc_help_requested && !gsc_help_hints_silenced) {
+ g_vm->glk_set_style(style_Emphasized);
+ g_vm->glk_put_string("[Try 'glk help' for help on special interpreter"
+ " commands]\n");
- gsc_help_requested = FALSE;
- g_vm->glk_set_style (style_Normal);
- }
+ gsc_help_requested = FALSE;
+ g_vm->glk_set_style(style_Normal);
+ }
}
@@ -1129,67 +1098,58 @@ gsc_output_provide_help_hint()
*
* Set a Glk style based on the top of the font stack and attributes.
*/
-static void gsc_set_glk_style()
-{
- sc_bool is_monospaced;
- sc_int font_size;
-
- /* Get the current font stack top, or default value. */
- if (gsc_font_index > 0)
- {
- is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
- font_size = gsc_font_stack[gsc_font_index - 1].size;
- }
- else
- {
- is_monospaced = FALSE;
- font_size = GSC_DEFAULT_FONT_SIZE;
- }
-
- /*
- * Map the font and current attributes into a Glk style. Because Glk styles
- * aren't cumulative this has to be done by precedences.
- */
- if (is_monospaced)
- {
- /*
- * No matter the size or attributes, if monospaced use Preformatted
- * style, as it's all we have.
- */
- g_vm->glk_set_style (style_Preformatted);
- }
- else
- {
- /*
- * For large and medium point sizes, use Header or Subheader styles
- * respectively.
- */
- if (font_size >= GSC_LARGE_FONT_SIZE)
- g_vm->glk_set_style (style_Header);
- else if (font_size >= GSC_MEDIUM_FONT_SIZE)
- g_vm->glk_set_style (style_Subheader);
- else
- {
- /*
- * For bold, use Subheader; for italics, underline, or secondary
- * color, use Emphasized.
- */
- if (gsc_attribute_bold > 0)
- g_vm->glk_set_style (style_Subheader);
- else if (gsc_attribute_italic > 0
- || gsc_attribute_underline > 0
- || gsc_attribute_secondary_color > 0)
- g_vm->glk_set_style (style_Emphasized);
- else
- {
- /*
- * There's nothing special about this text, so drop down to
- * Normal style.
- */
- g_vm->glk_set_style (style_Normal);
- }
- }
- }
+static void gsc_set_glk_style() {
+ sc_bool is_monospaced;
+ sc_int font_size;
+
+ /* Get the current font stack top, or default value. */
+ if (gsc_font_index > 0) {
+ is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
+ font_size = gsc_font_stack[gsc_font_index - 1].size;
+ } else {
+ is_monospaced = FALSE;
+ font_size = GSC_DEFAULT_FONT_SIZE;
+ }
+
+ /*
+ * Map the font and current attributes into a Glk style. Because Glk styles
+ * aren't cumulative this has to be done by precedences.
+ */
+ if (is_monospaced) {
+ /*
+ * No matter the size or attributes, if monospaced use Preformatted
+ * style, as it's all we have.
+ */
+ g_vm->glk_set_style(style_Preformatted);
+ } else {
+ /*
+ * For large and medium point sizes, use Header or Subheader styles
+ * respectively.
+ */
+ if (font_size >= GSC_LARGE_FONT_SIZE)
+ g_vm->glk_set_style(style_Header);
+ else if (font_size >= GSC_MEDIUM_FONT_SIZE)
+ g_vm->glk_set_style(style_Subheader);
+ else {
+ /*
+ * For bold, use Subheader; for italics, underline, or secondary
+ * color, use Emphasized.
+ */
+ if (gsc_attribute_bold > 0)
+ g_vm->glk_set_style(style_Subheader);
+ else if (gsc_attribute_italic > 0
+ || gsc_attribute_underline > 0
+ || gsc_attribute_secondary_color > 0)
+ g_vm->glk_set_style(style_Emphasized);
+ else {
+ /*
+ * There's nothing special about this text, so drop down to
+ * Normal style.
+ */
+ g_vm->glk_set_style(style_Normal);
+ }
+ }
+ }
}
@@ -1201,83 +1161,74 @@ static void gsc_set_glk_style()
* font tag. Set the appropriate Glk style.
*/
static void
-gsc_handle_font_tag (const sc_char *argument)
-{
- /* Ignore the call on stack overrun. */
- if (gsc_font_index < GSC_MAX_STYLE_NESTING)
- {
- sc_char *lower, *face, *size;
- sc_bool is_monospaced;
- sc_int index_, font_size;
-
- /* Get the current top of stack, or default on empty stack. */
- if (gsc_font_index > 0)
- {
- is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
- font_size = gsc_font_stack[gsc_font_index - 1].size;
- }
- else
- {
- is_monospaced = FALSE;
- font_size = GSC_DEFAULT_FONT_SIZE;
- }
-
- /* Copy and convert argument to all lowercase. */
- lower = (sc_char *)gsc_malloc (strlen (argument) + 1);
- strcpy (lower, argument);
- for (index_ = 0; lower[index_] != '\0'; index_++)
- lower[index_] = g_vm->glk_char_to_lower (lower[index_]);
-
- /* Find any face= portion of the tag argument. */
- face = strstr (lower, "face=");
- if (face)
- {
- /*
- * There may be plenty of monospaced fonts, but we do only courier
- * and terminal.
- */
- is_monospaced = strncmp (face, "face=\"courier\"", 14) == 0
- || strncmp (face, "face=\"terminal\"", 15) == 0;
- }
-
- /* Find the size= portion of the tag argument. */
- size = strstr (lower, "size=");
- if (size)
- {
- sc_uint value;
-
- /* Deal with incremental and absolute sizes. */
- if (strncmp (size, "size=+", 6) == 0
- && sscanf (size, "size=+%lu", &value) == 1)
- font_size += value;
- else if (strncmp (size, "size=-", 6) == 0
- && sscanf (size, "size=-%lu", &value) == 1)
- font_size -= value;
- else if (sscanf (size, "size=%lu", &value) == 1)
- font_size = value;
- }
-
- /* Done with tag argument copy. */
- free (lower);
-
- /*
- * Push the new font setting onto the font stack, and set Glk style.
- */
- gsc_font_stack[gsc_font_index].is_monospaced = is_monospaced;
- gsc_font_stack[gsc_font_index++].size = font_size;
- gsc_set_glk_style();
- }
+gsc_handle_font_tag(const sc_char *argument) {
+ /* Ignore the call on stack overrun. */
+ if (gsc_font_index < GSC_MAX_STYLE_NESTING) {
+ sc_char *lower, *face, *size;
+ sc_bool is_monospaced;
+ sc_int index_, font_size;
+
+ /* Get the current top of stack, or default on empty stack. */
+ if (gsc_font_index > 0) {
+ is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
+ font_size = gsc_font_stack[gsc_font_index - 1].size;
+ } else {
+ is_monospaced = FALSE;
+ font_size = GSC_DEFAULT_FONT_SIZE;
+ }
+
+ /* Copy and convert argument to all lowercase. */
+ lower = (sc_char *)gsc_malloc(strlen(argument) + 1);
+ strcpy(lower, argument);
+ for (index_ = 0; lower[index_] != '\0'; index_++)
+ lower[index_] = g_vm->glk_char_to_lower(lower[index_]);
+
+ /* Find any face= portion of the tag argument. */
+ face = strstr(lower, "face=");
+ if (face) {
+ /*
+ * There may be plenty of monospaced fonts, but we do only courier
+ * and terminal.
+ */
+ is_monospaced = strncmp(face, "face=\"courier\"", 14) == 0
+ || strncmp(face, "face=\"terminal\"", 15) == 0;
+ }
+
+ /* Find the size= portion of the tag argument. */
+ size = strstr(lower, "size=");
+ if (size) {
+ sc_uint value;
+
+ /* Deal with incremental and absolute sizes. */
+ if (strncmp(size, "size=+", 6) == 0
+ && sscanf(size, "size=+%lu", &value) == 1)
+ font_size += value;
+ else if (strncmp(size, "size=-", 6) == 0
+ && sscanf(size, "size=-%lu", &value) == 1)
+ font_size -= value;
+ else if (sscanf(size, "size=%lu", &value) == 1)
+ font_size = value;
+ }
+
+ /* Done with tag argument copy. */
+ free(lower);
+
+ /*
+ * Push the new font setting onto the font stack, and set Glk style.
+ */
+ gsc_font_stack[gsc_font_index].is_monospaced = is_monospaced;
+ gsc_font_stack[gsc_font_index++].size = font_size;
+ gsc_set_glk_style();
+ }
}
static void
-gsc_handle_endfont_tag()
-{
- /* Unless underrun, pop the font stack and set Glk style. */
- if (gsc_font_index > 0)
- {
- gsc_font_index--;
- gsc_set_glk_style();
- }
+gsc_handle_endfont_tag() {
+ /* Unless underrun, pop the font stack and set Glk style. */
+ if (gsc_font_index > 0) {
+ gsc_font_index--;
+ gsc_set_glk_style();
+ }
}
@@ -1288,60 +1239,56 @@ gsc_handle_endfont_tag()
* tag. Set the appropriate Glk style.
*/
static void
-gsc_handle_attribute_tag (sc_int tag)
-{
- /*
- * Increment the required attribute nesting counter, and set Glk style.
- */
- switch (tag)
- {
- case SC_TAG_BOLD:
- gsc_attribute_bold++;
- break;
- case SC_TAG_ITALICS:
- gsc_attribute_italic++;
- break;
- case SC_TAG_UNDERLINE:
- gsc_attribute_underline++;
- break;
- case SC_TAG_COLOR:
- gsc_attribute_secondary_color++;
- break;
- default:
- break;
- }
- gsc_set_glk_style();
+gsc_handle_attribute_tag(sc_int tag) {
+ /*
+ * Increment the required attribute nesting counter, and set Glk style.
+ */
+ switch (tag) {
+ case SC_TAG_BOLD:
+ gsc_attribute_bold++;
+ break;
+ case SC_TAG_ITALICS:
+ gsc_attribute_italic++;
+ break;
+ case SC_TAG_UNDERLINE:
+ gsc_attribute_underline++;
+ break;
+ case SC_TAG_COLOR:
+ gsc_attribute_secondary_color++;
+ break;
+ default:
+ break;
+ }
+ gsc_set_glk_style();
}
static void
-gsc_handle_endattribute_tag (sc_int tag)
-{
- /*
- * Decrement the required attribute nesting counter, unless underrun, and
- * set Glk style.
- */
- switch (tag)
- {
- case SC_TAG_ENDBOLD:
- if (gsc_attribute_bold > 0)
- gsc_attribute_bold--;
- break;
- case SC_TAG_ENDITALICS:
- if (gsc_attribute_italic > 0)
- gsc_attribute_italic--;
- break;
- case SC_TAG_ENDUNDERLINE:
- if (gsc_attribute_underline > 0)
- gsc_attribute_underline--;
- break;
- case SC_TAG_ENDCOLOR:
- if (gsc_attribute_secondary_color > 0)
- gsc_attribute_secondary_color--;
- break;
- default:
- break;
- }
- gsc_set_glk_style();
+gsc_handle_endattribute_tag(sc_int tag) {
+ /*
+ * Decrement the required attribute nesting counter, unless underrun, and
+ * set Glk style.
+ */
+ switch (tag) {
+ case SC_TAG_ENDBOLD:
+ if (gsc_attribute_bold > 0)
+ gsc_attribute_bold--;
+ break;
+ case SC_TAG_ENDITALICS:
+ if (gsc_attribute_italic > 0)
+ gsc_attribute_italic--;
+ break;
+ case SC_TAG_ENDUNDERLINE:
+ if (gsc_attribute_underline > 0)
+ gsc_attribute_underline--;
+ break;
+ case SC_TAG_ENDCOLOR:
+ if (gsc_attribute_secondary_color > 0)
+ gsc_attribute_secondary_color--;
+ break;
+ default:
+ break;
+ }
+ gsc_set_glk_style();
}
@@ -1351,62 +1298,55 @@ gsc_handle_endattribute_tag (sc_int tag)
* If Glk offers timers, delay for the requested period. Otherwise, this
* function does nothing.
*/
-static void gsc_handle_wait_tag(const sc_char *argument)
-{
- double delay = 0.0;
-
- /* Ignore the wait tag if the Glk doesn't have timers. */
- if (!g_vm->glk_gestalt (gestalt_Timer, 0))
- return;
-
- /* Determine the delay time, and convert to milliseconds. */
- if (sscanf (argument, "%lf", &delay) == 1 && delay > 0.0)
- {
- glui32 milliseconds, timeout;
-
- /*
- * Work with timeouts at 1/10 of the wait period, to minimize Glk
- * timer jitter. Allow the timeout to be canceled by keypress, as a
- * user convenience.
- */
- milliseconds = (glui32) (delay * GSC_MILLISECONDS_PER_SECOND);
- timeout = milliseconds / GSC_TIMEOUTS_COUNT;
- if (timeout > 0)
- {
- glui32 delayed;
- sc_bool is_completed;
-
- /* Request timer events, and let a keypress cancel the wait. */
- g_vm->glk_request_char_event (gsc_main_window);
- g_vm->glk_request_timer_events (timeout);
-
- /* Loop until delay completed or canceled by a keypress. */
- is_completed = TRUE;
- for (delayed = 0; delayed < milliseconds; delayed += timeout)
- {
- event_t event;
-
- gsc_event_wait_2 (evtype_CharInput, evtype_Timer, &event);
- if (event.type == evtype_CharInput)
- {
- /* Cancel the delay, or reissue the input request. */
- if (event.val1 == GSC_CANCEL_WAIT_1
- || event.val1 == GSC_CANCEL_WAIT_2)
- {
- is_completed = FALSE;
- break;
- }
- else
- g_vm->glk_request_char_event (gsc_main_window);
- }
- }
-
- /* Cancel any pending character input, and stop timers. */
- if (is_completed)
- g_vm->glk_cancel_char_event (gsc_main_window);
- g_vm->glk_request_timer_events (0);
- }
- }
+static void gsc_handle_wait_tag(const sc_char *argument) {
+ double delay = 0.0;
+
+ /* Ignore the wait tag if the Glk doesn't have timers. */
+ if (!g_vm->glk_gestalt(gestalt_Timer, 0))
+ return;
+
+ /* Determine the delay time, and convert to milliseconds. */
+ if (sscanf(argument, "%lf", &delay) == 1 && delay > 0.0) {
+ glui32 milliseconds, timeout;
+
+ /*
+ * Work with timeouts at 1/10 of the wait period, to minimize Glk
+ * timer jitter. Allow the timeout to be canceled by keypress, as a
+ * user convenience.
+ */
+ milliseconds = (glui32)(delay * GSC_MILLISECONDS_PER_SECOND);
+ timeout = milliseconds / GSC_TIMEOUTS_COUNT;
+ if (timeout > 0) {
+ glui32 delayed;
+ sc_bool is_completed;
+
+ /* Request timer events, and let a keypress cancel the wait. */
+ g_vm->glk_request_char_event(gsc_main_window);
+ g_vm->glk_request_timer_events(timeout);
+
+ /* Loop until delay completed or canceled by a keypress. */
+ is_completed = TRUE;
+ for (delayed = 0; delayed < milliseconds; delayed += timeout) {
+ event_t event;
+
+ gsc_event_wait_2(evtype_CharInput, evtype_Timer, &event);
+ if (event.type == evtype_CharInput) {
+ /* Cancel the delay, or reissue the input request. */
+ if (event.val1 == GSC_CANCEL_WAIT_1
+ || event.val1 == GSC_CANCEL_WAIT_2) {
+ is_completed = FALSE;
+ break;
+ } else
+ g_vm->glk_request_char_event(gsc_main_window);
+ }
+ }
+
+ /* Cancel any pending character input, and stop timers. */
+ if (is_completed)
+ g_vm->glk_cancel_char_event(gsc_main_window);
+ g_vm->glk_request_timer_events(0);
+ }
+ }
}
@@ -1417,15 +1357,14 @@ static void gsc_handle_wait_tag(const sc_char *argument)
* style.
*/
static void
-gsc_reset_glk_style()
-{
- /* Reset the font stack and attributes, and set a normal style. */
- gsc_font_index = 0;
- gsc_attribute_bold = 0;
- gsc_attribute_italic = 0;
- gsc_attribute_underline = 0;
- gsc_attribute_secondary_color = 0;
- gsc_set_glk_style();
+gsc_reset_glk_style() {
+ /* Reset the font stack and attributes, and set a normal style. */
+ gsc_font_index = 0;
+ gsc_attribute_bold = 0;
+ gsc_attribute_italic = 0;
+ gsc_attribute_underline = 0;
+ gsc_attribute_secondary_color = 0;
+ gsc_set_glk_style();
}
@@ -1436,88 +1375,84 @@ gsc_reset_glk_style()
* here; several are ignored.
*/
void
-os_print_tag (sc_int tag, const sc_char *argument)
-{
- event_t event;
- assert (argument);
-
- switch (tag)
- {
- case SC_TAG_CLS:
- /* Clear the main text display window. */
- g_vm->glk_window_clear (gsc_main_window);
- break;
-
- case SC_TAG_FONT:
- /* Handle with specific tag handler function. */
- gsc_handle_font_tag (argument);
- break;
-
- case SC_TAG_ENDFONT:
- /* Handle with specific endtag handler function. */
- gsc_handle_endfont_tag ();
- break;
-
- case SC_TAG_BOLD:
- case SC_TAG_ITALICS:
- case SC_TAG_UNDERLINE:
- case SC_TAG_COLOR:
- /* Handle with common attribute tag handler function. */
- gsc_handle_attribute_tag (tag);
- break;
-
- case SC_TAG_ENDBOLD:
- case SC_TAG_ENDITALICS:
- case SC_TAG_ENDUNDERLINE:
- case SC_TAG_ENDCOLOR:
- /* Handle with common attribute endtag handler function. */
- gsc_handle_endattribute_tag (tag);
- break;
-
- case SC_TAG_CENTER:
- case SC_TAG_RIGHT:
- case SC_TAG_ENDCENTER:
- case SC_TAG_ENDRIGHT:
- /*
- * We don't center or justify text, but so that things look right we do
- * want a newline on starting or ending such a section.
- */
- g_vm->glk_put_char ('\n');
- break;
-
- case SC_TAG_WAIT:
- /*
- * Update the status line now only if it has its own window, then
- * handle with a specialized handler.
- */
- if (gsc_status_window)
- gsc_status_notify ();
- gsc_handle_wait_tag (argument);
- break;
-
- case SC_TAG_WAITKEY:
- /*
- * If reading an input log, ignore; it disrupts replay. Write a newline
- * to separate off any unterminated game output instead.
- */
- if (!gsc_readlog_stream)
- {
- /* Update the status line now only if it has its own window. */
- if (gsc_status_window)
- gsc_status_notify ();
-
- /* Request a character event, and wait for it to be filled. */
- g_vm->glk_request_char_event (gsc_main_window);
- gsc_event_wait (evtype_CharInput, &event);
- }
- else
- g_vm->glk_put_char ('\n');
- break;
-
- default:
- /* Ignore unimplemented and unknown tags. */
- break;
- }
+os_print_tag(sc_int tag, const sc_char *argument) {
+ event_t event;
+ assert(argument);
+
+ switch (tag) {
+ case SC_TAG_CLS:
+ /* Clear the main text display window. */
+ g_vm->glk_window_clear(gsc_main_window);
+ break;
+
+ case SC_TAG_FONT:
+ /* Handle with specific tag handler function. */
+ gsc_handle_font_tag(argument);
+ break;
+
+ case SC_TAG_ENDFONT:
+ /* Handle with specific endtag handler function. */
+ gsc_handle_endfont_tag();
+ break;
+
+ case SC_TAG_BOLD:
+ case SC_TAG_ITALICS:
+ case SC_TAG_UNDERLINE:
+ case SC_TAG_COLOR:
+ /* Handle with common attribute tag handler function. */
+ gsc_handle_attribute_tag(tag);
+ break;
+
+ case SC_TAG_ENDBOLD:
+ case SC_TAG_ENDITALICS:
+ case SC_TAG_ENDUNDERLINE:
+ case SC_TAG_ENDCOLOR:
+ /* Handle with common attribute endtag handler function. */
+ gsc_handle_endattribute_tag(tag);
+ break;
+
+ case SC_TAG_CENTER:
+ case SC_TAG_RIGHT:
+ case SC_TAG_ENDCENTER:
+ case SC_TAG_ENDRIGHT:
+ /*
+ * We don't center or justify text, but so that things look right we do
+ * want a newline on starting or ending such a section.
+ */
+ g_vm->glk_put_char('\n');
+ break;
+
+ case SC_TAG_WAIT:
+ /*
+ * Update the status line now only if it has its own window, then
+ * handle with a specialized handler.
+ */
+ if (gsc_status_window)
+ gsc_status_notify();
+ gsc_handle_wait_tag(argument);
+ break;
+
+ case SC_TAG_WAITKEY:
+ /*
+ * If reading an input log, ignore; it disrupts replay. Write a newline
+ * to separate off any unterminated game output instead.
+ */
+ if (!gsc_readlog_stream) {
+ /* Update the status line now only if it has its own window. */
+ if (gsc_status_window)
+ gsc_status_notify();
+
+ /* Request a character event, and wait for it to be filled. */
+ g_vm->glk_request_char_event(gsc_main_window);
+ gsc_event_wait(evtype_CharInput, &event);
+ } else
+ g_vm->glk_put_char('\n');
+ break;
+
+ default:
+ /* Ignore unimplemented and unknown tags. */
+ break;
+ }
}
@@ -1527,30 +1462,30 @@ os_print_tag (sc_int tag, const sc_char *argument)
* Print a text string to the main output window.
*/
void os_print_string(const sc_char *string) {
- sc_bool is_monospaced;
- assert (string);
- assert (g_vm->glk_stream_get_current ());
-
- /*
- * Get the monospace font setting from the current top of stack, or
- * default on empty stack. If set, we may need to use an alternative
- * function to write this string.
- */
- if (gsc_font_index > 0)
- is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
- else
- is_monospaced = FALSE;
-
- /*
- * The main window should always be the currently set window at this point,
- * so we never be attempting monospaced output to the status window.
- * Nevertheless, check anyway.
- */
- if (is_monospaced
- && g_vm->glk_stream_get_current () == g_vm->glk_window_get_stream (gsc_main_window))
- gsc_put_string_alternate (string);
- else
- gsc_put_string (string);
+ sc_bool is_monospaced;
+ assert(string);
+ assert(g_vm->glk_stream_get_current());
+
+ /*
+ * Get the monospace font setting from the current top of stack, or
+ * default on empty stack. If set, we may need to use an alternative
+ * function to write this string.
+ */
+ if (gsc_font_index > 0)
+ is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced;
+ else
+ is_monospaced = FALSE;
+
+ /*
+ * The main window should always be the currently set window at this point,
+ * so we never be attempting monospaced output to the status window.
+ * Nevertheless, check anyway.
+ */
+ if (is_monospaced
+ && g_vm->glk_stream_get_current() == g_vm->glk_window_get_stream(gsc_main_window))
+ gsc_put_string_alternate(string);
+ else
+ gsc_put_string(string);
}
@@ -1561,12 +1496,11 @@ void os_print_string(const sc_char *string) {
* dedicated debugging window attempted.
*/
void
-os_print_string_debug (const sc_char *string)
-{
- assert (string);
- assert (g_vm->glk_stream_get_current ());
+os_print_string_debug(const sc_char *string) {
+ assert(string);
+ assert(g_vm->glk_stream_get_current());
- gsc_put_string (string);
+ gsc_put_string(string);
}
@@ -1583,53 +1517,46 @@ os_print_string_debug (const sc_char *string)
* string is one that hints that it's from the interpreter, not the game.
*/
static void
-gsc_styled_string (glui32 style, const char *message)
-{
- assert (message);
+gsc_styled_string(glui32 style, const char *message) {
+ assert(message);
- g_vm->glk_set_style (style);
- g_vm->glk_put_string ((char *) message);
- g_vm->glk_set_style (style_Normal);
+ g_vm->glk_set_style(style);
+ g_vm->glk_put_string((char *) message);
+ g_vm->glk_set_style(style_Normal);
}
static void
-gsc_styled_char (glui32 style, char c)
-{
- char buffer[2];
+gsc_styled_char(glui32 style, char c) {
+ char buffer[2];
- buffer[0] = c;
- buffer[1] = '\0';
- gsc_styled_string (style, buffer);
+ buffer[0] = c;
+ buffer[1] = '\0';
+ gsc_styled_string(style, buffer);
}
static void
-gsc_standout_string (const char *message)
-{
- gsc_styled_string (style_Emphasized, message);
+gsc_standout_string(const char *message) {
+ gsc_styled_string(style_Emphasized, message);
}
static void
-gsc_standout_char (char c)
-{
- gsc_styled_char (style_Emphasized, c);
+gsc_standout_char(char c) {
+ gsc_styled_char(style_Emphasized, c);
}
static void
-gsc_normal_string (const char *message)
-{
- gsc_styled_string (style_Normal, message);
+gsc_normal_string(const char *message) {
+ gsc_styled_string(style_Normal, message);
}
static void
-gsc_normal_char (char c)
-{
- gsc_styled_char (style_Normal, c);
+gsc_normal_char(char c) {
+ gsc_styled_char(style_Normal, c);
}
static void
-gsc_header_string (const char *message)
-{
- gsc_styled_string (style_Header, message);
+gsc_header_string(const char *message) {
+ gsc_styled_string(style_Header, message);
}
@@ -1641,60 +1568,53 @@ gsc_header_string (const char *message)
* it's sort of good enough for the moment.
*/
void
-os_display_hints (sc_game game)
-{
- sc_game_hint hint;
- sc_int refused;
-
- /* For each hint, print the question, and confirm hint display. */
- refused = 0;
- for (hint = sc_get_first_game_hint (game);
- hint; hint = sc_get_next_game_hint (game, hint))
- {
- const sc_char *hint_question, *hint_text;
-
- /* If enough refusals, offer a way out of the loop. */
- if (refused >= GSC_HINT_REFUSAL_LIMIT)
- {
- if (!os_confirm (GSC_CONF_CONTINUE_HINTS))
- break;
- refused = 0;
- }
-
- /* Pop the question. */
- hint_question = sc_get_game_hint_question (game, hint);
- gsc_normal_char ('\n');
- gsc_standout_string (hint_question);
- gsc_normal_char ('\n');
-
- /* Print the subtle hint, or on to the next hint. */
- hint_text = sc_get_game_subtle_hint (game, hint);
- if (hint_text)
- {
- if (!os_confirm (GSC_CONF_SUBTLE_HINT))
- {
- refused++;
- continue;
- }
- gsc_normal_char ('\n');
- gsc_standout_string (hint_text);
- gsc_normal_string ("\n\n");
- }
-
- /* Print the less than subtle hint, or on to the next hint. */
- hint_text = sc_get_game_unsubtle_hint (game, hint);
- if (hint_text)
- {
- if (!os_confirm (GSC_CONF_UNSUBTLE_HINT))
- {
- refused++;
- continue;
- }
- gsc_normal_char ('\n');
- gsc_standout_string (hint_text);
- gsc_normal_string ("\n\n");
- }
- }
+os_display_hints(sc_game game) {
+ sc_game_hint hint;
+ sc_int refused;
+
+ /* For each hint, print the question, and confirm hint display. */
+ refused = 0;
+ for (hint = sc_get_first_game_hint(game);
+ hint; hint = sc_get_next_game_hint(game, hint)) {
+ const sc_char *hint_question, *hint_text;
+
+ /* If enough refusals, offer a way out of the loop. */
+ if (refused >= GSC_HINT_REFUSAL_LIMIT) {
+ if (!os_confirm(GSC_CONF_CONTINUE_HINTS))
+ break;
+ refused = 0;
+ }
+
+ /* Pop the question. */
+ hint_question = sc_get_game_hint_question(game, hint);
+ gsc_normal_char('\n');
+ gsc_standout_string(hint_question);
+ gsc_normal_char('\n');
+
+ /* Print the subtle hint, or on to the next hint. */
+ hint_text = sc_get_game_subtle_hint(game, hint);
+ if (hint_text) {
+ if (!os_confirm(GSC_CONF_SUBTLE_HINT)) {
+ refused++;
+ continue;
+ }
+ gsc_normal_char('\n');
+ gsc_standout_string(hint_text);
+ gsc_normal_string("\n\n");
+ }
+
+ /* Print the less than subtle hint, or on to the next hint. */
+ hint_text = sc_get_game_unsubtle_hint(game, hint);
+ if (hint_text) {
+ if (!os_confirm(GSC_CONF_UNSUBTLE_HINT)) {
+ refused++;
+ continue;
+ }
+ gsc_normal_char('\n');
+ gsc_standout_string(hint_text);
+ gsc_normal_string("\n\n");
+ }
+ }
}
@@ -1709,21 +1629,19 @@ os_display_hints (sc_game game)
* Stub functions. The unused variables defeat gcc warnings.
*/
void
-os_play_sound (const sc_char *filepath,
- sc_int offset, sc_int length, sc_bool is_looping)
-{
- const sc_char *unused1;
- sc_int unused2, unused3;
- sc_bool unused4;
- unused1 = filepath;
- unused2 = offset;
- unused3 = length;
- unused4 = is_looping;
+os_play_sound(const sc_char *filepath,
+ sc_int offset, sc_int length, sc_bool is_looping) {
+ const sc_char *unused1;
+ sc_int unused2, unused3;
+ sc_bool unused4;
+ unused1 = filepath;
+ unused2 = offset;
+ unused3 = length;
+ unused4 = is_looping;
}
void
-os_stop_sound()
-{
+os_stop_sound() {
}
@@ -1742,43 +1660,40 @@ os_stop_sound()
static int gsclinux_graphics_enabled = TRUE;
static char *gsclinux_game_file = nullptr;
void
-os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length)
-{
- const sc_char *unused1;
- unused1 = filepath;
-
- if (length > 0
- && gsclinux_graphics_enabled && g_vm->glk_gestalt (gestalt_Graphics, 0))
- {
- sc_char *buffer;
-
- /*
- * Try to extract data with dd. Assuming that works, background xv to
- * display the image, then background a job to delay ten seconds and
- * then delete the temporary file containing the image. Systems lacking
- * xv can usually use a small script, named xv, to invoke eog or an
- * alternative image display binary. Not exactly finessed.
- */
- assert (gsclinux_game_file);
- buffer = gsc_malloc (strlen (gsclinux_game_file) + 128);
- sprintf (buffer, "dd if=%s ibs=1c skip=%ld count=%ld obs=100k"
- " of=/tmp/scare.jpg 2>/dev/null",
- gsclinux_game_file, offset, length);
- system (buffer);
- free (buffer);
- system ("xv /tmp/scare.jpg >/dev/null 2>&1 &");
- system ("( sleep 10; rm /tmp/scare.jpg ) >/dev/null 2>&1 &");
- }
+os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
+ const sc_char *unused1;
+ unused1 = filepath;
+
+ if (length > 0
+ && gsclinux_graphics_enabled && g_vm->glk_gestalt(gestalt_Graphics, 0)) {
+ sc_char *buffer;
+
+ /*
+ * Try to extract data with dd. Assuming that works, background xv to
+ * display the image, then background a job to delay ten seconds and
+ * then delete the temporary file containing the image. Systems lacking
+ * xv can usually use a small script, named xv, to invoke eog or an
+ * alternative image display binary. Not exactly finessed.
+ */
+ assert(gsclinux_game_file);
+ buffer = gsc_malloc(strlen(gsclinux_game_file) + 128);
+ sprintf(buffer, "dd if=%s ibs=1c skip=%ld count=%ld obs=100k"
+ " of=/tmp/scare.jpg 2>/dev/null",
+ gsclinux_game_file, offset, length);
+ system(buffer);
+ free(buffer);
+ system("xv /tmp/scare.jpg >/dev/null 2>&1 &");
+ system("( sleep 10; rm /tmp/scare.jpg ) >/dev/null 2>&1 &");
+ }
}
#else
void
-os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length)
-{
- const sc_char *unused1;
- sc_int unused2, unused3;
- unused1 = filepath;
- unused2 = offset;
- unused3 = length;
+os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
+ const sc_char *unused1;
+ sc_int unused2, unused3;
+ unused1 = filepath;
+ unused2 = offset;
+ unused3 = length;
}
#endif
@@ -1793,74 +1708,65 @@ os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length)
* Turn game output scripting (logging) on and off.
*/
static void
-gsc_command_script (const char *argument)
-{
- assert (argument);
-
- if (sc_strcasecmp (argument, "on") == 0)
- {
- frefid_t fileref;
-
- if (gsc_transcript_stream)
- {
- gsc_normal_string ("Glk transcript is already on.\n");
- return;
- }
-
- fileref = g_vm->glk_fileref_create_by_prompt (fileusage_Transcript
- | fileusage_TextMode,
- filemode_WriteAppend, 0);
- if (!fileref)
- {
- gsc_standout_string ("Glk transcript failed.\n");
- return;
- }
-
- gsc_transcript_stream = g_vm->glk_stream_open_file (fileref,
- filemode_WriteAppend, 0);
- g_vm->glk_fileref_destroy (fileref);
- if (!gsc_transcript_stream)
- {
- gsc_standout_string ("Glk transcript failed.\n");
- return;
- }
-
- g_vm->glk_window_set_echo_stream (gsc_main_window, gsc_transcript_stream);
-
- gsc_normal_string ("Glk transcript is now on.\n");
- }
-
- else if (sc_strcasecmp (argument, "off") == 0)
- {
- if (!gsc_transcript_stream)
- {
- gsc_normal_string ("Glk transcript is already off.\n");
- return;
- }
-
- g_vm->glk_stream_close (gsc_transcript_stream, nullptr);
- gsc_transcript_stream = nullptr;
-
- g_vm->glk_window_set_echo_stream (gsc_main_window, nullptr);
-
- gsc_normal_string ("Glk transcript is now off.\n");
- }
-
- else if (strlen (argument) == 0)
- {
- gsc_normal_string ("Glk transcript is ");
- gsc_normal_string (gsc_transcript_stream ? "on" : "off");
- gsc_normal_string (".\n");
- }
-
- else
- {
- gsc_normal_string ("Glk transcript can be ");
- gsc_standout_string ("on");
- gsc_normal_string (", or ");
- gsc_standout_string ("off");
- gsc_normal_string (".\n");
- }
+gsc_command_script(const char *argument) {
+ assert(argument);
+
+ if (sc_strcasecmp(argument, "on") == 0) {
+ frefid_t fileref;
+
+ if (gsc_transcript_stream) {
+ gsc_normal_string("Glk transcript is already on.\n");
+ return;
+ }
+
+ fileref = g_vm->glk_fileref_create_by_prompt(fileusage_Transcript
+ | fileusage_TextMode,
+ filemode_WriteAppend, 0);
+ if (!fileref) {
+ gsc_standout_string("Glk transcript failed.\n");
+ return;
+ }
+
+ gsc_transcript_stream = g_vm->glk_stream_open_file(fileref,
+ filemode_WriteAppend, 0);
+ g_vm->glk_fileref_destroy(fileref);
+ if (!gsc_transcript_stream) {
+ gsc_standout_string("Glk transcript failed.\n");
+ return;
+ }
+
+ g_vm->glk_window_set_echo_stream(gsc_main_window, gsc_transcript_stream);
+
+ gsc_normal_string("Glk transcript is now on.\n");
+ }
+
+ else if (sc_strcasecmp(argument, "off") == 0) {
+ if (!gsc_transcript_stream) {
+ gsc_normal_string("Glk transcript is already off.\n");
+ return;
+ }
+
+ g_vm->glk_stream_close(gsc_transcript_stream, nullptr);
+ gsc_transcript_stream = nullptr;
+
+ g_vm->glk_window_set_echo_stream(gsc_main_window, nullptr);
+
+ gsc_normal_string("Glk transcript is now off.\n");
+ }
+
+ else if (strlen(argument) == 0) {
+ gsc_normal_string("Glk transcript is ");
+ gsc_normal_string(gsc_transcript_stream ? "on" : "off");
+ gsc_normal_string(".\n");
+ }
+
+ else {
+ gsc_normal_string("Glk transcript can be ");
+ gsc_standout_string("on");
+ gsc_normal_string(", or ");
+ gsc_standout_string("off");
+ gsc_normal_string(".\n");
+ }
}
@@ -1870,70 +1776,61 @@ gsc_command_script (const char *argument)
* Turn game input logging on and off.
*/
static void
-gsc_command_inputlog (const char *argument)
-{
- assert (argument);
-
- if (sc_strcasecmp (argument, "on") == 0)
- {
- frefid_t fileref;
-
- if (gsc_inputlog_stream)
- {
- gsc_normal_string ("Glk input logging is already on.\n");
- return;
- }
-
- fileref = g_vm->glk_fileref_create_by_prompt (fileusage_InputRecord
- | fileusage_BinaryMode,
- filemode_WriteAppend, 0);
- if (!fileref)
- {
- gsc_standout_string ("Glk input logging failed.\n");
- return;
- }
-
- gsc_inputlog_stream = g_vm->glk_stream_open_file (fileref,
- filemode_WriteAppend, 0);
- g_vm->glk_fileref_destroy (fileref);
- if (!gsc_inputlog_stream)
- {
- gsc_standout_string ("Glk input logging failed.\n");
- return;
- }
-
- gsc_normal_string ("Glk input logging is now on.\n");
- }
-
- else if (sc_strcasecmp (argument, "off") == 0)
- {
- if (!gsc_inputlog_stream)
- {
- gsc_normal_string ("Glk input logging is already off.\n");
- return;
- }
-
- g_vm->glk_stream_close (gsc_inputlog_stream, nullptr);
- gsc_inputlog_stream = nullptr;
-
- gsc_normal_string ("Glk input log is now off.\n");
- }
-
- else if (strlen (argument) == 0)
- {
- gsc_normal_string ("Glk input logging is ");
- gsc_normal_string (gsc_inputlog_stream ? "on" : "off");
- gsc_normal_string (".\n");
- }
-
- else
- {
- gsc_normal_string ("Glk input logging can be ");
- gsc_standout_string ("on");
- gsc_normal_string (", or ");
- gsc_standout_string ("off");
- gsc_normal_string (".\n");
- }
+gsc_command_inputlog(const char *argument) {
+ assert(argument);
+
+ if (sc_strcasecmp(argument, "on") == 0) {
+ frefid_t fileref;
+
+ if (gsc_inputlog_stream) {
+ gsc_normal_string("Glk input logging is already on.\n");
+ return;
+ }
+
+ fileref = g_vm->glk_fileref_create_by_prompt(fileusage_InputRecord
+ | fileusage_BinaryMode,
+ filemode_WriteAppend, 0);
+ if (!fileref) {
+ gsc_standout_string("Glk input logging failed.\n");
+ return;
+ }
+
+ gsc_inputlog_stream = g_vm->glk_stream_open_file(fileref,
+ filemode_WriteAppend, 0);
+ g_vm->glk_fileref_destroy(fileref);
+ if (!gsc_inputlog_stream) {
+ gsc_standout_string("Glk input logging failed.\n");
+ return;
+ }
+
+ gsc_normal_string("Glk input logging is now on.\n");
+ }
+
+ else if (sc_strcasecmp(argument, "off") == 0) {
+ if (!gsc_inputlog_stream) {
+ gsc_normal_string("Glk input logging is already off.\n");
+ return;
+ }
+
+ g_vm->glk_stream_close(gsc_inputlog_stream, nullptr);
+ gsc_inputlog_stream = nullptr;
+
+ gsc_normal_string("Glk input log is now off.\n");
+ }
+
+ else if (strlen(argument) == 0) {
+ gsc_normal_string("Glk input logging is ");
+ gsc_normal_string(gsc_inputlog_stream ? "on" : "off");
+ gsc_normal_string(".\n");
+ }
+
+ else {
+ gsc_normal_string("Glk input logging can be ");
+ gsc_standout_string("on");
+ gsc_normal_string(", or ");
+ gsc_standout_string("off");
+ gsc_normal_string(".\n");
+ }
}
@@ -1943,76 +1840,66 @@ gsc_command_inputlog (const char *argument)
* Set the game input log, to read input from a file.
*/
static void
-gsc_command_readlog (const char *argument)
-{
- assert (argument);
-
- if (sc_strcasecmp (argument, "on") == 0)
- {
- frefid_t fileref;
-
- if (gsc_readlog_stream)
- {
- gsc_normal_string ("Glk read log is already on.\n");
- return;
- }
-
- fileref = g_vm->glk_fileref_create_by_prompt (fileusage_InputRecord
- | fileusage_BinaryMode,
- filemode_Read, 0);
- if (!fileref)
- {
- gsc_standout_string ("Glk read log failed.\n");
- return;
- }
-
- if (!g_vm->glk_fileref_does_file_exist (fileref))
- {
- g_vm->glk_fileref_destroy (fileref);
- gsc_standout_string ("Glk read log failed.\n");
- return;
- }
-
- gsc_readlog_stream = g_vm->glk_stream_open_file (fileref, filemode_Read, 0);
- g_vm->glk_fileref_destroy (fileref);
- if (!gsc_readlog_stream)
- {
- gsc_standout_string ("Glk read log failed.\n");
- return;
- }
-
- gsc_normal_string ("Glk read log is now on.\n");
- }
-
- else if (sc_strcasecmp (argument, "off") == 0)
- {
- if (!gsc_readlog_stream)
- {
- gsc_normal_string ("Glk read log is already off.\n");
- return;
- }
-
- g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
- gsc_readlog_stream = nullptr;
-
- gsc_normal_string ("Glk read log is now off.\n");
- }
-
- else if (strlen (argument) == 0)
- {
- gsc_normal_string ("Glk read log is ");
- gsc_normal_string (gsc_readlog_stream ? "on" : "off");
- gsc_normal_string (".\n");
- }
-
- else
- {
- gsc_normal_string ("Glk read log can be ");
- gsc_standout_string ("on");
- gsc_normal_string (", or ");
- gsc_standout_string ("off");
- gsc_normal_string (".\n");
- }
+gsc_command_readlog(const char *argument) {
+ assert(argument);
+
+ if (sc_strcasecmp(argument, "on") == 0) {
+ frefid_t fileref;
+
+ if (gsc_readlog_stream) {
+ gsc_normal_string("Glk read log is already on.\n");
+ return;
+ }
+
+ fileref = g_vm->glk_fileref_create_by_prompt(fileusage_InputRecord
+ | fileusage_BinaryMode,
+ filemode_Read, 0);
+ if (!fileref) {
+ gsc_standout_string("Glk read log failed.\n");
+ return;
+ }
+
+ if (!g_vm->glk_fileref_does_file_exist(fileref)) {
+ g_vm->glk_fileref_destroy(fileref);
+ gsc_standout_string("Glk read log failed.\n");
+ return;
+ }
+
+ gsc_readlog_stream = g_vm->glk_stream_open_file(fileref, filemode_Read, 0);
+ g_vm->glk_fileref_destroy(fileref);
+ if (!gsc_readlog_stream) {
+ gsc_standout_string("Glk read log failed.\n");
+ return;
+ }
+
+ gsc_normal_string("Glk read log is now on.\n");
+ }
+
+ else if (sc_strcasecmp(argument, "off") == 0) {
+ if (!gsc_readlog_stream) {
+ gsc_normal_string("Glk read log is already off.\n");
+ return;
+ }
+
+ g_vm->glk_stream_close(gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+
+ gsc_normal_string("Glk read log is now off.\n");
+ }
+
+ else if (strlen(argument) == 0) {
+ gsc_normal_string("Glk read log is ");
+ gsc_normal_string(gsc_readlog_stream ? "on" : "off");
+ gsc_normal_string(".\n");
+ }
+
+ else {
+ gsc_normal_string("Glk read log can be ");
+ gsc_standout_string("on");
+ gsc_normal_string(", or ");
+ gsc_standout_string("off");
+ gsc_normal_string(".\n");
+ }
}
@@ -2022,49 +1909,42 @@ gsc_command_readlog (const char *argument)
* Turn abbreviation expansions on and off.
*/
static void
-gsc_command_abbreviations (const char *argument)
-{
- assert (argument);
-
- if (sc_strcasecmp (argument, "on") == 0)
- {
- if (gsc_abbreviations_enabled)
- {
- gsc_normal_string ("Glk abbreviation expansions are already on.\n");
- return;
- }
-
- gsc_abbreviations_enabled = TRUE;
- gsc_normal_string ("Glk abbreviation expansions are now on.\n");
- }
-
- else if (sc_strcasecmp (argument, "off") == 0)
- {
- if (!gsc_abbreviations_enabled)
- {
- gsc_normal_string ("Glk abbreviation expansions are already off.\n");
- return;
- }
-
- gsc_abbreviations_enabled = FALSE;
- gsc_normal_string ("Glk abbreviation expansions are now off.\n");
- }
-
- else if (strlen (argument) == 0)
- {
- gsc_normal_string ("Glk abbreviation expansions are ");
- gsc_normal_string (gsc_abbreviations_enabled ? "on" : "off");
- gsc_normal_string (".\n");
- }
-
- else
- {
- gsc_normal_string ("Glk abbreviation expansions can be ");
- gsc_standout_string ("on");
- gsc_normal_string (", or ");
- gsc_standout_string ("off");
- gsc_normal_string (".\n");
- }
+gsc_command_abbreviations(const char *argument) {
+ assert(argument);
+
+ if (sc_strcasecmp(argument, "on") == 0) {
+ if (gsc_abbreviations_enabled) {
+ gsc_normal_string("Glk abbreviation expansions are already on.\n");
+ return;
+ }
+
+ gsc_abbreviations_enabled = TRUE;
+ gsc_normal_string("Glk abbreviation expansions are now on.\n");
+ }
+
+ else if (sc_strcasecmp(argument, "off") == 0) {
+ if (!gsc_abbreviations_enabled) {
+ gsc_normal_string("Glk abbreviation expansions are already off.\n");
+ return;
+ }
+
+ gsc_abbreviations_enabled = FALSE;
+ gsc_normal_string("Glk abbreviation expansions are now off.\n");
+ }
+
+ else if (strlen(argument) == 0) {
+ gsc_normal_string("Glk abbreviation expansions are ");
+ gsc_normal_string(gsc_abbreviations_enabled ? "on" : "off");
+ gsc_normal_string(".\n");
+ }
+
+ else {
+ gsc_normal_string("Glk abbreviation expansions can be ");
+ gsc_standout_string("on");
+ gsc_normal_string(", or ");
+ gsc_standout_string("off");
+ gsc_normal_string(".\n");
+ }
}
@@ -2075,31 +1955,29 @@ gsc_command_abbreviations (const char *argument)
* Print out the Glk library version number.
*/
static void
-gsc_command_print_version_number (glui32 version)
-{
- char buffer[64];
+gsc_command_print_version_number(glui32 version) {
+ char buffer[64];
- sprintf (buffer, "%lu.%lu.%lu",
- (unsigned long) version >> 16,
- (unsigned long) (version >> 8) & 0xff,
- (unsigned long) version & 0xff);
- gsc_normal_string (buffer);
+ sprintf(buffer, "%lu.%lu.%lu",
+ (unsigned long) version >> 16,
+ (unsigned long)(version >> 8) & 0xff,
+ (unsigned long) version & 0xff);
+ gsc_normal_string(buffer);
}
static void
-gsc_command_version (const char *argument)
-{
- glui32 version;
- assert (argument);
+gsc_command_version(const char *argument) {
+ glui32 version;
+ assert(argument);
- gsc_normal_string ("This is version ");
- gsc_command_print_version_number (GSC_PORT_VERSION);
- gsc_normal_string (" of the Glk SCARE port.\n");
+ gsc_normal_string("This is version ");
+ gsc_command_print_version_number(GSC_PORT_VERSION);
+ gsc_normal_string(" of the Glk SCARE port.\n");
- version = g_vm->glk_gestalt (gestalt_Version, 0);
- gsc_normal_string ("The Glk library version is ");
- gsc_command_print_version_number (version);
- gsc_normal_string (".\n");
+ version = g_vm->glk_gestalt(gestalt_Version, 0);
+ gsc_normal_string("The Glk library version is ");
+ gsc_command_print_version_number(version);
+ gsc_normal_string(".\n");
}
@@ -2110,36 +1988,31 @@ gsc_command_version (const char *argument)
* Commands must be on already to enter this function.
*/
static void
-gsc_command_commands (const char *argument)
-{
- assert (argument);
+gsc_command_commands(const char *argument) {
+ assert(argument);
- if (sc_strcasecmp (argument, "on") == 0)
- {
- gsc_normal_string ("Glk commands are already on.\n");
- }
+ if (sc_strcasecmp(argument, "on") == 0) {
+ gsc_normal_string("Glk commands are already on.\n");
+ }
- else if (sc_strcasecmp (argument, "off") == 0)
- {
- gsc_commands_enabled = FALSE;
- gsc_normal_string ("Glk commands are now off.\n");
- }
+ else if (sc_strcasecmp(argument, "off") == 0) {
+ gsc_commands_enabled = FALSE;
+ gsc_normal_string("Glk commands are now off.\n");
+ }
- else if (strlen (argument) == 0)
- {
- gsc_normal_string ("Glk commands are ");
- gsc_normal_string (gsc_commands_enabled ? "on" : "off");
- gsc_normal_string (".\n");
- }
+ else if (strlen(argument) == 0) {
+ gsc_normal_string("Glk commands are ");
+ gsc_normal_string(gsc_commands_enabled ? "on" : "off");
+ gsc_normal_string(".\n");
+ }
- else
- {
- gsc_normal_string ("Glk commands can be ");
- gsc_standout_string ("on");
- gsc_normal_string (", or ");
- gsc_standout_string ("off");
- gsc_normal_string (".\n");
- }
+ else {
+ gsc_normal_string("Glk commands can be ");
+ gsc_standout_string("on");
+ gsc_normal_string(", or ");
+ gsc_standout_string("off");
+ gsc_normal_string(".\n");
+ }
}
@@ -2149,59 +2022,57 @@ gsc_command_commands (const char *argument)
* Print licensing terms.
*/
static void
-gsc_command_license (const char *argument)
-{
- assert (argument);
+gsc_command_license(const char *argument) {
+ assert(argument);
- gsc_normal_string ("This program is free software; you can redistribute it"
- " and/or modify it under the terms of version 2 of the"
- " GNU General Public License as published by the Free"
- " Software Foundation.\n\n");
+ gsc_normal_string("This program is free software; you can redistribute it"
+ " and/or modify it under the terms of version 2 of the"
+ " GNU General Public License as published by the Free"
+ " Software Foundation.\n\n");
- gsc_normal_string ("This program is distributed in the hope that it will be"
- " useful, but ");
- gsc_standout_string ("WITHOUT ANY WARRANTY");
- gsc_normal_string ("; without even the implied warranty of ");
- gsc_standout_string ("MERCHANTABILITY");
- gsc_normal_string (" or ");
- gsc_standout_string ("FITNESS FOR A PARTICULAR PURPOSE");
- gsc_normal_string (". See the GNU General Public License for more"
- " details.\n\n");
+ gsc_normal_string("This program is distributed in the hope that it will be"
+ " useful, but ");
+ gsc_standout_string("WITHOUT ANY WARRANTY");
+ gsc_normal_string("; without even the implied warranty of ");
+ gsc_standout_string("MERCHANTABILITY");
+ gsc_normal_string(" or ");
+ gsc_standout_string("FITNESS FOR A PARTICULAR PURPOSE");
+ gsc_normal_string(". See the GNU General Public License for more"
+ " details.\n\n");
- gsc_normal_string ("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\n\n");
+ gsc_normal_string("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\n\n");
- gsc_normal_string ("Please report any bugs, omissions, or misfeatures to ");
- gsc_standout_string ("simon_baldwin at yahoo.com");
- gsc_normal_string (".\n");
+ gsc_normal_string("Please report any bugs, omissions, or misfeatures to ");
+ gsc_standout_string("simon_baldwin at yahoo.com");
+ gsc_normal_string(".\n");
}
/* Glk subcommands and handler functions. */
-typedef const struct
-{
- const char * const command; /* Glk subcommand. */
- void (* const handler) (const char *argument); /* Subcommand handler. */
- const int takes_argument; /* Argument flag. */
+typedef const struct {
+ const char *const command; /* Glk subcommand. */
+ void (* const handler)(const char *argument); /* Subcommand handler. */
+ const int takes_argument; /* Argument flag. */
} gsc_command_t;
typedef gsc_command_t *gsc_commandref_t;
-static void gsc_command_summary (const char *argument);
-static void gsc_command_help (const char *argument);
+static void gsc_command_summary(const char *argument);
+static void gsc_command_help(const char *argument);
static gsc_command_t GSC_COMMAND_TABLE[] = {
- {"summary", gsc_command_summary, FALSE},
- {"script", gsc_command_script, TRUE},
- {"inputlog", gsc_command_inputlog, TRUE},
- {"readlog", gsc_command_readlog, TRUE},
- {"abbreviations", gsc_command_abbreviations, TRUE},
- {"version", gsc_command_version, FALSE},
- {"commands", gsc_command_commands, TRUE},
- {"license", gsc_command_license, FALSE},
- {"help", gsc_command_help, TRUE},
- {nullptr, nullptr, FALSE}
+ {"summary", gsc_command_summary, FALSE},
+ {"script", gsc_command_script, TRUE},
+ {"inputlog", gsc_command_inputlog, TRUE},
+ {"readlog", gsc_command_readlog, TRUE},
+ {"abbreviations", gsc_command_abbreviations, TRUE},
+ {"version", gsc_command_version, FALSE},
+ {"commands", gsc_command_commands, TRUE},
+ {"license", gsc_command_license, FALSE},
+ {"help", gsc_command_help, TRUE},
+ {nullptr, nullptr, FALSE}
};
@@ -2211,24 +2082,22 @@ static gsc_command_t GSC_COMMAND_TABLE[] = {
* Report all current Glk settings.
*/
static void
-gsc_command_summary (const char *argument)
-{
- gsc_commandref_t entry;
- assert (argument);
+gsc_command_summary(const char *argument) {
+ gsc_commandref_t entry;
+ assert(argument);
- /*
- * Call handlers that have status to report with an empty argument,
- * prompting each to print its current setting.
- */
- for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
- {
- if (entry->handler == gsc_command_summary
- || entry->handler == gsc_command_license
- || entry->handler == gsc_command_help)
- continue;
+ /*
+ * Call handlers that have status to report with an empty argument,
+ * prompting each to print its current setting.
+ */
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++) {
+ if (entry->handler == gsc_command_summary
+ || entry->handler == gsc_command_license
+ || entry->handler == gsc_command_help)
+ continue;
- entry->handler ("");
- }
+ entry->handler("");
+ }
}
@@ -2238,139 +2107,124 @@ gsc_command_summary (const char *argument)
* Document the available Glk commands.
*/
static void
-gsc_command_help (const char *command)
-{
- gsc_commandref_t entry, matched;
- assert (command);
-
- if (strlen (command) == 0)
- {
- gsc_normal_string ("Glk commands are");
- for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
- {
- gsc_commandref_t next;
-
- next = entry + 1;
- gsc_normal_string (next->command ? " " : " and ");
- gsc_standout_string (entry->command);
- gsc_normal_string (next->command ? "," : ".\n\n");
- }
-
- gsc_normal_string ("Glk commands may be abbreviated, as long as"
- " the abbreviation is unambiguous. Use ");
- gsc_standout_string ("glk help");
- gsc_normal_string (" followed by a Glk command name for help on that"
- " command.\n");
- return;
- }
-
- matched = nullptr;
- for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
- {
- if (sc_strncasecmp (command, entry->command, strlen (command)) == 0)
- {
- if (matched)
- {
- gsc_normal_string ("The Glk command ");
- gsc_standout_string (command);
- gsc_normal_string (" is ambiguous. Try ");
- gsc_standout_string ("glk help");
- gsc_normal_string (" for more information.\n");
- return;
- }
- matched = entry;
- }
- }
- if (!matched)
- {
- gsc_normal_string ("The Glk command ");
- gsc_standout_string (command);
- gsc_normal_string (" is not valid. Try ");
- gsc_standout_string ("glk help");
- gsc_normal_string (" for more information.\n");
- return;
- }
-
- if (matched->handler == gsc_command_summary)
- {
- gsc_normal_string ("Prints a summary of all the current Glk SCARE"
- " settings.\n");
- }
-
- else if (matched->handler == gsc_command_script)
- {
- gsc_normal_string ("Logs the game's output to a file.\n\nUse ");
- gsc_standout_string ("glk script on");
- gsc_normal_string (" to begin logging game output, and ");
- gsc_standout_string ("glk script off");
- gsc_normal_string (" to end it. Glk SCARE will ask you for a file"
- " when you turn scripts on.\n");
- }
-
- else if (matched->handler == gsc_command_inputlog)
- {
- gsc_normal_string ("Records the commands you type into a game.\n\nUse ");
- gsc_standout_string ("glk inputlog on");
- gsc_normal_string (", to begin recording your commands, and ");
- gsc_standout_string ("glk inputlog off");
- gsc_normal_string (" to turn off input logs. You can play back"
- " recorded commands into a game with the ");
- gsc_standout_string ("glk readlog");
- gsc_normal_string (" command.\n");
- }
-
- else if (matched->handler == gsc_command_readlog)
- {
- gsc_normal_string ("Plays back commands recorded with ");
- gsc_standout_string ("glk inputlog on");
- gsc_normal_string (".\n\nUse ");
- gsc_standout_string ("glk readlog on");
- gsc_normal_string (". Command play back stops at the end of the"
- " file. You can also play back commands from a"
- " text file created using any standard editor.\n");
- }
-
- else if (matched->handler == gsc_command_abbreviations)
- {
- gsc_normal_string ("Controls abbreviation expansion.\n\nGlk SCARE"
- " automatically expands several standard single"
- " letter abbreviations for you; for example, \"x\""
- " becomes \"examine\". Use ");
- gsc_standout_string ("glk abbreviations on");
- gsc_normal_string (" to turn this feature on, and ");
- gsc_standout_string ("glk abbreviations off");
- gsc_normal_string (" to turn it off. While the feature is on, you"
- " can bypass abbreviation expansion for an"
- " individual game command by prefixing it with a"
- " single quote.\n");
- }
-
- else if (matched->handler == gsc_command_version)
- {
- gsc_normal_string ("Prints the version numbers of the Glk library"
- " and the Glk SCARE port.\n");
- }
-
- else if (matched->handler == gsc_command_commands)
- {
- gsc_normal_string ("Turn off Glk commands.\n\nUse ");
- gsc_standout_string ("glk commands off");
- gsc_normal_string (" to disable all Glk commands, including this one."
- " Once turned off, there is no way to turn Glk"
- " commands back on while inside the game.\n");
- }
-
- else if (matched->handler == gsc_command_license)
- {
- gsc_normal_string ("Prints Glk SCARE's software license.\n");
- }
-
- else if (matched->handler == gsc_command_help)
- gsc_command_help ("");
-
- else
- gsc_normal_string ("There is no help available on that Glk command."
- " Sorry.\n");
+gsc_command_help(const char *command) {
+ gsc_commandref_t entry, matched;
+ assert(command);
+
+ if (strlen(command) == 0) {
+ gsc_normal_string("Glk commands are");
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++) {
+ gsc_commandref_t next;
+
+ next = entry + 1;
+ gsc_normal_string(next->command ? " " : " and ");
+ gsc_standout_string(entry->command);
+ gsc_normal_string(next->command ? "," : ".\n\n");
+ }
+
+ gsc_normal_string("Glk commands may be abbreviated, as long as"
+ " the abbreviation is unambiguous. Use ");
+ gsc_standout_string("glk help");
+ gsc_normal_string(" followed by a Glk command name for help on that"
+ " command.\n");
+ return;
+ }
+
+ matched = nullptr;
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++) {
+ if (sc_strncasecmp(command, entry->command, strlen(command)) == 0) {
+ if (matched) {
+ gsc_normal_string("The Glk command ");
+ gsc_standout_string(command);
+ gsc_normal_string(" is ambiguous. Try ");
+ gsc_standout_string("glk help");
+ gsc_normal_string(" for more information.\n");
+ return;
+ }
+ matched = entry;
+ }
+ }
+ if (!matched) {
+ gsc_normal_string("The Glk command ");
+ gsc_standout_string(command);
+ gsc_normal_string(" is not valid. Try ");
+ gsc_standout_string("glk help");
+ gsc_normal_string(" for more information.\n");
+ return;
+ }
+
+ if (matched->handler == gsc_command_summary) {
+ gsc_normal_string("Prints a summary of all the current Glk SCARE"
+ " settings.\n");
+ }
+
+ else if (matched->handler == gsc_command_script) {
+ gsc_normal_string("Logs the game's output to a file.\n\nUse ");
+ gsc_standout_string("glk script on");
+ gsc_normal_string(" to begin logging game output, and ");
+ gsc_standout_string("glk script off");
+ gsc_normal_string(" to end it. Glk SCARE will ask you for a file"
+ " when you turn scripts on.\n");
+ }
+
+ else if (matched->handler == gsc_command_inputlog) {
+ gsc_normal_string("Records the commands you type into a game.\n\nUse ");
+ gsc_standout_string("glk inputlog on");
+ gsc_normal_string(", to begin recording your commands, and ");
+ gsc_standout_string("glk inputlog off");
+ gsc_normal_string(" to turn off input logs. You can play back"
+ " recorded commands into a game with the ");
+ gsc_standout_string("glk readlog");
+ gsc_normal_string(" command.\n");
+ }
+
+ else if (matched->handler == gsc_command_readlog) {
+ gsc_normal_string("Plays back commands recorded with ");
+ gsc_standout_string("glk inputlog on");
+ gsc_normal_string(".\n\nUse ");
+ gsc_standout_string("glk readlog on");
+ gsc_normal_string(". Command play back stops at the end of the"
+ " file. You can also play back commands from a"
+ " text file created using any standard editor.\n");
+ }
+
+ else if (matched->handler == gsc_command_abbreviations) {
+ gsc_normal_string("Controls abbreviation expansion.\n\nGlk SCARE"
+ " automatically expands several standard single"
+ " letter abbreviations for you; for example, \"x\""
+ " becomes \"examine\". Use ");
+ gsc_standout_string("glk abbreviations on");
+ gsc_normal_string(" to turn this feature on, and ");
+ gsc_standout_string("glk abbreviations off");
+ gsc_normal_string(" to turn it off. While the feature is on, you"
+ " can bypass abbreviation expansion for an"
+ " individual game command by prefixing it with a"
+ " single quote.\n");
+ }
+
+ else if (matched->handler == gsc_command_version) {
+ gsc_normal_string("Prints the version numbers of the Glk library"
+ " and the Glk SCARE port.\n");
+ }
+
+ else if (matched->handler == gsc_command_commands) {
+ gsc_normal_string("Turn off Glk commands.\n\nUse ");
+ gsc_standout_string("glk commands off");
+ gsc_normal_string(" to disable all Glk commands, including this one."
+ " Once turned off, there is no way to turn Glk"
+ " commands back on while inside the game.\n");
+ }
+
+ else if (matched->handler == gsc_command_license) {
+ gsc_normal_string("Prints Glk SCARE's software license.\n");
+ }
+
+ else if (matched->handler == gsc_command_help)
+ gsc_command_help("");
+
+ else
+ gsc_normal_string("There is no help available on that Glk command."
+ " Sorry.\n");
}
@@ -2381,103 +2235,94 @@ gsc_command_help (const char *command)
* Glk port command, handle it and return TRUE, otherwise return FALSE.
*/
static int
-gsc_command_escape (const char *string)
-{
- int posn;
- char *string_copy, *command, *argument;
- assert (string);
-
- /*
- * Return FALSE if the string doesn't begin with the Glk command escape
- * introducer.
- */
- posn = strspn (string, "\t ");
- if (sc_strncasecmp (string + posn, "glk", strlen ("glk")) != 0)
- return FALSE;
-
- /* Take a copy of the string, without any leading space or introducer. */
- string_copy = (char *)gsc_malloc (strlen (string + posn) + 1 - strlen ("glk"));
- strcpy (string_copy, string + posn + strlen ("glk"));
-
- /*
- * Find the subcommand; the first word in the string copy. Find its end,
- * and ensure it terminates with a NUL.
- */
- posn = strspn (string_copy, "\t ");
- command = string_copy + posn;
- posn += strcspn (string_copy + posn, "\t ");
- if (string_copy[posn] != '\0')
- string_copy[posn++] = '\0';
-
- /*
- * Now find any argument data for the command, ensuring it too terminates
- * with a NUL.
- */
- posn += strspn (string_copy + posn, "\t ");
- argument = string_copy + posn;
- posn += strcspn (string_copy + posn, "\t ");
- string_copy[posn] = '\0';
-
- /*
- * Try to handle the command and argument as a Glk subcommand. If it
- * doesn't run unambiguously, print command usage. Treat an empty command
- * as "help".
- */
- if (strlen (command) > 0)
- {
- gsc_commandref_t entry, matched;
- int matches;
-
- /*
- * Search for the first unambiguous table command string matching
- * the command passed in.
- */
- matches = 0;
- matched = nullptr;
- for (entry = GSC_COMMAND_TABLE; entry->command; entry++)
- {
- if (sc_strncasecmp (command, entry->command, strlen (command)) == 0)
- {
- matches++;
- matched = entry;
- }
- }
-
- /* If the match was unambiguous, call the command handler. */
- if (matches == 1)
- {
- gsc_normal_char ('\n');
- matched->handler (argument);
-
- if (!matched->takes_argument && strlen (argument) > 0)
- {
- gsc_normal_string ("[The ");
- gsc_standout_string (matched->command);
- gsc_normal_string (" command ignores arguments.]\n");
- }
- }
-
- /* No match, or the command was ambiguous. */
- else
- {
- gsc_normal_string ("\nThe Glk command ");
- gsc_standout_string (command);
- gsc_normal_string (" is ");
- gsc_normal_string (matches == 0 ? "not valid" : "ambiguous");
- gsc_normal_string (". Try ");
- gsc_standout_string ("glk help");
- gsc_normal_string (" for more information.\n");
- }
- }
- else
- {
- gsc_normal_char ('\n');
- gsc_command_help ("");
- }
-
- /* The string contained a Glk command; return TRUE. */
- free (string_copy);
- return TRUE;
+gsc_command_escape(const char *string) {
+ int posn;
+ char *string_copy, *command, *argument;
+ assert(string);
+
+ /*
+ * Return FALSE if the string doesn't begin with the Glk command escape
+ * introducer.
+ */
+ posn = strspn(string, "\t ");
+ if (sc_strncasecmp(string + posn, "glk", strlen("glk")) != 0)
+ return FALSE;
+
+ /* Take a copy of the string, without any leading space or introducer. */
+ string_copy = (char *)gsc_malloc(strlen(string + posn) + 1 - strlen("glk"));
+ strcpy(string_copy, string + posn + strlen("glk"));
+
+ /*
+ * Find the subcommand; the first word in the string copy. Find its end,
+ * and ensure it terminates with a NUL.
+ */
+ posn = strspn(string_copy, "\t ");
+ command = string_copy + posn;
+ posn += strcspn(string_copy + posn, "\t ");
+ if (string_copy[posn] != '\0')
+ string_copy[posn++] = '\0';
+
+ /*
+ * Now find any argument data for the command, ensuring it too terminates
+ * with a NUL.
+ */
+ posn += strspn(string_copy + posn, "\t ");
+ argument = string_copy + posn;
+ posn += strcspn(string_copy + posn, "\t ");
+ string_copy[posn] = '\0';
+
+ /*
+ * Try to handle the command and argument as a Glk subcommand. If it
+ * doesn't run unambiguously, print command usage. Treat an empty command
+ * as "help".
+ */
+ if (strlen(command) > 0) {
+ gsc_commandref_t entry, matched;
+ int matches;
+
+ /*
+ * Search for the first unambiguous table command string matching
+ * the command passed in.
+ */
+ matches = 0;
+ matched = nullptr;
+ for (entry = GSC_COMMAND_TABLE; entry->command; entry++) {
+ if (sc_strncasecmp(command, entry->command, strlen(command)) == 0) {
+ matches++;
+ matched = entry;
+ }
+ }
+
+ /* If the match was unambiguous, call the command handler. */
+ if (matches == 1) {
+ gsc_normal_char('\n');
+ matched->handler(argument);
+
+ if (!matched->takes_argument && strlen(argument) > 0) {
+ gsc_normal_string("[The ");
+ gsc_standout_string(matched->command);
+ gsc_normal_string(" command ignores arguments.]\n");
+ }
+ }
+
+ /* No match, or the command was ambiguous. */
+ else {
+ gsc_normal_string("\nThe Glk command ");
+ gsc_standout_string(command);
+ gsc_normal_string(" is ");
+ gsc_normal_string(matches == 0 ? "not valid" : "ambiguous");
+ gsc_normal_string(". Try ");
+ gsc_standout_string("glk help");
+ gsc_normal_string(" for more information.\n");
+ }
+ } else {
+ gsc_normal_char('\n');
+ gsc_command_help("");
+ }
+
+ /* The string contained a Glk command; return TRUE. */
+ free(string_copy);
+ return TRUE;
}
@@ -2490,19 +2335,18 @@ static const char GSC_QUOTED_INPUT = '\'';
/* Table of single-character command abbreviations. */
-typedef const struct
-{
- const char abbreviation; /* Abbreviation character. */
- const char *const expansion; /* Expansion string. */
+typedef const struct {
+ const char abbreviation; /* Abbreviation character. */
+ const char *const expansion; /* Expansion string. */
} gsc_abbreviation_t;
typedef gsc_abbreviation_t *gsc_abbreviationref_t;
static gsc_abbreviation_t GSC_ABBREVIATIONS[] = {
- {'c', "close"}, {'g', "again"}, {'i', "inventory"},
- {'k', "attack"}, {'l', "look"}, {'p', "open"},
- {'q', "quit"}, {'r', "drop"}, {'t', "take"},
- {'x', "examine"}, {'y', "yes"}, {'z', "wait"},
- {'\0', nullptr}
+ {'c', "close"}, {'g', "again"}, {'i', "inventory"},
+ {'k', "attack"}, {'l', "look"}, {'p', "open"},
+ {'q', "quit"}, {'r', "drop"}, {'t', "take"},
+ {'x', "examine"}, {'y', "yes"}, {'z', "wait"},
+ {'\0', nullptr}
};
@@ -2513,49 +2357,45 @@ static gsc_abbreviation_t GSC_ABBREVIATIONS[] = {
* game systems.
*/
static void
-gsc_expand_abbreviations (char *buffer, int size)
-{
- char *command, abbreviation;
- const char *expansion;
- gsc_abbreviationref_t entry;
- assert (buffer);
-
- /* Ignore anything that isn't a single letter command. */
- command = buffer + strspn (buffer, "\t ");
- if (!(strlen (command) == 1
- || (strlen (command) > 1 && Common::isSpace(command[1]))))
- return;
-
- /* Scan the abbreviations table for a match. */
- abbreviation = g_vm->glk_char_to_lower ((unsigned char) command[0]);
- expansion = nullptr;
- for (entry = GSC_ABBREVIATIONS; entry->expansion; entry++)
- {
- if (entry->abbreviation == abbreviation)
- {
- expansion = entry->expansion;
- break;
- }
- }
-
- /*
- * If a match found, check for a fit, then replace the character with the
- * expansion string.
- */
- if (expansion)
- {
- if (strlen (buffer) + strlen (expansion) - 1 >= (unsigned int) size)
- return;
-
- memmove (command + strlen (expansion) - 1, command, strlen (command) + 1);
- memcpy (command, expansion, strlen (expansion));
-
- gsc_standout_string ("[");
- gsc_standout_char (abbreviation);
- gsc_standout_string (" -> ");
- gsc_standout_string (expansion);
- gsc_standout_string ("]\n");
- }
+gsc_expand_abbreviations(char *buffer, int size) {
+ char *command, abbreviation;
+ const char *expansion;
+ gsc_abbreviationref_t entry;
+ assert(buffer);
+
+ /* Ignore anything that isn't a single letter command. */
+ command = buffer + strspn(buffer, "\t ");
+ if (!(strlen(command) == 1
+ || (strlen(command) > 1 && Common::isSpace(command[1]))))
+ return;
+
+ /* Scan the abbreviations table for a match. */
+ abbreviation = g_vm->glk_char_to_lower((unsigned char) command[0]);
+ expansion = nullptr;
+ for (entry = GSC_ABBREVIATIONS; entry->expansion; entry++) {
+ if (entry->abbreviation == abbreviation) {
+ expansion = entry->expansion;
+ break;
+ }
+ }
+
+ /*
+ * If a match found, check for a fit, then replace the character with the
+ * expansion string.
+ */
+ if (expansion) {
+ if (strlen(buffer) + strlen(expansion) - 1 >= (unsigned int) size)
+ return;
+
+ memmove(command + strlen(expansion) - 1, command, strlen(command) + 1);
+ memcpy(command, expansion, strlen(expansion));
+
+ gsc_standout_string("[");
+ gsc_standout_char(abbreviation);
+ gsc_standout_string(" -> ");
+ gsc_standout_string(expansion);
+ gsc_standout_string("]\n");
+ }
}
@@ -2565,123 +2405,111 @@ gsc_expand_abbreviations (char *buffer, int size)
* Read and return a line of player input.
*/
sc_bool
-os_read_line (sc_char *buffer, sc_int length)
-{
- sc_int characters;
- assert (buffer && length > 0);
-
- /* If a help request is pending, provide a user hint. */
- gsc_output_provide_help_hint ();
-
- /*
- * Ensure normal style, update the status line, and issue an input prompt.
- */
- gsc_reset_glk_style ();
- gsc_status_notify ();
- g_vm->glk_put_string (">");
-
- /*
- * If we have an input log to read from, use that until it is exhausted.
- * On end of file, close the stream and resume input from line requests.
- */
- if (gsc_readlog_stream)
- {
- glui32 chars;
-
- /* Get the next line from the log stream. */
- chars = g_vm->glk_get_line_stream (gsc_readlog_stream, buffer, length);
- if (chars > 0)
- {
- /* Echo the line just read in input style. */
- g_vm->glk_set_style (style_Input);
- gsc_put_buffer (buffer, chars);
- g_vm->glk_set_style (style_Normal);
-
- /* Return this line as player input. */
- return TRUE;
- }
-
- /*
- * We're at the end of the log stream. Close it, and then continue
- * on to request a line from Glk.
- */
- g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
- gsc_readlog_stream = nullptr;
- }
-
- /*
- * No input log being read, or we just hit the end of file on one. Revert
- * to normal line input; start by getting a new line from Glk.
- */
- characters = gsc_read_line (buffer, length - 1);
- assert (characters <= length);
- buffer[characters] = '\0';
-
- /*
- * If neither abbreviations nor local commands are enabled, use the data
- * read above without further massaging.
- */
- if (gsc_abbreviations_enabled || gsc_commands_enabled)
- {
- char *command;
-
- /*
- * If the first non-space input character is a quote, bypass all
- * abbreviation expansion and local command recognition, and use the
- * unadulterated input, less introductory quote.
- */
- command = buffer + strspn (buffer, "\t ");
- if (command[0] == GSC_QUOTED_INPUT)
- {
- /* Delete the quote with memmove(). */
- memmove (command, command + 1, strlen (command));
- }
- else
- {
- /* Check for, and expand, and abbreviated commands. */
- if (gsc_abbreviations_enabled)
- gsc_expand_abbreviations (buffer, length);
-
- /*
- * Check for standalone "help", then for Glk port special commands;
- * suppress the interpreter's use of this input for Glk commands by
- * returning FALSE.
- */
- if (gsc_commands_enabled)
- {
- int posn;
-
- posn = strspn (buffer, "\t ");
- if (sc_strncasecmp (buffer + posn, "help", strlen ("help"))== 0)
- {
- if (strspn (buffer + posn + strlen ("help"), "\t ")
- == strlen (buffer + posn + strlen ("help")))
- {
- gsc_output_register_help_request ();
- }
- }
-
- if (gsc_command_escape (buffer))
- {
- gsc_output_silence_help_hints ();
- return FALSE;
- }
- }
- }
- }
-
- /*
- * If there is an input log active, log this input string to it. Note that
- * by logging here we get any abbreviation expansions but we won't log glk
- * special commands, nor any input read from a current open input log.
- */
- if (gsc_inputlog_stream)
- {
- g_vm->glk_put_string_stream (gsc_inputlog_stream, buffer);
- g_vm->glk_put_char_stream (gsc_inputlog_stream, '\n');
- }
-
- return TRUE;
+os_read_line(sc_char *buffer, sc_int length) {
+ sc_int characters;
+ assert(buffer && length > 0);
+
+ /* If a help request is pending, provide a user hint. */
+ gsc_output_provide_help_hint();
+
+ /*
+ * Ensure normal style, update the status line, and issue an input prompt.
+ */
+ gsc_reset_glk_style();
+ gsc_status_notify();
+ g_vm->glk_put_string(">");
+
+ /*
+ * If we have an input log to read from, use that until it is exhausted.
+ * On end of file, close the stream and resume input from line requests.
+ */
+ if (gsc_readlog_stream) {
+ glui32 chars;
+
+ /* Get the next line from the log stream. */
+ chars = g_vm->glk_get_line_stream(gsc_readlog_stream, buffer, length);
+ if (chars > 0) {
+ /* Echo the line just read in input style. */
+ g_vm->glk_set_style(style_Input);
+ gsc_put_buffer(buffer, chars);
+ g_vm->glk_set_style(style_Normal);
+
+ /* Return this line as player input. */
+ return TRUE;
+ }
+
+ /*
+ * We're at the end of the log stream. Close it, and then continue
+ * on to request a line from Glk.
+ */
+ g_vm->glk_stream_close(gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+ }
+
+ /*
+ * No input log being read, or we just hit the end of file on one. Revert
+ * to normal line input; start by getting a new line from Glk.
+ */
+ characters = gsc_read_line(buffer, length - 1);
+ assert(characters <= length);
+ buffer[characters] = '\0';
+
+ /*
+ * If neither abbreviations nor local commands are enabled, use the data
+ * read above without further massaging.
+ */
+ if (gsc_abbreviations_enabled || gsc_commands_enabled) {
+ char *command;
+
+ /*
+ * If the first non-space input character is a quote, bypass all
+ * abbreviation expansion and local command recognition, and use the
+ * unadulterated input, less introductory quote.
+ */
+ command = buffer + strspn(buffer, "\t ");
+ if (command[0] == GSC_QUOTED_INPUT) {
+ /* Delete the quote with memmove(). */
+ memmove(command, command + 1, strlen(command));
+ } else {
+ /* Check for, and expand, and abbreviated commands. */
+ if (gsc_abbreviations_enabled)
+ gsc_expand_abbreviations(buffer, length);
+
+ /*
+ * Check for standalone "help", then for Glk port special commands;
+ * suppress the interpreter's use of this input for Glk commands by
+ * returning FALSE.
+ */
+ if (gsc_commands_enabled) {
+ int posn;
+
+ posn = strspn(buffer, "\t ");
+ if (sc_strncasecmp(buffer + posn, "help", strlen("help")) == 0) {
+ if (strspn(buffer + posn + strlen("help"), "\t ")
+ == strlen(buffer + posn + strlen("help"))) {
+ gsc_output_register_help_request();
+ }
+ }
+
+ if (gsc_command_escape(buffer)) {
+ gsc_output_silence_help_hints();
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ /*
+ * If there is an input log active, log this input string to it. Note that
+ * by logging here we get any abbreviation expansions but we won't log glk
+ * special commands, nor any input read from a current open input log.
+ */
+ if (gsc_inputlog_stream) {
+ g_vm->glk_put_string_stream(gsc_inputlog_stream, buffer);
+ g_vm->glk_put_char_stream(gsc_inputlog_stream, '\n');
+ }
+
+ return TRUE;
}
@@ -2693,12 +2521,11 @@ os_read_line (sc_char *buffer, sc_int length)
* prompt.
*/
sc_bool
-os_read_line_debug (sc_char *buffer, sc_int length)
-{
- gsc_output_silence_help_hints ();
- gsc_reset_glk_style ();
- g_vm->glk_put_string ("[SCARE debug]");
- return os_read_line (buffer, length);
+os_read_line_debug(sc_char *buffer, sc_int length) {
+ gsc_output_silence_help_hints();
+ gsc_reset_glk_style();
+ g_vm->glk_put_string("[SCARE debug]");
+ return os_read_line(buffer, length);
}
@@ -2708,85 +2535,78 @@ os_read_line_debug (sc_char *buffer, sc_int length)
* Confirm a game action with a yes/no prompt.
*/
sc_bool
-os_confirm (sc_int type)
-{
- sc_char response;
-
- /*
- * Always allow game saves and hint display, and if we're reading from an
- * input log, allow everything no matter what, on the assumption that the
- * user knows what they are doing.
- */
- if (gsc_readlog_stream
- || type == SC_CONF_SAVE || type == SC_CONF_VIEW_HINTS)
- return TRUE;
-
- /* Ensure back to normal style, and update status. */
- gsc_reset_glk_style ();
- gsc_status_notify ();
-
- /* Prompt for the confirmation, based on the type. */
- if (type == GSC_CONF_SUBTLE_HINT)
- g_vm->glk_put_string ("View the subtle hint for this topic");
- else if (type == GSC_CONF_UNSUBTLE_HINT)
- g_vm->glk_put_string ("View the unsubtle hint for this topic");
- else if (type == GSC_CONF_CONTINUE_HINTS)
- g_vm->glk_put_string ("Continue with hints");
- else
- {
- g_vm->glk_put_string ("Do you really want to ");
- switch (type)
- {
- case SC_CONF_QUIT:
- g_vm->glk_put_string ("quit");
- break;
- case SC_CONF_RESTART:
- g_vm->glk_put_string ("restart");
- break;
- case SC_CONF_SAVE:
- g_vm->glk_put_string ("save");
- break;
- case SC_CONF_RESTORE:
- g_vm->glk_put_string ("restore");
- break;
- case SC_CONF_VIEW_HINTS:
- g_vm->glk_put_string ("view hints");
- break;
- default:
- g_vm->glk_put_string ("do that");
- break;
- }
- }
- g_vm->glk_put_string ("? ");
-
- /* Loop until 'yes' or 'no' returned. */
- do
- {
- event_t event;
-
- /* Wait for a standard key, ignoring Glk special keys. */
- do
- {
- g_vm->glk_request_char_event (gsc_main_window);
- gsc_event_wait (evtype_CharInput, &event);
- }
- while (event.val1 > UCHAR_MAX);
- response = g_vm->glk_char_to_upper (event.val1);
- }
- while (response != 'Y' && response != 'N');
-
- /* Echo the confirmation response, and a new line. */
- g_vm->glk_set_style (style_Input);
- g_vm->glk_put_string (response == 'Y' ? "Yes" : "No");
- g_vm->glk_set_style (style_Normal);
- g_vm->glk_put_char ('\n');
-
- /* Use a short delay on restarts, if confirmed. */
- if (type == SC_CONF_RESTART && response == 'Y')
- gsc_short_delay ();
-
- /* Return TRUE if 'Y' was entered. */
- return (response == 'Y');
+os_confirm(sc_int type) {
+ sc_char response;
+
+ /*
+ * Always allow game saves and hint display, and if we're reading from an
+ * input log, allow everything no matter what, on the assumption that the
+ * user knows what they are doing.
+ */
+ if (gsc_readlog_stream
+ || type == SC_CONF_SAVE || type == SC_CONF_VIEW_HINTS)
+ return TRUE;
+
+ /* Ensure back to normal style, and update status. */
+ gsc_reset_glk_style();
+ gsc_status_notify();
+
+ /* Prompt for the confirmation, based on the type. */
+ if (type == GSC_CONF_SUBTLE_HINT)
+ g_vm->glk_put_string("View the subtle hint for this topic");
+ else if (type == GSC_CONF_UNSUBTLE_HINT)
+ g_vm->glk_put_string("View the unsubtle hint for this topic");
+ else if (type == GSC_CONF_CONTINUE_HINTS)
+ g_vm->glk_put_string("Continue with hints");
+ else {
+ g_vm->glk_put_string("Do you really want to ");
+ switch (type) {
+ case SC_CONF_QUIT:
+ g_vm->glk_put_string("quit");
+ break;
+ case SC_CONF_RESTART:
+ g_vm->glk_put_string("restart");
+ break;
+ case SC_CONF_SAVE:
+ g_vm->glk_put_string("save");
+ break;
+ case SC_CONF_RESTORE:
+ g_vm->glk_put_string("restore");
+ break;
+ case SC_CONF_VIEW_HINTS:
+ g_vm->glk_put_string("view hints");
+ break;
+ default:
+ g_vm->glk_put_string("do that");
+ break;
+ }
+ }
+ g_vm->glk_put_string("? ");
+
+ /* Loop until 'yes' or 'no' returned. */
+ do {
+ event_t event;
+
+ /* Wait for a standard key, ignoring Glk special keys. */
+ do {
+ g_vm->glk_request_char_event(gsc_main_window);
+ gsc_event_wait(evtype_CharInput, &event);
+ } while (event.val1 > UCHAR_MAX);
+ response = g_vm->glk_char_to_upper(event.val1);
+ } while (response != 'Y' && response != 'N');
+
+ /* Echo the confirmation response, and a new line. */
+ g_vm->glk_set_style(style_Input);
+ g_vm->glk_put_string(response == 'Y' ? "Yes" : "No");
+ g_vm->glk_set_style(style_Normal);
+ g_vm->glk_put_char('\n');
+
+ /* Use a short delay on restarts, if confirmed. */
+ if (type == SC_CONF_RESTART && response == 'Y')
+ gsc_short_delay();
+
+ /* Return TRUE if 'Y' was entered. */
+ return (response == 'Y');
}
@@ -2806,23 +2626,20 @@ static const glui32 GSC_DELAY_TIMEOUTS_COUNT = 10;
* immediate, and abrupt, restart.
*/
static void
-gsc_short_delay()
-{
- /* Ignore the call if the Glk doesn't have timers. */
- if (g_vm->glk_gestalt (gestalt_Timer, 0))
- {
- glui32 timeout;
-
- /* Timeout in small chunks to minimize Glk jitter. */
- g_vm->glk_request_timer_events (GSC_DELAY_TIMEOUT);
- for (timeout = 0; timeout < GSC_DELAY_TIMEOUTS_COUNT; timeout++)
- {
- event_t event;
+gsc_short_delay() {
+ /* Ignore the call if the Glk doesn't have timers. */
+ if (g_vm->glk_gestalt(gestalt_Timer, 0)) {
+ glui32 timeout;
+
+ /* Timeout in small chunks to minimize Glk jitter. */
+ g_vm->glk_request_timer_events(GSC_DELAY_TIMEOUT);
+ for (timeout = 0; timeout < GSC_DELAY_TIMEOUTS_COUNT; timeout++) {
+ event_t event;
- gsc_event_wait (evtype_Timer, &event);
- }
- g_vm->glk_request_timer_events (0);
- }
+ gsc_event_wait(evtype_Timer, &event);
+ }
+ g_vm->glk_request_timer_events(0);
+ }
}
@@ -2834,36 +2651,31 @@ gsc_short_delay()
* Return the event of that type.
*/
static void
-gsc_event_wait_2 (glui32 wait_type_1, glui32 wait_type_2, event_t * event)
-{
- assert (event);
-
- do
- {
- g_vm->glk_select (event);
- if (g_vm->shouldQuit()) {
- g_vm->glk_cancel_line_event(gsc_main_window, event);
- return;
- }
-
- switch (event->type)
- {
- case evtype_Arrange:
- case evtype_Redraw:
- /* Refresh any sensitive windows on size events. */
- gsc_status_redraw ();
- break;
- }
- }
- while (!(event->type == (EvType)wait_type_1 || event->type == (EvType)wait_type_2));
+gsc_event_wait_2(glui32 wait_type_1, glui32 wait_type_2, event_t *event) {
+ assert(event);
+
+ do {
+ g_vm->glk_select(event);
+ if (g_vm->shouldQuit()) {
+ g_vm->glk_cancel_line_event(gsc_main_window, event);
+ return;
+ }
+
+ switch (event->type) {
+ case evtype_Arrange:
+ case evtype_Redraw:
+ /* Refresh any sensitive windows on size events. */
+ gsc_status_redraw();
+ break;
+ }
+ } while (!(event->type == (EvType)wait_type_1 || event->type == (EvType)wait_type_2));
}
static void
-gsc_event_wait (glui32 wait_type, event_t * event)
-{
- assert (event);
+gsc_event_wait(glui32 wait_type, event_t *event) {
+ assert(event);
- gsc_event_wait_2 (wait_type, evtype_None, event);
+ gsc_event_wait_2(wait_type, evtype_None, event);
}
@@ -2877,28 +2689,27 @@ gsc_event_wait (glui32 wait_type, event_t * event)
* Open a file for save or restore, and return a Glk stream for the opened
* file.
*/
-void *os_open_file (sc_bool is_save) {
- glui32 usage, fmode;
- frefid_t fileref;
- strid_t stream;
+void *os_open_file(sc_bool is_save) {
+ glui32 usage, fmode;
+ frefid_t fileref;
+ strid_t stream;
- usage = fileusage_SavedGame | fileusage_BinaryMode;
- fmode = is_save ? filemode_Write : filemode_Read;
+ usage = fileusage_SavedGame | fileusage_BinaryMode;
+ fmode = is_save ? filemode_Write : filemode_Read;
- fileref = g_vm->glk_fileref_create_by_prompt(usage, (FileMode)fmode, 0);
- if (!fileref)
- return nullptr;
+ fileref = g_vm->glk_fileref_create_by_prompt(usage, (FileMode)fmode, 0);
+ if (!fileref)
+ return nullptr;
- if (!is_save && !g_vm->glk_fileref_does_file_exist (fileref))
- {
- g_vm->glk_fileref_destroy (fileref);
- return nullptr;
- }
+ if (!is_save && !g_vm->glk_fileref_does_file_exist(fileref)) {
+ g_vm->glk_fileref_destroy(fileref);
+ return nullptr;
+ }
- stream = g_vm->glk_stream_open_file (fileref, (FileMode)fmode, 0);
- g_vm->glk_fileref_destroy (fileref);
+ stream = g_vm->glk_stream_open_file(fileref, (FileMode)fmode, 0);
+ g_vm->glk_fileref_destroy(fileref);
- return stream;
+ return stream;
}
@@ -2909,21 +2720,19 @@ void *os_open_file (sc_bool is_save) {
* Write/read the given buffered data to/from the open Glk stream.
*/
void
-os_write_file (void *opaque, const sc_byte *buffer, sc_int length)
-{
- strid_t stream = (strid_t) opaque;
- assert (opaque && buffer);
+os_write_file(void *opaque, const sc_byte *buffer, sc_int length) {
+ strid_t stream = (strid_t) opaque;
+ assert(opaque && buffer);
- g_vm->glk_put_buffer_stream (stream, (char *) buffer, length);
+ g_vm->glk_put_buffer_stream(stream, (char *) buffer, length);
}
sc_int
-os_read_file (void *opaque, sc_byte *buffer, sc_int length)
-{
- strid_t stream = (strid_t) opaque;
- assert (opaque && buffer);
+os_read_file(void *opaque, sc_byte *buffer, sc_int length) {
+ strid_t stream = (strid_t) opaque;
+ assert(opaque && buffer);
- return g_vm->glk_get_buffer_stream (stream, (char *) buffer, length);
+ return g_vm->glk_get_buffer_stream(stream, (char *) buffer, length);
}
@@ -2933,12 +2742,11 @@ os_read_file (void *opaque, sc_byte *buffer, sc_int length)
* Close the opened Glk stream.
*/
void
-os_close_file (void *opaque)
-{
- strid_t stream = (strid_t) opaque;
- assert (opaque);
+os_close_file(void *opaque) {
+ strid_t stream = (strid_t) opaque;
+ assert(opaque);
- g_vm->glk_stream_close (stream, nullptr);
+ g_vm->glk_stream_close(stream, nullptr);
}
@@ -2981,68 +2789,63 @@ static sc_int gsc_callback(void *opaque, sc_byte *buffer, sc_int length) {
* end option. Called on game completion.
*/
static enum gsc_end_option
-gsc_get_ending_option()
-{
- sc_char response;
-
- /* Ensure back to normal style, and update status. */
- gsc_reset_glk_style ();
- gsc_status_notify ();
-
- /* Prompt for restart, undo, or quit. */
- g_vm->glk_put_string ("\nWould you like to RESTART, UNDO a turn, or QUIT? ");
-
- /* Loop until 'restart', 'undo' or 'quit'. */
- do
- {
- event_t event;
-
- do
- {
- g_vm->glk_request_char_event (gsc_main_window);
- gsc_event_wait (evtype_CharInput, &event);
- }
- while (event.val1 > UCHAR_MAX);
- response = g_vm->glk_char_to_upper (event.val1);
- }
- while (response != 'R' && response != 'U' && response != 'Q');
-
- /* Echo the confirmation response, and a new line. */
- g_vm->glk_set_style (style_Input);
- switch (response)
- {
- case 'R':
- g_vm->glk_put_string ("Restart");
- break;
- case 'U':
- g_vm->glk_put_string ("Undo");
- break;
- case 'Q':
- g_vm->glk_put_string ("Quit");
- break;
- default:
- gsc_fatal ("GLK: Invalid response encountered");
- g_vm->glk_exit ();
- }
- g_vm->glk_set_style (style_Normal);
- g_vm->glk_put_char ('\n');
-
- /* Return the appropriate value for response. */
- switch (response)
- {
- case 'R':
- return GAME_RESTART;
- case 'U':
- return GAME_UNDO;
- case 'Q':
- return GAME_QUIT;
- default:
- gsc_fatal ("GLK: Invalid response encountered");
- g_vm->glk_exit ();
- }
-
- /* Unreachable; supplied to suppress compiler warning. */
- return GAME_QUIT;
+gsc_get_ending_option() {
+ sc_char response;
+
+ /* Ensure back to normal style, and update status. */
+ gsc_reset_glk_style();
+ gsc_status_notify();
+
+ /* Prompt for restart, undo, or quit. */
+ g_vm->glk_put_string("\nWould you like to RESTART, UNDO a turn, or QUIT? ");
+
+ /* Loop until 'restart', 'undo' or 'quit'. */
+ do
+ {
+ event_t event;
+
+ do
+ {
+ g_vm->glk_request_char_event(gsc_main_window);
+ gsc_event_wait(evtype_CharInput, &event);
+ } while (event.val1 > UCHAR_MAX);
+ response = g_vm->glk_char_to_upper(event.val1);
+ } while (response != 'R' && response != 'U' && response != 'Q');
+
+ /* Echo the confirmation response, and a new line. */
+ g_vm->glk_set_style(style_Input);
+ switch (response) {
+ case 'R':
+ g_vm->glk_put_string("Restart");
+ break;
+ case 'U':
+ g_vm->glk_put_string("Undo");
+ break;
+ case 'Q':
+ g_vm->glk_put_string("Quit");
+ break;
+ default:
+ gsc_fatal("GLK: Invalid response encountered");
+ g_vm->glk_exit();
+ }
+ g_vm->glk_set_style(style_Normal);
+ g_vm->glk_put_char('\n');
+
+ /* Return the appropriate value for response. */
+ switch (response) {
+ case 'R':
+ return GAME_RESTART;
+ case 'U':
+ return GAME_UNDO;
+ case 'Q':
+ return GAME_QUIT;
+ default:
+ gsc_fatal("GLK: Invalid response encountered");
+ g_vm->glk_exit();
+ }
+
+ /* Unreachable; supplied to suppress compiler warning. */
+ return GAME_QUIT;
}
@@ -3057,16 +2860,14 @@ gsc_get_ending_option()
*/
static int
gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream,
- sc_uint trace_flags, sc_bool enable_debugger,
- sc_bool stable_random, const sc_char *locale)
-{
+ sc_uint trace_flags, sc_bool enable_debugger,
+ sc_bool stable_random, const sc_char *locale) {
winid_t window;
assert(game_stream);
/* Open a temporary Glk main window. */
window = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
- if (window)
- {
+ if (window) {
/* Clear and initialize the temporary window. */
g_vm->glk_window_clear(window);
g_vm->glk_set_window(window);
@@ -3113,42 +2914,35 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream
*/
sc_set_trace_flags(trace_flags);
gsc_game = sc_game_from_callback(gsc_callback, game_stream);
- if (!gsc_game)
- {
+ if (!gsc_game) {
gsc_game = nullptr;
gsc_game_message = "Unable to load an Adrift game from the requested file.";
- }
- else
+ } else
gsc_game_message = nullptr;
/*
* If the game was created successfully and there is a restore stream, try
* to immediately restore the game from that stream.
*/
- if (gsc_game && restore_stream)
- {
- if (!sc_load_game_from_callback(gsc_game, gsc_callback, restore_stream))
- {
+ if (gsc_game && restore_stream) {
+ if (!sc_load_game_from_callback(gsc_game, gsc_callback, restore_stream)) {
sc_free_game(gsc_game);
gsc_game = nullptr;
gsc_game_message = "Unable to restore this Adrift game from the requested file.";
- }
- else
+ } else
gsc_game_message = nullptr;
}
if (restore_stream)
g_vm->glk_stream_close(restore_stream, nullptr);
/* If successful, set game debugging and synchronize to the core's locale. */
- if (gsc_game)
- {
+ if (gsc_game) {
sc_set_game_debugger_enabled(gsc_game, enable_debugger);
gsc_set_locale(sc_get_locale());
}
/* Set portable and predictable random number generation if requested. */
- if (stable_random)
- {
+ if (stable_random) {
sc_set_portable_random(TRUE);
sc_reseed_random_sequence(1);
}
@@ -3167,126 +2961,112 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream
}
static void
-gsc_main()
-{
- sc_bool is_running;
-
- /* Ensure SCARE internal types have the right sizes. */
- if (!(sizeof (sc_byte) == 1 && sizeof (sc_char) == 1
- && sizeof (sc_uint) >= 4 && sizeof (sc_int) >= 4
- && sizeof (sc_uint) <= 8 && sizeof (sc_int) <= 8))
- {
- gsc_fatal ("GLK: Types sized incorrectly, recompilation is needed");
- g_vm->glk_exit ();
- }
-
- /* Create the Glk window, and set its stream as the current one. */
- gsc_main_window = g_vm->glk_window_open (0, 0, 0, wintype_TextBuffer, 0);
- if (!gsc_main_window)
- {
- gsc_fatal ("GLK: Can't open main window");
- g_vm->glk_exit ();
- }
- g_vm->glk_window_clear (gsc_main_window);
- g_vm->glk_set_window (gsc_main_window);
- g_vm->glk_set_style (style_Normal);
-
- /* If there's a problem with the game file, complain now. */
- if (!gsc_game)
- {
- assert (gsc_game_message);
- gsc_header_string ("Glk SCARE Error\n\n");
- gsc_normal_string (gsc_game_message);
- gsc_normal_char ('\n');
- g_vm->glk_exit ();
- }
-
- /* Try to create a one-line status window. We can live without it. */
- g_vm->glk_stylehint_set (wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
- gsc_status_window = g_vm->glk_window_open (gsc_main_window,
- winmethod_Above | winmethod_Fixed,
- 1, wintype_TextGrid, 0);
-
- /* Repeat the game until no more restarts requested. */
- is_running = TRUE;
- while (is_running)
- {
- /* Run the game until it ends, or the user quits. */
- gsc_status_notify ();
- sc_interpret_game (gsc_game);
-
- /*
- * If the game did not complete, the user quit explicitly, so leave the
- * game repeat loop.
- */
- if (!sc_has_game_completed (gsc_game))
- {
- is_running = FALSE;
- break;
- }
-
- /*
- * If reading from an input log, close it now. We need to request a
- * user selection, probably modal, and after that we probably don't
- * want the follow-on readlog data being used as game input.
- */
- if (gsc_readlog_stream)
- {
- g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
- gsc_readlog_stream = nullptr;
- }
-
- /*
- * Get user selection of restart, undo a turn, or quit completed game.
- * If undo is unavailable (this should not be possible), degrade to
- * restart.
- */
- switch (gsc_get_ending_option ())
- {
- case GAME_RESTART:
- gsc_short_delay ();
- sc_restart_game (gsc_game);
- break;
-
- case GAME_UNDO:
- if (sc_is_game_undo_available (gsc_game))
- {
- sc_undo_game_turn (gsc_game);
- gsc_normal_string ("The previous turn has been undone.\n");
- }
- else
- {
- gsc_normal_string ("Sorry, no undo is available.\n");
- gsc_short_delay ();
- sc_restart_game (gsc_game);
- }
- break;
-
- case GAME_QUIT:
- is_running = FALSE;
- break;
- }
- }
-
- /* All done -- release game resources. */
- sc_free_game (gsc_game);
-
- /* Close any open transcript, input log, and/or read log. */
- if (gsc_transcript_stream)
- {
- g_vm->glk_stream_close (gsc_transcript_stream, nullptr);
- gsc_transcript_stream = nullptr;
- }
- if (gsc_inputlog_stream)
- {
- g_vm->glk_stream_close (gsc_inputlog_stream, nullptr);
- gsc_inputlog_stream = nullptr;
- }
- if (gsc_readlog_stream)
- {
- g_vm->glk_stream_close (gsc_readlog_stream, nullptr);
- gsc_readlog_stream = nullptr;
- }
+gsc_main() {
+ sc_bool is_running;
+
+ /* Ensure SCARE internal types have the right sizes. */
+ if (!(sizeof(sc_byte) == 1 && sizeof(sc_char) == 1
+ && sizeof(sc_uint) >= 4 && sizeof(sc_int) >= 4
+ && sizeof(sc_uint) <= 8 && sizeof(sc_int) <= 8)) {
+ gsc_fatal("GLK: Types sized incorrectly, recompilation is needed");
+ g_vm->glk_exit();
+ }
+
+ /* Create the Glk window, and set its stream as the current one. */
+ gsc_main_window = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
+ if (!gsc_main_window) {
+ gsc_fatal("GLK: Can't open main window");
+ g_vm->glk_exit();
+ }
+ g_vm->glk_window_clear(gsc_main_window);
+ g_vm->glk_set_window(gsc_main_window);
+ g_vm->glk_set_style(style_Normal);
+
+ /* If there's a problem with the game file, complain now. */
+ if (!gsc_game) {
+ assert(gsc_game_message);
+ gsc_header_string("Glk SCARE Error\n\n");
+ gsc_normal_string(gsc_game_message);
+ gsc_normal_char('\n');
+ g_vm->glk_exit();
+ }
+
+ /* Try to create a one-line status window. We can live without it. */
+ g_vm->glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
+ gsc_status_window = g_vm->glk_window_open(gsc_main_window,
+ winmethod_Above | winmethod_Fixed,
+ 1, wintype_TextGrid, 0);
+
+ /* Repeat the game until no more restarts requested. */
+ is_running = TRUE;
+ while (is_running) {
+ /* Run the game until it ends, or the user quits. */
+ gsc_status_notify();
+ sc_interpret_game(gsc_game);
+
+ /*
+ * If the game did not complete, the user quit explicitly, so leave the
+ * game repeat loop.
+ */
+ if (!sc_has_game_completed(gsc_game)) {
+ is_running = FALSE;
+ break;
+ }
+
+ /*
+ * If reading from an input log, close it now. We need to request a
+ * user selection, probably modal, and after that we probably don't
+ * want the follow-on readlog data being used as game input.
+ */
+ if (gsc_readlog_stream) {
+ g_vm->glk_stream_close(gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+ }
+
+ /*
+ * Get user selection of restart, undo a turn, or quit completed game.
+ * If undo is unavailable (this should not be possible), degrade to
+ * restart.
+ */
+ switch (gsc_get_ending_option()) {
+ case GAME_RESTART:
+ gsc_short_delay();
+ sc_restart_game(gsc_game);
+ break;
+
+ case GAME_UNDO:
+ if (sc_is_game_undo_available(gsc_game)) {
+ sc_undo_game_turn(gsc_game);
+ gsc_normal_string("The previous turn has been undone.\n");
+ } else {
+ gsc_normal_string("Sorry, no undo is available.\n");
+ gsc_short_delay();
+ sc_restart_game(gsc_game);
+ }
+ break;
+
+ case GAME_QUIT:
+ is_running = FALSE;
+ break;
+ }
+ }
+
+ /* All done -- release game resources. */
+ sc_free_game(gsc_game);
+
+ /* Close any open transcript, input log, and/or read log. */
+ if (gsc_transcript_stream) {
+ g_vm->glk_stream_close(gsc_transcript_stream, nullptr);
+ gsc_transcript_stream = nullptr;
+ }
+ if (gsc_inputlog_stream) {
+ g_vm->glk_stream_close(gsc_inputlog_stream, nullptr);
+ gsc_inputlog_stream = nullptr;
+ }
+ if (gsc_readlog_stream) {
+ g_vm->glk_stream_close(gsc_readlog_stream, nullptr);
+ gsc_readlog_stream = nullptr;
+ }
}
@@ -3325,21 +3105,33 @@ void adrift_main() {
* Glk arguments for UNIX versions of the Glk interpreter.
*/
glkunix_argumentlist_t glkunix_arguments[] = {
- {(char *) "-nc", glkunix_arg_NoValue,
- (char *) "-nc No local handling for Glk special commands"},
- {(char *) "-na", glkunix_arg_NoValue,
- (char *) "-na Turn off abbreviation expansions"},
- {(char *) "-nu", glkunix_arg_NoValue,
- (char *) "-nu Turn off any use of Unicode output"},
+ {
+ (char *) "-nc", glkunix_arg_NoValue,
+ (char *) "-nc No local handling for Glk special commands"
+ },
+ {
+ (char *) "-na", glkunix_arg_NoValue,
+ (char *) "-na Turn off abbreviation expansions"
+ },
+ {
+ (char *) "-nu", glkunix_arg_NoValue,
+ (char *) "-nu Turn off any use of Unicode output"
+ },
#ifdef LINUX_GRAPHICS
- {(char *) "-ng", glkunix_arg_NoValue,
- (char *) "-ng Turn off attempts at game graphics"},
+ {
+ (char *) "-ng", glkunix_arg_NoValue,
+ (char *) "-ng Turn off attempts at game graphics"
+ },
#endif
- {(char *) "-r", glkunix_arg_ValueFollows,
- (char *) "-r FILE Restore from FILE on starting the game"},
- {(char *) "", glkunix_arg_ValueCanFollow,
- (char *) "filename game to run"},
- {nullptr, glkunix_arg_End, nullptr}
+ {
+ (char *) "-r", glkunix_arg_ValueFollows,
+ (char *) "-r FILE Restore from FILE on starting the game"
+ },
+ {
+ (char *) "", glkunix_arg_ValueCanFollow,
+ (char *) "filename game to run"
+ },
+ {nullptr, glkunix_arg_End, nullptr}
};
#endif
diff --git a/engines/glk/adrift/scare.h b/engines/glk/adrift/scare.h
index 43ce75a..d4e0231 100644
--- a/engines/glk/adrift/scare.h
+++ b/engines/glk/adrift/scare.h
@@ -50,67 +50,67 @@ typedef unsigned long sc_uint;
typedef int sc_bool;
/* Enumerated confirmation types, passed to os_confirm(). */
-enum
-{ SC_CONF_QUIT = 0,
- SC_CONF_RESTART, SC_CONF_SAVE, SC_CONF_RESTORE, SC_CONF_VIEW_HINTS
+enum {
+ SC_CONF_QUIT = 0,
+ SC_CONF_RESTART, SC_CONF_SAVE, SC_CONF_RESTORE, SC_CONF_VIEW_HINTS
};
/* HTML-like tag enumerated values, passed to os_print_tag(). */
-enum
-{ SC_TAG_UNKNOWN = 0, SC_TAG_ITALICS, SC_TAG_ENDITALICS, SC_TAG_BOLD,
- SC_TAG_ENDBOLD, SC_TAG_UNDERLINE, SC_TAG_ENDUNDERLINE, SC_TAG_COLOR,
- SC_TAG_ENDCOLOR, SC_TAG_FONT, SC_TAG_ENDFONT, SC_TAG_BGCOLOR, SC_TAG_CENTER,
- SC_TAG_ENDCENTER, SC_TAG_RIGHT, SC_TAG_ENDRIGHT, SC_TAG_WAIT, SC_TAG_WAITKEY,
- SC_TAG_CLS,
-
- /* British spelling equivalents. */
- SC_TAG_COLOUR = SC_TAG_COLOR,
- SC_TAG_ENDCOLOUR = SC_TAG_ENDCOLOR,
- SC_TAG_BGCOLOUR = SC_TAG_BGCOLOR,
- SC_TAG_CENTRE = SC_TAG_CENTER,
- SC_TAG_ENDCENTRE = SC_TAG_ENDCENTER
+enum {
+ SC_TAG_UNKNOWN = 0, SC_TAG_ITALICS, SC_TAG_ENDITALICS, SC_TAG_BOLD,
+ SC_TAG_ENDBOLD, SC_TAG_UNDERLINE, SC_TAG_ENDUNDERLINE, SC_TAG_COLOR,
+ SC_TAG_ENDCOLOR, SC_TAG_FONT, SC_TAG_ENDFONT, SC_TAG_BGCOLOR, SC_TAG_CENTER,
+ SC_TAG_ENDCENTER, SC_TAG_RIGHT, SC_TAG_ENDRIGHT, SC_TAG_WAIT, SC_TAG_WAITKEY,
+ SC_TAG_CLS,
+
+ /* British spelling equivalents. */
+ SC_TAG_COLOUR = SC_TAG_COLOR,
+ SC_TAG_ENDCOLOUR = SC_TAG_ENDCOLOR,
+ SC_TAG_BGCOLOUR = SC_TAG_BGCOLOR,
+ SC_TAG_CENTRE = SC_TAG_CENTER,
+ SC_TAG_ENDCENTRE = SC_TAG_ENDCENTER
};
/* OS interface function prototypes; interpreters must define these. */
typedef void *sc_game;
-extern void os_print_string (const sc_char *string);
+extern void os_print_string(const sc_char *string);
extern void os_print_tag(sc_int tag, const sc_char *argument);
-extern void os_play_sound (const sc_char *filepath,
- sc_int offset, sc_int length, sc_bool is_looping);
+extern void os_play_sound(const sc_char *filepath,
+ sc_int offset, sc_int length, sc_bool is_looping);
extern void os_stop_sound();
-extern void os_show_graphic (const sc_char *filepath,
- sc_int offset, sc_int length);
+extern void os_show_graphic(const sc_char *filepath,
+ sc_int offset, sc_int length);
extern sc_bool os_read_line(sc_char *buffer, sc_int length);
extern sc_bool os_confirm(sc_int type);
extern void *os_open_file(sc_bool is_save);
-extern void os_write_file (void *opaque, const sc_byte *buffer, sc_int length);
-extern sc_int os_read_file (void *opaque, sc_byte *buffer, sc_int length);
-extern void os_close_file (void *opaque);
+extern void os_write_file(void *opaque, const sc_byte *buffer, sc_int length);
+extern sc_int os_read_file(void *opaque, sc_byte *buffer, sc_int length);
+extern void os_close_file(void *opaque);
extern void os_display_hints(sc_game game);
-extern void os_print_string_debug (const sc_char *string);
+extern void os_print_string_debug(const sc_char *string);
extern sc_bool os_read_line_debug(sc_char *buffer, sc_int length);
/* Interpreter trace flag bits, passed to sc_set_trace_flags(). */
-enum
-{ SC_TRACE_PARSE = 1, SC_TRACE_PROPERTIES = 2, SC_TRACE_VARIABLES = 4,
- SC_TRACE_PARSER = 8, SC_TRACE_LIBRARY = 16, SC_TRACE_EVENTS = 32,
- SC_TRACE_NPCS = 64, SC_TRACE_OBJECTS = 128, SC_TRACE_TASKS = 256,
- SC_TRACE_PRINTFILTER = 512,
-
- SC_DUMP_TAF = 1024, SC_DUMP_PROPERTIES = 2048, SC_DUMP_VARIABLES = 4096,
- SC_DUMP_PARSER_TREES = 8192, SC_DUMP_LOCALE_TABLES = 16384
+enum {
+ SC_TRACE_PARSE = 1, SC_TRACE_PROPERTIES = 2, SC_TRACE_VARIABLES = 4,
+ SC_TRACE_PARSER = 8, SC_TRACE_LIBRARY = 16, SC_TRACE_EVENTS = 32,
+ SC_TRACE_NPCS = 64, SC_TRACE_OBJECTS = 128, SC_TRACE_TASKS = 256,
+ SC_TRACE_PRINTFILTER = 512,
+
+ SC_DUMP_TAF = 1024, SC_DUMP_PROPERTIES = 2048, SC_DUMP_VARIABLES = 4096,
+ SC_DUMP_PARSER_TREES = 8192, SC_DUMP_LOCALE_TABLES = 16384
};
/* Module-wide trace control function prototype. */
extern void sc_set_trace_flags(sc_uint trace_flags);
/* Interpreter interface function prototypes. */
-extern sc_game sc_game_from_filename (const sc_char *filename);
-extern sc_game sc_game_from_stream (Common::SeekableReadStream *stream);
-extern sc_game sc_game_from_callback(sc_int (*callback)
- (void *, sc_byte *, sc_int),
- void *opaque);
+extern sc_game sc_game_from_filename(const sc_char *filename);
+extern sc_game sc_game_from_stream(Common::SeekableReadStream *stream);
+extern sc_game sc_game_from_callback(sc_int(*callback)
+ (void *, sc_byte *, sc_int),
+ void *opaque);
extern void sc_interpret_game(sc_game game);
extern void sc_restart_game(sc_game game);
extern sc_bool sc_save_game(sc_game game);
@@ -120,16 +120,16 @@ extern void sc_quit_game(sc_game game);
extern sc_bool sc_save_game_to_filename(sc_game game, const sc_char *filename);
extern void sc_save_game_to_stream(sc_game game, Common::SeekableReadStream *stream);
extern void sc_save_game_to_callback(sc_game game,
- void (*callback)
- (void *, const sc_byte *, sc_int),
- void *opaque);
+ void (*callback)
+ (void *, const sc_byte *, sc_int),
+ void *opaque);
extern sc_bool sc_load_game_from_filename(sc_game game,
- const sc_char *filename);
+ const sc_char *filename);
extern sc_bool sc_load_game_from_stream(sc_game game, Common::SeekableReadStream *stream);
extern sc_bool sc_load_game_from_callback(sc_game game,
- sc_int (*callback)
- (void *, sc_byte *, sc_int),
- void *opaque);
+ sc_int(*callback)
+ (void *, sc_byte *, sc_int),
+ void *opaque);
extern void sc_free_game(sc_game game);
extern sc_bool sc_is_game_running(sc_game game);
extern const sc_char *sc_get_game_name(sc_game game);
@@ -157,26 +157,26 @@ typedef void *sc_game_hint;
extern sc_game_hint sc_get_first_game_hint(sc_game game);
extern sc_game_hint sc_get_next_game_hint(sc_game game, sc_game_hint hint);
extern const sc_char *sc_get_game_hint_question(sc_game game,
- sc_game_hint hint);
+ sc_game_hint hint);
extern const sc_char *sc_get_game_subtle_hint(sc_game game,
- sc_game_hint hint);
+ sc_game_hint hint);
extern const sc_char *sc_get_game_unsubtle_hint(sc_game game,
- sc_game_hint hint);
+ sc_game_hint hint);
extern void sc_set_game_debugger_enabled(sc_game game, sc_bool flag);
extern sc_bool sc_get_game_debugger_enabled(sc_game game);
extern sc_bool sc_run_game_debugger_command(sc_game game,
- const sc_char *debug_command);
+ const sc_char *debug_command);
extern void sc_set_portable_random(sc_bool flag);
extern void sc_reseed_random_sequence(sc_uint new_seed);
/* Locale control and query functions. */
-extern sc_bool sc_set_locale (const sc_char *name);
+extern sc_bool sc_set_locale(const sc_char *name);
extern const sc_char *sc_get_locale();
/* A few possibly useful utilities. */
-extern sc_int sc_strncasecmp (const sc_char *s1, const sc_char *s2, sc_int n);
-extern sc_int sc_strcasecmp (const sc_char *s1, const sc_char *s2);
+extern sc_int sc_strncasecmp(const sc_char *s1, const sc_char *s2, sc_int n);
+extern sc_int sc_strcasecmp(const sc_char *s1, const sc_char *s2);
extern const sc_char *sc_scare_version();
extern sc_int sc_scare_emulation();
diff --git a/engines/glk/adrift/scdebug.cpp b/engines/glk/adrift/scdebug.cpp
index 3852d16..35900c3 100644
--- a/engines/glk/adrift/scdebug.cpp
+++ b/engines/glk/adrift/scdebug.cpp
@@ -32,19 +32,19 @@ static const sc_uint DEBUG_MAGIC = 0xc4584d2e;
enum { DEBUG_BUFFER_SIZE = 256 };
/* Debugging command and command argument type. */
-typedef enum
-{ DEBUG_NONE = 0, DEBUG_CONTINUE, DEBUG_STEP, DEBUG_BUFFER, DEBUG_RESOURCES,
- DEBUG_HELP, DEBUG_GAME,
- DEBUG_PLAYER, DEBUG_ROOMS, DEBUG_OBJECTS, DEBUG_NPCS, DEBUG_EVENTS,
- DEBUG_TASKS, DEBUG_VARIABLES,
- DEBUG_OLDPLAYER, DEBUG_OLDROOMS, DEBUG_OLDOBJECTS, DEBUG_OLDNPCS,
- DEBUG_OLDEVENTS, DEBUG_OLDTASKS, DEBUG_OLDVARIABLES,
- DEBUG_WATCHPLAYER, DEBUG_WATCHOBJECTS, DEBUG_WATCHNPCS, DEBUG_WATCHEVENTS,
- DEBUG_WATCHTASKS, DEBUG_WATCHVARIABLES,
- DEBUG_CLEARPLAYER, DEBUG_CLEAROBJECTS, DEBUG_CLEARNPCS, DEBUG_CLEAREVENTS,
- DEBUG_CLEARTASKS, DEBUG_CLEARVARIABLES,
- DEBUG_WATCHALL, DEBUG_CLEARALL, DEBUG_RANDOM,
- DEBUG_QUIT
+typedef enum {
+ DEBUG_NONE = 0, DEBUG_CONTINUE, DEBUG_STEP, DEBUG_BUFFER, DEBUG_RESOURCES,
+ DEBUG_HELP, DEBUG_GAME,
+ DEBUG_PLAYER, DEBUG_ROOMS, DEBUG_OBJECTS, DEBUG_NPCS, DEBUG_EVENTS,
+ DEBUG_TASKS, DEBUG_VARIABLES,
+ DEBUG_OLDPLAYER, DEBUG_OLDROOMS, DEBUG_OLDOBJECTS, DEBUG_OLDNPCS,
+ DEBUG_OLDEVENTS, DEBUG_OLDTASKS, DEBUG_OLDVARIABLES,
+ DEBUG_WATCHPLAYER, DEBUG_WATCHOBJECTS, DEBUG_WATCHNPCS, DEBUG_WATCHEVENTS,
+ DEBUG_WATCHTASKS, DEBUG_WATCHVARIABLES,
+ DEBUG_CLEARPLAYER, DEBUG_CLEAROBJECTS, DEBUG_CLEARNPCS, DEBUG_CLEAREVENTS,
+ DEBUG_CLEARTASKS, DEBUG_CLEARVARIABLES,
+ DEBUG_WATCHALL, DEBUG_CLEARALL, DEBUG_RANDOM,
+ DEBUG_QUIT
}
sc_command_t;
@@ -53,30 +53,29 @@ typedef enum
sc_command_type_t;
/* Table connecting debugging command strings to commands. */
-typedef struct
-{
- const sc_char *const command_string;
- const sc_command_t command;
+typedef struct {
+ const sc_char *const command_string;
+ const sc_command_t command;
} sc_strings_t;
static const sc_strings_t DEBUG_COMMANDS[] = {
- {"continue", DEBUG_CONTINUE}, {"step", DEBUG_STEP}, {"buffer", DEBUG_BUFFER},
- {"resources", DEBUG_RESOURCES}, {"help", DEBUG_HELP}, {"game", DEBUG_GAME},
- {"player", DEBUG_PLAYER}, {"rooms", DEBUG_ROOMS}, {"objects", DEBUG_OBJECTS},
- {"npcs", DEBUG_NPCS}, {"events", DEBUG_EVENTS}, {"tasks", DEBUG_TASKS},
- {"variables", DEBUG_VARIABLES},
- {"oldplayer", DEBUG_OLDPLAYER}, {"oldrooms", DEBUG_OLDROOMS},
- {"oldobjects", DEBUG_OLDOBJECTS}, {"oldnpcs", DEBUG_OLDNPCS},
- {"oldevents", DEBUG_OLDEVENTS}, {"oldtasks", DEBUG_OLDTASKS},
- {"oldvariables", DEBUG_OLDVARIABLES},
- {"watchplayer", DEBUG_WATCHPLAYER}, {"clearplayer", DEBUG_CLEARPLAYER},
- {"watchobjects", DEBUG_WATCHOBJECTS}, {"watchnpcs", DEBUG_WATCHNPCS},
- {"watchevents", DEBUG_WATCHEVENTS}, {"watchtasks", DEBUG_WATCHTASKS},
- {"watchvariables", DEBUG_WATCHVARIABLES},
- {"clearobjects", DEBUG_CLEAROBJECTS}, {"clearnpcs", DEBUG_CLEARNPCS},
- {"clearevents", DEBUG_CLEAREVENTS}, {"cleartasks", DEBUG_CLEARTASKS},
- {"clearvariables", DEBUG_CLEARVARIABLES}, {"watchall", DEBUG_WATCHALL},
- {"clearall", DEBUG_CLEARALL}, {"random", DEBUG_RANDOM}, {"quit", DEBUG_QUIT},
- {NULL, DEBUG_NONE}
+ {"continue", DEBUG_CONTINUE}, {"step", DEBUG_STEP}, {"buffer", DEBUG_BUFFER},
+ {"resources", DEBUG_RESOURCES}, {"help", DEBUG_HELP}, {"game", DEBUG_GAME},
+ {"player", DEBUG_PLAYER}, {"rooms", DEBUG_ROOMS}, {"objects", DEBUG_OBJECTS},
+ {"npcs", DEBUG_NPCS}, {"events", DEBUG_EVENTS}, {"tasks", DEBUG_TASKS},
+ {"variables", DEBUG_VARIABLES},
+ {"oldplayer", DEBUG_OLDPLAYER}, {"oldrooms", DEBUG_OLDROOMS},
+ {"oldobjects", DEBUG_OLDOBJECTS}, {"oldnpcs", DEBUG_OLDNPCS},
+ {"oldevents", DEBUG_OLDEVENTS}, {"oldtasks", DEBUG_OLDTASKS},
+ {"oldvariables", DEBUG_OLDVARIABLES},
+ {"watchplayer", DEBUG_WATCHPLAYER}, {"clearplayer", DEBUG_CLEARPLAYER},
+ {"watchobjects", DEBUG_WATCHOBJECTS}, {"watchnpcs", DEBUG_WATCHNPCS},
+ {"watchevents", DEBUG_WATCHEVENTS}, {"watchtasks", DEBUG_WATCHTASKS},
+ {"watchvariables", DEBUG_WATCHVARIABLES},
+ {"clearobjects", DEBUG_CLEAROBJECTS}, {"clearnpcs", DEBUG_CLEARNPCS},
+ {"clearevents", DEBUG_CLEAREVENTS}, {"cleartasks", DEBUG_CLEARTASKS},
+ {"clearvariables", DEBUG_CLEARVARIABLES}, {"watchall", DEBUG_WATCHALL},
+ {"clearall", DEBUG_CLEARALL}, {"random", DEBUG_RANDOM}, {"quit", DEBUG_QUIT},
+ {NULL, DEBUG_NONE}
};
/*
@@ -84,18 +83,17 @@ static const sc_strings_t DEBUG_COMMANDS[] = {
* added to the game on enabling debug, and removed and destroyed on
* disabling debugging.
*/
-typedef struct sc_debugger_s
-{
- sc_uint magic;
- sc_bool *watch_objects;
- sc_bool *watch_npcs;
- sc_bool *watch_events;
- sc_bool *watch_tasks;
- sc_bool *watch_variables;
- sc_bool watch_player;
- sc_bool single_step;
- sc_bool quit_pending;
- sc_uint elapsed_seconds;
+typedef struct sc_debugger_s {
+ sc_uint magic;
+ sc_bool *watch_objects;
+ sc_bool *watch_npcs;
+ sc_bool *watch_events;
+ sc_bool *watch_tasks;
+ sc_bool *watch_variables;
+ sc_bool watch_player;
+ sc_bool single_step;
+ sc_bool quit_pending;
+ sc_uint elapsed_seconds;
} sc_debugger_t;
@@ -105,9 +103,8 @@ typedef struct sc_debugger_s
* Return TRUE if pointer is a valid debugger, FALSE otherwise.
*/
static sc_bool
-debug_is_valid (sc_debuggerref_t debug)
-{
- return debug && debug->magic == DEBUG_MAGIC;
+debug_is_valid(sc_debuggerref_t debug) {
+ return debug && debug->magic == DEBUG_MAGIC;
}
@@ -117,11 +114,10 @@ debug_is_valid (sc_debuggerref_t debug)
* Return the debugger reference from a game, or NULL if none.
*/
static sc_debuggerref_t
-debug_get_debugger (sc_gameref_t game)
-{
- assert (gs_is_game_valid (game));
+debug_get_debugger(sc_gameref_t game) {
+ assert(gs_is_game_valid(game));
- return game->debugger;
+ return game->debugger;
}
@@ -131,17 +127,16 @@ debug_get_debugger (sc_gameref_t game)
* Common helper to return the count of variables defined in a game.
*/
static sc_int
-debug_variable_count (sc_gameref_t game)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key;
- sc_int variable_count;
+debug_variable_count(sc_gameref_t game) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key;
+ sc_int variable_count;
- /* Find and return the variables count. */
- vt_key.string = "Variables";
- variable_count = prop_get_child_count (bundle, "I<-s", &vt_key);
+ /* Find and return the variables count. */
+ vt_key.string = "Variables";
+ variable_count = prop_get_child_count(bundle, "I<-s", &vt_key);
- return variable_count;
+ return variable_count;
}
@@ -152,45 +147,44 @@ debug_variable_count (sc_gameref_t game)
* game passed in.
*/
static void
-debug_initialize (sc_gameref_t game)
-{
- sc_debuggerref_t debug;
-
- /* Create the easy bits of the new debugging set. */
- debug = (sc_debuggerref_t)sc_malloc (sizeof (*debug));
- debug->magic = DEBUG_MAGIC;
- debug->watch_player = FALSE;
- debug->single_step = FALSE;
- debug->quit_pending = FALSE;
- debug->elapsed_seconds = 0;
-
- /* Allocate watchpoints for everything we can watch. */
- debug->watch_objects = (sc_bool *)sc_malloc (gs_object_count (game)
- * sizeof (*debug->watch_objects));
- debug->watch_npcs = (sc_bool *)sc_malloc (gs_npc_count (game)
- * sizeof (*debug->watch_npcs));
- debug->watch_events = (sc_bool *)sc_malloc (gs_event_count (game)
- * sizeof (*debug->watch_events));
- debug->watch_tasks = (sc_bool *)sc_malloc (gs_task_count (game)
- * sizeof (*debug->watch_tasks));
- debug->watch_variables = (sc_bool *)sc_malloc (debug_variable_count (game)
- * sizeof (*debug->watch_variables));
-
- /* Clear all watchpoint arrays. */
- memset (debug->watch_objects, FALSE,
- gs_object_count (game) * sizeof (*debug->watch_objects));
- memset (debug->watch_npcs, FALSE,
- gs_npc_count (game) * sizeof (*debug->watch_npcs));
- memset (debug->watch_events, FALSE,
- gs_event_count (game) * sizeof (*debug->watch_events));
- memset (debug->watch_tasks, FALSE,
- gs_task_count (game) * sizeof (*debug->watch_tasks));
- memset (debug->watch_variables, FALSE,
- debug_variable_count (game) * sizeof (*debug->watch_variables));
-
- /* Append the new debugger set to the game. */
- assert (!game->debugger);
- game->debugger = debug;
+debug_initialize(sc_gameref_t game) {
+ sc_debuggerref_t debug;
+
+ /* Create the easy bits of the new debugging set. */
+ debug = (sc_debuggerref_t)sc_malloc(sizeof(*debug));
+ debug->magic = DEBUG_MAGIC;
+ debug->watch_player = FALSE;
+ debug->single_step = FALSE;
+ debug->quit_pending = FALSE;
+ debug->elapsed_seconds = 0;
+
+ /* Allocate watchpoints for everything we can watch. */
+ debug->watch_objects = (sc_bool *)sc_malloc(gs_object_count(game)
+ * sizeof(*debug->watch_objects));
+ debug->watch_npcs = (sc_bool *)sc_malloc(gs_npc_count(game)
+ * sizeof(*debug->watch_npcs));
+ debug->watch_events = (sc_bool *)sc_malloc(gs_event_count(game)
+ * sizeof(*debug->watch_events));
+ debug->watch_tasks = (sc_bool *)sc_malloc(gs_task_count(game)
+ * sizeof(*debug->watch_tasks));
+ debug->watch_variables = (sc_bool *)sc_malloc(debug_variable_count(game)
+ * sizeof(*debug->watch_variables));
+
+ /* Clear all watchpoint arrays. */
+ memset(debug->watch_objects, FALSE,
+ gs_object_count(game) * sizeof(*debug->watch_objects));
+ memset(debug->watch_npcs, FALSE,
+ gs_npc_count(game) * sizeof(*debug->watch_npcs));
+ memset(debug->watch_events, FALSE,
+ gs_event_count(game) * sizeof(*debug->watch_events));
+ memset(debug->watch_tasks, FALSE,
+ gs_task_count(game) * sizeof(*debug->watch_tasks));
+ memset(debug->watch_variables, FALSE,
+ debug_variable_count(game) * sizeof(*debug->watch_variables));
+
+ /* Append the new debugger set to the game. */
+ assert(!game->debugger);
+ game->debugger = debug;
}
@@ -201,24 +195,23 @@ debug_initialize (sc_gameref_t game)
* from the game.
*/
static void
-debug_finalize (sc_gameref_t game)
-{
- sc_debuggerref_t debug = debug_get_debugger (game);
- assert (debug_is_valid (debug));
-
- /* Free all allocated watchpoint arrays. */
- sc_free (debug->watch_objects);
- sc_free (debug->watch_npcs);
- sc_free (debug->watch_events);
- sc_free (debug->watch_tasks);
- sc_free (debug->watch_variables);
-
- /* Poison and free the debugger itself. */
- memset (debug, 0xaa, sizeof (*debug));
- sc_free (debug);
-
- /* Remove the debug reference from the game. */
- game->debugger = NULL;
+debug_finalize(sc_gameref_t game) {
+ sc_debuggerref_t debug = debug_get_debugger(game);
+ assert(debug_is_valid(debug));
+
+ /* Free all allocated watchpoint arrays. */
+ sc_free(debug->watch_objects);
+ sc_free(debug->watch_npcs);
+ sc_free(debug->watch_events);
+ sc_free(debug->watch_tasks);
+ sc_free(debug->watch_variables);
+
+ /* Poison and free the debugger itself. */
+ memset(debug, 0xaa, sizeof(*debug));
+ sc_free(debug);
+
+ /* Remove the debug reference from the game. */
+ game->debugger = NULL;
}
@@ -228,312 +221,309 @@ debug_finalize (sc_gameref_t game)
* Print debugging help.
*/
static void
-debug_help (sc_command_t topic)
-{
- /* Is help general, or specific? */
- if (topic == DEBUG_NONE)
- {
- if_print_debug (
- "The following debugging commands examine game state:\n\n");
- if_print_debug (
- " game -- Print general game information,"
- " and class counts\n"
- " player -- Show the player location and position\n"
- " rooms [Range] -- Print information on game rooms\n"
- " objects [Range] -- Print information on objects in the game\n"
- " npcs [Range] -- Print information on game NPCs\n"
- " events [Range] -- Print information on the game's events\n"
- " tasks [Range] -- Print information on the game's tasks\n"
- " variables [Range] -- Show variables defined by the game\n\n");
- if_print_debug (
- "Most commands take range inputs. This can be a single number, to"
- " apply the command to just that item, a range such as '0 to 10' (or"
- " '0 - 10', '0 .. 10', or simply '0 10') to apply to that range of"
- " items, or '*' to apply the command to all items of the class. If"
- " omitted, the command is applied only to the items of the class"
- " 'relevant' to the current game state; see the help for specific"
- " commands for more on what is 'relevant'.\n\n");
- if_print_debug (
- "The 'player', 'objects', 'npcs', 'events', 'tasks', and 'variables'"
- " commands may be prefixed with 'old', in which case the values"
- " printed will be those for the previous game turn, rather than the"
- " current values.\n\n");
- if_print_debug (
- "These debugging commands manage watchpoints:\n\n");
- if_print_debug (
- "The 'player', 'objects', 'npcs', 'events', 'tasks', and 'variables'"
- " commands may be prefixed with 'watch', to set watchpoints."
- " Watchpoints automatically enter the debugger when the item changes"
- " state during a game turn. For example 'watchobject 10' monitors"
- " object 10 for changes, and 'watchnpc *' monitors all NPCs. A"
- " 'watch' command with no range prints out all watchpoints set for"
- " that class.\n\n");
- if_print_debug (
- "Prefix commands with 'clear' to clear watchpoints, for example"
- " 'clearnpcs *'. Use 'watchall' to obtain a complete list of every"
- " watchpoint set, and 'clearall' to clear all watchpoints in one go."
- " A 'clear' command with no range behaves the same as a 'watch'"
- " command with no range.\n\n");
- if_print_debug (
- "These debugging commands print details of game output and control the"
- " debugger and interpreter:\n\n");
- if_print_debug (
- " buffer -- Show the current buffered game text\n"
- " resources -- Show current and requested game resources\n"
- " random [Seed] -- Control the random number generator\n"
- " step -- Run one game turn, then re-enter the debugger\n"
- " continue -- Leave the debugger and resume the game\n"
- " quit -- Exit the interpreter main loop\n"
- " help [Command] -- Print help specific to Command\n\n");
- if_print_debug (
- "Debugging commands may be abbreviated to their shortest unambiguous"
- " form.\n\n");
- if_print_debug (
- "Use the 'debug' or '#debug' command in a game, typed at the usual"
- " game prompt, to return to the debugger.\n");
- return;
- }
-
- /* Command-specific help. */
- switch (topic)
- {
- case DEBUG_HELP:
- if_print_debug (
- "Give the name of the command you want help on, for example 'help"
- " continue'.\n");
- break;
-
- case DEBUG_CONTINUE:
- if_print_debug (
- "Leave the debugger and resume the game. Use the 'debug' or '#debug'"
- " command in a game, typed at the usual game prompt, to return to the"
- " debugger.\n");
- break;
-
- case DEBUG_STEP:
- if_print_debug (
- "Run one game turn, then re-enter the debugger. Useful for games that"
- " intercept empty input lines, which otherwise catch the 'debug'"
- " command before SCARE can get to it.\n");
- break;
-
- case DEBUG_QUIT:
- if_print_debug (
- "Exit the interpreter main loop. Equivalent to a confirmed 'quit'"
- " from within the game itself, this ends the interpreter session.\n");
- break;
-
- case DEBUG_BUFFER:
- if_print_debug (
- "Print the current text that the game has buffered for output. The"
- " debugger catches games before they have printed their turn output"
- " -- this is the text that will be filtered and printed on exiting the"
- " debugger.\n");
- break;
-
- case DEBUG_RESOURCES:
- if_print_debug (
- "Print any resources currently active, and any requested by the game"
- " on the current turn. The requested resources will become the active"
- " ones on exiting the debugger.\n");
- break;
-
- case DEBUG_RANDOM:
- if_print_debug (
- "If no seed is given, report the current random number generator"
- " setting. Otherwise, seed the random number generator with the value"
- " given. This is useful for persuading games with random sections to"
- " behave predictably. A new seed value of zero is invalid.\n");
- break;
-
- case DEBUG_GAME:
- if_print_debug (
- "Print general game information, including the number of rooms,"
- " objects, events, tasks, and variables that the game defines\n");
- break;
-
- case DEBUG_PLAYER:
- if_print_debug (
- "Print out the current player room and position, and any parent object"
- " of the player character.\n");
- break;
-
- case DEBUG_OLDPLAYER:
- if_print_debug (
- "Print out the player room and position from the previous turn, and"
- " any parent object of the player character.\n");
- break;
-
- case DEBUG_ROOMS:
- if_print_debug (
- "Print out the name and contents of rooms in the range. If no range,"
- " print details of the room containing the player.\n");
- break;
-
- case DEBUG_OLDROOMS:
- if_print_debug (
- "Print out the name and contents of rooms in the range for the"
- " previous turn. If no range, print details of the room that"
- " contained the player on the previous turn.\n");
- break;
-
- case DEBUG_OBJECTS:
- if_print_debug (
- "Print out details of all objects in the range. If no range, print"
- " details of objects in the room containing the player, and visible to"
- " the player.\n");
- break;
-
- case DEBUG_OLDOBJECTS:
- if_print_debug (
- "Print out details of all objects in the range for the previous turn."
- " If no range, print details of objects in the room that contained"
- " the player, and were visible to the player.\n");
- break;
-
- case DEBUG_NPCS:
- if_print_debug (
- "Print out details of all NPCs in the range. If no range, print"
- " details of only NPCs in the room containing the player.\n");
- break;
-
- case DEBUG_OLDNPCS:
- if_print_debug (
- "Print out details of all NPCs in the range for the previous turn."
- " If no range, print details of only NPCs in the room that contained"
- " the player.\n");
- break;
-
- case DEBUG_EVENTS:
- if_print_debug (
- "Print out details of all events in the range. If no range, print"
- " details of only events currently running.\n");
- break;
-
- case DEBUG_OLDEVENTS:
- if_print_debug (
- "Print out details of all events in the range for the previous turn."
- " If no range, print details of only events running on the previous"
- " turn.\n");
- break;
-
- case DEBUG_TASKS:
- if_print_debug (
- "Print out details of all tasks in the range. If no range, print"
- " details of only tasks that are runnable, for the current state of"
- " the game.\n");
- break;
-
- case DEBUG_OLDTASKS:
- if_print_debug (
- "Print out details of all tasks in the range for the previous turn."
- " If no range, print details of only tasks that were runnable, for"
- " the previous state of the game.\n");
- break;
-
- case DEBUG_VARIABLES:
- if_print_debug (
- "Print out the names, types, and values of all game variables in the"
- " range. If no range, print details of all variables (equivalent to"
- " 'variables *').\n");
- break;
-
- case DEBUG_OLDVARIABLES:
- if_print_debug (
- "Print out the names, types, and values at the previous turn of all"
- " game variables in the range. If no range, print details of all"
- " variables (equivalent to 'variables *').\n");
- break;
-
- case DEBUG_WATCHPLAYER:
- if_print_debug (
- "If no range is given, list any watchpoint on player movement. If"
- " range '0' is given, set a watchpoint on player movement. Other"
- " usages of 'watchplayer' behave as if no range is given.\n");
- break;
-
- case DEBUG_WATCHOBJECTS:
- if_print_debug (
- "Set watchpoints on all objects in the range. If no range, list out"
- " object watchpoints currently set.\n");
- break;
-
- case DEBUG_WATCHNPCS:
- if_print_debug (
- "Set watchpoints on all NPCs in the range. If no range, list out NPC"
- " watchpoints currently set.\n");
- break;
-
- case DEBUG_WATCHEVENTS:
- if_print_debug (
- "Set watchpoints on all events in the range. If no range, list out"
- " event watchpoints currently set.\n");
- break;
-
- case DEBUG_WATCHTASKS:
- if_print_debug (
- "Set watchpoints on all tasks in the range. If no range, list out"
- " task watchpoints currently set.\n");
- break;
-
- case DEBUG_WATCHVARIABLES:
- if_print_debug (
- "Set watchpoints on all game variables in the range. If no range,"
- " list variable watchpoints currently set.\n");
- break;
-
- case DEBUG_CLEARPLAYER:
- if_print_debug (
- "Clear any watchpoint set on player movements.\n");
- break;
-
- case DEBUG_CLEAROBJECTS:
- if_print_debug (
- "Clear watchpoints on all objects in the range. If no range, list"
- " out object watchpoints currently set.\n");
- break;
-
- case DEBUG_CLEARNPCS:
- if_print_debug (
- "Clear watchpoints on all NPCs in the range. If no range, list out"
- " NPC watchpoints currently set.\n");
- break;
-
- case DEBUG_CLEAREVENTS:
- if_print_debug (
- "Clear watchpoints on all events in the range. If no range, list out"
- " event watchpoints currently set.\n");
- break;
-
- case DEBUG_CLEARTASKS:
- if_print_debug (
- "Clear watchpoints on all tasks in the range. If no range, list out"
- " task watchpoints currently set.\n");
- break;
-
- case DEBUG_CLEARVARIABLES:
- if_print_debug (
- "Clear watchpoints on all game variables in the range. If no range,"
- " list variable watchpoints currently set.\n");
- break;
-
- case DEBUG_WATCHALL:
- if_print_debug (
- "Print out a list of all all watchpoints set for all the classes of"
- " item on which watchpoints can be used.\n");
- break;
-
- case DEBUG_CLEARALL:
- if_print_debug (
- "Clear all watchpoints set, on all classes of item on which"
- " watchpoints can be used.\n");
- break;
-
- default:
- if_print_debug (
- "Sorry, there is no help available on that at the moment.\n");
- break;
- }
+debug_help(sc_command_t topic) {
+ /* Is help general, or specific? */
+ if (topic == DEBUG_NONE) {
+ if_print_debug(
+ "The following debugging commands examine game state:\n\n");
+ if_print_debug(
+ " game -- Print general game information,"
+ " and class counts\n"
+ " player -- Show the player location and position\n"
+ " rooms [Range] -- Print information on game rooms\n"
+ " objects [Range] -- Print information on objects in the game\n"
+ " npcs [Range] -- Print information on game NPCs\n"
+ " events [Range] -- Print information on the game's events\n"
+ " tasks [Range] -- Print information on the game's tasks\n"
+ " variables [Range] -- Show variables defined by the game\n\n");
+ if_print_debug(
+ "Most commands take range inputs. This can be a single number, to"
+ " apply the command to just that item, a range such as '0 to 10' (or"
+ " '0 - 10', '0 .. 10', or simply '0 10') to apply to that range of"
+ " items, or '*' to apply the command to all items of the class. If"
+ " omitted, the command is applied only to the items of the class"
+ " 'relevant' to the current game state; see the help for specific"
+ " commands for more on what is 'relevant'.\n\n");
+ if_print_debug(
+ "The 'player', 'objects', 'npcs', 'events', 'tasks', and 'variables'"
+ " commands may be prefixed with 'old', in which case the values"
+ " printed will be those for the previous game turn, rather than the"
+ " current values.\n\n");
+ if_print_debug(
+ "These debugging commands manage watchpoints:\n\n");
+ if_print_debug(
+ "The 'player', 'objects', 'npcs', 'events', 'tasks', and 'variables'"
+ " commands may be prefixed with 'watch', to set watchpoints."
+ " Watchpoints automatically enter the debugger when the item changes"
+ " state during a game turn. For example 'watchobject 10' monitors"
+ " object 10 for changes, and 'watchnpc *' monitors all NPCs. A"
+ " 'watch' command with no range prints out all watchpoints set for"
+ " that class.\n\n");
+ if_print_debug(
+ "Prefix commands with 'clear' to clear watchpoints, for example"
+ " 'clearnpcs *'. Use 'watchall' to obtain a complete list of every"
+ " watchpoint set, and 'clearall' to clear all watchpoints in one go."
+ " A 'clear' command with no range behaves the same as a 'watch'"
+ " command with no range.\n\n");
+ if_print_debug(
+ "These debugging commands print details of game output and control the"
+ " debugger and interpreter:\n\n");
+ if_print_debug(
+ " buffer -- Show the current buffered game text\n"
+ " resources -- Show current and requested game resources\n"
+ " random [Seed] -- Control the random number generator\n"
+ " step -- Run one game turn, then re-enter the debugger\n"
+ " continue -- Leave the debugger and resume the game\n"
+ " quit -- Exit the interpreter main loop\n"
+ " help [Command] -- Print help specific to Command\n\n");
+ if_print_debug(
+ "Debugging commands may be abbreviated to their shortest unambiguous"
+ " form.\n\n");
+ if_print_debug(
+ "Use the 'debug' or '#debug' command in a game, typed at the usual"
+ " game prompt, to return to the debugger.\n");
+ return;
+ }
+
+ /* Command-specific help. */
+ switch (topic) {
+ case DEBUG_HELP:
+ if_print_debug(
+ "Give the name of the command you want help on, for example 'help"
+ " continue'.\n");
+ break;
+
+ case DEBUG_CONTINUE:
+ if_print_debug(
+ "Leave the debugger and resume the game. Use the 'debug' or '#debug'"
+ " command in a game, typed at the usual game prompt, to return to the"
+ " debugger.\n");
+ break;
+
+ case DEBUG_STEP:
+ if_print_debug(
+ "Run one game turn, then re-enter the debugger. Useful for games that"
+ " intercept empty input lines, which otherwise catch the 'debug'"
+ " command before SCARE can get to it.\n");
+ break;
+
+ case DEBUG_QUIT:
+ if_print_debug(
+ "Exit the interpreter main loop. Equivalent to a confirmed 'quit'"
+ " from within the game itself, this ends the interpreter session.\n");
+ break;
+
+ case DEBUG_BUFFER:
+ if_print_debug(
+ "Print the current text that the game has buffered for output. The"
+ " debugger catches games before they have printed their turn output"
+ " -- this is the text that will be filtered and printed on exiting the"
+ " debugger.\n");
+ break;
+
+ case DEBUG_RESOURCES:
+ if_print_debug(
+ "Print any resources currently active, and any requested by the game"
+ " on the current turn. The requested resources will become the active"
+ " ones on exiting the debugger.\n");
+ break;
+
+ case DEBUG_RANDOM:
+ if_print_debug(
+ "If no seed is given, report the current random number generator"
+ " setting. Otherwise, seed the random number generator with the value"
+ " given. This is useful for persuading games with random sections to"
+ " behave predictably. A new seed value of zero is invalid.\n");
+ break;
+
+ case DEBUG_GAME:
+ if_print_debug(
+ "Print general game information, including the number of rooms,"
+ " objects, events, tasks, and variables that the game defines\n");
+ break;
+
+ case DEBUG_PLAYER:
+ if_print_debug(
+ "Print out the current player room and position, and any parent object"
+ " of the player character.\n");
+ break;
+
+ case DEBUG_OLDPLAYER:
+ if_print_debug(
+ "Print out the player room and position from the previous turn, and"
+ " any parent object of the player character.\n");
+ break;
+
+ case DEBUG_ROOMS:
+ if_print_debug(
+ "Print out the name and contents of rooms in the range. If no range,"
+ " print details of the room containing the player.\n");
+ break;
+
+ case DEBUG_OLDROOMS:
+ if_print_debug(
+ "Print out the name and contents of rooms in the range for the"
+ " previous turn. If no range, print details of the room that"
+ " contained the player on the previous turn.\n");
+ break;
+
+ case DEBUG_OBJECTS:
+ if_print_debug(
+ "Print out details of all objects in the range. If no range, print"
+ " details of objects in the room containing the player, and visible to"
+ " the player.\n");
+ break;
+
+ case DEBUG_OLDOBJECTS:
+ if_print_debug(
+ "Print out details of all objects in the range for the previous turn."
+ " If no range, print details of objects in the room that contained"
+ " the player, and were visible to the player.\n");
+ break;
+
+ case DEBUG_NPCS:
+ if_print_debug(
+ "Print out details of all NPCs in the range. If no range, print"
+ " details of only NPCs in the room containing the player.\n");
+ break;
+
+ case DEBUG_OLDNPCS:
+ if_print_debug(
+ "Print out details of all NPCs in the range for the previous turn."
+ " If no range, print details of only NPCs in the room that contained"
+ " the player.\n");
+ break;
+
+ case DEBUG_EVENTS:
+ if_print_debug(
+ "Print out details of all events in the range. If no range, print"
+ " details of only events currently running.\n");
+ break;
+
+ case DEBUG_OLDEVENTS:
+ if_print_debug(
+ "Print out details of all events in the range for the previous turn."
+ " If no range, print details of only events running on the previous"
+ " turn.\n");
+ break;
+
+ case DEBUG_TASKS:
+ if_print_debug(
+ "Print out details of all tasks in the range. If no range, print"
+ " details of only tasks that are runnable, for the current state of"
+ " the game.\n");
+ break;
+
+ case DEBUG_OLDTASKS:
+ if_print_debug(
+ "Print out details of all tasks in the range for the previous turn."
+ " If no range, print details of only tasks that were runnable, for"
+ " the previous state of the game.\n");
+ break;
+
+ case DEBUG_VARIABLES:
+ if_print_debug(
+ "Print out the names, types, and values of all game variables in the"
+ " range. If no range, print details of all variables (equivalent to"
+ " 'variables *').\n");
+ break;
+
+ case DEBUG_OLDVARIABLES:
+ if_print_debug(
+ "Print out the names, types, and values at the previous turn of all"
+ " game variables in the range. If no range, print details of all"
+ " variables (equivalent to 'variables *').\n");
+ break;
+
+ case DEBUG_WATCHPLAYER:
+ if_print_debug(
+ "If no range is given, list any watchpoint on player movement. If"
+ " range '0' is given, set a watchpoint on player movement. Other"
+ " usages of 'watchplayer' behave as if no range is given.\n");
+ break;
+
+ case DEBUG_WATCHOBJECTS:
+ if_print_debug(
+ "Set watchpoints on all objects in the range. If no range, list out"
+ " object watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHNPCS:
+ if_print_debug(
+ "Set watchpoints on all NPCs in the range. If no range, list out NPC"
+ " watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHEVENTS:
+ if_print_debug(
+ "Set watchpoints on all events in the range. If no range, list out"
+ " event watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHTASKS:
+ if_print_debug(
+ "Set watchpoints on all tasks in the range. If no range, list out"
+ " task watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHVARIABLES:
+ if_print_debug(
+ "Set watchpoints on all game variables in the range. If no range,"
+ " list variable watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARPLAYER:
+ if_print_debug(
+ "Clear any watchpoint set on player movements.\n");
+ break;
+
+ case DEBUG_CLEAROBJECTS:
+ if_print_debug(
+ "Clear watchpoints on all objects in the range. If no range, list"
+ " out object watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARNPCS:
+ if_print_debug(
+ "Clear watchpoints on all NPCs in the range. If no range, list out"
+ " NPC watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEAREVENTS:
+ if_print_debug(
+ "Clear watchpoints on all events in the range. If no range, list out"
+ " event watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARTASKS:
+ if_print_debug(
+ "Clear watchpoints on all tasks in the range. If no range, list out"
+ " task watchpoints currently set.\n");
+ break;
+
+ case DEBUG_CLEARVARIABLES:
+ if_print_debug(
+ "Clear watchpoints on all game variables in the range. If no range,"
+ " list variable watchpoints currently set.\n");
+ break;
+
+ case DEBUG_WATCHALL:
+ if_print_debug(
+ "Print out a list of all all watchpoints set for all the classes of"
+ " item on which watchpoints can be used.\n");
+ break;
+
+ case DEBUG_CLEARALL:
+ if_print_debug(
+ "Clear all watchpoints set, on all classes of item on which"
+ " watchpoints can be used.\n");
+ break;
+
+ default:
+ if_print_debug(
+ "Sorry, there is no help available on that at the moment.\n");
+ break;
+ }
}
@@ -550,217 +540,200 @@ debug_help (sc_command_t topic)
* Low level output helpers.
*/
static void
-debug_print_quoted (const sc_char *string)
-{
- if_print_debug_character ('"');
- if_print_debug (string);
- if_print_debug_character ('"');
+debug_print_quoted(const sc_char *string) {
+ if_print_debug_character('"');
+ if_print_debug(string);
+ if_print_debug_character('"');
}
static void
-debug_print_player (sc_gameref_t game)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[2];
- const sc_char *playername;
-
- vt_key[0].string = "Globals";
- vt_key[1].string = "PlayerName";
- playername = prop_get_string (bundle, "S<-ss", vt_key);
- if_print_debug ("Player ");
- debug_print_quoted (playername);
+debug_print_player(sc_gameref_t game) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[2];
+ const sc_char *playername;
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "PlayerName";
+ playername = prop_get_string(bundle, "S<-ss", vt_key);
+ if_print_debug("Player ");
+ debug_print_quoted(playername);
}
static void
-debug_print_room (sc_gameref_t game, sc_int room)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_char buffer[32];
- const sc_char *name;
-
- if_print_debug ("Room ");
- if (room < 0 || room >= gs_room_count (game))
- {
- sprintf (buffer, "%ld ", room);
- if_print_debug (buffer);
- if_print_debug ("[Out of range]");
- return;
- }
-
- vt_key[0].string = "Rooms";
- vt_key[1].integer = room;
- vt_key[2].string = "Short";
- name = prop_get_string (bundle, "S<-sis", vt_key);
- sprintf (buffer, "%ld ", room);
- if_print_debug (buffer);
- debug_print_quoted (name);
+debug_print_room(sc_gameref_t game, sc_int room) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_char buffer[32];
+ const sc_char *name;
+
+ if_print_debug("Room ");
+ if (room < 0 || room >= gs_room_count(game)) {
+ sprintf(buffer, "%ld ", room);
+ if_print_debug(buffer);
+ if_print_debug("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Rooms";
+ vt_key[1].integer = room;
+ vt_key[2].string = "Short";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+ sprintf(buffer, "%ld ", room);
+ if_print_debug(buffer);
+ debug_print_quoted(name);
}
static void
-debug_print_object (sc_gameref_t game, sc_int object)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_bool bstatic;
- sc_char buffer[32];
- const sc_char *prefix, *name;
-
- if (object < 0 || object >= gs_object_count (game))
- {
- if_print_debug ("Object ");
- sprintf (buffer, "%ld ", object);
- if_print_debug (buffer);
- if_print_debug ("[Out of range]");
- return;
- }
-
- vt_key[0].string = "Objects";
- vt_key[1].integer = object;
- vt_key[2].string = "Static";
- bstatic = prop_get_boolean (bundle, "B<-sis", vt_key);
- vt_key[2].string = "Prefix";
- prefix = prop_get_string (bundle, "S<-sis", vt_key);
- vt_key[2].string = "Short";
- name = prop_get_string (bundle, "S<-sis", vt_key);
- if (bstatic)
- if_print_debug ("Static ");
- else
- if_print_debug ("Dynamic ");
- sprintf (buffer, "%ld ", object);
- if_print_debug (buffer);
- debug_print_quoted (prefix);
- if_print_debug_character (' ');
- debug_print_quoted (name);
+debug_print_object(sc_gameref_t game, sc_int object) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_bool bstatic;
+ sc_char buffer[32];
+ const sc_char *prefix, *name;
+
+ if (object < 0 || object >= gs_object_count(game)) {
+ if_print_debug("Object ");
+ sprintf(buffer, "%ld ", object);
+ if_print_debug(buffer);
+ if_print_debug("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ bstatic = prop_get_boolean(bundle, "B<-sis", vt_key);
+ vt_key[2].string = "Prefix";
+ prefix = prop_get_string(bundle, "S<-sis", vt_key);
+ vt_key[2].string = "Short";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+ if (bstatic)
+ if_print_debug("Static ");
+ else
+ if_print_debug("Dynamic ");
+ sprintf(buffer, "%ld ", object);
+ if_print_debug(buffer);
+ debug_print_quoted(prefix);
+ if_print_debug_character(' ');
+ debug_print_quoted(name);
}
static void
-debug_print_npc (sc_gameref_t game, sc_int npc)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_char buffer[32];
- const sc_char *prefix, *name;
-
- if_print_debug ("NPC ");
- if (npc < 0 || npc >= gs_npc_count (game))
- {
- sprintf (buffer, "%ld ", npc);
- if_print_debug (buffer);
- if_print_debug ("[Out of range]");
- return;
- }
-
- vt_key[0].string = "NPCs";
- vt_key[1].integer = npc;
- vt_key[2].string = "Prefix";
- prefix = prop_get_string (bundle, "S<-sis", vt_key);
- vt_key[2].string = "Name";
- name = prop_get_string (bundle, "S<-sis", vt_key);
- sprintf (buffer, "%ld ", npc);
- if_print_debug (buffer);
- debug_print_quoted (prefix);
- if_print_debug_character (' ');
- debug_print_quoted (name);
+debug_print_npc(sc_gameref_t game, sc_int npc) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_char buffer[32];
+ const sc_char *prefix, *name;
+
+ if_print_debug("NPC ");
+ if (npc < 0 || npc >= gs_npc_count(game)) {
+ sprintf(buffer, "%ld ", npc);
+ if_print_debug(buffer);
+ if_print_debug("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "NPCs";
+ vt_key[1].integer = npc;
+ vt_key[2].string = "Prefix";
+ prefix = prop_get_string(bundle, "S<-sis", vt_key);
+ vt_key[2].string = "Name";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+ sprintf(buffer, "%ld ", npc);
+ if_print_debug(buffer);
+ debug_print_quoted(prefix);
+ if_print_debug_character(' ');
+ debug_print_quoted(name);
}
static void
-debug_print_event (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_char buffer[32];
- const sc_char *name;
-
- if_print_debug ("Event ");
- if (event < 0 || event >= gs_event_count (game))
- {
- sprintf (buffer, "%ld ", event);
- if_print_debug (buffer);
- if_print_debug ("[Out of range]");
- return;
- }
-
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "Short";
- name = prop_get_string (bundle, "S<-sis", vt_key);
- sprintf (buffer, "%ld ", event);
- if_print_debug (buffer);
- debug_print_quoted (name);
+debug_print_event(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_char buffer[32];
+ const sc_char *name;
+
+ if_print_debug("Event ");
+ if (event < 0 || event >= gs_event_count(game)) {
+ sprintf(buffer, "%ld ", event);
+ if_print_debug(buffer);
+ if_print_debug("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Short";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+ sprintf(buffer, "%ld ", event);
+ if_print_debug(buffer);
+ debug_print_quoted(name);
}
static void
-debug_print_task (sc_gameref_t game, sc_int task)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[4];
- sc_char buffer[32];
- const sc_char *command;
-
- if_print_debug ("Task ");
- if (task < 0 || task >= gs_task_count (game))
- {
- sprintf (buffer, "%ld ", task);
- if_print_debug (buffer);
- if_print_debug ("[Out of range]");
- return;
- }
-
- vt_key[0].string = "Tasks";
- vt_key[1].integer = task;
- vt_key[2].string = "Command";
- vt_key[3].integer = 0;
- command = prop_get_string (bundle, "S<-sisi", vt_key);
- sprintf (buffer, "%ld ", task);
- if_print_debug (buffer);
- debug_print_quoted (command);
+debug_print_task(sc_gameref_t game, sc_int task) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[4];
+ sc_char buffer[32];
+ const sc_char *command;
+
+ if_print_debug("Task ");
+ if (task < 0 || task >= gs_task_count(game)) {
+ sprintf(buffer, "%ld ", task);
+ if_print_debug(buffer);
+ if_print_debug("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Tasks";
+ vt_key[1].integer = task;
+ vt_key[2].string = "Command";
+ vt_key[3].integer = 0;
+ command = prop_get_string(bundle, "S<-sisi", vt_key);
+ sprintf(buffer, "%ld ", task);
+ if_print_debug(buffer);
+ debug_print_quoted(command);
}
static void
-debug_print_variable (sc_gameref_t game, sc_int variable)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- const sc_var_setref_t vars = gs_get_vars (game);
- sc_vartype_t vt_key[3], vt_rvalue;
- sc_char buffer[32];
- sc_int var_type;
- const sc_char *name;
-
- if (variable < 0 || variable >= debug_variable_count (game))
- {
- if_print_debug ("Variable ");
- sprintf (buffer, "%ld ", variable);
- if_print_debug (buffer);
- if_print_debug ("[Out of range]");
- return;
- }
-
- vt_key[0].string = "Variables";
- vt_key[1].integer = variable;
- vt_key[2].string = "Name";
- name = prop_get_string (bundle, "S<-sis", vt_key);
-
- if (var_get (vars, name, &var_type, &vt_rvalue))
- {
- switch (var_type)
- {
- case VAR_INTEGER:
- if_print_debug ("Integer ");
- break;
- case VAR_STRING:
- if_print_debug ("String ");
- break;
- default:
- if_print_debug ("[Invalid type] ");
- break;
- }
- }
- else
- if_print_debug ("[Invalid variable] ");
- sprintf (buffer, "%ld ", variable);
- if_print_debug (buffer);
- debug_print_quoted (name);
+debug_print_variable(sc_gameref_t game, sc_int variable) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ const sc_var_setref_t vars = gs_get_vars(game);
+ sc_vartype_t vt_key[3], vt_rvalue;
+ sc_char buffer[32];
+ sc_int var_type;
+ const sc_char *name;
+
+ if (variable < 0 || variable >= debug_variable_count(game)) {
+ if_print_debug("Variable ");
+ sprintf(buffer, "%ld ", variable);
+ if_print_debug(buffer);
+ if_print_debug("[Out of range]");
+ return;
+ }
+
+ vt_key[0].string = "Variables";
+ vt_key[1].integer = variable;
+ vt_key[2].string = "Name";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+
+ if (var_get(vars, name, &var_type, &vt_rvalue)) {
+ switch (var_type) {
+ case VAR_INTEGER:
+ if_print_debug("Integer ");
+ break;
+ case VAR_STRING:
+ if_print_debug("String ");
+ break;
+ default:
+ if_print_debug("[Invalid type] ");
+ break;
+ }
+ } else
+ if_print_debug("[Invalid variable] ");
+ sprintf(buffer, "%ld ", variable);
+ if_print_debug(buffer);
+ debug_print_quoted(name);
}
@@ -770,148 +743,145 @@ debug_print_variable (sc_gameref_t game, sc_int variable)
* Display overall game details.
*/
static void
-debug_game (sc_gameref_t game, sc_command_type_t type)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- const sc_debuggerref_t debug = debug_get_debugger (game);
- sc_vartype_t vt_key[2];
- const sc_char *version, *gamename, *compiledate, *gameauthor;
- sc_int perspective, waitturns;
- sc_bool has_sound, has_graphics, has_battle;
- sc_char buffer[32];
- assert (debug_is_valid (debug));
-
- if (type != COMMAND_QUERY)
- {
- if_print_debug ("The Game command takes no arguments.\n");
- return;
- }
-
- if_print_debug ("Game ");
- vt_key[0].string = "Globals";
- vt_key[1].string = "GameName";
- gamename = prop_get_string (bundle, "S<-ss", vt_key);
- debug_print_quoted (gamename);
- if_print_debug_character ('\n');
-
- if_print_debug (" Compiled ");
- vt_key[0].string = "CompileDate";
- compiledate = prop_get_string (bundle, "S<-s", vt_key);
- debug_print_quoted (compiledate);
-
- if_print_debug (", Author ");
- vt_key[0].string = "Globals";
- vt_key[1].string = "GameAuthor";
- gameauthor = prop_get_string (bundle, "S<-ss", vt_key);
- debug_print_quoted (gameauthor);
- if_print_debug_character ('\n');
-
- vt_key[0].string = "VersionString";
- version = prop_get_string (bundle, "S<-s", vt_key);
- if_print_debug (" Version ");
- if_print_debug (version);
-
- vt_key[0].string = "Globals";
- vt_key[1].string = "Perspective";
- perspective = prop_get_integer (bundle, "I<-ss", vt_key);
- switch (perspective)
- {
- case 0:
- if_print_debug (", First person");
- break;
- case 1:
- if_print_debug (", Second person");
- break;
- case 2:
- if_print_debug (", Third person");
- break;
- default:
- if_print_debug (", [Unknown perspective]");
- break;
- }
-
- vt_key[0].string = "Globals";
- vt_key[1].string = "WaitTurns";
- waitturns = prop_get_integer (bundle, "I<-ss", vt_key);
- if_print_debug (", Waitturns ");
- sprintf (buffer, "%ld", waitturns);
- if_print_debug (buffer);
-
- vt_key[0].string = "Globals";
- vt_key[1].string = "Sound";
- has_sound = prop_get_boolean (bundle, "B<-ss", vt_key);
- vt_key[1].string = "Graphics";
- has_graphics = prop_get_boolean (bundle, "B<-ss", vt_key);
- if (has_sound)
- if_print_debug (", Sound");
- if (has_graphics)
- if_print_debug (", Graphics");
- if_print_debug_character ('\n');
-
- vt_key[0].string = "Globals";
- vt_key[1].string = "BattleSystem";
- has_battle = prop_get_boolean (bundle, "B<-ss", vt_key);
- if (has_battle)
- if_print_debug (" Battle system\n");
-
- if_print_debug (" Room count ");
- sprintf (buffer, "%ld", gs_room_count (game));
- if_print_debug (buffer);
-
- if_print_debug (", Object count ");
- sprintf (buffer, "%ld", gs_object_count (game));
- if_print_debug (buffer);
-
- if_print_debug (", NPC count ");
- sprintf (buffer, "%ld", gs_npc_count (game));
- if_print_debug (buffer);
- if_print_debug_character ('\n');
-
- if_print_debug (" Event count ");
- sprintf (buffer, "%ld", gs_event_count (game));
- if_print_debug (buffer);
-
- if_print_debug (", Task count ");
- sprintf (buffer, "%ld", gs_task_count (game));
- if_print_debug (buffer);
-
- if_print_debug (", Variable count ");
- sprintf (buffer, "%ld", debug_variable_count (game));
- if_print_debug (buffer);
- if_print_debug_character ('\n');
-
- if (game->is_running)
- if_print_debug (" Running");
- else
- if_print_debug (" Not running");
- if (game->has_completed)
- if_print_debug (", Completed");
- else
- if_print_debug (", Not completed");
- if (game->verbose)
- if_print_debug (", Verbose");
- else
- if_print_debug (", Not verbose");
- if (game->bold_room_names)
- if_print_debug (", Bold");
- else
- if_print_debug (", Not bold");
- if (game->undo_available)
- if_print_debug (", Undo");
- else
- if_print_debug (", No undo");
- if_print_debug_character ('\n');
-
- if_print_debug (" Score ");
- sprintf (buffer, "%ld", game->score);
- if_print_debug (buffer);
- if_print_debug (", Turns ");
- sprintf (buffer, "%ld", game->turns);
- if_print_debug (buffer);
- if_print_debug (", Seconds ");
- sprintf (buffer, "%lu", debug->elapsed_seconds);
- if_print_debug (buffer);
- if_print_debug_character ('\n');
+debug_game(sc_gameref_t game, sc_command_type_t type) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+ sc_vartype_t vt_key[2];
+ const sc_char *version, *gamename, *compiledate, *gameauthor;
+ sc_int perspective, waitturns;
+ sc_bool has_sound, has_graphics, has_battle;
+ sc_char buffer[32];
+ assert(debug_is_valid(debug));
+
+ if (type != COMMAND_QUERY) {
+ if_print_debug("The Game command takes no arguments.\n");
+ return;
+ }
+
+ if_print_debug("Game ");
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "GameName";
+ gamename = prop_get_string(bundle, "S<-ss", vt_key);
+ debug_print_quoted(gamename);
+ if_print_debug_character('\n');
+
+ if_print_debug(" Compiled ");
+ vt_key[0].string = "CompileDate";
+ compiledate = prop_get_string(bundle, "S<-s", vt_key);
+ debug_print_quoted(compiledate);
+
+ if_print_debug(", Author ");
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "GameAuthor";
+ gameauthor = prop_get_string(bundle, "S<-ss", vt_key);
+ debug_print_quoted(gameauthor);
+ if_print_debug_character('\n');
+
+ vt_key[0].string = "VersionString";
+ version = prop_get_string(bundle, "S<-s", vt_key);
+ if_print_debug(" Version ");
+ if_print_debug(version);
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "Perspective";
+ perspective = prop_get_integer(bundle, "I<-ss", vt_key);
+ switch (perspective) {
+ case 0:
+ if_print_debug(", First person");
+ break;
+ case 1:
+ if_print_debug(", Second person");
+ break;
+ case 2:
+ if_print_debug(", Third person");
+ break;
+ default:
+ if_print_debug(", [Unknown perspective]");
+ break;
+ }
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "WaitTurns";
+ waitturns = prop_get_integer(bundle, "I<-ss", vt_key);
+ if_print_debug(", Waitturns ");
+ sprintf(buffer, "%ld", waitturns);
+ if_print_debug(buffer);
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "Sound";
+ has_sound = prop_get_boolean(bundle, "B<-ss", vt_key);
+ vt_key[1].string = "Graphics";
+ has_graphics = prop_get_boolean(bundle, "B<-ss", vt_key);
+ if (has_sound)
+ if_print_debug(", Sound");
+ if (has_graphics)
+ if_print_debug(", Graphics");
+ if_print_debug_character('\n');
+
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "BattleSystem";
+ has_battle = prop_get_boolean(bundle, "B<-ss", vt_key);
+ if (has_battle)
+ if_print_debug(" Battle system\n");
+
+ if_print_debug(" Room count ");
+ sprintf(buffer, "%ld", gs_room_count(game));
+ if_print_debug(buffer);
+
+ if_print_debug(", Object count ");
+ sprintf(buffer, "%ld", gs_object_count(game));
+ if_print_debug(buffer);
+
+ if_print_debug(", NPC count ");
+ sprintf(buffer, "%ld", gs_npc_count(game));
+ if_print_debug(buffer);
+ if_print_debug_character('\n');
+
+ if_print_debug(" Event count ");
+ sprintf(buffer, "%ld", gs_event_count(game));
+ if_print_debug(buffer);
+
+ if_print_debug(", Task count ");
+ sprintf(buffer, "%ld", gs_task_count(game));
+ if_print_debug(buffer);
+
+ if_print_debug(", Variable count ");
+ sprintf(buffer, "%ld", debug_variable_count(game));
+ if_print_debug(buffer);
+ if_print_debug_character('\n');
+
+ if (game->is_running)
+ if_print_debug(" Running");
+ else
+ if_print_debug(" Not running");
+ if (game->has_completed)
+ if_print_debug(", Completed");
+ else
+ if_print_debug(", Not completed");
+ if (game->verbose)
+ if_print_debug(", Verbose");
+ else
+ if_print_debug(", Not verbose");
+ if (game->bold_room_names)
+ if_print_debug(", Bold");
+ else
+ if_print_debug(", Not bold");
+ if (game->undo_available)
+ if_print_debug(", Undo");
+ else
+ if_print_debug(", No undo");
+ if_print_debug_character('\n');
+
+ if_print_debug(" Score ");
+ sprintf(buffer, "%ld", game->score);
+ if_print_debug(buffer);
+ if_print_debug(", Turns ");
+ sprintf(buffer, "%ld", game->turns);
+ if_print_debug(buffer);
+ if_print_debug(", Seconds ");
+ sprintf(buffer, "%lu", debug->elapsed_seconds);
+ if_print_debug(buffer);
+ if_print_debug_character('\n');
}
@@ -921,61 +891,54 @@ debug_game (sc_gameref_t game, sc_command_type_t type)
* Print a few brief details about the player status.
*/
static void
-debug_player (sc_gameref_t game,
- sc_command_t command, sc_command_type_t type)
-{
- if (type != COMMAND_QUERY)
- {
- if_print_debug ("The Player command takes no arguments.\n");
- return;
- }
-
- if (command == DEBUG_OLDPLAYER)
- {
- if (!game->undo_available)
- {
- if_print_debug ("There is no previous game state to examine.\n");
- return;
- }
-
- game = game->undo;
- assert (gs_is_game_valid (game));
- }
-
- debug_print_player (game);
- if_print_debug_character ('\n');
-
- if (gs_playerroom (game) == -1)
- if_print_debug (" Hidden!\n");
- else
- {
- if_print_debug (" In ");
- debug_print_room (game, gs_playerroom (game));
- if_print_debug_character ('\n');
- }
-
- switch (gs_playerposition (game))
- {
- case 0:
- if_print_debug (" Standing\n");
- break;
- case 1:
- if_print_debug (" Sitting\n");
- break;
- case 2:
- if_print_debug (" Lying\n");
- break;
- default:
- if_print_debug (" [Invalid position]\n");
- break;
- }
-
- if (gs_playerparent (game) != -1)
- {
- if_print_debug (" Parent is ");
- debug_print_object (game, gs_playerparent (game));
- if_print_debug_character ('\n');
- }
+debug_player(sc_gameref_t game,
+ sc_command_t command, sc_command_type_t type) {
+ if (type != COMMAND_QUERY) {
+ if_print_debug("The Player command takes no arguments.\n");
+ return;
+ }
+
+ if (command == DEBUG_OLDPLAYER) {
+ if (!game->undo_available) {
+ if_print_debug("There is no previous game state to examine.\n");
+ return;
+ }
+
+ game = game->undo;
+ assert(gs_is_game_valid(game));
+ }
+
+ debug_print_player(game);
+ if_print_debug_character('\n');
+
+ if (gs_playerroom(game) == -1)
+ if_print_debug(" Hidden!\n");
+ else {
+ if_print_debug(" In ");
+ debug_print_room(game, gs_playerroom(game));
+ if_print_debug_character('\n');
+ }
+
+ switch (gs_playerposition(game)) {
+ case 0:
+ if_print_debug(" Standing\n");
+ break;
+ case 1:
+ if_print_debug(" Sitting\n");
+ break;
+ case 2:
+ if_print_debug(" Lying\n");
+ break;
+ default:
+ if_print_debug(" [Invalid position]\n");
+ break;
+ }
+
+ if (gs_playerparent(game) != -1) {
+ if_print_debug(" Parent is ");
+ debug_print_object(game, gs_playerparent(game));
+ if_print_debug_character('\n');
+ }
}
@@ -986,41 +949,38 @@ debug_player (sc_gameref_t game,
* debug commands that take ranges.
*/
static sc_bool
-debug_normalize_arguments (sc_command_type_t type,
- sc_int *arg1, sc_int *arg2, sc_int limit)
-{
- sc_int low = 0, high = 0;
-
- /* Set range low and high depending on the command type. */
- switch (type)
- {
- case COMMAND_QUERY:
- case COMMAND_ALL:
- low = 0;
- high = limit - 1;
- break;
- case COMMAND_ONE:
- low = *arg1;
- high = *arg1;
- break;
- case COMMAND_RANGE:
- low = *arg1;
- high = *arg2;
- break;
- default:
- sc_fatal ("debug_normalize_arguments: bad command type\n");
- }
-
- /* If range is valid, copy out and return TRUE. */
- if (low >= 0 && low < limit && high >= 0 && high < limit && high >= low)
- {
- *arg1 = low;
- *arg2 = high;
- return TRUE;
- }
-
- /* Input range is invalid. */
- return FALSE;
+debug_normalize_arguments(sc_command_type_t type,
+ sc_int *arg1, sc_int *arg2, sc_int limit) {
+ sc_int low = 0, high = 0;
+
+ /* Set range low and high depending on the command type. */
+ switch (type) {
+ case COMMAND_QUERY:
+ case COMMAND_ALL:
+ low = 0;
+ high = limit - 1;
+ break;
+ case COMMAND_ONE:
+ low = *arg1;
+ high = *arg1;
+ break;
+ case COMMAND_RANGE:
+ low = *arg1;
+ high = *arg2;
+ break;
+ default:
+ sc_fatal("debug_normalize_arguments: bad command type\n");
+ }
+
+ /* If range is valid, copy out and return TRUE. */
+ if (low >= 0 && low < limit && high >= 0 && high < limit && high >= low) {
+ *arg1 = low;
+ *arg2 = high;
+ return TRUE;
+ }
+
+ /* Input range is invalid. */
+ return FALSE;
}
@@ -1031,50 +991,43 @@ debug_normalize_arguments (sc_command_type_t type,
* Print details of rooms and their direct contents.
*/
static sc_bool
-debug_filter_room (sc_gameref_t game, sc_int room)
-{
- return room == gs_playerroom (game);
+debug_filter_room(sc_gameref_t game, sc_int room) {
+ return room == gs_playerroom(game);
}
static void
-debug_dump_room (sc_gameref_t game, sc_int room)
-{
- sc_int object, npc;
-
- debug_print_room (game, room);
- if_print_debug_character ('\n');
-
- if (gs_room_seen (game, room))
- if_print_debug (" Visited\n");
- else
- if_print_debug (" Not visited\n");
-
- if (gs_playerroom (game) == room)
- {
- if_print_debug (" ");
- debug_print_player (game);
- if_print_debug_character ('\n');
- }
-
- for (object = 0; object < gs_object_count (game); object++)
- {
- if (obj_indirectly_in_room (game, object, room))
- {
- if_print_debug (" ");
- debug_print_object (game, object);
- if_print_debug_character ('\n');
- }
- }
-
- for (npc = 0; npc < gs_npc_count (game); npc++)
- {
- if (npc_in_room (game, npc, room))
- {
- if_print_debug (" ");
- debug_print_npc (game, npc);
- if_print_debug_character ('\n');
- }
- }
+debug_dump_room(sc_gameref_t game, sc_int room) {
+ sc_int object, npc;
+
+ debug_print_room(game, room);
+ if_print_debug_character('\n');
+
+ if (gs_room_seen(game, room))
+ if_print_debug(" Visited\n");
+ else
+ if_print_debug(" Not visited\n");
+
+ if (gs_playerroom(game) == room) {
+ if_print_debug(" ");
+ debug_print_player(game);
+ if_print_debug_character('\n');
+ }
+
+ for (object = 0; object < gs_object_count(game); object++) {
+ if (obj_indirectly_in_room(game, object, room)) {
+ if_print_debug(" ");
+ debug_print_object(game, object);
+ if_print_debug_character('\n');
+ }
+ }
+
+ for (npc = 0; npc < gs_npc_count(game); npc++) {
+ if (npc_in_room(game, npc, room)) {
+ if_print_debug(" ");
+ debug_print_npc(game, npc);
+ if_print_debug_character('\n');
+ }
+ }
}
@@ -1085,139 +1038,130 @@ debug_dump_room (sc_gameref_t game, sc_int room)
* Print the changeable details of game objects.
*/
static sc_bool
-debug_filter_object (sc_gameref_t game, sc_int object)
-{
- return obj_indirectly_in_room (game, object, gs_playerroom (game));
+debug_filter_object(sc_gameref_t game, sc_int object) {
+ return obj_indirectly_in_room(game, object, gs_playerroom(game));
}
static void
-debug_dump_object (sc_gameref_t game, sc_int object)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_int openness;
- sc_vartype_t vt_key[3];
- sc_bool bstatic, is_statussed;
- sc_int position, parent;
-
- debug_print_object (game, object);
- if_print_debug_character ('\n');
-
- vt_key[0].string = "Objects";
- vt_key[1].integer = object;
- vt_key[2].string = "Static";
- bstatic = prop_get_boolean (bundle, "B<-sis", vt_key);
-
- if (gs_object_seen (game, object))
- if_print_debug (" Seen");
- else
- if_print_debug (" Not seen");
- if (bstatic)
- {
- if (gs_object_static_unmoved (game, object))
- if_print_debug (", Not relocated");
- else
- if_print_debug (", Relocated");
- }
- else
- {
- vt_key[2].string = "OnlyWhenNotMoved";
- if (prop_get_integer (bundle, "I<-sis", vt_key) == 1)
- {
- if (gs_object_unmoved (game, object))
- if_print_debug (", Not moved");
- else
- if_print_debug (", Moved");
- }
- }
- openness = gs_object_openness (game, object);
- switch (openness)
- {
- case OBJ_OPEN:
- if_print_debug (", Open");
- break;
- case OBJ_CLOSED:
- if_print_debug (", Closed");
- break;
- case OBJ_LOCKED:
- if_print_debug (", Locked");
- break;
- }
- if_print_debug_character ('\n');
-
- position = gs_object_position (game, object);
- parent = gs_object_parent (game, object);
- switch (position)
- {
- case OBJ_HIDDEN:
- if (bstatic)
- if_print_debug (" Static default\n");
- else
- if_print_debug (" Hidden\n");
- break;
- case OBJ_HELD_PLAYER:
- if_print_debug (" Held by ");
- debug_print_player (game);
- if_print_debug_character ('\n');
- break;
- case OBJ_HELD_NPC:
- if_print_debug (" Held by ");
- debug_print_npc (game, parent);
- if_print_debug_character ('\n');
- break;
- case OBJ_WORN_PLAYER:
- if_print_debug (" Worn by ");
- debug_print_player (game);
- if_print_debug_character ('\n');
- break;
- case OBJ_WORN_NPC:
- if_print_debug (" Worn by ");
- debug_print_npc (game, parent);
- if_print_debug_character ('\n');
- break;
- case OBJ_PART_NPC:
- if_print_debug (" Part of ");
- if (parent == -1)
- debug_print_player (game);
- else
- debug_print_npc (game, parent);
- if_print_debug_character ('\n');
- break;
- case OBJ_ON_OBJECT:
- if_print_debug (" On ");
- debug_print_object (game, parent);
- if_print_debug_character ('\n');
- break;
- case OBJ_IN_OBJECT:
- if_print_debug (" Inside ");
- debug_print_object (game, parent);
- if_print_debug_character ('\n');
- break;
- default:
- if_print_debug (" In ");
- debug_print_room (game, position - 1);
- if_print_debug_character ('\n');
- break;
- }
-
- vt_key[0].string = "Objects";
- vt_key[1].integer = object;
- vt_key[2].string = "CurrentState";
- is_statussed = prop_get_integer (bundle, "I<-sis", vt_key) != 0;
- if (is_statussed)
- {
- sc_char buffer[32];
- const sc_char *states;
-
- if_print_debug (" State ");
- sprintf (buffer, "%ld", gs_object_state (game, object));
- if_print_debug (buffer);
-
- vt_key[2].string = "States";
- states = prop_get_string (bundle, "S<-sis", vt_key);
- if_print_debug (" of ");
- debug_print_quoted (states);
- if_print_debug_character ('\n');
- }
+debug_dump_object(sc_gameref_t game, sc_int object) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_int openness;
+ sc_vartype_t vt_key[3];
+ sc_bool bstatic, is_statussed;
+ sc_int position, parent;
+
+ debug_print_object(game, object);
+ if_print_debug_character('\n');
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ bstatic = prop_get_boolean(bundle, "B<-sis", vt_key);
+
+ if (gs_object_seen(game, object))
+ if_print_debug(" Seen");
+ else
+ if_print_debug(" Not seen");
+ if (bstatic) {
+ if (gs_object_static_unmoved(game, object))
+ if_print_debug(", Not relocated");
+ else
+ if_print_debug(", Relocated");
+ } else {
+ vt_key[2].string = "OnlyWhenNotMoved";
+ if (prop_get_integer(bundle, "I<-sis", vt_key) == 1) {
+ if (gs_object_unmoved(game, object))
+ if_print_debug(", Not moved");
+ else
+ if_print_debug(", Moved");
+ }
+ }
+ openness = gs_object_openness(game, object);
+ switch (openness) {
+ case OBJ_OPEN:
+ if_print_debug(", Open");
+ break;
+ case OBJ_CLOSED:
+ if_print_debug(", Closed");
+ break;
+ case OBJ_LOCKED:
+ if_print_debug(", Locked");
+ break;
+ }
+ if_print_debug_character('\n');
+
+ position = gs_object_position(game, object);
+ parent = gs_object_parent(game, object);
+ switch (position) {
+ case OBJ_HIDDEN:
+ if (bstatic)
+ if_print_debug(" Static default\n");
+ else
+ if_print_debug(" Hidden\n");
+ break;
+ case OBJ_HELD_PLAYER:
+ if_print_debug(" Held by ");
+ debug_print_player(game);
+ if_print_debug_character('\n');
+ break;
+ case OBJ_HELD_NPC:
+ if_print_debug(" Held by ");
+ debug_print_npc(game, parent);
+ if_print_debug_character('\n');
+ break;
+ case OBJ_WORN_PLAYER:
+ if_print_debug(" Worn by ");
+ debug_print_player(game);
+ if_print_debug_character('\n');
+ break;
+ case OBJ_WORN_NPC:
+ if_print_debug(" Worn by ");
+ debug_print_npc(game, parent);
+ if_print_debug_character('\n');
+ break;
+ case OBJ_PART_NPC:
+ if_print_debug(" Part of ");
+ if (parent == -1)
+ debug_print_player(game);
+ else
+ debug_print_npc(game, parent);
+ if_print_debug_character('\n');
+ break;
+ case OBJ_ON_OBJECT:
+ if_print_debug(" On ");
+ debug_print_object(game, parent);
+ if_print_debug_character('\n');
+ break;
+ case OBJ_IN_OBJECT:
+ if_print_debug(" Inside ");
+ debug_print_object(game, parent);
+ if_print_debug_character('\n');
+ break;
+ default:
+ if_print_debug(" In ");
+ debug_print_room(game, position - 1);
+ if_print_debug_character('\n');
+ break;
+ }
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "CurrentState";
+ is_statussed = prop_get_integer(bundle, "I<-sis", vt_key) != 0;
+ if (is_statussed) {
+ sc_char buffer[32];
+ const sc_char *states;
+
+ if_print_debug(" State ");
+ sprintf(buffer, "%ld", gs_object_state(game, object));
+ if_print_debug(buffer);
+
+ vt_key[2].string = "States";
+ states = prop_get_string(bundle, "S<-sis", vt_key);
+ if_print_debug(" of ");
+ debug_print_quoted(states);
+ if_print_debug_character('\n');
+ }
}
@@ -1228,71 +1172,64 @@ debug_dump_object (sc_gameref_t game, sc_int object)
* Print stuff about NPCs.
*/
static sc_bool
-debug_filter_npc (sc_gameref_t game, sc_int npc)
-{
- return npc_in_room (game, npc, gs_playerroom (game));
+debug_filter_npc(sc_gameref_t game, sc_int npc) {
+ return npc_in_room(game, npc, gs_playerroom(game));
}
static void
-debug_dump_npc (sc_gameref_t game, sc_int npc)
-{
- debug_print_npc (game, npc);
- if_print_debug_character ('\n');
-
- if (gs_npc_seen (game, npc))
- if_print_debug (" Seen\n");
- else
- if_print_debug (" Not seen\n");
-
- if (gs_npc_location (game, npc) - 1 == -1)
- if_print_debug (" Hidden\n");
- else
- {
- if_print_debug (" In ");
- debug_print_room (game, gs_npc_location (game, npc) - 1);
- if_print_debug_character ('\n');
- }
-
- switch (gs_npc_position (game, npc))
- {
- case 0:
- if_print_debug (" Standing\n");
- break;
- case 1:
- if_print_debug (" Sitting\n");
- break;
- case 2:
- if_print_debug (" Lying\n");
- break;
- default:
- if_print_debug (" [Invalid position]\n");
- break;
- }
-
- if (gs_npc_parent (game, npc) != -1)
- {
- if_print_debug (" Parent is ");
- debug_print_object (game, gs_npc_parent (game, npc));
- if_print_debug_character ('\n');
- }
-
- if (gs_npc_walkstep_count (game, npc) > 0)
- {
- sc_char buffer[32];
- sc_int walk;
-
- if_print_debug (" Walkstep count ");
- sprintf (buffer, "%ld", gs_npc_walkstep_count (game, npc));
- if_print_debug (buffer);
- if_print_debug (", Walks { ");
- for (walk = 0; walk < gs_npc_walkstep_count (game, npc); walk++)
- {
- sprintf (buffer, "%ld", gs_npc_walkstep (game, npc, walk));
- if_print_debug (buffer);
- if_print_debug_character (' ');
- }
- if_print_debug ("}.\n");
- }
+debug_dump_npc(sc_gameref_t game, sc_int npc) {
+ debug_print_npc(game, npc);
+ if_print_debug_character('\n');
+
+ if (gs_npc_seen(game, npc))
+ if_print_debug(" Seen\n");
+ else
+ if_print_debug(" Not seen\n");
+
+ if (gs_npc_location(game, npc) - 1 == -1)
+ if_print_debug(" Hidden\n");
+ else {
+ if_print_debug(" In ");
+ debug_print_room(game, gs_npc_location(game, npc) - 1);
+ if_print_debug_character('\n');
+ }
+
+ switch (gs_npc_position(game, npc)) {
+ case 0:
+ if_print_debug(" Standing\n");
+ break;
+ case 1:
+ if_print_debug(" Sitting\n");
+ break;
+ case 2:
+ if_print_debug(" Lying\n");
+ break;
+ default:
+ if_print_debug(" [Invalid position]\n");
+ break;
+ }
+
+ if (gs_npc_parent(game, npc) != -1) {
+ if_print_debug(" Parent is ");
+ debug_print_object(game, gs_npc_parent(game, npc));
+ if_print_debug_character('\n');
+ }
+
+ if (gs_npc_walkstep_count(game, npc) > 0) {
+ sc_char buffer[32];
+ sc_int walk;
+
+ if_print_debug(" Walkstep count ");
+ sprintf(buffer, "%ld", gs_npc_walkstep_count(game, npc));
+ if_print_debug(buffer);
+ if_print_debug(", Walks { ");
+ for (walk = 0; walk < gs_npc_walkstep_count(game, npc); walk++) {
+ sprintf(buffer, "%ld", gs_npc_walkstep(game, npc, walk));
+ if_print_debug(buffer);
+ if_print_debug_character(' ');
+ }
+ if_print_debug("}.\n");
+ }
}
@@ -1303,44 +1240,41 @@ debug_dump_npc (sc_gameref_t game, sc_int npc)
* Print stuff about events.
*/
static sc_bool
-debug_filter_event (sc_gameref_t game, sc_int event)
-{
- return gs_event_state (game, event) == ES_RUNNING;
+debug_filter_event(sc_gameref_t game, sc_int event) {
+ return gs_event_state(game, event) == ES_RUNNING;
}
static void
-debug_dump_event (sc_gameref_t game, sc_int event)
-{
- sc_char buffer[32];
-
- debug_print_event (game, event);
- if_print_debug_character ('\n');
-
- switch (gs_event_state (game, event))
- {
- case ES_WAITING:
- if_print_debug (" Waiting\n");
- break;
- case ES_RUNNING:
- if_print_debug (" Running\n");
- break;
- case ES_AWAITING:
- if_print_debug (" Awaiting\n");
- break;
- case ES_FINISHED:
- if_print_debug (" Finished\n");
- break;
- case ES_PAUSED:
- if_print_debug (" Paused\n");
- break;
- default:
- if_print_debug (" [Invalid state]\n");
- break;
- }
-
- if_print_debug (" Time ");
- sprintf (buffer, "%ld\n", gs_event_time (game, event));
- if_print_debug (buffer);
+debug_dump_event(sc_gameref_t game, sc_int event) {
+ sc_char buffer[32];
+
+ debug_print_event(game, event);
+ if_print_debug_character('\n');
+
+ switch (gs_event_state(game, event)) {
+ case ES_WAITING:
+ if_print_debug(" Waiting\n");
+ break;
+ case ES_RUNNING:
+ if_print_debug(" Running\n");
+ break;
+ case ES_AWAITING:
+ if_print_debug(" Awaiting\n");
+ break;
+ case ES_FINISHED:
+ if_print_debug(" Finished\n");
+ break;
+ case ES_PAUSED:
+ if_print_debug(" Paused\n");
+ break;
+ default:
+ if_print_debug(" [Invalid state]\n");
+ break;
+ }
+
+ if_print_debug(" Time ");
+ sprintf(buffer, "%ld\n", gs_event_time(game, event));
+ if_print_debug(buffer);
}
@@ -1351,29 +1285,27 @@ debug_dump_event (sc_gameref_t game, sc_int event)
* Print stuff about tasks.
*/
static sc_bool
-debug_filter_task (sc_gameref_t game, sc_int task)
-{
- return task_can_run_task (game, task);
+debug_filter_task(sc_gameref_t game, sc_int task) {
+ return task_can_run_task(game, task);
}
static void
-debug_dump_task (sc_gameref_t game, sc_int task)
-{
- debug_print_task (game, task);
- if_print_debug_character ('\n');
-
- if (task_can_run_task (game, task))
- if_print_debug (" Runnable");
- else
- if_print_debug (" Not runnable");
- if (gs_task_done (game, task))
- if_print_debug (", Done");
- else
- if_print_debug (", Not done");
- if (gs_task_scored (game, task))
- if_print_debug (", Scored\n");
- else
- if_print_debug (", Not scored\n");
+debug_dump_task(sc_gameref_t game, sc_int task) {
+ debug_print_task(game, task);
+ if_print_debug_character('\n');
+
+ if (task_can_run_task(game, task))
+ if_print_debug(" Runnable");
+ else
+ if_print_debug(" Not runnable");
+ if (gs_task_done(game, task))
+ if_print_debug(", Done");
+ else
+ if_print_debug(", Not done");
+ if (gs_task_scored(game, task))
+ if_print_debug(", Scored\n");
+ else
+ if_print_debug(", Not scored\n");
}
@@ -1383,46 +1315,41 @@ debug_dump_task (sc_gameref_t game, sc_int task)
* Print stuff about variables.
*/
static void
-debug_dump_variable (sc_gameref_t game, sc_int variable)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- const sc_var_setref_t vars = gs_get_vars (game);
- sc_vartype_t vt_key[3], vt_rvalue;
- const sc_char *name;
- sc_int var_type;
-
- debug_print_variable (game, variable);
- if_print_debug_character ('\n');
-
- vt_key[0].string = "Variables";
- vt_key[1].integer = variable;
- vt_key[2].string = "Name";
- name = prop_get_string (bundle, "S<-sis", vt_key);
-
- if_print_debug (" Value = ");
- if (var_get (vars, name, &var_type, &vt_rvalue))
- {
- switch (var_type)
- {
- case VAR_INTEGER:
- {
- sc_char buffer[32];
-
- sprintf (buffer, "%ld", vt_rvalue.integer);
- if_print_debug (buffer);
- break;
- }
- case VAR_STRING:
- debug_print_quoted (vt_rvalue.string);
- break;
- default:
- if_print_debug ("[Unknown]");
- break;
- }
- }
- else
- if_print_debug ("[Unknown]");
- if_print_debug_character ('\n');
+debug_dump_variable(sc_gameref_t game, sc_int variable) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ const sc_var_setref_t vars = gs_get_vars(game);
+ sc_vartype_t vt_key[3], vt_rvalue;
+ const sc_char *name;
+ sc_int var_type;
+
+ debug_print_variable(game, variable);
+ if_print_debug_character('\n');
+
+ vt_key[0].string = "Variables";
+ vt_key[1].integer = variable;
+ vt_key[2].string = "Name";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+
+ if_print_debug(" Value = ");
+ if (var_get(vars, name, &var_type, &vt_rvalue)) {
+ switch (var_type) {
+ case VAR_INTEGER: {
+ sc_char buffer[32];
+
+ sprintf(buffer, "%ld", vt_rvalue.integer);
+ if_print_debug(buffer);
+ break;
+ }
+ case VAR_STRING:
+ debug_print_quoted(vt_rvalue.string);
+ break;
+ default:
+ if_print_debug("[Unknown]");
+ break;
+ }
+ } else
+ if_print_debug("[Unknown]");
+ if_print_debug_character('\n');
}
@@ -1432,142 +1359,131 @@ debug_dump_variable (sc_gameref_t game, sc_int variable)
* Common handler for iterating dumps of classes.
*/
static void
-debug_dump_common (sc_gameref_t game, sc_command_t command,
- sc_command_type_t type, sc_int arg1, sc_int arg2)
-{
- sc_int low = arg1, high = arg2;
- sc_int limit, index_;
- const sc_char *class_;
- sc_bool (*filter_function) (sc_gameref_t, sc_int);
- void (*dumper_function) (sc_gameref_t, sc_int);
- sc_bool printed = FALSE;
-
- /* Initialize variables to avoid gcc warnings. */
- limit = 0;
- class_ = NULL;
- filter_function = NULL;
- dumper_function = NULL;
-
- /* Switch to undo game on relevant commands. */
- switch (command)
- {
- case DEBUG_OLDROOMS:
- case DEBUG_OLDOBJECTS:
- case DEBUG_OLDNPCS:
- case DEBUG_OLDEVENTS:
- case DEBUG_OLDTASKS:
- case DEBUG_OLDVARIABLES:
- if (!game->undo_available)
- {
- if_print_debug ("There is no previous game state to examine.\n");
- return;
- }
-
- game = game->undo;
- assert (gs_is_game_valid (game));
- break;
-
- default:
- break;
- }
-
- /* Demultiplex dump command. */
- switch (command)
- {
- case DEBUG_ROOMS:
- case DEBUG_OLDROOMS:
- class_ = "Room";
- filter_function = debug_filter_room;
- dumper_function = debug_dump_room;
- limit = gs_room_count (game);
- break;
- case DEBUG_OBJECTS:
- case DEBUG_OLDOBJECTS:
- class_ = "Object";
- filter_function = debug_filter_object;
- dumper_function = debug_dump_object;
- limit = gs_object_count (game);
- break;
- case DEBUG_NPCS:
- case DEBUG_OLDNPCS:
- class_ = "NPC";
- filter_function = debug_filter_npc;
- dumper_function = debug_dump_npc;
- limit = gs_npc_count (game);
- break;
- case DEBUG_EVENTS:
- case DEBUG_OLDEVENTS:
- class_ = "Event";
- filter_function = debug_filter_event;
- dumper_function = debug_dump_event;
- limit = gs_event_count (game);
- break;
- case DEBUG_TASKS:
- case DEBUG_OLDTASKS:
- class_ = "Task";
- filter_function = debug_filter_task;
- dumper_function = debug_dump_task;
- limit = gs_task_count (game);
- break;
- case DEBUG_VARIABLES:
- case DEBUG_OLDVARIABLES:
- class_ = "Variable";
- filter_function = NULL;
- dumper_function = debug_dump_variable;
- limit = debug_variable_count (game);
- break;
- default:
- sc_fatal ("debug_dump_common: invalid command\n");
- }
-
- /* Normalize to this limit. */
- if (!debug_normalize_arguments (type, &low, &high, limit))
- {
- if (limit == 0)
- {
- if_print_debug ("There is nothing of type ");
- debug_print_quoted (class_);
- if_print_debug (" to print.\n");
- }
- else
- {
- if_print_debug ("Invalid item or range for ");
- debug_print_quoted (class_);
- if (limit == 1)
- if_print_debug ("; only 0 is valid.\n");
- else
- {
- sc_char buffer[32];
-
- if_print_debug ("; valid values are 0 to ");
- sprintf (buffer, "%ld", limit - 1);
- if_print_debug (buffer);
- if_print_debug (".\n");
- }
- }
- return;
- }
-
- /* Print each item of the class, filtering on query commands. */
- for (index_ = low; index_ <= high; index_++)
- {
- if (type == COMMAND_QUERY
- && filter_function && !filter_function (game, index_))
- continue;
-
- if (printed)
- if_print_debug_character ('\n');
- dumper_function (game, index_);
- printed = TRUE;
- }
- if (!printed)
- {
- if_print_debug ("Nothing of type ");
- debug_print_quoted (class_);
- if_print_debug (" is relevant.\nTry \"");
- if_print_debug (class_);
- if_print_debug (" *\" to show all items of this type.\n");
- }
+debug_dump_common(sc_gameref_t game, sc_command_t command,
+ sc_command_type_t type, sc_int arg1, sc_int arg2) {
+ sc_int low = arg1, high = arg2;
+ sc_int limit, index_;
+ const sc_char *class_;
+ sc_bool(*filter_function)(sc_gameref_t, sc_int);
+ void (*dumper_function)(sc_gameref_t, sc_int);
+ sc_bool printed = FALSE;
+
+ /* Initialize variables to avoid gcc warnings. */
+ limit = 0;
+ class_ = NULL;
+ filter_function = NULL;
+ dumper_function = NULL;
+
+ /* Switch to undo game on relevant commands. */
+ switch (command) {
+ case DEBUG_OLDROOMS:
+ case DEBUG_OLDOBJECTS:
+ case DEBUG_OLDNPCS:
+ case DEBUG_OLDEVENTS:
+ case DEBUG_OLDTASKS:
+ case DEBUG_OLDVARIABLES:
+ if (!game->undo_available) {
+ if_print_debug("There is no previous game state to examine.\n");
+ return;
+ }
+
+ game = game->undo;
+ assert(gs_is_game_valid(game));
+ break;
+
+ default:
+ break;
+ }
+
+ /* Demultiplex dump command. */
+ switch (command) {
+ case DEBUG_ROOMS:
+ case DEBUG_OLDROOMS:
+ class_ = "Room";
+ filter_function = debug_filter_room;
+ dumper_function = debug_dump_room;
+ limit = gs_room_count(game);
+ break;
+ case DEBUG_OBJECTS:
+ case DEBUG_OLDOBJECTS:
+ class_ = "Object";
+ filter_function = debug_filter_object;
+ dumper_function = debug_dump_object;
+ limit = gs_object_count(game);
+ break;
+ case DEBUG_NPCS:
+ case DEBUG_OLDNPCS:
+ class_ = "NPC";
+ filter_function = debug_filter_npc;
+ dumper_function = debug_dump_npc;
+ limit = gs_npc_count(game);
+ break;
+ case DEBUG_EVENTS:
+ case DEBUG_OLDEVENTS:
+ class_ = "Event";
+ filter_function = debug_filter_event;
+ dumper_function = debug_dump_event;
+ limit = gs_event_count(game);
+ break;
+ case DEBUG_TASKS:
+ case DEBUG_OLDTASKS:
+ class_ = "Task";
+ filter_function = debug_filter_task;
+ dumper_function = debug_dump_task;
+ limit = gs_task_count(game);
+ break;
+ case DEBUG_VARIABLES:
+ case DEBUG_OLDVARIABLES:
+ class_ = "Variable";
+ filter_function = NULL;
+ dumper_function = debug_dump_variable;
+ limit = debug_variable_count(game);
+ break;
+ default:
+ sc_fatal("debug_dump_common: invalid command\n");
+ }
+
+ /* Normalize to this limit. */
+ if (!debug_normalize_arguments(type, &low, &high, limit)) {
+ if (limit == 0) {
+ if_print_debug("There is nothing of type ");
+ debug_print_quoted(class_);
+ if_print_debug(" to print.\n");
+ } else {
+ if_print_debug("Invalid item or range for ");
+ debug_print_quoted(class_);
+ if (limit == 1)
+ if_print_debug("; only 0 is valid.\n");
+ else {
+ sc_char buffer[32];
+
+ if_print_debug("; valid values are 0 to ");
+ sprintf(buffer, "%ld", limit - 1);
+ if_print_debug(buffer);
+ if_print_debug(".\n");
+ }
+ }
+ return;
+ }
+
+ /* Print each item of the class, filtering on query commands. */
+ for (index_ = low; index_ <= high; index_++) {
+ if (type == COMMAND_QUERY
+ && filter_function && !filter_function(game, index_))
+ continue;
+
+ if (printed)
+ if_print_debug_character('\n');
+ dumper_function(game, index_);
+ printed = TRUE;
+ }
+ if (!printed) {
+ if_print_debug("Nothing of type ");
+ debug_print_quoted(class_);
+ if_print_debug(" is relevant.\nTry \"");
+ if_print_debug(class_);
+ if_print_debug(" *\" to show all items of this type.\n");
+ }
}
@@ -1577,22 +1493,20 @@ debug_dump_common (sc_gameref_t game, sc_command_t command,
* Print the current raw printfilter contents.
*/
static void
-debug_buffer (sc_gameref_t game, sc_command_type_t type)
-{
- const sc_filterref_t filter = gs_get_filter (game);
- const sc_char *buffer;
-
- if (type != COMMAND_QUERY)
- {
- if_print_debug ("The Buffer command takes no arguments.\n");
- return;
- }
-
- buffer = pf_get_buffer (filter);
- if (buffer)
- if_print_debug (buffer);
- else
- if_print_debug ("There is no game text buffered.\n");
+debug_buffer(sc_gameref_t game, sc_command_type_t type) {
+ const sc_filterref_t filter = gs_get_filter(game);
+ const sc_char *buffer;
+
+ if (type != COMMAND_QUERY) {
+ if_print_debug("The Buffer command takes no arguments.\n");
+ return;
+ }
+
+ buffer = pf_get_buffer(filter);
+ if (buffer)
+ if_print_debug(buffer);
+ else
+ if_print_debug("There is no game text buffered.\n");
}
@@ -1602,17 +1516,16 @@ debug_buffer (sc_gameref_t game, sc_command_type_t type)
* Helper for debug_resources().
*/
static void
-debug_print_resource (const sc_resource_t *resource)
-{
- sc_char buffer[32];
-
- debug_print_quoted (resource->name);
- if_print_debug (", offset ");
- sprintf (buffer, "%ld", resource->offset);
- if_print_debug (buffer);
- if_print_debug (", length ");
- sprintf (buffer, "%ld", resource->length);
- if_print_debug (buffer);
+debug_print_resource(const sc_resource_t *resource) {
+ sc_char buffer[32];
+
+ debug_print_quoted(resource->name);
+ if_print_debug(", offset ");
+ sprintf(buffer, "%ld", resource->offset);
+ if_print_debug(buffer);
+ if_print_debug(", length ");
+ sprintf(buffer, "%ld", resource->length);
+ if_print_debug(buffer);
}
@@ -1622,61 +1535,54 @@ debug_print_resource (const sc_resource_t *resource)
* Print any active and requested resources.
*/
static void
-debug_resources (sc_gameref_t game, sc_command_type_t type)
-{
- sc_bool printed = FALSE;
-
- if (type != COMMAND_QUERY)
- {
- if_print_debug ("The Resources command takes no arguments.\n");
- return;
- }
-
- if (game->stop_sound)
- {
- if_print_debug ("Sound stop");
- if (strlen (game->requested_sound.name) > 0)
- if_print_debug (" before new sound");
- if_print_debug (" requested");
- if (game->sound_active)
- if_print_debug (", sound active");
- if_print_debug (".\n");
- printed = TRUE;
- }
- if (!res_compare_resource (&game->requested_sound,
- &game->playing_sound))
- {
- if_print_debug ("Requested Sound ");
- debug_print_resource (&game->requested_sound);
- if_print_debug (".\n");
- printed = TRUE;
- }
- if (!res_compare_resource (&game->requested_graphic,
- &game->displayed_graphic))
- {
- if_print_debug ("Requested Graphic ");
- debug_print_resource (&game->requested_graphic);
- if_print_debug (".\n");
- printed = TRUE;
- }
-
- if (strlen (game->playing_sound.name) > 0)
- {
- if_print_debug ("Playing Sound ");
- debug_print_resource (&game->playing_sound);
- if_print_debug (".\n");
- printed = TRUE;
- }
- if (strlen (game->displayed_graphic.name) > 0)
- {
- if_print_debug ("Displaying Graphic ");
- debug_print_resource (&game->displayed_graphic);
- if_print_debug (".\n");
- printed = TRUE;
- }
-
- if (!printed)
- if_print_debug ("There is no game resource activity.\n");
+debug_resources(sc_gameref_t game, sc_command_type_t type) {
+ sc_bool printed = FALSE;
+
+ if (type != COMMAND_QUERY) {
+ if_print_debug("The Resources command takes no arguments.\n");
+ return;
+ }
+
+ if (game->stop_sound) {
+ if_print_debug("Sound stop");
+ if (strlen(game->requested_sound.name) > 0)
+ if_print_debug(" before new sound");
+ if_print_debug(" requested");
+ if (game->sound_active)
+ if_print_debug(", sound active");
+ if_print_debug(".\n");
+ printed = TRUE;
+ }
+ if (!res_compare_resource(&game->requested_sound,
+ &game->playing_sound)) {
+ if_print_debug("Requested Sound ");
+ debug_print_resource(&game->requested_sound);
+ if_print_debug(".\n");
+ printed = TRUE;
+ }
+ if (!res_compare_resource(&game->requested_graphic,
+ &game->displayed_graphic)) {
+ if_print_debug("Requested Graphic ");
+ debug_print_resource(&game->requested_graphic);
+ if_print_debug(".\n");
+ printed = TRUE;
+ }
+
+ if (strlen(game->playing_sound.name) > 0) {
+ if_print_debug("Playing Sound ");
+ debug_print_resource(&game->playing_sound);
+ if_print_debug(".\n");
+ printed = TRUE;
+ }
+ if (strlen(game->displayed_graphic.name) > 0) {
+ if_print_debug("Displaying Graphic ");
+ debug_print_resource(&game->displayed_graphic);
+ if_print_debug(".\n");
+ printed = TRUE;
+ }
+
+ if (!printed)
+ if_print_debug("There is no game resource activity.\n");
}
@@ -1687,42 +1593,38 @@ debug_resources (sc_gameref_t game, sc_command_type_t type)
* given value.
*/
static void
-debug_random (sc_command_type_t type, sc_int new_seed)
-{
- const sc_char *random_type;
- sc_char buffer[32];
-
- if (type != COMMAND_ONE && type != COMMAND_QUERY)
- {
- if_print_debug ("The Random command takes either one argument or"
- " no arguments.\n");
- return;
- }
-
- random_type = sc_is_congruential_random () ? "congruential" : "platform";
-
- if (type == COMMAND_QUERY)
- {
- if_print_debug ("The ");
- if_print_debug (random_type);
- if_print_debug (" random number generator is selected.\n");
- return;
- }
-
- if (new_seed == 0)
- {
- if_print_debug ("The seed value may not be zero.\n");
- return;
- }
-
- sc_seed_random (new_seed);
-
- if_print_debug ("Set seed ");
- sprintf (buffer, "%ld", new_seed);
- if_print_debug (buffer);
- if_print_debug (" for the ");
- if_print_debug (random_type);
- if_print_debug (" random number generator.\n");
+debug_random(sc_command_type_t type, sc_int new_seed) {
+ const sc_char *random_type;
+ sc_char buffer[32];
+
+ if (type != COMMAND_ONE && type != COMMAND_QUERY) {
+ if_print_debug("The Random command takes either one argument or"
+ " no arguments.\n");
+ return;
+ }
+
+ random_type = sc_is_congruential_random() ? "congruential" : "platform";
+
+ if (type == COMMAND_QUERY) {
+ if_print_debug("The ");
+ if_print_debug(random_type);
+ if_print_debug(" random number generator is selected.\n");
+ return;
+ }
+
+ if (new_seed == 0) {
+ if_print_debug("The seed value may not be zero.\n");
+ return;
+ }
+
+ sc_seed_random(new_seed);
+
+ if_print_debug("Set seed ");
+ sprintf(buffer, "%ld", new_seed);
+ if_print_debug(buffer);
+ if_print_debug(" for the ");
+ if_print_debug(random_type);
+ if_print_debug(" random number generator.\n");
}
@@ -1732,184 +1634,165 @@ debug_random (sc_command_type_t type, sc_int new_seed)
* Common handler for setting and clearing watchpoints.
*/
static void
-debug_watchpoint_common (sc_gameref_t game, sc_command_t command,
- sc_command_type_t type, sc_int arg1, sc_int arg2)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
- sc_int low = arg1, high = arg2;
- sc_int limit, index_;
- const sc_char *class_;
- sc_bool *watchpoints, action;
- sc_char buffer[32];
- assert (debug_is_valid (debug));
-
- /* Initialize variables to avoid gcc warnings. */
- limit = 0;
- class_ = NULL;
- watchpoints = NULL;
- action = FALSE;
-
- /* Set action to TRUE or FALSE, for setting/clearing watchpoints. */
- switch (command)
- {
- case DEBUG_WATCHPLAYER:
- case DEBUG_WATCHOBJECTS:
- case DEBUG_WATCHNPCS:
- case DEBUG_WATCHEVENTS:
- case DEBUG_WATCHTASKS:
- case DEBUG_WATCHVARIABLES:
- action = TRUE;
- break;
- case DEBUG_CLEARPLAYER:
- case DEBUG_CLEAROBJECTS:
- case DEBUG_CLEARNPCS:
- case DEBUG_CLEAREVENTS:
- case DEBUG_CLEARTASKS:
- case DEBUG_CLEARVARIABLES:
- action = FALSE;
- break;
- default:
- sc_fatal ("debug_watchpoint_common: invalid command\n");
- }
-
- /* Handle player watchpoint setting. */
- if (command == DEBUG_WATCHPLAYER || command == DEBUG_CLEARPLAYER)
- {
- if (command == DEBUG_CLEARPLAYER)
- {
- debug->watch_player = action;
- if_print_debug ("Cleared Player watchpoint.\n");
- }
- else if (type == COMMAND_ONE && arg1 == 0)
- {
- debug->watch_player = action;
- if_print_debug ("Set Player watchpoint.\n");
- }
- else
- {
- if (debug->watch_player)
- if_print_debug ("Player watchpoint is set.\n");
- else
- if_print_debug ("No Player watchpoint is set; to set one, use"
- " \"Watchplayer 0\".\n");
- }
- return;
- }
-
- /* Demultiplex watchpoint command. */
- switch (command)
- {
- case DEBUG_WATCHOBJECTS:
- case DEBUG_CLEAROBJECTS:
- class_ = "Object";
- watchpoints = debug->watch_objects;
- limit = gs_object_count (game);
- break;
- case DEBUG_WATCHNPCS:
- case DEBUG_CLEARNPCS:
- class_ = "NPC";
- watchpoints = debug->watch_npcs;
- limit = gs_npc_count (game);
- break;
- case DEBUG_WATCHEVENTS:
- case DEBUG_CLEAREVENTS:
- class_ = "Event";
- watchpoints = debug->watch_events;
- limit = gs_event_count (game);
- break;
- case DEBUG_WATCHTASKS:
- case DEBUG_CLEARTASKS:
- class_ = "Task";
- watchpoints = debug->watch_tasks;
- limit = gs_task_count (game);
- break;
- case DEBUG_WATCHVARIABLES:
- case DEBUG_CLEARVARIABLES:
- class_ = "Variable";
- watchpoints = debug->watch_variables;
- limit = debug_variable_count (game);
- break;
- default:
- sc_fatal ("debug_watchpoint_common: invalid command\n");
- }
-
- /* Normalize to this limit. */
- if (!debug_normalize_arguments (type, &low, &high, limit))
- {
- if (limit == 0)
- {
- if_print_debug ("There is nothing of type ");
- debug_print_quoted (class_);
- if_print_debug (" to watch.\n");
- }
- else
- {
- if_print_debug ("Invalid item or range for ");
- debug_print_quoted (class_);
- if (limit == 1)
- if_print_debug ("; only 0 is valid.\n");
- else
- {
- if_print_debug ("; valid values are 0 to ");
- sprintf (buffer, "%ld", limit - 1);
- if_print_debug (buffer);
- if_print_debug (".\n");
- }
- }
- return;
- }
-
- /* On query, search the array for set flags, and print out. */
- if (type == COMMAND_QUERY)
- {
- sc_bool printed = FALSE;
-
- /* Scan for set watchpoints, and list each found. */
- for (index_ = low; index_ <= high; index_++)
- {
- if (watchpoints[index_])
- {
- if (!printed)
- {
- if_print_debug ("Watchpoints are set for ");
- if_print_debug (class_);
- if_print_debug (" { ");
- }
- sprintf (buffer, "%ld", index_);
- if_print_debug (buffer);
- if_print_debug_character (' ');
- printed = TRUE;
- }
- }
- if (printed)
- if_print_debug ("}.\n");
- else
- {
- if_print_debug ("No ");
- if_print_debug (class_);
- if_print_debug (" watchpoints are set.\n");
- }
- return;
- }
-
- /*
- * For non-queries, set watchpoint flags as defined in action for
- * the range determined, and print confirmation.
- */
- for (index_ = low; index_ <= high; index_++)
- watchpoints[index_] = action;
-
- if (action)
- if_print_debug ("Set ");
- else
- if_print_debug ("Cleared ");
- sprintf (buffer, "%ld ", high - low + 1);
- if_print_debug (buffer);
- if_print_debug (class_);
- if (high == low)
- if_print_debug (" watchpoint.\n");
- else
- if_print_debug (" watchpoints.\n");
+debug_watchpoint_common(sc_gameref_t game, sc_command_t command,
+ sc_command_type_t type, sc_int arg1, sc_int arg2) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+ sc_int low = arg1, high = arg2;
+ sc_int limit, index_;
+ const sc_char *class_;
+ sc_bool *watchpoints, action;
+ sc_char buffer[32];
+ assert(debug_is_valid(debug));
+
+ /* Initialize variables to avoid gcc warnings. */
+ limit = 0;
+ class_ = NULL;
+ watchpoints = NULL;
+ action = FALSE;
+
+ /* Set action to TRUE or FALSE, for setting/clearing watchpoints. */
+ switch (command) {
+ case DEBUG_WATCHPLAYER:
+ case DEBUG_WATCHOBJECTS:
+ case DEBUG_WATCHNPCS:
+ case DEBUG_WATCHEVENTS:
+ case DEBUG_WATCHTASKS:
+ case DEBUG_WATCHVARIABLES:
+ action = TRUE;
+ break;
+ case DEBUG_CLEARPLAYER:
+ case DEBUG_CLEAROBJECTS:
+ case DEBUG_CLEARNPCS:
+ case DEBUG_CLEAREVENTS:
+ case DEBUG_CLEARTASKS:
+ case DEBUG_CLEARVARIABLES:
+ action = FALSE;
+ break;
+ default:
+ sc_fatal("debug_watchpoint_common: invalid command\n");
+ }
+
+ /* Handle player watchpoint setting. */
+ if (command == DEBUG_WATCHPLAYER || command == DEBUG_CLEARPLAYER) {
+ if (command == DEBUG_CLEARPLAYER) {
+ debug->watch_player = action;
+ if_print_debug("Cleared Player watchpoint.\n");
+ } else if (type == COMMAND_ONE && arg1 == 0) {
+ debug->watch_player = action;
+ if_print_debug("Set Player watchpoint.\n");
+ } else {
+ if (debug->watch_player)
+ if_print_debug("Player watchpoint is set.\n");
+ else
+ if_print_debug("No Player watchpoint is set; to set one, use"
+ " \"Watchplayer 0\".\n");
+ }
+ return;
+ }
+
+ /* Demultiplex watchpoint command. */
+ switch (command) {
+ case DEBUG_WATCHOBJECTS:
+ case DEBUG_CLEAROBJECTS:
+ class_ = "Object";
+ watchpoints = debug->watch_objects;
+ limit = gs_object_count(game);
+ break;
+ case DEBUG_WATCHNPCS:
+ case DEBUG_CLEARNPCS:
+ class_ = "NPC";
+ watchpoints = debug->watch_npcs;
+ limit = gs_npc_count(game);
+ break;
+ case DEBUG_WATCHEVENTS:
+ case DEBUG_CLEAREVENTS:
+ class_ = "Event";
+ watchpoints = debug->watch_events;
+ limit = gs_event_count(game);
+ break;
+ case DEBUG_WATCHTASKS:
+ case DEBUG_CLEARTASKS:
+ class_ = "Task";
+ watchpoints = debug->watch_tasks;
+ limit = gs_task_count(game);
+ break;
+ case DEBUG_WATCHVARIABLES:
+ case DEBUG_CLEARVARIABLES:
+ class_ = "Variable";
+ watchpoints = debug->watch_variables;
+ limit = debug_variable_count(game);
+ break;
+ default:
+ sc_fatal("debug_watchpoint_common: invalid command\n");
+ }
+
+ /* Normalize to this limit. */
+ if (!debug_normalize_arguments(type, &low, &high, limit)) {
+ if (limit == 0) {
+ if_print_debug("There is nothing of type ");
+ debug_print_quoted(class_);
+ if_print_debug(" to watch.\n");
+ } else {
+ if_print_debug("Invalid item or range for ");
+ debug_print_quoted(class_);
+ if (limit == 1)
+ if_print_debug("; only 0 is valid.\n");
+ else {
+ if_print_debug("; valid values are 0 to ");
+ sprintf(buffer, "%ld", limit - 1);
+ if_print_debug(buffer);
+ if_print_debug(".\n");
+ }
+ }
+ return;
+ }
+
+ /* On query, search the array for set flags, and print out. */
+ if (type == COMMAND_QUERY) {
+ sc_bool printed = FALSE;
+
+ /* Scan for set watchpoints, and list each found. */
+ for (index_ = low; index_ <= high; index_++) {
+ if (watchpoints[index_]) {
+ if (!printed) {
+ if_print_debug("Watchpoints are set for ");
+ if_print_debug(class_);
+ if_print_debug(" { ");
+ }
+ sprintf(buffer, "%ld", index_);
+ if_print_debug(buffer);
+ if_print_debug_character(' ');
+ printed = TRUE;
+ }
+ }
+ if (printed)
+ if_print_debug("}.\n");
+ else {
+ if_print_debug("No ");
+ if_print_debug(class_);
+ if_print_debug(" watchpoints are set.\n");
+ }
+ return;
+ }
+
+ /*
+ * For non-queries, set watchpoint flags as defined in action for
+ * the range determined, and print confirmation.
+ */
+ for (index_ = low; index_ <= high; index_++)
+ watchpoints[index_] = action;
+
+ if (action)
+ if_print_debug("Set ");
+ else
+ if_print_debug("Cleared ");
+ sprintf(buffer, "%ld ", high - low + 1);
+ if_print_debug(buffer);
+ if_print_debug(class_);
+ if (high == low)
+ if_print_debug(" watchpoint.\n");
+ else
+ if_print_debug(" watchpoints.\n");
}
@@ -1919,53 +1802,50 @@ debug_watchpoint_common (sc_gameref_t game, sc_command_t command,
* Common handler to list out and clear all set watchpoints at a stroke.
*/
static void
-debug_watchall_common (sc_gameref_t game,
- sc_command_t command, sc_command_type_t type)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
- assert (debug_is_valid (debug));
-
- if (type != COMMAND_QUERY)
- {
- if (command == DEBUG_WATCHALL)
- if_print_debug ("The Watchall command takes no arguments.\n");
- else
- if_print_debug ("The Clearall command takes no arguments.\n");
- return;
- }
-
- /* Query all set watchpoints using common watchpoint handler... */
- if (command == DEBUG_WATCHALL)
- {
- debug_watchpoint_common (game,
- DEBUG_WATCHPLAYER, COMMAND_QUERY, 0, 0);
- debug_watchpoint_common (game,
- DEBUG_WATCHOBJECTS, COMMAND_QUERY, 0, 0);
- debug_watchpoint_common (game,
- DEBUG_WATCHNPCS, COMMAND_QUERY, 0, 0);
- debug_watchpoint_common (game,
- DEBUG_WATCHEVENTS, COMMAND_QUERY, 0, 0);
- debug_watchpoint_common (game,
- DEBUG_WATCHTASKS, COMMAND_QUERY, 0, 0);
- debug_watchpoint_common (game,
- DEBUG_WATCHVARIABLES, COMMAND_QUERY, 0, 0);
- return;
- }
-
- /* ...but reset all the fast way, with memset(). */
- assert (command == DEBUG_CLEARALL);
- debug->watch_player = FALSE;
- memset (debug->watch_objects, FALSE,
- gs_object_count (game) * sizeof (*debug->watch_objects));
- memset (debug->watch_npcs, FALSE,
- gs_npc_count (game) * sizeof (*debug->watch_npcs));
- memset (debug->watch_events, FALSE,
- gs_event_count (game) * sizeof (*debug->watch_events));
- memset (debug->watch_tasks, FALSE,
- gs_task_count (game) * sizeof (*debug->watch_tasks));
- memset (debug->watch_variables, FALSE,
- debug_variable_count (game) * sizeof (*debug->watch_variables));
- if_print_debug ("Cleared all watchpoints.\n");
+debug_watchall_common(sc_gameref_t game,
+ sc_command_t command, sc_command_type_t type) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+ assert(debug_is_valid(debug));
+
+ if (type != COMMAND_QUERY) {
+ if (command == DEBUG_WATCHALL)
+ if_print_debug("The Watchall command takes no arguments.\n");
+ else
+ if_print_debug("The Clearall command takes no arguments.\n");
+ return;
+ }
+
+ /* Query all set watchpoints using common watchpoint handler... */
+ if (command == DEBUG_WATCHALL) {
+ debug_watchpoint_common(game,
+ DEBUG_WATCHPLAYER, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common(game,
+ DEBUG_WATCHOBJECTS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common(game,
+ DEBUG_WATCHNPCS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common(game,
+ DEBUG_WATCHEVENTS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common(game,
+ DEBUG_WATCHTASKS, COMMAND_QUERY, 0, 0);
+ debug_watchpoint_common(game,
+ DEBUG_WATCHVARIABLES, COMMAND_QUERY, 0, 0);
+ return;
+ }
+
+ /* ...but reset all the fast way, with memset(). */
+ assert(command == DEBUG_CLEARALL);
+ debug->watch_player = FALSE;
+ memset(debug->watch_objects, FALSE,
+ gs_object_count(game) * sizeof(*debug->watch_objects));
+ memset(debug->watch_npcs, FALSE,
+ gs_npc_count(game) * sizeof(*debug->watch_npcs));
+ memset(debug->watch_events, FALSE,
+ gs_event_count(game) * sizeof(*debug->watch_events));
+ memset(debug->watch_tasks, FALSE,
+ gs_task_count(game) * sizeof(*debug->watch_tasks));
+ memset(debug->watch_variables, FALSE,
+ debug_variable_count(game) * sizeof(*debug->watch_variables));
+ if_print_debug("Cleared all watchpoints.\n");
}
@@ -1975,18 +1855,17 @@ debug_watchall_common (sc_gameref_t game,
* Compare two objects, and return TRUE if the same.
*/
static sc_bool
-debug_compare_object (sc_gameref_t from, sc_gameref_t with, sc_int object)
-{
- const sc_objectstate_t *from_object = from->objects + object;
- const sc_objectstate_t *with_object = with->objects + object;
-
- return from_object->unmoved == with_object->unmoved
- && from_object->static_unmoved == with_object->static_unmoved
- && from_object->position == with_object->position
- && from_object->parent == with_object->parent
- && from_object->openness == with_object->openness
- && from_object->state == with_object->state
- && from_object->seen == with_object->seen;
+debug_compare_object(sc_gameref_t from, sc_gameref_t with, sc_int object) {
+ const sc_objectstate_t *from_object = from->objects + object;
+ const sc_objectstate_t *with_object = with->objects + object;
+
+ return from_object->unmoved == with_object->unmoved
+ && from_object->static_unmoved == with_object->static_unmoved
+ && from_object->position == with_object->position
+ && from_object->parent == with_object->parent
+ && from_object->openness == with_object->openness
+ && from_object->state == with_object->state
+ && from_object->seen == with_object->seen;
}
@@ -1996,21 +1875,20 @@ debug_compare_object (sc_gameref_t from, sc_gameref_t with, sc_int object)
* Compare two NPCs, and return TRUE if the same.
*/
static sc_bool
-debug_compare_npc (sc_gameref_t from, sc_gameref_t with, sc_int npc)
-{
- const sc_npcstate_t *from_npc = from->npcs + npc;
- const sc_npcstate_t *with_npc = with->npcs + npc;
-
- if (from_npc->walkstep_count != with_npc->walkstep_count)
- sc_fatal ("debug_compare_npc: walkstep count error\n");
-
- return from_npc->location == with_npc->location
- && from_npc->position == with_npc->position
- && from_npc->parent == with_npc->parent
- && from_npc->seen == with_npc->seen
- && memcmp (from_npc->walksteps, with_npc->walksteps,
- from_npc->walkstep_count
- * sizeof (*from_npc->walksteps)) == 0;
+debug_compare_npc(sc_gameref_t from, sc_gameref_t with, sc_int npc) {
+ const sc_npcstate_t *from_npc = from->npcs + npc;
+ const sc_npcstate_t *with_npc = with->npcs + npc;
+
+ if (from_npc->walkstep_count != with_npc->walkstep_count)
+ sc_fatal("debug_compare_npc: walkstep count error\n");
+
+ return from_npc->location == with_npc->location
+ && from_npc->position == with_npc->position
+ && from_npc->parent == with_npc->parent
+ && from_npc->seen == with_npc->seen
+ && memcmp(from_npc->walksteps, with_npc->walksteps,
+ from_npc->walkstep_count
+ * sizeof(*from_npc->walksteps)) == 0;
}
@@ -2020,13 +1898,12 @@ debug_compare_npc (sc_gameref_t from, sc_gameref_t with, sc_int npc)
* Compare two events, and return TRUE if the same.
*/
static sc_bool
-debug_compare_event (sc_gameref_t from, sc_gameref_t with, sc_int event)
-{
- const sc_eventstate_t *from_event = from->events + event;
- const sc_eventstate_t *with_event = with->events + event;
+debug_compare_event(sc_gameref_t from, sc_gameref_t with, sc_int event) {
+ const sc_eventstate_t *from_event = from->events + event;
+ const sc_eventstate_t *with_event = with->events + event;
- return from_event->state == with_event->state
- && from_event->time == with_event->time;
+ return from_event->state == with_event->state
+ && from_event->time == with_event->time;
}
@@ -2036,13 +1913,12 @@ debug_compare_event (sc_gameref_t from, sc_gameref_t with, sc_int event)
* Compare two tasks, and return TRUE if the same.
*/
static sc_bool
-debug_compare_task (sc_gameref_t from, sc_gameref_t with, sc_int task)
-{
- const sc_taskstate_t *from_task = from->tasks + task;
- const sc_taskstate_t *with_task = with->tasks + task;
+debug_compare_task(sc_gameref_t from, sc_gameref_t with, sc_int task) {
+ const sc_taskstate_t *from_task = from->tasks + task;
+ const sc_taskstate_t *with_task = with->tasks + task;
- return from_task->done == with_task->done
- && from_task->scored == with_task->scored;
+ return from_task->done == with_task->done
+ && from_task->scored == with_task->scored;
}
@@ -2052,44 +1928,42 @@ debug_compare_task (sc_gameref_t from, sc_gameref_t with, sc_int task)
* Compare two variables, and return TRUE if the same.
*/
static sc_bool
-debug_compare_variable (sc_gameref_t from, sc_gameref_t with, sc_int variable)
-{
- const sc_prop_setref_t bundle = from->bundle;
- const sc_var_setref_t from_var = from->vars;
- const sc_var_setref_t with_var = with->vars;
- sc_vartype_t vt_key[3], vt_rvalue, vt_rvalue2;
- const sc_char *name;
- sc_int var_type, var_type2;
- sc_bool equal = FALSE;
-
- if (from->bundle != with->bundle)
- sc_fatal ("debug_compare_variable: property sharing malfunction\n");
-
- vt_key[0].string = "Variables";
- vt_key[1].integer = variable;
- vt_key[2].string = "Name";
- name = prop_get_string (bundle, "S<-sis", vt_key);
-
- if (!var_get (from_var, name, &var_type, &vt_rvalue)
- || !var_get (with_var, name, &var_type2, &vt_rvalue2))
- sc_fatal ("debug_compare_variable: can't find variable %s\n", name);
- else if (var_type != var_type2)
- sc_fatal ("debug_compare_variable: variable type mismatch %s\n", name);
-
- switch (var_type)
- {
- case VAR_INTEGER:
- equal = (vt_rvalue.integer == vt_rvalue2.integer);
- break;
- case VAR_STRING:
- equal = !strcmp (vt_rvalue.string, vt_rvalue2.string);
- break;
- default:
- sc_fatal ("debug_compare_variable:"
- " invalid variable type, %ld\n", var_type);
- }
-
- return equal;
+debug_compare_variable(sc_gameref_t from, sc_gameref_t with, sc_int variable) {
+ const sc_prop_setref_t bundle = from->bundle;
+ const sc_var_setref_t from_var = from->vars;
+ const sc_var_setref_t with_var = with->vars;
+ sc_vartype_t vt_key[3], vt_rvalue, vt_rvalue2;
+ const sc_char *name;
+ sc_int var_type, var_type2;
+ sc_bool equal = FALSE;
+
+ if (from->bundle != with->bundle)
+ sc_fatal("debug_compare_variable: property sharing malfunction\n");
+
+ vt_key[0].string = "Variables";
+ vt_key[1].integer = variable;
+ vt_key[2].string = "Name";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+
+ if (!var_get(from_var, name, &var_type, &vt_rvalue)
+ || !var_get(with_var, name, &var_type2, &vt_rvalue2))
+ sc_fatal("debug_compare_variable: can't find variable %s\n", name);
+ else if (var_type != var_type2)
+ sc_fatal("debug_compare_variable: variable type mismatch %s\n", name);
+
+ switch (var_type) {
+ case VAR_INTEGER:
+ equal = (vt_rvalue.integer == vt_rvalue2.integer);
+ break;
+ case VAR_STRING:
+ equal = !strcmp(vt_rvalue.string, vt_rvalue2.string);
+ break;
+ default:
+ sc_fatal("debug_compare_variable:"
+ " invalid variable type, %ld\n", var_type);
+ }
+
+ return equal;
}
@@ -2102,44 +1976,40 @@ debug_compare_variable (sc_gameref_t from, sc_gameref_t with, sc_int variable)
* if any differed.
*/
static sc_bool
-debug_check_class (sc_gameref_t from, sc_gameref_t with,
- const sc_char *class_, sc_int class_count,
- const sc_bool *watchpoints,
- sc_bool (*const compare_function)
- (sc_gameref_t, sc_gameref_t, sc_int))
-{
- sc_int index_;
- sc_bool triggered = FALSE;
-
- /*
- * Scan the watchpoints array for set watchpoints, comparing classes
- * where the watchpoint flag is set.
- */
- for (index_ = 0; index_ < class_count; index_++)
- {
- if (!watchpoints[index_])
- continue;
-
- if (!compare_function (from, with, index_))
- {
- sc_char buffer[32];
-
- if (!triggered)
- {
- if_print_debug ("--- ");
- if_print_debug (class_);
- if_print_debug (" watchpoint triggered { ");
- }
- sprintf (buffer, "%ld ", index_);
- if_print_debug (buffer);
- triggered = TRUE;
- }
- }
- if (triggered)
- if_print_debug ("}.\n");
-
- /* Return TRUE if anything differed. */
- return triggered;
+debug_check_class(sc_gameref_t from, sc_gameref_t with,
+ const sc_char *class_, sc_int class_count,
+ const sc_bool *watchpoints,
+ sc_bool(*const compare_function)
+ (sc_gameref_t, sc_gameref_t, sc_int)) {
+ sc_int index_;
+ sc_bool triggered = FALSE;
+
+ /*
+ * Scan the watchpoints array for set watchpoints, comparing classes
+ * where the watchpoint flag is set.
+ */
+ for (index_ = 0; index_ < class_count; index_++) {
+ if (!watchpoints[index_])
+ continue;
+
+ if (!compare_function(from, with, index_)) {
+ sc_char buffer[32];
+
+ if (!triggered) {
+ if_print_debug("--- ");
+ if_print_debug(class_);
+ if_print_debug(" watchpoint triggered { ");
+ }
+ sprintf(buffer, "%ld ", index_);
+ if_print_debug(buffer);
+ triggered = TRUE;
+ }
+ }
+ if (triggered)
+ if_print_debug("}.\n");
+
+ /* Return TRUE if anything differed. */
+ return triggered;
}
@@ -2151,49 +2021,46 @@ debug_check_class (sc_gameref_t from, sc_gameref_t with,
* in which case no check is possible).
*/
static sc_bool
-debug_check_watchpoints (sc_gameref_t game)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
- const sc_gameref_t undo = game->undo;
- sc_bool triggered;
- assert (debug_is_valid (debug) && gs_is_game_valid (undo));
-
- /* If no undo is present, no check is possible. */
- if (!game->undo_available)
- return FALSE;
-
- /* Check first for player watchpoint. */
- triggered = FALSE;
- if (debug->watch_player)
- {
- if (gs_playerroom (game) != gs_playerroom (undo)
- || gs_playerposition (game) != gs_playerposition (undo)
- || gs_playerparent (game) != gs_playerparent (undo))
- {
- if_print_debug ("--- Player watchpoint triggered.\n");
- triggered |= TRUE;
- }
- }
-
- /* Now check other classes of watchpoint. */
- triggered |= debug_check_class (game, undo,
- "Object", gs_object_count (game),
- debug->watch_objects, debug_compare_object);
- triggered |= debug_check_class (game, undo,
- "NPC", gs_npc_count (game),
- debug->watch_npcs, debug_compare_npc);
- triggered |= debug_check_class (game, undo,
- "Event", gs_event_count (game),
- debug->watch_events, debug_compare_event);
- triggered |= debug_check_class (game, undo,
- "Task", gs_task_count (game),
- debug->watch_tasks, debug_compare_task);
- triggered |= debug_check_class (game, undo,
- "Variable", debug_variable_count (game),
- debug->watch_variables,
- debug_compare_variable);
-
- return triggered;
+debug_check_watchpoints(sc_gameref_t game) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+ const sc_gameref_t undo = game->undo;
+ sc_bool triggered;
+ assert(debug_is_valid(debug) && gs_is_game_valid(undo));
+
+ /* If no undo is present, no check is possible. */
+ if (!game->undo_available)
+ return FALSE;
+
+ /* Check first for player watchpoint. */
+ triggered = FALSE;
+ if (debug->watch_player) {
+ if (gs_playerroom(game) != gs_playerroom(undo)
+ || gs_playerposition(game) != gs_playerposition(undo)
+ || gs_playerparent(game) != gs_playerparent(undo)) {
+ if_print_debug("--- Player watchpoint triggered.\n");
+ triggered |= TRUE;
+ }
+ }
+
+ /* Now check other classes of watchpoint. */
+ triggered |= debug_check_class(game, undo,
+ "Object", gs_object_count(game),
+ debug->watch_objects, debug_compare_object);
+ triggered |= debug_check_class(game, undo,
+ "NPC", gs_npc_count(game),
+ debug->watch_npcs, debug_compare_npc);
+ triggered |= debug_check_class(game, undo,
+ "Event", gs_event_count(game),
+ debug->watch_events, debug_compare_event);
+ triggered |= debug_check_class(game, undo,
+ "Task", gs_task_count(game),
+ debug->watch_tasks, debug_compare_task);
+ triggered |= debug_check_class(game, undo,
+ "Variable", debug_variable_count(game),
+ debug->watch_variables,
+ debug_compare_variable);
+
+ return triggered;
}
@@ -2205,123 +2072,112 @@ debug_check_watchpoints (sc_gameref_t game)
* fails.
*/
static sc_command_t
-debug_parse_command (const sc_char *command_string,
- sc_command_type_t *type,
- sc_int *arg1, sc_int *arg2, sc_command_t *help_topic)
-{
- sc_command_t return_command;
- sc_command_type_t return_type;
- sc_int val1, val2, converted, matches;
- sc_char *help, *string, junk, wildcard;
- sc_bool is_help, is_parsed, is_wildcard;
- const sc_strings_t *entry;
-
- /* Allocate temporary strings long enough to take a copy of the input. */
- string = (sc_char *)sc_malloc (strlen (command_string) + 1);
- help = (sc_char *)sc_malloc (strlen (command_string) + 1);
-
- /*
- * Parse the input line, in a very simplistic fashion. The argument count
- * is one less than sscanf converts.
- */
- is_parsed = is_wildcard = is_help = FALSE;
- val1 = val2 = 0;
- converted = sscanf (command_string, " %s %s %c", help, string, &junk);
- if (converted == 2 && sc_strcasecmp (help, "help") == 0)
- {
- is_help = TRUE;
- is_parsed = TRUE;
- }
- sc_free (help);
- if (!is_parsed)
- {
- converted = sscanf (command_string,
- " %s %ld to %ld %c", string, &val1, &val2, &junk);
- if (converted != 3)
- converted = sscanf (command_string,
- " %s %ld - %ld %c", string, &val1, &val2, &junk);
- if (converted != 3)
- converted = sscanf (command_string,
- " %s %ld .. %ld %c", string, &val1, &val2, &junk);
- if (converted != 3)
- converted = sscanf (command_string,
- " %s %ld %ld %c", string, &val1, &val2, &junk);
- is_parsed |= converted == 3;
- }
- if (!is_parsed)
- {
- converted = sscanf (command_string,
- " %s %ld %c", string, &val1, &junk);
- is_parsed |= converted == 2;
- }
- if (!is_parsed)
- {
- converted = sscanf (command_string,
- " %s %c %c", string, &wildcard, &junk);
- if (converted == 2 && wildcard == '*')
- {
- is_wildcard = TRUE;
- is_parsed = TRUE;
- }
- else
- is_parsed |= converted == 1;
- }
- if (!is_parsed)
- {
- if_print_debug ("Invalid debug command.");
- if_print_debug (" Type 'help' for a list of valid commands.\n");
- sc_free (string);
- return DEBUG_NONE;
- }
-
- /* Decide on a command type based on the parse. */
- if (is_wildcard)
- return_type = COMMAND_ALL;
- else if (converted == 3)
- return_type = COMMAND_RANGE;
- else if (converted == 2)
- return_type = COMMAND_ONE;
- else
- return_type = COMMAND_QUERY;
-
- /*
- * Find the first unambiguous command matching the string. If none,
- * return DEBUG_NONE.
- */
- matches = 0;
- return_command = DEBUG_NONE;
- for (entry = DEBUG_COMMANDS; entry->command_string; entry++)
- {
- if (sc_strncasecmp (string, entry->command_string, strlen (string)) == 0)
- {
- matches++;
- return_command = entry->command;
- }
- }
- if (matches != 1)
- {
- if (matches > 1)
- if_print_debug ("Ambiguous debug command.");
- else
- if_print_debug ("Unrecognized debug command.");
- if_print_debug (" Type 'help' for a list of valid commands.\n");
- sc_free (string);
- return DEBUG_NONE;
- }
-
- /* Done with temporary command parse area. */
- sc_free (string);
-
- /*
- * Return the command type, arguments, and the debugging command. For help
- * <topic>, the command is help, with the command on which help requested
- * in *help_topic. All clear, then?
- */
- *type = return_type;
- *arg1 = val1;
- *arg2 = val2;
- *help_topic = is_help ? return_command : DEBUG_NONE;
- return is_help ? DEBUG_HELP : return_command;
+debug_parse_command(const sc_char *command_string,
+ sc_command_type_t *type,
+ sc_int *arg1, sc_int *arg2, sc_command_t *help_topic) {
+ sc_command_t return_command;
+ sc_command_type_t return_type;
+ sc_int val1, val2, converted, matches;
+ sc_char *help, *string, junk, wildcard;
+ sc_bool is_help, is_parsed, is_wildcard;
+ const sc_strings_t *entry;
+
+ /* Allocate temporary strings long enough to take a copy of the input. */
+ string = (sc_char *)sc_malloc(strlen(command_string) + 1);
+ help = (sc_char *)sc_malloc(strlen(command_string) + 1);
+
+ /*
+ * Parse the input line, in a very simplistic fashion. The argument count
+ * is one less than sscanf converts.
+ */
+ is_parsed = is_wildcard = is_help = FALSE;
+ val1 = val2 = 0;
+ converted = sscanf(command_string, " %s %s %c", help, string, &junk);
+ if (converted == 2 && sc_strcasecmp(help, "help") == 0) {
+ is_help = TRUE;
+ is_parsed = TRUE;
+ }
+ sc_free(help);
+ if (!is_parsed) {
+ converted = sscanf(command_string,
+ " %s %ld to %ld %c", string, &val1, &val2, &junk);
+ if (converted != 3)
+ converted = sscanf(command_string,
+ " %s %ld - %ld %c", string, &val1, &val2, &junk);
+ if (converted != 3)
+ converted = sscanf(command_string,
+ " %s %ld .. %ld %c", string, &val1, &val2, &junk);
+ if (converted != 3)
+ converted = sscanf(command_string,
+ " %s %ld %ld %c", string, &val1, &val2, &junk);
+ is_parsed |= converted == 3;
+ }
+ if (!is_parsed) {
+ converted = sscanf(command_string,
+ " %s %ld %c", string, &val1, &junk);
+ is_parsed |= converted == 2;
+ }
+ if (!is_parsed) {
+ converted = sscanf(command_string,
+ " %s %c %c", string, &wildcard, &junk);
+ if (converted == 2 && wildcard == '*') {
+ is_wildcard = TRUE;
+ is_parsed = TRUE;
+ } else
+ is_parsed |= converted == 1;
+ }
+ if (!is_parsed) {
+ if_print_debug("Invalid debug command.");
+ if_print_debug(" Type 'help' for a list of valid commands.\n");
+ sc_free(string);
+ return DEBUG_NONE;
+ }
+
+ /* Decide on a command type based on the parse. */
+ if (is_wildcard)
+ return_type = COMMAND_ALL;
+ else if (converted == 3)
+ return_type = COMMAND_RANGE;
+ else if (converted == 2)
+ return_type = COMMAND_ONE;
+ else
+ return_type = COMMAND_QUERY;
+
+ /*
+ * Find the first unambiguous command matching the string. If none,
+ * return DEBUG_NONE.
+ */
+ matches = 0;
+ return_command = DEBUG_NONE;
+ for (entry = DEBUG_COMMANDS; entry->command_string; entry++) {
+ if (sc_strncasecmp(string, entry->command_string, strlen(string)) == 0) {
+ matches++;
+ return_command = entry->command;
+ }
+ }
+ if (matches != 1) {
+ if (matches > 1)
+ if_print_debug("Ambiguous debug command.");
+ else
+ if_print_debug("Unrecognized debug command.");
+ if_print_debug(" Type 'help' for a list of valid commands.\n");
+ sc_free(string);
+ return DEBUG_NONE;
+ }
+
+ /* Done with temporary command parse area. */
+ sc_free(string);
+
+ /*
+ * Return the command type, arguments, and the debugging command. For help
+ * <topic>, the command is help, with the command on which help requested
+ * in *help_topic. All clear, then?
+ */
+ *type = return_type;
+ *arg1 = val1;
+ *arg2 = val2;
+ *help_topic = is_help ? return_command : DEBUG_NONE;
+ return is_help ? DEBUG_HELP : return_command;
}
@@ -2331,69 +2187,67 @@ debug_parse_command (const sc_char *command_string,
* Dispatch a debugging command to the appropriate handler.
*/
static void
-debug_dispatch (sc_gameref_t game,
- sc_command_t command, sc_command_type_t type,
- sc_int arg1, sc_int arg2, sc_command_t help_topic)
-{
- /* Demultiplex debugging command, and call handlers. */
- switch (command)
- {
- case DEBUG_HELP:
- debug_help (help_topic);
- break;
- case DEBUG_BUFFER:
- debug_buffer (game, type);
- break;
- case DEBUG_RESOURCES:
- debug_resources (game, type);
- break;
- case DEBUG_RANDOM:
- debug_random (type, arg1);
- break;
- case DEBUG_GAME:
- debug_game (game, type);
- break;
- case DEBUG_PLAYER:
- case DEBUG_OLDPLAYER:
- debug_player (game, command, type);
- break;
- case DEBUG_ROOMS:
- case DEBUG_OBJECTS:
- case DEBUG_NPCS:
- case DEBUG_EVENTS:
- case DEBUG_TASKS:
- case DEBUG_VARIABLES:
- case DEBUG_OLDROOMS:
- case DEBUG_OLDOBJECTS:
- case DEBUG_OLDNPCS:
- case DEBUG_OLDEVENTS:
- case DEBUG_OLDTASKS:
- case DEBUG_OLDVARIABLES:
- debug_dump_common (game, command, type, arg1, arg2);
- break;
- case DEBUG_WATCHPLAYER:
- case DEBUG_WATCHOBJECTS:
- case DEBUG_WATCHNPCS:
- case DEBUG_WATCHEVENTS:
- case DEBUG_WATCHTASKS:
- case DEBUG_WATCHVARIABLES:
- case DEBUG_CLEARPLAYER:
- case DEBUG_CLEAROBJECTS:
- case DEBUG_CLEARNPCS:
- case DEBUG_CLEAREVENTS:
- case DEBUG_CLEARTASKS:
- case DEBUG_CLEARVARIABLES:
- debug_watchpoint_common (game, command, type, arg1, arg2);
- break;
- case DEBUG_WATCHALL:
- case DEBUG_CLEARALL:
- debug_watchall_common (game, command, type);
- break;
- case DEBUG_NONE:
- break;
- default:
- sc_fatal ("debug_dispatch: invalid debug command\n");
- }
+debug_dispatch(sc_gameref_t game,
+ sc_command_t command, sc_command_type_t type,
+ sc_int arg1, sc_int arg2, sc_command_t help_topic) {
+ /* Demultiplex debugging command, and call handlers. */
+ switch (command) {
+ case DEBUG_HELP:
+ debug_help(help_topic);
+ break;
+ case DEBUG_BUFFER:
+ debug_buffer(game, type);
+ break;
+ case DEBUG_RESOURCES:
+ debug_resources(game, type);
+ break;
+ case DEBUG_RANDOM:
+ debug_random(type, arg1);
+ break;
+ case DEBUG_GAME:
+ debug_game(game, type);
+ break;
+ case DEBUG_PLAYER:
+ case DEBUG_OLDPLAYER:
+ debug_player(game, command, type);
+ break;
+ case DEBUG_ROOMS:
+ case DEBUG_OBJECTS:
+ case DEBUG_NPCS:
+ case DEBUG_EVENTS:
+ case DEBUG_TASKS:
+ case DEBUG_VARIABLES:
+ case DEBUG_OLDROOMS:
+ case DEBUG_OLDOBJECTS:
+ case DEBUG_OLDNPCS:
+ case DEBUG_OLDEVENTS:
+ case DEBUG_OLDTASKS:
+ case DEBUG_OLDVARIABLES:
+ debug_dump_common(game, command, type, arg1, arg2);
+ break;
+ case DEBUG_WATCHPLAYER:
+ case DEBUG_WATCHOBJECTS:
+ case DEBUG_WATCHNPCS:
+ case DEBUG_WATCHEVENTS:
+ case DEBUG_WATCHTASKS:
+ case DEBUG_WATCHVARIABLES:
+ case DEBUG_CLEARPLAYER:
+ case DEBUG_CLEAROBJECTS:
+ case DEBUG_CLEARNPCS:
+ case DEBUG_CLEAREVENTS:
+ case DEBUG_CLEARTASKS:
+ case DEBUG_CLEARVARIABLES:
+ debug_watchpoint_common(game, command, type, arg1, arg2);
+ break;
+ case DEBUG_WATCHALL:
+ case DEBUG_CLEARALL:
+ debug_watchall_common(game, command, type);
+ break;
+ case DEBUG_NONE:
+ break;
+ default:
+ sc_fatal("debug_dispatch: invalid debug command\n");
+ }
}
@@ -2403,91 +2257,82 @@ debug_dispatch (sc_gameref_t game,
* Create a small debugging dialog with the user.
*/
static void
-debug_dialog (sc_gameref_t game)
-{
- const sc_filterref_t filter = gs_get_filter (game);
- const sc_debuggerref_t debug = debug_get_debugger (game);
- const sc_var_setref_t vars = gs_get_vars (game);
- assert (debug_is_valid (debug));
-
- /*
- * Note elapsed seconds, so time stands still while debugging, and clear
- * any pending game quit left over from prior dialogs (just in case).
- */
- debug->elapsed_seconds = var_get_elapsed_seconds (vars);
- debug->quit_pending = FALSE;
-
- /* Handle debug commands until debugger quit or game quit. */
- while (TRUE)
- {
- sc_char buffer[DEBUG_BUFFER_SIZE];
- sc_command_t command, help_topic;
- sc_command_type_t type;
- sc_int arg1, arg2;
-
- /* Get a debugging command string from the user. */
- do
- {
- if_read_debug (buffer, sizeof (buffer));
-
- if (g_vm->shouldQuit())
- return;
- }
- while (sc_strempty (buffer));
-
- /* Parse the command read, and handle dialog exit commands. */
- command = debug_parse_command (buffer,
- &type, &arg1, &arg2, &help_topic);
- if (command == DEBUG_CONTINUE || command == DEBUG_STEP)
- {
- if (!game->is_running)
- {
- if_print_debug ("The game is no longer running.\n");
- continue;
- }
-
- debug->single_step = (command == DEBUG_STEP);
- break;
- }
- else if (command == DEBUG_QUIT)
- {
- /*
- * If the game is not running, we can't halt it, and we don't need
- * to confirm the quit (either the player "quit" or the game
- * completed), so leave the dialog loop.
- */
- if (!game->is_running)
- break;
-
- /*
- * The game is still running, so confirm quit by requiring a repeat,
- * or if this is the confirmation, force the game to a halt.
- */
- if (!debug->quit_pending)
- {
- if_print_debug ("Use 'quit' again to confirm, or another"
- " debugger command to cancel.\n");
- debug->quit_pending = TRUE;
- continue;
- }
-
- /* Drop printfilter contents and quit the game. */
- pf_empty (filter);
- run_quit (game);
-
- /* Just in case... */
- if_print_debug ("Unable to quit from the game. Sorry.\n");
- continue;
- }
-
- /* Dispatch the remaining debugging commands, and clear quit flag. */
- debug_dispatch (game, command, type, arg1, arg2, help_topic);
- debug->quit_pending = FALSE;
- }
-
- /* Restart time, and clear any pending game quit. */
- var_set_elapsed_seconds (vars, debug->elapsed_seconds);
- debug->quit_pending = FALSE;
+debug_dialog(sc_gameref_t game) {
+ const sc_filterref_t filter = gs_get_filter(game);
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+ const sc_var_setref_t vars = gs_get_vars(game);
+ assert(debug_is_valid(debug));
+
+ /*
+ * Note elapsed seconds, so time stands still while debugging, and clear
+ * any pending game quit left over from prior dialogs (just in case).
+ */
+ debug->elapsed_seconds = var_get_elapsed_seconds(vars);
+ debug->quit_pending = FALSE;
+
+ /* Handle debug commands until debugger quit or game quit. */
+ while (TRUE) {
+ sc_char buffer[DEBUG_BUFFER_SIZE];
+ sc_command_t command, help_topic;
+ sc_command_type_t type;
+ sc_int arg1, arg2;
+
+ /* Get a debugging command string from the user. */
+ do {
+ if_read_debug(buffer, sizeof(buffer));
+
+ if (g_vm->shouldQuit())
+ return;
+ } while (sc_strempty(buffer));
+
+ /* Parse the command read, and handle dialog exit commands. */
+ command = debug_parse_command(buffer,
+ &type, &arg1, &arg2, &help_topic);
+ if (command == DEBUG_CONTINUE || command == DEBUG_STEP) {
+ if (!game->is_running) {
+ if_print_debug("The game is no longer running.\n");
+ continue;
+ }
+
+ debug->single_step = (command == DEBUG_STEP);
+ break;
+ } else if (command == DEBUG_QUIT) {
+ /*
+ * If the game is not running, we can't halt it, and we don't need
+ * to confirm the quit (either the player "quit" or the game
+ * completed), so leave the dialog loop.
+ */
+ if (!game->is_running)
+ break;
+
+ /*
+ * The game is still running, so confirm quit by requiring a repeat,
+ * or if this is the confirmation, force the game to a halt.
+ */
+ if (!debug->quit_pending) {
+ if_print_debug("Use 'quit' again to confirm, or another"
+ " debugger command to cancel.\n");
+ debug->quit_pending = TRUE;
+ continue;
+ }
+
+ /* Drop printfilter contents and quit the game. */
+ pf_empty(filter);
+ run_quit(game);
+
+ /* Just in case... */
+ if_print_debug("Unable to quit from the game. Sorry.\n");
+ continue;
+ }
+
+ /* Dispatch the remaining debugging commands, and clear quit flag. */
+ debug_dispatch(game, command, type, arg1, arg2, help_topic);
+ debug->quit_pending = FALSE;
+ }
+
+ /* Restart time, and clear any pending game quit. */
+ var_set_elapsed_seconds(vars, debug->elapsed_seconds);
+ debug->quit_pending = FALSE;
}
@@ -2498,34 +2343,32 @@ debug_dialog (sc_gameref_t game)
* TRUE if valid, FALSE if invalid (parse failed, not understood).
*/
sc_bool
-debug_run_command (sc_gameref_t game, const sc_char *debug_command)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
- sc_command_t command, help_topic;
- sc_command_type_t type;
- sc_int arg1, arg2;
-
- /* If debugging disallowed (not initialized), refuse the call. */
- if (debug)
- {
- /*
- * Parse the command string passed in, and return FALSE if the parse
- * fails, or if it returns DEBUG_CONTINUE, DEBUG_STEP, or DEBUG_QUIT,
- * none of which make any sense in this context.
- */
- command = debug_parse_command (debug_command,
- &type, &arg1, &arg2, &help_topic);
- if (command == DEBUG_NONE
- || command == DEBUG_CONTINUE || command == DEBUG_STEP
- || command == DEBUG_QUIT)
- return FALSE;
-
- /* Dispatch the remaining debugging commands, return successfully. */
- debug_dispatch (game, command, type, arg1, arg2, help_topic);
- return TRUE;
- }
-
- return FALSE;
+debug_run_command(sc_gameref_t game, const sc_char *debug_command) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+ sc_command_t command, help_topic;
+ sc_command_type_t type;
+ sc_int arg1, arg2;
+
+ /* If debugging disallowed (not initialized), refuse the call. */
+ if (debug) {
+ /*
+ * Parse the command string passed in, and return FALSE if the parse
+ * fails, or if it returns DEBUG_CONTINUE, DEBUG_STEP, or DEBUG_QUIT,
+ * none of which make any sense in this context.
+ */
+ command = debug_parse_command(debug_command,
+ &type, &arg1, &arg2, &help_topic);
+ if (command == DEBUG_NONE
+ || command == DEBUG_CONTINUE || command == DEBUG_STEP
+ || command == DEBUG_QUIT)
+ return FALSE;
+
+ /* Dispatch the remaining debugging commands, return successfully. */
+ debug_dispatch(game, command, type, arg1, arg2, help_topic);
+ return TRUE;
+ }
+
+ return FALSE;
}
@@ -2537,22 +2380,21 @@ debug_run_command (sc_gameref_t game, const sc_char *debug_command)
* dialog. Uses if_print_string() as this isn't debug output.
*/
sc_bool
-debug_cmd_debugger (sc_gameref_t game)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
-
- /* If debugging disallowed (not initialized), ignore the call. */
- if (debug)
- debug_dialog (game);
- else
- if_print_string ("SCARE's game debugger is not enabled. Sorry.\n");
-
- /*
- * Set as administrative command, so as not to consume a game turn, and
- * return successfully.
- */
- game->is_admin = TRUE;
- return TRUE;
+debug_cmd_debugger(sc_gameref_t game) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug)
+ debug_dialog(game);
+ else
+ if_print_string("SCARE's game debugger is not enabled. Sorry.\n");
+
+ /*
+ * Set as administrative command, so as not to consume a game turn, and
+ * return successfully.
+ */
+ game->is_admin = TRUE;
+ return TRUE;
}
@@ -2569,79 +2411,67 @@ debug_cmd_debugger (sc_gameref_t game)
* watchpoints and offer the debug dialog one last time.
*/
void
-debug_game_started (sc_gameref_t game)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
-
- /* If debugging disallowed (not initialized), ignore the call. */
- if (debug)
- {
- /* Starting a new game, or a restore or undo of an old one? */
- if (!gs_room_seen (game, gs_playerroom (game)))
- {
- /*
- * It's a new game starting or restarting. Print a banner, and
- * run the debugger dialog.
- */
- if_print_debug ("\n--- SCARE " SCARE_VERSION SCARE_PATCH_LEVEL
- " Game Debugger\n"
- "--- Type 'help' for a list of commands.\n");
- debug_dialog (game);
- }
- else
- {
- /*
- * It's a restore or undo through memos, so run the dialog only if
- * single-stepping; no need to check watchpoints for this case as
- * none can be set -- no undo.
- */
- if (debug->single_step)
- debug_dialog (game);
- }
- }
+debug_game_started(sc_gameref_t game) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug) {
+ /* Starting a new game, or a restore or undo of an old one? */
+ if (!gs_room_seen(game, gs_playerroom(game))) {
+ /*
+ * It's a new game starting or restarting. Print a banner, and
+ * run the debugger dialog.
+ */
+ if_print_debug("\n--- SCARE " SCARE_VERSION SCARE_PATCH_LEVEL
+ " Game Debugger\n"
+ "--- Type 'help' for a list of commands.\n");
+ debug_dialog(game);
+ } else {
+ /*
+ * It's a restore or undo through memos, so run the dialog only if
+ * single-stepping; no need to check watchpoints for this case as
+ * none can be set -- no undo.
+ */
+ if (debug->single_step)
+ debug_dialog(game);
+ }
+ }
}
void
-debug_game_ended (sc_gameref_t game)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
-
- /* If debugging disallowed (not initialized), ignore the call. */
- if (debug)
- {
- /*
- * Using our carnal knowledge of the run main loop, we know here that
- * if the loop exited with do_restart or do_restore, we'll get a call to
- * debug_game_start() when the loop restarts. So in this case, ignore
- * the call (even if single stepping).
- */
- if (game->do_restart || game->do_restore)
- return;
-
- /*
- * Check for any final watchpoints, and print a message describing why
- * we're here. Suppress the check for watchpoints if the user exited
- * the game, as it'll only be a repeat of any found last turn update.
- */
- if (!game->is_running)
- {
- if (game->has_completed)
- {
- debug_check_watchpoints (game);
- if_print_debug ("\n--- The game has completed.\n");
- }
- else
- if_print_debug ("\n--- The game has exited.\n");
- }
- else
- {
- debug_check_watchpoints (game);
- if_print_debug ("\n--- The game is still running!\n");
- }
-
- /* Run a final dialog. */
- debug_dialog (game);
- }
+debug_game_ended(sc_gameref_t game) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug) {
+ /*
+ * Using our carnal knowledge of the run main loop, we know here that
+ * if the loop exited with do_restart or do_restore, we'll get a call to
+ * debug_game_start() when the loop restarts. So in this case, ignore
+ * the call (even if single stepping).
+ */
+ if (game->do_restart || game->do_restore)
+ return;
+
+ /*
+ * Check for any final watchpoints, and print a message describing why
+ * we're here. Suppress the check for watchpoints if the user exited
+ * the game, as it'll only be a repeat of any found last turn update.
+ */
+ if (!game->is_running) {
+ if (game->has_completed) {
+ debug_check_watchpoints(game);
+ if_print_debug("\n--- The game has completed.\n");
+ } else
+ if_print_debug("\n--- The game has exited.\n");
+ } else {
+ debug_check_watchpoints(game);
+ if_print_debug("\n--- The game is still running!\n");
+ }
+
+ /* Run a final dialog. */
+ debug_dialog(game);
+ }
}
@@ -2652,29 +2482,27 @@ debug_game_ended (sc_gameref_t game)
* watchpoints, and triggers a debug dialog when any fire.
*/
void
-debug_turn_update (sc_gameref_t game)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
-
- /* If debugging disallowed (not initialized), ignore the call. */
- if (debug)
- {
- /*
- * Again using carnal knowledge of the run main loop, if we're in
- * mid-wait, ignore the call. Also, ignore the call if the game is
- * no longer running, as we'll see a debug_game_ended() call come
- * along to handle that.
- */
- if (game->waitcounter > 0 || !game->is_running)
- return;
-
- /*
- * Run debugger dialog if any watchpoints triggered, or if single
- * stepping (even if none triggered).
- */
- if (debug_check_watchpoints (game) || debug->single_step)
- debug_dialog (game);
- }
+debug_turn_update(sc_gameref_t game) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+
+ /* If debugging disallowed (not initialized), ignore the call. */
+ if (debug) {
+ /*
+ * Again using carnal knowledge of the run main loop, if we're in
+ * mid-wait, ignore the call. Also, ignore the call if the game is
+ * no longer running, as we'll see a debug_game_ended() call come
+ * along to handle that.
+ */
+ if (game->waitcounter > 0 || !game->is_running)
+ return;
+
+ /*
+ * Run debugger dialog if any watchpoints triggered, or if single
+ * stepping (even if none triggered).
+ */
+ if (debug_check_watchpoints(game) || debug->single_step)
+ debug_dialog(game);
+ }
}
@@ -2690,30 +2518,27 @@ debug_turn_update (sc_gameref_t game)
* disabling.
*/
void
-debug_set_enabled (sc_gameref_t game, sc_bool enable)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
-
- /*
- * If enabling and not already enabled, or disabling and not already
- * disabled, either initialize or finalize..
- */
- if ((enable && !debug) || (!enable && debug))
- {
- /* Initialize or finalize debugging, as appropriate. */
- if (enable)
- debug_initialize (game);
- else
- debug_finalize (game);
- }
+debug_set_enabled(sc_gameref_t game, sc_bool enable) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
+
+ /*
+ * If enabling and not already enabled, or disabling and not already
+ * disabled, either initialize or finalize..
+ */
+ if ((enable && !debug) || (!enable && debug)) {
+ /* Initialize or finalize debugging, as appropriate. */
+ if (enable)
+ debug_initialize(game);
+ else
+ debug_finalize(game);
+ }
}
sc_bool
-debug_get_enabled (sc_gameref_t game)
-{
- const sc_debuggerref_t debug = debug_get_debugger (game);
+debug_get_enabled(sc_gameref_t game) {
+ const sc_debuggerref_t debug = debug_get_debugger(game);
- return debug != NULL;
+ return debug != NULL;
}
} // End of namespace Adrift
diff --git a/engines/glk/adrift/scevents.cpp b/engines/glk/adrift/scevents.cpp
index 18d95b1..0048cd6 100644
--- a/engines/glk/adrift/scevents.cpp
+++ b/engines/glk/adrift/scevents.cpp
@@ -43,19 +43,17 @@ static sc_bool evt_trace = FALSE;
* Return TRUE if any task at all matches the given completion state.
*/
static sc_bool
-evt_any_task_in_state (sc_gameref_t game, sc_bool state)
-{
- sc_int task;
-
- /* Scan tasks for any whose completion matches input. */
- for (task = 0; task < gs_task_count (game); task++)
- {
- if (gs_task_done (game, task) == state)
- return TRUE;
- }
-
- /* No tasks matched. */
- return FALSE;
+evt_any_task_in_state(sc_gameref_t game, sc_bool state) {
+ sc_int task;
+
+ /* Scan tasks for any whose completion matches input. */
+ for (task = 0; task < gs_task_count(game); task++) {
+ if (gs_task_done(game, task) == state)
+ return TRUE;
+ }
+
+ /* No tasks matched. */
+ return FALSE;
}
@@ -65,39 +63,37 @@ evt_any_task_in_state (sc_gameref_t game, sc_bool state)
* Return TRUE if player is in the right room for event text.
*/
sc_bool
-evt_can_see_event (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[5];
- sc_int type;
-
- /* Check room list for the event and return it. */
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "Where";
- vt_key[3].string = "Type";
- type = prop_get_integer (bundle, "I<-siss", vt_key);
- switch (type)
- {
- case ROOMLIST_NO_ROOMS:
- return FALSE;
- case ROOMLIST_ALL_ROOMS:
- return TRUE;
-
- case ROOMLIST_ONE_ROOM:
- vt_key[3].string = "Room";
- return prop_get_integer (bundle, "I<-siss", vt_key)
- == gs_playerroom (game);
-
- case ROOMLIST_SOME_ROOMS:
- vt_key[3].string = "Rooms";
- vt_key[4].integer = gs_playerroom (game);
- return prop_get_boolean (bundle, "B<-sissi", vt_key);
-
- default:
- sc_fatal ("evt_can_see_event: invalid type, %ld\n", type);
- return FALSE;
- }
+evt_can_see_event(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[5];
+ sc_int type;
+
+ /* Check room list for the event and return it. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Where";
+ vt_key[3].string = "Type";
+ type = prop_get_integer(bundle, "I<-siss", vt_key);
+ switch (type) {
+ case ROOMLIST_NO_ROOMS:
+ return FALSE;
+ case ROOMLIST_ALL_ROOMS:
+ return TRUE;
+
+ case ROOMLIST_ONE_ROOM:
+ vt_key[3].string = "Room";
+ return prop_get_integer(bundle, "I<-siss", vt_key)
+ == gs_playerroom(game);
+
+ case ROOMLIST_SOME_ROOMS:
+ vt_key[3].string = "Rooms";
+ vt_key[4].integer = gs_playerroom(game);
+ return prop_get_boolean(bundle, "B<-sissi", vt_key);
+
+ default:
+ sc_fatal("evt_can_see_event: invalid type, %ld\n", type);
+ return FALSE;
+ }
}
@@ -107,55 +103,50 @@ evt_can_see_event (sc_gameref_t game, sc_int event)
* Move an object from within an event.
*/
static void
-evt_move_object (sc_gameref_t game, sc_int object, sc_int destination)
-{
- /* Ignore negative values of object. */
- if (object >= 0)
- {
- if (evt_trace)
- {
- sc_trace ("Event: moving object %ld to room %ld\n",
- object, destination);
- }
-
- /* Move object depending on destination. */
- switch (destination)
- {
- case -1: /* Hidden. */
- gs_object_make_hidden (game, object);
- break;
-
- case 0: /* Held by player. */
- gs_object_player_get (game, object);
- break;
-
- case 1: /* Same room as player. */
- gs_object_to_room (game, object, gs_playerroom (game));
- break;
-
- default:
- if (destination < gs_room_count (game) + 2)
- gs_object_to_room (game, object, destination - 2);
- else
- {
- sc_int roomgroup, room;
-
- roomgroup = destination - gs_room_count (game) - 2;
- room = lib_random_roomgroup_member (game, roomgroup);
- gs_object_to_room (game, object, room);
- }
- break;
- }
-
- /*
- * If static, mark as no longer unmoved.
- *
- * TODO Is this the only place static objects can be moved? And just
- * how static is a static object if it's moveable, anyway?
- */
- if (obj_is_static (game, object))
- gs_set_object_static_unmoved (game, object, FALSE);
- }
+evt_move_object(sc_gameref_t game, sc_int object, sc_int destination) {
+ /* Ignore negative values of object. */
+ if (object >= 0) {
+ if (evt_trace) {
+ sc_trace("Event: moving object %ld to room %ld\n",
+ object, destination);
+ }
+
+ /* Move object depending on destination. */
+ switch (destination) {
+ case -1: /* Hidden. */
+ gs_object_make_hidden(game, object);
+ break;
+
+ case 0: /* Held by player. */
+ gs_object_player_get(game, object);
+ break;
+
+ case 1: /* Same room as player. */
+ gs_object_to_room(game, object, gs_playerroom(game));
+ break;
+
+ default:
+ if (destination < gs_room_count(game) + 2)
+ gs_object_to_room(game, object, destination - 2);
+ else {
+ sc_int roomgroup, room;
+
+ roomgroup = destination - gs_room_count(game) - 2;
+ room = lib_random_roomgroup_member(game, roomgroup);
+ gs_object_to_room(game, object, room);
+ }
+ break;
+ }
+
+ /*
+ * If static, mark as no longer unmoved.
+ *
+ * TODO Is this the only place static objects can be moved? And just
+ * how static is a static object if it's moveable, anyway?
+ */
+ if (obj_is_static(game, object))
+ gs_set_object_static_unmoved(game, object, FALSE);
+ }
}
@@ -168,36 +159,34 @@ evt_move_object (sc_gameref_t game, sc_int object, sc_int destination)
* can do the same thing here, though it's ugly.
*/
static sc_bool
-evt_fixup_v390_v380_immediate_restart (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_int version;
-
- vt_key[0].string = "Version";
- version = prop_get_integer (bundle, "I<-s", vt_key);
- if (version < TAF_VERSION_400)
- {
- sc_int time1, time2;
-
- if (evt_trace)
- sc_trace ("Event: applying 3.9/3.8 restart fixup\n");
-
- /* Set to running state. */
- gs_set_event_state (game, event, ES_RUNNING);
-
- /* Set up event time to be one less than a proper start. */
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "Time1";
- time1 = prop_get_integer (bundle, "I<-sis", vt_key);
- vt_key[2].string = "Time2";
- time2 = prop_get_integer (bundle, "I<-sis", vt_key);
- gs_set_event_time (game, event, sc_randomint (time1, time2) - 1);
- }
-
- /* Return TRUE if we applied the fixup. */
- return version < TAF_VERSION_400;
+evt_fixup_v390_v380_immediate_restart(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_int version;
+
+ vt_key[0].string = "Version";
+ version = prop_get_integer(bundle, "I<-s", vt_key);
+ if (version < TAF_VERSION_400) {
+ sc_int time1, time2;
+
+ if (evt_trace)
+ sc_trace("Event: applying 3.9/3.8 restart fixup\n");
+
+ /* Set to running state. */
+ gs_set_event_state(game, event, ES_RUNNING);
+
+ /* Set up event time to be one less than a proper start. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Time1";
+ time1 = prop_get_integer(bundle, "I<-sis", vt_key);
+ vt_key[2].string = "Time2";
+ time2 = prop_get_integer(bundle, "I<-sis", vt_key);
+ gs_set_event_time(game, event, sc_randomint(time1, time2) - 1);
+ }
+
+ /* Return TRUE if we applied the fixup. */
+ return version < TAF_VERSION_400;
}
@@ -207,58 +196,55 @@ evt_fixup_v390_v380_immediate_restart (sc_gameref_t game, sc_int event)
* Change an event from WAITING to RUNNING.
*/
static void
-evt_start_event (sc_gameref_t game, sc_int event)
-{
- const sc_filterref_t filter = gs_get_filter (game);
- const sc_prop_setref_t bundle = gs_get_bundle (game);
Commit: c147d0fda0a9607fe5ecbcaeea87533f84402e71
https://github.com/scummvm/scummvm/commit/c147d0fda0a9607fe5ecbcaeea87533f84402e71
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Formatting
Changed paths:
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/scdebug.cpp
engines/glk/adrift/scevents.cpp
engines/glk/adrift/scexpr.cpp
engines/glk/adrift/scgamest.cpp
engines/glk/adrift/scinterf.cpp
engines/glk/adrift/sclibrar.cpp
engines/glk/adrift/sclocale.cpp
engines/glk/adrift/scmemos.cpp
engines/glk/adrift/scnpcs.cpp
engines/glk/adrift/scobjcts.cpp
engines/glk/adrift/scparser.cpp
engines/glk/adrift/scprintf.cpp
engines/glk/adrift/scprops.cpp
engines/glk/adrift/scprotos.h
engines/glk/adrift/scresour.cpp
engines/glk/adrift/screstrs.cpp
engines/glk/adrift/scrunner.cpp
engines/glk/adrift/scserial.cpp
engines/glk/adrift/sctaffil.cpp
engines/glk/adrift/sctafpar.cpp
engines/glk/adrift/sctasks.cpp
engines/glk/adrift/scutils.cpp
engines/glk/adrift/scvars.cpp
engines/glk/adrift/sxfile.cpp
engines/glk/adrift/sxglob.cpp
engines/glk/adrift/sxscript.cpp
engines/glk/adrift/sxtester.cpp
engines/glk/adrift/sxutils.cpp
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index 37ac07f..cfe61ac 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -62,23 +62,20 @@ namespace Adrift {
static const glui32 GSC_PORT_VERSION = 0x00010310;
/* Two windows, one for the main text, and one for a status line. */
-static winid_t gsc_main_window = nullptr,
- gsc_status_window = nullptr;
+static winid_t gsc_main_window = nullptr, gsc_status_window = nullptr;
/*
* Transcript stream and input log. These are nullptr if there is no current
* collection of these strings.
*/
-static strid_t gsc_transcript_stream = nullptr,
- gsc_inputlog_stream = nullptr;
+static strid_t gsc_transcript_stream = nullptr, gsc_inputlog_stream = nullptr;
/* Input read log stream, for reading back an input log. */
static strid_t gsc_readlog_stream = nullptr;
/* Options that may be turned off or set by command line flags. */
-static int gsc_commands_enabled = TRUE,
- gsc_abbreviations_enabled = TRUE,
- gsc_unicode_enabled = TRUE;
+static int gsc_commands_enabled = TRUE, gsc_abbreviations_enabled = TRUE,
+ gsc_unicode_enabled = TRUE;
/* Adrift game to interpret. */
static sc_game gsc_game = nullptr;
@@ -86,7 +83,7 @@ static sc_game gsc_game = nullptr;
/* Special out-of-band os_confirm() options used locally with os_glk. */
static const sc_int GSC_CONF_SUBTLE_HINT = INT_MAX,
GSC_CONF_UNSUBTLE_HINT = INT_MAX - 1,
- GSC_CONF_CONTINUE_HINTS = INT_MAX - 2;
+ GSC_CONF_CONTINUE_HINTS = INT_MAX - 2;
/* Forward declaration of event wait functions, and a short delay. */
static void gsc_event_wait_2(glui32 wait_type_1,
@@ -105,8 +102,7 @@ static void gsc_short_delay();
* Fatal error handler. The function returns, expecting the caller to
* abort() or otherwise handle the error.
*/
-static void
-gsc_fatal(const char *string) {
+static void gsc_fatal(const char *string) {
/*
* If the failure happens too early for us to have a window, print
* the message to stderr.
@@ -136,8 +132,7 @@ gsc_fatal(const char *string) {
*
* Non-failing malloc; call gsc_fatal and exit if memory allocation fails.
*/
-static void *
-gsc_malloc(size_t size) {
+static void *gsc_malloc(size_t size) {
void *pointer;
pointer = malloc(size > 0 ? size : 1);
@@ -166,20 +161,20 @@ static const glui32 GSC_ISO_8859_EQUIVALENCE = 256;
* codepages where they're not (dingbats, for example).
*/
enum { GSC_TABLE_SIZE = 256 };
-typedef struct {
+struct gsc_codepages_t {
const glui32 unicode[GSC_TABLE_SIZE];
const sc_char *const ascii[GSC_TABLE_SIZE];
-} gsc_codepages_t;
+};
/*
* Locale contains a name and a pair of codepage structures, a main one and
* an alternate. The latter is intended for monospaced output.
*/
-typedef struct {
+struct gsc_locale_t {
const sc_char *const name;
const gsc_codepages_t main;
const gsc_codepages_t alternate;
-} gsc_locale_t;
+};
/*
@@ -513,8 +508,7 @@ static const gsc_locale_t *const gsc_fallback_locale = &GSC_LATIN1_LOCALE;
*
* Set a locale explicitly from the name passed in.
*/
-static void
-gsc_set_locale(const sc_char *name) {
+static void gsc_set_locale(const sc_char *name) {
const gsc_locale_t *matched = nullptr;
const gsc_locale_t *const *iterator;
assert(name);
@@ -544,8 +538,7 @@ gsc_set_locale(const sc_char *name) {
* Wrapper around g_vm->glk_put_char_uni(). Handles, inelegantly, the problem of
* having to write transcripts as ascii.
*/
-static void
-gsc_put_char_uni(glui32 unicode, const char *ascii) {
+static void gsc_put_char_uni(glui32 unicode, const char *ascii) {
/* If there is an transcript stream, temporarily disconnect it. */
if (gsc_transcript_stream)
g_vm->glk_window_set_echo_stream(gsc_main_window, nullptr);
@@ -570,9 +563,7 @@ gsc_put_char_uni(glui32 unicode, const char *ascii) {
* Write a single character using the supplied locale. Select either the
* main or the alternate codepage depending on the flag passed in.
*/
-static void
-gsc_put_char_locale(sc_char ch,
- const gsc_locale_t *locale, sc_bool is_alternate) {
+static void gsc_put_char_locale(sc_char ch, const gsc_locale_t *locale, sc_bool is_alternate) {
const gsc_codepages_t *codepage;
unsigned char character;
glui32 unicode;
@@ -657,47 +648,40 @@ gsc_put_char_locale(sc_char ch,
*
* Public functions for writing using the current or fallback locale.
*/
-static void
-gsc_put_char(const sc_char character) {
+static void gsc_put_char(const sc_char character) {
const gsc_locale_t *locale;
locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
gsc_put_char_locale(character, locale, FALSE);
}
-static void
-gsc_put_char_alternate(const sc_char character) {
+static void gsc_put_char_alternate(const sc_char character) {
const gsc_locale_t *locale;
locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
gsc_put_char_locale(character, locale, TRUE);
}
-static void
-gsc_put_buffer_using(const sc_char *buffer,
- sc_int length, void (*putchar_function)(sc_char)) {
+static void gsc_put_buffer_using(const sc_char *buffer, sc_int length, void (*putchar_function)(sc_char)) {
sc_int index_;
for (index_ = 0; index_ < length; index_++)
putchar_function(buffer[index_]);
}
-static void
-gsc_put_buffer(const sc_char *buffer, sc_int length) {
+static void gsc_put_buffer(const sc_char *buffer, sc_int length) {
assert(buffer);
gsc_put_buffer_using(buffer, length, gsc_put_char);
}
-static void
-gsc_put_string(const sc_char *string) {
+static void gsc_put_string(const sc_char *string) {
assert(string);
gsc_put_buffer_using(string, strlen(string), gsc_put_char);
}
-static void
-gsc_put_string_alternate(const sc_char *string) {
+static void gsc_put_string_alternate(const sc_char *string) {
assert(string);
gsc_put_buffer_using(string, strlen(string), gsc_put_char_alternate);
@@ -712,8 +696,7 @@ gsc_put_string_alternate(const sc_char *string) {
* reverse translations in line input. Returns '?' if there is no translation
* available.
*/
-static sc_char
-gsc_unicode_to_locale(glui32 unicode, const gsc_locale_t *locale) {
+static sc_char gsc_unicode_to_locale(glui32 unicode, const gsc_locale_t *locale) {
const gsc_codepages_t *codepage;
sc_int character;
@@ -733,9 +716,8 @@ gsc_unicode_to_locale(glui32 unicode, const gsc_locale_t *locale) {
return character < GSC_TABLE_SIZE ? (sc_char) character : '?';
}
-static void
-gsc_unicode_buffer_to_locale(const glui32 *unicode, sc_int length,
- sc_char *buffer, const gsc_locale_t *locale) {
+static void gsc_unicode_buffer_to_locale(const glui32 *unicode, sc_int length,
+ sc_char *buffer, const gsc_locale_t *locale) {
sc_int index_;
for (index_ = 0; index_ < length; index_++)
@@ -749,9 +731,7 @@ gsc_unicode_buffer_to_locale(const glui32 *unicode, sc_int length,
* Read in a line and translate out of the given locale. Returns the count
* of characters placed in the buffer.
*/
-static sc_int
-gsc_read_line_locale(sc_char *buffer,
- sc_int length, const gsc_locale_t *locale) {
+static sc_int gsc_read_line_locale(sc_char *buffer, sc_int length, const gsc_locale_t *locale) {
event_t event;
/*
@@ -791,8 +771,7 @@ gsc_read_line_locale(sc_char *buffer,
*
* Public function for reading using the current or fallback locale.
*/
-static sc_int
-gsc_read_line(sc_char *buffer, sc_int length) {
+static sc_int gsc_read_line(sc_char *buffer, sc_int length) {
const gsc_locale_t *locale;
locale = gsc_locale ? gsc_locale : gsc_fallback_locale;
@@ -824,8 +803,7 @@ static const sc_char *const GSC_WHITESPACE = "\t\n\v\f\r ";
* Return TRUE if string is non-null, not zero-length or contains characters
* other than whitespace.
*/
-static sc_bool
-gsc_is_string_usable(const sc_char *string) {
+static sc_bool gsc_is_string_usable(const sc_char *string) {
/* If non-null, scan for any non-space character. */
if (string) {
sc_int index_;
@@ -847,8 +825,7 @@ gsc_is_string_usable(const sc_char *string) {
* Update the status line from the current game state. This is for windowing
* Glk libraries.
*/
-static void
-gsc_status_update() {
+static void gsc_status_update() {
glui32 width, height;
uint index;
assert(gsc_status_window);
@@ -913,8 +890,7 @@ gsc_status_update() {
* Helper for gsc_status_print(), concatenates strings only up to the
* available length.
*/
-static void
-gsc_status_safe_strcat(char *dest, size_t length, const char *src) {
+static void gsc_status_safe_strcat(char *dest, size_t length, const char *src) {
size_t available, src_length;
/* Append only as many characters as will fit. */
@@ -932,8 +908,7 @@ gsc_status_safe_strcat(char *dest, size_t length, const char *src) {
* main window, if it has changed since the last call. This is for non-
* windowing Glk libraries.
*/
-static void
-gsc_status_print() {
+static void gsc_status_print() {
static char current_status[GSC_STATUS_BUFFER_LENGTH + 1];
const sc_char *room;
@@ -980,8 +955,7 @@ gsc_status_print() {
* Front end function for updating status. Either updates the status window
* or prints the status line to the main window.
*/
-static void
-gsc_status_notify() {
+static void gsc_status_notify() {
if (gsc_status_window)
gsc_status_update();
else
@@ -996,8 +970,7 @@ gsc_status_notify() {
* This function should be called on the appropriate Glk window resize and
* arrange events.
*/
-static void
-gsc_status_redraw() {
+static void gsc_status_redraw() {
if (gsc_status_window) {
winid_t parent;
@@ -1031,10 +1004,10 @@ static int gsc_help_requested = FALSE,
gsc_help_hints_silenced = FALSE;
/* Font descriptor type, encapsulating size and monospaced boolean. */
-typedef struct {
+struct gsc_font_size_t {
sc_bool is_monospaced;
sc_int size;
-} gsc_font_size_t;
+};
/* Font stack and attributes for nesting tags. */
enum { GSC_MAX_STYLE_NESTING = 32 };
@@ -1070,18 +1043,15 @@ static const glui32 GSC_CANCEL_WAIT_1 = ' ',
* Register a request for help, and print a note of how to get Glk command
* help from the interpreter unless silenced.
*/
-static void
-gsc_output_register_help_request() {
+static void gsc_output_register_help_request() {
gsc_help_requested = TRUE;
}
-static void
-gsc_output_silence_help_hints() {
+static void gsc_output_silence_help_hints() {
gsc_help_hints_silenced = TRUE;
}
-static void
-gsc_output_provide_help_hint() {
+static void gsc_output_provide_help_hint() {
if (gsc_help_requested && !gsc_help_hints_silenced) {
g_vm->glk_set_style(style_Emphasized);
g_vm->glk_put_string("[Try 'glk help' for help on special interpreter"
@@ -1160,8 +1130,7 @@ static void gsc_set_glk_style() {
* Push the settings of a font tag onto the font stack, and pop on end of
* font tag. Set the appropriate Glk style.
*/
-static void
-gsc_handle_font_tag(const sc_char *argument) {
+static void gsc_handle_font_tag(const sc_char *argument) {
/* Ignore the call on stack overrun. */
if (gsc_font_index < GSC_MAX_STYLE_NESTING) {
sc_char *lower, *face, *size;
@@ -1222,8 +1191,7 @@ gsc_handle_font_tag(const sc_char *argument) {
}
}
-static void
-gsc_handle_endfont_tag() {
+static void gsc_handle_endfont_tag() {
/* Unless underrun, pop the font stack and set Glk style. */
if (gsc_font_index > 0) {
gsc_font_index--;
@@ -1238,8 +1206,7 @@ gsc_handle_endfont_tag() {
* Increment the required attribute nesting counter, or decrement on end
* tag. Set the appropriate Glk style.
*/
-static void
-gsc_handle_attribute_tag(sc_int tag) {
+static void gsc_handle_attribute_tag(sc_int tag) {
/*
* Increment the required attribute nesting counter, and set Glk style.
*/
@@ -1262,8 +1229,7 @@ gsc_handle_attribute_tag(sc_int tag) {
gsc_set_glk_style();
}
-static void
-gsc_handle_endattribute_tag(sc_int tag) {
+static void gsc_handle_endattribute_tag(sc_int tag) {
/*
* Decrement the required attribute nesting counter, unless underrun, and
* set Glk style.
@@ -1356,8 +1322,7 @@ static void gsc_handle_wait_tag(const sc_char *argument) {
* Drop all stacked fonts and nested attributes, and return to normal Glk
* style.
*/
-static void
-gsc_reset_glk_style() {
+static void gsc_reset_glk_style() {
/* Reset the font stack and attributes, and set a normal style. */
gsc_font_index = 0;
gsc_attribute_bold = 0;
@@ -1374,8 +1339,7 @@ gsc_reset_glk_style() {
* Interpret selected Adrift output control tags. Not all are implemented
* here; several are ignored.
*/
-void
-os_print_tag(sc_int tag, const sc_char *argument) {
+void os_print_tag(sc_int tag, const sc_char *argument) {
event_t event;
assert(argument);
@@ -1495,8 +1459,7 @@ void os_print_string(const sc_char *string) {
* Debugging output goes to the main Glk window -- no special effects or
* dedicated debugging window attempted.
*/
-void
-os_print_string_debug(const sc_char *string) {
+void os_print_string_debug(const sc_char *string) {
assert(string);
assert(g_vm->glk_stream_get_current());
@@ -1516,8 +1479,7 @@ os_print_string_debug(const sc_char *string) {
* Convenience functions to print strings in assorted styles. A standout
* string is one that hints that it's from the interpreter, not the game.
*/
-static void
-gsc_styled_string(glui32 style, const char *message) {
+static void gsc_styled_string(glui32 style, const char *message) {
assert(message);
g_vm->glk_set_style(style);
@@ -1525,8 +1487,7 @@ gsc_styled_string(glui32 style, const char *message) {
g_vm->glk_set_style(style_Normal);
}
-static void
-gsc_styled_char(glui32 style, char c) {
+static void gsc_styled_char(glui32 style, char c) {
char buffer[2];
buffer[0] = c;
@@ -1534,28 +1495,23 @@ gsc_styled_char(glui32 style, char c) {
gsc_styled_string(style, buffer);
}
-static void
-gsc_standout_string(const char *message) {
+static void gsc_standout_string(const char *message) {
gsc_styled_string(style_Emphasized, message);
}
-static void
-gsc_standout_char(char c) {
+static void gsc_standout_char(char c) {
gsc_styled_char(style_Emphasized, c);
}
-static void
-gsc_normal_string(const char *message) {
+static void gsc_normal_string(const char *message) {
gsc_styled_string(style_Normal, message);
}
-static void
-gsc_normal_char(char c) {
+static void gsc_normal_char(char c) {
gsc_styled_char(style_Normal, c);
}
-static void
-gsc_header_string(const char *message) {
+static void gsc_header_string(const char *message) {
gsc_styled_string(style_Header, message);
}
@@ -1567,8 +1523,7 @@ gsc_header_string(const char *message) {
* hints at all, and those that do are usually sparse in what they hint at, so
* it's sort of good enough for the moment.
*/
-void
-os_display_hints(sc_game game) {
+void os_display_hints(sc_game game) {
sc_game_hint hint;
sc_int refused;
@@ -1628,9 +1583,7 @@ os_display_hints(sc_game game) {
*
* Stub functions. The unused variables defeat gcc warnings.
*/
-void
-os_play_sound(const sc_char *filepath,
- sc_int offset, sc_int length, sc_bool is_looping) {
+void os_play_sound(const sc_char *filepath, sc_int offset, sc_int length, sc_bool is_looping) {
const sc_char *unused1;
sc_int unused2, unused3;
sc_bool unused4;
@@ -1640,8 +1593,7 @@ os_play_sound(const sc_char *filepath,
unused4 = is_looping;
}
-void
-os_stop_sound() {
+void os_stop_sound() {
}
@@ -1659,8 +1611,7 @@ os_stop_sound() {
#ifdef LINUX_GRAPHICS
static int gsclinux_graphics_enabled = TRUE;
static char *gsclinux_game_file = nullptr;
-void
-os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
+void os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
const sc_char *unused1;
unused1 = filepath;
@@ -1687,8 +1638,7 @@ os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
}
}
#else
-void
-os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
+void os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
const sc_char *unused1;
sc_int unused2, unused3;
unused1 = filepath;
@@ -1707,8 +1657,7 @@ os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
*
* Turn game output scripting (logging) on and off.
*/
-static void
-gsc_command_script(const char *argument) {
+static void gsc_command_script(const char *argument) {
assert(argument);
if (sc_strcasecmp(argument, "on") == 0) {
@@ -1775,8 +1724,7 @@ gsc_command_script(const char *argument) {
*
* Turn game input logging on and off.
*/
-static void
-gsc_command_inputlog(const char *argument) {
+static void gsc_command_inputlog(const char *argument) {
assert(argument);
if (sc_strcasecmp(argument, "on") == 0) {
@@ -1839,8 +1787,7 @@ gsc_command_inputlog(const char *argument) {
*
* Set the game input log, to read input from a file.
*/
-static void
-gsc_command_readlog(const char *argument) {
+static void gsc_command_readlog(const char *argument) {
assert(argument);
if (sc_strcasecmp(argument, "on") == 0) {
@@ -1908,8 +1855,7 @@ gsc_command_readlog(const char *argument) {
*
* Turn abbreviation expansions on and off.
*/
-static void
-gsc_command_abbreviations(const char *argument) {
+static void gsc_command_abbreviations(const char *argument) {
assert(argument);
if (sc_strcasecmp(argument, "on") == 0) {
@@ -1954,8 +1900,7 @@ gsc_command_abbreviations(const char *argument) {
*
* Print out the Glk library version number.
*/
-static void
-gsc_command_print_version_number(glui32 version) {
+static void gsc_command_print_version_number(glui32 version) {
char buffer[64];
sprintf(buffer, "%lu.%lu.%lu",
@@ -1965,8 +1910,7 @@ gsc_command_print_version_number(glui32 version) {
gsc_normal_string(buffer);
}
-static void
-gsc_command_version(const char *argument) {
+static void gsc_command_version(const char *argument) {
glui32 version;
assert(argument);
@@ -1987,8 +1931,7 @@ gsc_command_version(const char *argument) {
* Turn command escapes off. Once off, there's no way to turn them back on.
* Commands must be on already to enter this function.
*/
-static void
-gsc_command_commands(const char *argument) {
+static void gsc_command_commands(const char *argument) {
assert(argument);
if (sc_strcasecmp(argument, "on") == 0) {
@@ -2021,8 +1964,7 @@ gsc_command_commands(const char *argument) {
*
* Print licensing terms.
*/
-static void
-gsc_command_license(const char *argument) {
+static void gsc_command_license(const char *argument) {
assert(argument);
gsc_normal_string("This program is free software; you can redistribute it"
@@ -2052,11 +1994,11 @@ gsc_command_license(const char *argument) {
/* Glk subcommands and handler functions. */
-typedef const struct {
+struct gsc_command_t {
const char *const command; /* Glk subcommand. */
void (* const handler)(const char *argument); /* Subcommand handler. */
const int takes_argument; /* Argument flag. */
-} gsc_command_t;
+};
typedef gsc_command_t *gsc_commandref_t;
static void gsc_command_summary(const char *argument);
@@ -2081,8 +2023,7 @@ static gsc_command_t GSC_COMMAND_TABLE[] = {
*
* Report all current Glk settings.
*/
-static void
-gsc_command_summary(const char *argument) {
+static void gsc_command_summary(const char *argument) {
gsc_commandref_t entry;
assert(argument);
@@ -2106,8 +2047,7 @@ gsc_command_summary(const char *argument) {
*
* Document the available Glk commands.
*/
-static void
-gsc_command_help(const char *command) {
+static void gsc_command_help(const char *command) {
gsc_commandref_t entry, matched;
assert(command);
@@ -2234,8 +2174,7 @@ gsc_command_help(const char *command) {
* This function is handed each input line. If the line contains a specific
* Glk port command, handle it and return TRUE, otherwise return FALSE.
*/
-static int
-gsc_command_escape(const char *string) {
+static int gsc_command_escape(const char *string) {
int posn;
char *string_copy, *command, *argument;
assert(string);
@@ -2356,8 +2295,7 @@ static gsc_abbreviation_t GSC_ABBREVIATIONS[] = {
* Expand a few common one-character abbreviations commonly found in other
* game systems.
*/
-static void
-gsc_expand_abbreviations(char *buffer, int size) {
+static void gsc_expand_abbreviations(char *buffer, int size) {
char *command, abbreviation;
const char *expansion;
gsc_abbreviationref_t entry;
@@ -2404,8 +2342,7 @@ gsc_expand_abbreviations(char *buffer, int size) {
*
* Read and return a line of player input.
*/
-sc_bool
-os_read_line(sc_char *buffer, sc_int length) {
+sc_bool os_read_line(sc_char *buffer, sc_int length) {
sc_int characters;
assert(buffer && length > 0);
@@ -2520,8 +2457,7 @@ os_read_line(sc_char *buffer, sc_int length) {
* window, so this is just a call to the normal readline, with an additional
* prompt.
*/
-sc_bool
-os_read_line_debug(sc_char *buffer, sc_int length) {
+sc_bool os_read_line_debug(sc_char *buffer, sc_int length) {
gsc_output_silence_help_hints();
gsc_reset_glk_style();
g_vm->glk_put_string("[SCARE debug]");
@@ -2534,8 +2470,7 @@ os_read_line_debug(sc_char *buffer, sc_int length) {
*
* Confirm a game action with a yes/no prompt.
*/
-sc_bool
-os_confirm(sc_int type) {
+sc_bool os_confirm(sc_int type) {
sc_char response;
/*
@@ -2625,8 +2560,7 @@ static const glui32 GSC_DELAY_TIMEOUTS_COUNT = 10;
* improve the display where 'r', or confirming restart, triggers an otherwise
* immediate, and abrupt, restart.
*/
-static void
-gsc_short_delay() {
+static void gsc_short_delay() {
/* Ignore the call if the Glk doesn't have timers. */
if (g_vm->glk_gestalt(gestalt_Timer, 0)) {
glui32 timeout;
@@ -2650,8 +2584,7 @@ gsc_short_delay() {
* Process Glk events until one of the expected type, or types, arrives.
* Return the event of that type.
*/
-static void
-gsc_event_wait_2(glui32 wait_type_1, glui32 wait_type_2, event_t *event) {
+static void gsc_event_wait_2(glui32 wait_type_1, glui32 wait_type_2, event_t *event) {
assert(event);
do {
@@ -2671,8 +2604,7 @@ gsc_event_wait_2(glui32 wait_type_1, glui32 wait_type_2, event_t *event) {
} while (!(event->type == (EvType)wait_type_1 || event->type == (EvType)wait_type_2));
}
-static void
-gsc_event_wait(glui32 wait_type, event_t *event) {
+static void gsc_event_wait(glui32 wait_type, event_t *event) {
assert(event);
gsc_event_wait_2(wait_type, evtype_None, event);
@@ -2719,16 +2651,14 @@ void *os_open_file(sc_bool is_save) {
*
* Write/read the given buffered data to/from the open Glk stream.
*/
-void
-os_write_file(void *opaque, const sc_byte *buffer, sc_int length) {
+void os_write_file(void *opaque, const sc_byte *buffer, sc_int length) {
strid_t stream = (strid_t) opaque;
assert(opaque && buffer);
g_vm->glk_put_buffer_stream(stream, (char *) buffer, length);
}
-sc_int
-os_read_file(void *opaque, sc_byte *buffer, sc_int length) {
+sc_int os_read_file(void *opaque, sc_byte *buffer, sc_int length) {
strid_t stream = (strid_t) opaque;
assert(opaque && buffer);
@@ -2741,8 +2671,7 @@ os_read_file(void *opaque, sc_byte *buffer, sc_int length) {
*
* Close the opened Glk stream.
*/
-void
-os_close_file(void *opaque) {
+void os_close_file(void *opaque) {
strid_t stream = (strid_t) opaque;
assert(opaque);
@@ -2788,8 +2717,7 @@ static sc_int gsc_callback(void *opaque, sc_byte *buffer, sc_int length) {
* Offer the option to restart, undo, or quit. Returns the selected game
* end option. Called on game completion.
*/
-static enum gsc_end_option
-gsc_get_ending_option() {
+static enum gsc_end_option gsc_get_ending_option() {
sc_char response;
/* Ensure back to normal style, and update status. */
@@ -2858,10 +2786,8 @@ gsc_get_ending_option() {
* and generally handle options. The second is called from g_vm->glk_main, and
* does the real work of running the game.
*/
-static int
-gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream,
- sc_uint trace_flags, sc_bool enable_debugger,
- sc_bool stable_random, const sc_char *locale) {
+static int gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream,
+ sc_uint trace_flags, sc_bool enable_debugger, sc_bool stable_random, const sc_char *locale) {
winid_t window;
assert(game_stream);
@@ -2960,8 +2886,7 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream
return TRUE;
}
-static void
-gsc_main() {
+static void gsc_main() {
sc_bool is_running;
/* Ensure SCARE internal types have the right sizes. */
@@ -3100,7 +3025,7 @@ void adrift_main() {
/* Glk linkage relevant only to the UNIX platform */
/*---------------------------------------------------------------------*/
-#ifdef UNUSED
+#if 0
/*
* Glk arguments for UNIX versions of the Glk interpreter.
*/
diff --git a/engines/glk/adrift/scdebug.cpp b/engines/glk/adrift/scdebug.cpp
index 35900c3..a752506 100644
--- a/engines/glk/adrift/scdebug.cpp
+++ b/engines/glk/adrift/scdebug.cpp
@@ -32,7 +32,7 @@ static const sc_uint DEBUG_MAGIC = 0xc4584d2e;
enum { DEBUG_BUFFER_SIZE = 256 };
/* Debugging command and command argument type. */
-typedef enum {
+enum sc_command_t {
DEBUG_NONE = 0, DEBUG_CONTINUE, DEBUG_STEP, DEBUG_BUFFER, DEBUG_RESOURCES,
DEBUG_HELP, DEBUG_GAME,
DEBUG_PLAYER, DEBUG_ROOMS, DEBUG_OBJECTS, DEBUG_NPCS, DEBUG_EVENTS,
@@ -45,18 +45,15 @@ typedef enum {
DEBUG_CLEARTASKS, DEBUG_CLEARVARIABLES,
DEBUG_WATCHALL, DEBUG_CLEARALL, DEBUG_RANDOM,
DEBUG_QUIT
-}
-sc_command_t;
+};
-typedef enum
-{ COMMAND_QUERY = 0, COMMAND_RANGE, COMMAND_ONE, COMMAND_ALL }
-sc_command_type_t;
+enum sc_command_type_t { COMMAND_QUERY = 0, COMMAND_RANGE, COMMAND_ONE, COMMAND_ALL };
/* Table connecting debugging command strings to commands. */
-typedef struct {
+struct sc_strings_t {
const sc_char *const command_string;
const sc_command_t command;
-} sc_strings_t;
+};
static const sc_strings_t DEBUG_COMMANDS[] = {
{"continue", DEBUG_CONTINUE}, {"step", DEBUG_STEP}, {"buffer", DEBUG_BUFFER},
{"resources", DEBUG_RESOURCES}, {"help", DEBUG_HELP}, {"game", DEBUG_GAME},
@@ -83,7 +80,7 @@ static const sc_strings_t DEBUG_COMMANDS[] = {
* added to the game on enabling debug, and removed and destroyed on
* disabling debugging.
*/
-typedef struct sc_debugger_s {
+struct sc_debugger_s {
sc_uint magic;
sc_bool *watch_objects;
sc_bool *watch_npcs;
@@ -94,7 +91,8 @@ typedef struct sc_debugger_s {
sc_bool single_step;
sc_bool quit_pending;
sc_uint elapsed_seconds;
-} sc_debugger_t;
+};
+typedef sc_debugger_s sc_debugger_t;
/*
@@ -102,8 +100,7 @@ typedef struct sc_debugger_s {
*
* Return TRUE if pointer is a valid debugger, FALSE otherwise.
*/
-static sc_bool
-debug_is_valid(sc_debuggerref_t debug) {
+static sc_bool debug_is_valid(sc_debuggerref_t debug) {
return debug && debug->magic == DEBUG_MAGIC;
}
@@ -113,8 +110,7 @@ debug_is_valid(sc_debuggerref_t debug) {
*
* Return the debugger reference from a game, or NULL if none.
*/
-static sc_debuggerref_t
-debug_get_debugger(sc_gameref_t game) {
+static sc_debuggerref_t debug_get_debugger(sc_gameref_t game) {
assert(gs_is_game_valid(game));
return game->debugger;
@@ -126,8 +122,7 @@ debug_get_debugger(sc_gameref_t game) {
*
* Common helper to return the count of variables defined in a game.
*/
-static sc_int
-debug_variable_count(sc_gameref_t game) {
+static sc_int debug_variable_count(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key;
sc_int variable_count;
@@ -146,8 +141,7 @@ debug_variable_count(sc_gameref_t game) {
* Create a new set of debug control information, and append it to the
* game passed in.
*/
-static void
-debug_initialize(sc_gameref_t game) {
+static void debug_initialize(sc_gameref_t game) {
sc_debuggerref_t debug;
/* Create the easy bits of the new debugging set. */
@@ -194,8 +188,7 @@ debug_initialize(sc_gameref_t game) {
* Destroy a debug data set, free its heap memory, and remove its reference
* from the game.
*/
-static void
-debug_finalize(sc_gameref_t game) {
+static void debug_finalize(sc_gameref_t game) {
sc_debuggerref_t debug = debug_get_debugger(game);
assert(debug_is_valid(debug));
@@ -220,8 +213,7 @@ debug_finalize(sc_gameref_t game) {
*
* Print debugging help.
*/
-static void
-debug_help(sc_command_t topic) {
+static void debug_help(sc_command_t topic) {
/* Is help general, or specific? */
if (topic == DEBUG_NONE) {
if_print_debug(
@@ -539,15 +531,13 @@ debug_help(sc_command_t topic) {
*
* Low level output helpers.
*/
-static void
-debug_print_quoted(const sc_char *string) {
+static void debug_print_quoted(const sc_char *string) {
if_print_debug_character('"');
if_print_debug(string);
if_print_debug_character('"');
}
-static void
-debug_print_player(sc_gameref_t game) {
+static void debug_print_player(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
const sc_char *playername;
@@ -559,8 +549,7 @@ debug_print_player(sc_gameref_t game) {
debug_print_quoted(playername);
}
-static void
-debug_print_room(sc_gameref_t game, sc_int room) {
+static void debug_print_room(sc_gameref_t game, sc_int room) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_char buffer[32];
@@ -583,8 +572,7 @@ debug_print_room(sc_gameref_t game, sc_int room) {
debug_print_quoted(name);
}
-static void
-debug_print_object(sc_gameref_t game, sc_int object) {
+static void debug_print_object(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_bool bstatic;
@@ -618,8 +606,7 @@ debug_print_object(sc_gameref_t game, sc_int object) {
debug_print_quoted(name);
}
-static void
-debug_print_npc(sc_gameref_t game, sc_int npc) {
+static void debug_print_npc(sc_gameref_t game, sc_int npc) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_char buffer[32];
@@ -646,8 +633,7 @@ debug_print_npc(sc_gameref_t game, sc_int npc) {
debug_print_quoted(name);
}
-static void
-debug_print_event(sc_gameref_t game, sc_int event) {
+static void debug_print_event(sc_gameref_t game, sc_int event) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_char buffer[32];
@@ -670,8 +656,7 @@ debug_print_event(sc_gameref_t game, sc_int event) {
debug_print_quoted(name);
}
-static void
-debug_print_task(sc_gameref_t game, sc_int task) {
+static void debug_print_task(sc_gameref_t game, sc_int task) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
sc_char buffer[32];
@@ -695,8 +680,7 @@ debug_print_task(sc_gameref_t game, sc_int task) {
debug_print_quoted(command);
}
-static void
-debug_print_variable(sc_gameref_t game, sc_int variable) {
+static void debug_print_variable(sc_gameref_t game, sc_int variable) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[3], vt_rvalue;
@@ -742,8 +726,7 @@ debug_print_variable(sc_gameref_t game, sc_int variable) {
*
* Display overall game details.
*/
-static void
-debug_game(sc_gameref_t game, sc_command_type_t type) {
+static void debug_game(sc_gameref_t game, sc_command_type_t type) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_debuggerref_t debug = debug_get_debugger(game);
sc_vartype_t vt_key[2];
@@ -890,9 +873,7 @@ debug_game(sc_gameref_t game, sc_command_type_t type) {
*
* Print a few brief details about the player status.
*/
-static void
-debug_player(sc_gameref_t game,
- sc_command_t command, sc_command_type_t type) {
+static void debug_player(sc_gameref_t game, sc_command_t command, sc_command_type_t type) {
if (type != COMMAND_QUERY) {
if_print_debug("The Player command takes no arguments.\n");
return;
@@ -948,9 +929,7 @@ debug_player(sc_gameref_t game,
* Normalize a set of arguments parsed from a debugger command line, for
* debug commands that take ranges.
*/
-static sc_bool
-debug_normalize_arguments(sc_command_type_t type,
- sc_int *arg1, sc_int *arg2, sc_int limit) {
+static sc_bool debug_normalize_arguments(sc_command_type_t type, sc_int *arg1, sc_int *arg2, sc_int limit) {
sc_int low = 0, high = 0;
/* Set range low and high depending on the command type. */
@@ -990,13 +969,11 @@ debug_normalize_arguments(sc_command_type_t type,
*
* Print details of rooms and their direct contents.
*/
-static sc_bool
-debug_filter_room(sc_gameref_t game, sc_int room) {
+static sc_bool debug_filter_room(sc_gameref_t game, sc_int room) {
return room == gs_playerroom(game);
}
-static void
-debug_dump_room(sc_gameref_t game, sc_int room) {
+static void debug_dump_room(sc_gameref_t game, sc_int room) {
sc_int object, npc;
debug_print_room(game, room);
@@ -1037,13 +1014,11 @@ debug_dump_room(sc_gameref_t game, sc_int room) {
*
* Print the changeable details of game objects.
*/
-static sc_bool
-debug_filter_object(sc_gameref_t game, sc_int object) {
+static sc_bool debug_filter_object(sc_gameref_t game, sc_int object) {
return obj_indirectly_in_room(game, object, gs_playerroom(game));
}
-static void
-debug_dump_object(sc_gameref_t game, sc_int object) {
+static void debug_dump_object(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int openness;
sc_vartype_t vt_key[3];
@@ -1171,13 +1146,11 @@ debug_dump_object(sc_gameref_t game, sc_int object) {
*
* Print stuff about NPCs.
*/
-static sc_bool
-debug_filter_npc(sc_gameref_t game, sc_int npc) {
+static sc_bool debug_filter_npc(sc_gameref_t game, sc_int npc) {
return npc_in_room(game, npc, gs_playerroom(game));
}
-static void
-debug_dump_npc(sc_gameref_t game, sc_int npc) {
+static void debug_dump_npc(sc_gameref_t game, sc_int npc) {
debug_print_npc(game, npc);
if_print_debug_character('\n');
@@ -1239,13 +1212,11 @@ debug_dump_npc(sc_gameref_t game, sc_int npc) {
*
* Print stuff about events.
*/
-static sc_bool
-debug_filter_event(sc_gameref_t game, sc_int event) {
+static sc_bool debug_filter_event(sc_gameref_t game, sc_int event) {
return gs_event_state(game, event) == ES_RUNNING;
}
-static void
-debug_dump_event(sc_gameref_t game, sc_int event) {
+static void debug_dump_event(sc_gameref_t game, sc_int event) {
sc_char buffer[32];
debug_print_event(game, event);
@@ -1284,13 +1255,11 @@ debug_dump_event(sc_gameref_t game, sc_int event) {
*
* Print stuff about tasks.
*/
-static sc_bool
-debug_filter_task(sc_gameref_t game, sc_int task) {
+static sc_bool debug_filter_task(sc_gameref_t game, sc_int task) {
return task_can_run_task(game, task);
}
-static void
-debug_dump_task(sc_gameref_t game, sc_int task) {
+static void debug_dump_task(sc_gameref_t game, sc_int task) {
debug_print_task(game, task);
if_print_debug_character('\n');
@@ -1314,8 +1283,7 @@ debug_dump_task(sc_gameref_t game, sc_int task) {
*
* Print stuff about variables.
*/
-static void
-debug_dump_variable(sc_gameref_t game, sc_int variable) {
+static void debug_dump_variable(sc_gameref_t game, sc_int variable) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[3], vt_rvalue;
@@ -1358,9 +1326,8 @@ debug_dump_variable(sc_gameref_t game, sc_int variable) {
*
* Common handler for iterating dumps of classes.
*/
-static void
-debug_dump_common(sc_gameref_t game, sc_command_t command,
- sc_command_type_t type, sc_int arg1, sc_int arg2) {
+static void debug_dump_common(sc_gameref_t game, sc_command_t command,
+ sc_command_type_t type, sc_int arg1, sc_int arg2) {
sc_int low = arg1, high = arg2;
sc_int limit, index_;
const sc_char *class_;
@@ -1492,8 +1459,7 @@ debug_dump_common(sc_gameref_t game, sc_command_t command,
*
* Print the current raw printfilter contents.
*/
-static void
-debug_buffer(sc_gameref_t game, sc_command_type_t type) {
+static void debug_buffer(sc_gameref_t game, sc_command_type_t type) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_char *buffer;
@@ -1515,8 +1481,7 @@ debug_buffer(sc_gameref_t game, sc_command_type_t type) {
*
* Helper for debug_resources().
*/
-static void
-debug_print_resource(const sc_resource_t *resource) {
+static void debug_print_resource(const sc_resource_t *resource) {
sc_char buffer[32];
debug_print_quoted(resource->name);
@@ -1534,8 +1499,7 @@ debug_print_resource(const sc_resource_t *resource) {
*
* Print any active and requested resources.
*/
-static void
-debug_resources(sc_gameref_t game, sc_command_type_t type) {
+static void debug_resources(sc_gameref_t game, sc_command_type_t type) {
sc_bool printed = FALSE;
if (type != COMMAND_QUERY) {
@@ -1592,8 +1556,7 @@ debug_resources(sc_gameref_t game, sc_command_type_t type) {
* Report the PRNG in use, and seed the random number generator to the
* given value.
*/
-static void
-debug_random(sc_command_type_t type, sc_int new_seed) {
+static void debug_random(sc_command_type_t type, sc_int new_seed) {
const sc_char *random_type;
sc_char buffer[32];
@@ -1633,9 +1596,8 @@ debug_random(sc_command_type_t type, sc_int new_seed) {
*
* Common handler for setting and clearing watchpoints.
*/
-static void
-debug_watchpoint_common(sc_gameref_t game, sc_command_t command,
- sc_command_type_t type, sc_int arg1, sc_int arg2) {
+static void debug_watchpoint_common(sc_gameref_t game, sc_command_t command,
+ sc_command_type_t type, sc_int arg1, sc_int arg2) {
const sc_debuggerref_t debug = debug_get_debugger(game);
sc_int low = arg1, high = arg2;
sc_int limit, index_;
@@ -1801,9 +1763,7 @@ debug_watchpoint_common(sc_gameref_t game, sc_command_t command,
*
* Common handler to list out and clear all set watchpoints at a stroke.
*/
-static void
-debug_watchall_common(sc_gameref_t game,
- sc_command_t command, sc_command_type_t type) {
+static void debug_watchall_common(sc_gameref_t game, sc_command_t command, sc_command_type_t type) {
const sc_debuggerref_t debug = debug_get_debugger(game);
assert(debug_is_valid(debug));
@@ -1854,8 +1814,7 @@ debug_watchall_common(sc_gameref_t game,
*
* Compare two objects, and return TRUE if the same.
*/
-static sc_bool
-debug_compare_object(sc_gameref_t from, sc_gameref_t with, sc_int object) {
+static sc_bool debug_compare_object(sc_gameref_t from, sc_gameref_t with, sc_int object) {
const sc_objectstate_t *from_object = from->objects + object;
const sc_objectstate_t *with_object = with->objects + object;
@@ -1874,8 +1833,7 @@ debug_compare_object(sc_gameref_t from, sc_gameref_t with, sc_int object) {
*
* Compare two NPCs, and return TRUE if the same.
*/
-static sc_bool
-debug_compare_npc(sc_gameref_t from, sc_gameref_t with, sc_int npc) {
+static sc_bool debug_compare_npc(sc_gameref_t from, sc_gameref_t with, sc_int npc) {
const sc_npcstate_t *from_npc = from->npcs + npc;
const sc_npcstate_t *with_npc = with->npcs + npc;
@@ -1897,8 +1855,7 @@ debug_compare_npc(sc_gameref_t from, sc_gameref_t with, sc_int npc) {
*
* Compare two events, and return TRUE if the same.
*/
-static sc_bool
-debug_compare_event(sc_gameref_t from, sc_gameref_t with, sc_int event) {
+static sc_bool debug_compare_event(sc_gameref_t from, sc_gameref_t with, sc_int event) {
const sc_eventstate_t *from_event = from->events + event;
const sc_eventstate_t *with_event = with->events + event;
@@ -1912,8 +1869,7 @@ debug_compare_event(sc_gameref_t from, sc_gameref_t with, sc_int event) {
*
* Compare two tasks, and return TRUE if the same.
*/
-static sc_bool
-debug_compare_task(sc_gameref_t from, sc_gameref_t with, sc_int task) {
+static sc_bool debug_compare_task(sc_gameref_t from, sc_gameref_t with, sc_int task) {
const sc_taskstate_t *from_task = from->tasks + task;
const sc_taskstate_t *with_task = with->tasks + task;
@@ -1927,8 +1883,7 @@ debug_compare_task(sc_gameref_t from, sc_gameref_t with, sc_int task) {
*
* Compare two variables, and return TRUE if the same.
*/
-static sc_bool
-debug_compare_variable(sc_gameref_t from, sc_gameref_t with, sc_int variable) {
+static sc_bool debug_compare_variable(sc_gameref_t from, sc_gameref_t with, sc_int variable) {
const sc_prop_setref_t bundle = from->bundle;
const sc_var_setref_t from_var = from->vars;
const sc_var_setref_t with_var = with->vars;
@@ -1975,12 +1930,9 @@ debug_compare_variable(sc_gameref_t from, sc_gameref_t with, sc_int variable) {
* watchpoints flags array. Prints entries that differ, and returns TRUE
* if any differed.
*/
-static sc_bool
-debug_check_class(sc_gameref_t from, sc_gameref_t with,
- const sc_char *class_, sc_int class_count,
- const sc_bool *watchpoints,
- sc_bool(*const compare_function)
- (sc_gameref_t, sc_gameref_t, sc_int)) {
+static sc_bool debug_check_class(sc_gameref_t from, sc_gameref_t with, const sc_char *class_,
+ sc_int class_count, const sc_bool *watchpoints,
+ sc_bool(*const compare_function) (sc_gameref_t, sc_gameref_t, sc_int)) {
sc_int index_;
sc_bool triggered = FALSE;
@@ -2020,8 +1972,7 @@ debug_check_class(sc_gameref_t from, sc_gameref_t with,
* TRUE if any triggered, FALSE if none (or if the undo game isn't available,
* in which case no check is possible).
*/
-static sc_bool
-debug_check_watchpoints(sc_gameref_t game) {
+static sc_bool debug_check_watchpoints(sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
const sc_gameref_t undo = game->undo;
sc_bool triggered;
@@ -2071,10 +2022,8 @@ debug_check_watchpoints(sc_gameref_t game) {
* appropriate command and its arguments. Returns DEBUG_NONE if the parse
* fails.
*/
-static sc_command_t
-debug_parse_command(const sc_char *command_string,
- sc_command_type_t *type,
- sc_int *arg1, sc_int *arg2, sc_command_t *help_topic) {
+static sc_command_t debug_parse_command(const sc_char *command_string,
+ sc_command_type_t *type, sc_int *arg1, sc_int *arg2, sc_command_t *help_topic) {
sc_command_t return_command;
sc_command_type_t return_type;
sc_int val1, val2, converted, matches;
@@ -2186,10 +2135,8 @@ debug_parse_command(const sc_char *command_string,
*
* Dispatch a debugging command to the appropriate handler.
*/
-static void
-debug_dispatch(sc_gameref_t game,
- sc_command_t command, sc_command_type_t type,
- sc_int arg1, sc_int arg2, sc_command_t help_topic) {
+static void debug_dispatch(sc_gameref_t game, sc_command_t command, sc_command_type_t type,
+ sc_int arg1, sc_int arg2, sc_command_t help_topic) {
/* Demultiplex debugging command, and call handlers. */
switch (command) {
case DEBUG_HELP:
@@ -2256,8 +2203,7 @@ debug_dispatch(sc_gameref_t game,
*
* Create a small debugging dialog with the user.
*/
-static void
-debug_dialog(sc_gameref_t game) {
+static void debug_dialog(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_debuggerref_t debug = debug_get_debugger(game);
const sc_var_setref_t vars = gs_get_vars(game);
@@ -2342,8 +2288,7 @@ debug_dialog(sc_gameref_t game) {
* Handle a single debugging command line from the outside world. Returns
* TRUE if valid, FALSE if invalid (parse failed, not understood).
*/
-sc_bool
-debug_run_command(sc_gameref_t game, const sc_char *debug_command) {
+sc_bool debug_run_command(sc_gameref_t game, const sc_char *debug_command) {
const sc_debuggerref_t debug = debug_get_debugger(game);
sc_command_t command, help_topic;
sc_command_type_t type;
@@ -2379,8 +2324,7 @@ debug_run_command(sc_gameref_t game, const sc_char *debug_command) {
* a polite refusal if debugging is not enabled, otherwise runs a debugging
* dialog. Uses if_print_string() as this isn't debug output.
*/
-sc_bool
-debug_cmd_debugger(sc_gameref_t game) {
+sc_bool debug_cmd_debugger(sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/* If debugging disallowed (not initialized), ignore the call. */
@@ -2410,8 +2354,7 @@ debug_cmd_debugger(sc_gameref_t game) {
* The second is called on exit from the game, and may make a final sweep for
* watchpoints and offer the debug dialog one last time.
*/
-void
-debug_game_started(sc_gameref_t game) {
+void debug_game_started(sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/* If debugging disallowed (not initialized), ignore the call. */
@@ -2438,8 +2381,7 @@ debug_game_started(sc_gameref_t game) {
}
}
-void
-debug_game_ended(sc_gameref_t game) {
+void debug_game_ended(sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/* If debugging disallowed (not initialized), ignore the call. */
@@ -2481,8 +2423,7 @@ debug_game_ended(sc_gameref_t game) {
* Called after each turn by the main game loop. Checks for any set
* watchpoints, and triggers a debug dialog when any fire.
*/
-void
-debug_turn_update(sc_gameref_t game) {
+void debug_turn_update(sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/* If debugging disallowed (not initialized), ignore the call. */
@@ -2517,8 +2458,7 @@ debug_turn_update(sc_gameref_t game) {
* and free'd on disabling; as a result, any set watchpoints are lost on
* disabling.
*/
-void
-debug_set_enabled(sc_gameref_t game, sc_bool enable) {
+void debug_set_enabled(sc_gameref_t game, sc_bool enable) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/*
@@ -2534,8 +2474,7 @@ debug_set_enabled(sc_gameref_t game, sc_bool enable) {
}
}
-sc_bool
-debug_get_enabled(sc_gameref_t game) {
+sc_bool debug_get_enabled(sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
return debug != NULL;
diff --git a/engines/glk/adrift/scevents.cpp b/engines/glk/adrift/scevents.cpp
index 0048cd6..b7cea8b 100644
--- a/engines/glk/adrift/scevents.cpp
+++ b/engines/glk/adrift/scevents.cpp
@@ -42,8 +42,7 @@ static sc_bool evt_trace = FALSE;
*
* Return TRUE if any task at all matches the given completion state.
*/
-static sc_bool
-evt_any_task_in_state(sc_gameref_t game, sc_bool state) {
+static sc_bool evt_any_task_in_state(sc_gameref_t game, sc_bool state) {
sc_int task;
/* Scan tasks for any whose completion matches input. */
@@ -62,8 +61,7 @@ evt_any_task_in_state(sc_gameref_t game, sc_bool state) {
*
* Return TRUE if player is in the right room for event text.
*/
-sc_bool
-evt_can_see_event(sc_gameref_t game, sc_int event) {
+sc_bool evt_can_see_event(sc_gameref_t game, sc_int event) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int type;
@@ -102,8 +100,7 @@ evt_can_see_event(sc_gameref_t game, sc_int event) {
*
* Move an object from within an event.
*/
-static void
-evt_move_object(sc_gameref_t game, sc_int object, sc_int destination) {
+static void evt_move_object(sc_gameref_t game, sc_int object, sc_int destination) {
/* Ignore negative values of object. */
if (object >= 0) {
if (evt_trace) {
@@ -158,8 +155,7 @@ evt_move_object(sc_gameref_t game, sc_int object, sc_int destination) {
* comment. It's arguable if this is a feature or a bug; nevertheless, we
* can do the same thing here, though it's ugly.
*/
-static sc_bool
-evt_fixup_v390_v380_immediate_restart(sc_gameref_t game, sc_int event) {
+static sc_bool evt_fixup_v390_v380_immediate_restart(sc_gameref_t game, sc_int event) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int version;
@@ -195,8 +191,7 @@ evt_fixup_v390_v380_immediate_restart(sc_gameref_t game, sc_int event) {
*
* Change an event from WAITING to RUNNING.
*/
-static void
-evt_start_event(sc_gameref_t game, sc_int event) {
+static void evt_start_event(sc_gameref_t game, sc_int event) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
@@ -253,8 +248,7 @@ evt_start_event(sc_gameref_t game, sc_int event) {
*
* Return the starter type for an event.
*/
-static sc_int
-evt_get_starter_type(sc_gameref_t game, sc_int event) {
+static sc_int evt_get_starter_type(sc_gameref_t game, sc_int event) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int startertype;
@@ -273,8 +267,7 @@ evt_get_starter_type(sc_gameref_t game, sc_int event) {
*
* Move an event to FINISHED, or restart it.
*/
-static void
-evt_finish_event(sc_gameref_t game, sc_int event) {
+static void evt_finish_event(sc_gameref_t game, sc_int event) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
@@ -415,16 +408,14 @@ evt_finish_event(sc_gameref_t game, sc_int event) {
*
* Return the status of start, pause and resume states of an event.
*/
-static sc_bool
-evt_has_starter_task(sc_gameref_t game, sc_int event) {
+static sc_bool evt_has_starter_task(sc_gameref_t game, sc_int event) {
sc_int startertype;
startertype = evt_get_starter_type(game, event);
return startertype == 3;
}
-static sc_bool
-evt_starter_task_is_complete(sc_gameref_t game, sc_int event) {
+static sc_bool evt_starter_task_is_complete(sc_gameref_t game, sc_int event) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int task;
@@ -447,8 +438,7 @@ evt_starter_task_is_complete(sc_gameref_t game, sc_int event) {
return start;
}
-static sc_bool
-evt_pauser_task_is_complete(sc_gameref_t game, sc_int event) {
+static sc_bool evt_pauser_task_is_complete(sc_gameref_t game, sc_int event) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int pausetask;
@@ -474,8 +464,7 @@ evt_pauser_task_is_complete(sc_gameref_t game, sc_int event) {
return pause;
}
-static sc_bool
-evt_resumer_task_is_complete(sc_gameref_t game, sc_int event) {
+static sc_bool evt_resumer_task_is_complete(sc_gameref_t game, sc_int event) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int resumetask;
@@ -508,8 +497,7 @@ evt_resumer_task_is_complete(sc_gameref_t game, sc_int event) {
* Print messages and handle resources for the event where we're in mid-event
* and getting close to some number of turns from its end.
*/
-static void
-evt_handle_preftime_notifications(sc_gameref_t game, sc_int event) {
+static void evt_handle_preftime_notifications(sc_gameref_t game, sc_int event) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
@@ -556,8 +544,7 @@ evt_handle_preftime_notifications(sc_gameref_t game, sc_int event) {
*
* Attempt to advance an event by one turn.
*/
-static void
-evt_tick_event(sc_gameref_t game, sc_int event) {
+static void evt_tick_event(sc_gameref_t game, sc_int event) {
if (evt_trace) {
sc_trace("Event: ticking event %ld: state %ld, time %ld\n", event,
gs_event_state(game, event), gs_event_time(game, event));
@@ -742,8 +729,7 @@ evt_tick_event(sc_gameref_t game, sc_int event) {
*
* Attempt to advance each event by one turn.
*/
-void
-evt_tick_events(sc_gameref_t game) {
+void evt_tick_events(sc_gameref_t game) {
sc_int event;
/*
@@ -778,8 +764,7 @@ evt_tick_events(sc_gameref_t game) {
*
* Set event tracing on/off.
*/
-void
-evt_debug_trace(sc_bool flag) {
+void evt_debug_trace(sc_bool flag) {
evt_trace = flag;
}
diff --git a/engines/glk/adrift/scexpr.cpp b/engines/glk/adrift/scexpr.cpp
index a316b7c..2375b5e 100644
--- a/engines/glk/adrift/scexpr.cpp
+++ b/engines/glk/adrift/scexpr.cpp
@@ -71,11 +71,11 @@ enum {
* Small tables tying multicharacter tokens strings to tokens. At present,
* the string lengths for names are not used.
*/
-typedef struct {
+struct sc_expr_multichar_t {
const sc_char *const name;
const sc_int length;
const sc_int token;
-} sc_expr_multichar_t;
+};
static const sc_expr_multichar_t FUNCTION_TOKENS[] = {
{"either", 6, TOK_EITHER},
@@ -103,8 +103,7 @@ static const sc_expr_multichar_t OPERATOR_TOKENS[] = {
* Multicharacter token table search, returns the matching token, or
* TOK_NONE if no match.
*/
-static sc_int
-expr_multichar_search(const sc_char *name, const sc_expr_multichar_t *table) {
+static sc_int expr_multichar_search(const sc_char *name, const sc_expr_multichar_t *table) {
const sc_expr_multichar_t *entry;
/* Scan the table for a case-independent full string match. */
@@ -131,8 +130,7 @@ static sc_int expr_current_token = TOK_NONE;
*
* Start and wrap up expression string tokenization.
*/
-static void
-expr_tokenize_start(const sc_char *expression) {
+static void expr_tokenize_start(const sc_char *expression) {
static sc_bool initialized = FALSE;
/* On first call only, verify the string lengths in the tables. */
@@ -171,8 +169,7 @@ expr_tokenize_start(const sc_char *expression) {
expr_current_token = TOK_NONE;
}
-static void
-expr_tokenize_end(void) {
+static void expr_tokenize_end(void) {
/* Deallocate temporary strings, clear expression. */
sc_free(expr_temporary);
expr_temporary = NULL;
@@ -189,8 +186,7 @@ expr_tokenize_end(void) {
* Return the next token from the current expression. The initial token may
* be adjusted into a unary +/- depending on the value of the previous token.
*/
-static sc_int
-expr_next_token_unadjusted(sc_vartype_t *token_value) {
+static sc_int expr_next_token_unadjusted(sc_vartype_t *token_value) {
sc_int c;
assert(expr_expression);
@@ -334,8 +330,7 @@ expr_next_token_unadjusted(sc_vartype_t *token_value) {
}
}
-static sc_int
-expr_next_token(void) {
+static sc_int expr_next_token(void) {
sc_int token;
sc_vartype_t token_value;
@@ -391,8 +386,7 @@ expr_next_token(void) {
* Return the token value of the current token. Undefined if the current
* token is not numeric, an id, or a variable.
*/
-static void
-expr_current_token_value(sc_vartype_t *value) {
+static void expr_current_token_value(sc_vartype_t *value) {
/* Quick check that the value is a valid one. */
switch (expr_current_token) {
case TOK_INTEGER:
@@ -416,10 +410,10 @@ expr_current_token_value(sc_vartype_t *value) {
* integers and strings, and flags strings for possible garbage collection
* on parse errors.
*/
-typedef struct {
+struct sc_stack_t {
sc_bool is_collectible;
sc_vartype_t value;
-} sc_stack_t;
+};
static sc_stack_t expr_eval_stack[MAX_NESTING_DEPTH];
static sc_int expr_eval_stack_index = 0;
@@ -432,8 +426,7 @@ static sc_var_setref_t expr_varset = NULL;
* Reset the evaluation stack to an empty state, and register the variables
* set to use when referencing %...% variables.
*/
-static void
-expr_eval_start(sc_var_setref_t vars) {
+static void expr_eval_start(sc_var_setref_t vars) {
expr_eval_stack_index = 0;
expr_varset = vars;
}
@@ -445,8 +438,7 @@ expr_eval_start(sc_var_setref_t vars) {
* In case of parse error, empty out and free all collectible malloced
* strings left in the evaluation array.
*/
-static void
-expr_eval_garbage_collect(void) {
+static void expr_eval_garbage_collect(void) {
sc_int index_;
/*
@@ -473,8 +465,7 @@ expr_eval_garbage_collect(void) {
* for this case, the input string is assumed to be already malloc'ed, and
* the caller should not subsequently free the string.
*/
-static void
-expr_eval_push_integer(sc_int value) {
+static void expr_eval_push_integer(sc_int value) {
if (expr_eval_stack_index >= MAX_NESTING_DEPTH)
sc_fatal("expr_eval_push_integer: stack overflow\n");
@@ -482,8 +473,7 @@ expr_eval_push_integer(sc_int value) {
expr_eval_stack[expr_eval_stack_index++].value.integer = value;
}
-static void
-expr_eval_push_string(const sc_char *value) {
+static void expr_eval_push_string(const sc_char *value) {
sc_char *value_copy;
if (expr_eval_stack_index >= MAX_NESTING_DEPTH)
@@ -496,8 +486,7 @@ expr_eval_push_string(const sc_char *value) {
expr_eval_stack[expr_eval_stack_index++].value.mutable_string = value_copy;
}
-static void
-expr_eval_push_alloced_string(sc_char *value) {
+static void expr_eval_push_alloced_string(sc_char *value) {
if (expr_eval_stack_index >= MAX_NESTING_DEPTH)
sc_fatal("expr_eval_push_alloced_string: stack overflow\n");
@@ -513,8 +502,7 @@ expr_eval_push_alloced_string(sc_char *value) {
* Pop values off the values stack. Returned strings are malloc'ed copies,
* and the caller is responsible for freeing them.
*/
-static sc_int
-expr_eval_pop_integer(void) {
+static sc_int expr_eval_pop_integer(void) {
if (expr_eval_stack_index == 0)
sc_fatal("expr_eval_pop_integer: stack underflow\n");
@@ -522,8 +510,7 @@ expr_eval_pop_integer(void) {
return expr_eval_stack[--expr_eval_stack_index].value.integer;
}
-static sc_char *
-expr_eval_pop_string(void) {
+static sc_char *expr_eval_pop_string(void) {
if (expr_eval_stack_index == 0)
sc_fatal("expr_eval_pop_string: stack underflow\n");
@@ -538,8 +525,7 @@ expr_eval_pop_string(void) {
*
* Return the top of the values stack as the expression result.
*/
-static void
-expr_eval_result(sc_vartype_t *vt_rvalue) {
+static void expr_eval_result(sc_vartype_t *vt_rvalue) {
if (expr_eval_stack_index != 1)
sc_fatal("expr_eval_result: values stack not completed\n");
@@ -555,8 +541,7 @@ expr_eval_result(sc_vartype_t *vt_rvalue) {
* Return the absolute value of the given sc_int. Replacement for labs(),
* avoids tying sc_int to long types too closely.
*/
-static sc_int
-expr_eval_abs(sc_int value) {
+static sc_int expr_eval_abs(sc_int value) {
return value < 0 ? -value : value;
}
@@ -569,8 +554,7 @@ static jmp_buf expr_parse_error;
*
* Evaluate the effect of a token into the values stack.
*/
-static void
-expr_eval_action(sc_int token) {
+static void expr_eval_action(sc_int token) {
sc_vartype_t token_value;
switch (token) {
@@ -1069,8 +1053,7 @@ static void expr_parse_string_expr(void);
*
* Match a token to the lookahead, then advance lookahead.
*/
-static void
-expr_parse_match(sc_int token) {
+static void expr_parse_match(sc_int token) {
if (expr_parse_lookahead == token)
expr_parse_lookahead = expr_next_token();
else {
@@ -1089,10 +1072,10 @@ expr_parse_match(sc_int token) {
* a list with no operators (although in practice we need to put a TOK_NONE
* in here since some C compilers won't accept { } as an empty initializer).
*/
-typedef struct {
+struct sc_precedence_entry_t {
const sc_int token_count;
const sc_int tokens[6];
-} sc_precedence_entry_t;
+};
#if 0
/*
* Conventional (BASIC, C) precedence table for the parser. Exponentiation
@@ -1136,8 +1119,7 @@ static const sc_precedence_entry_t PRECEDENCE_TABLE[] = {
* Helper for expr_parse_numeric_element(). Search the token list for the
* entry passed in, and return TRUE if it contains the given token.
*/
-static int
-expr_parse_contains_token(const sc_precedence_entry_t *entry, sc_int token) {
+static int expr_parse_contains_token(const sc_precedence_entry_t *entry, sc_int token) {
sc_bool is_matched;
sc_int index_;
@@ -1161,8 +1143,7 @@ expr_parse_contains_token(const sc_precedence_entry_t *entry, sc_int token) {
* to match tokens, then decide whether, and how, to recurse into itself, or
* whether to parse a highest-precedence factor.
*/
-static void
-expr_parse_numeric_element(sc_int precedence) {
+static void expr_parse_numeric_element(sc_int precedence) {
const sc_precedence_entry_t *entry;
/* See if the level passed in has listed tokens. */
@@ -1195,8 +1176,7 @@ expr_parse_numeric_element(sc_int precedence) {
*
* Parse a complete numeric (sub-)expression.
*/
-static void
-expr_parse_numeric_expr(void) {
+static void expr_parse_numeric_expr(void) {
/* Call the parser of the lowest precedence operators. */
expr_parse_numeric_element(0);
}
@@ -1207,8 +1187,7 @@ expr_parse_numeric_expr(void) {
*
* Parse a numeric expression factor.
*/
-static void
-expr_parse_numeric_factor(void) {
+static void expr_parse_numeric_factor(void) {
/* Handle factors based on lookahead token. */
switch (expr_parse_lookahead) {
/* Handle straightforward factors first. */
@@ -1365,8 +1344,7 @@ expr_parse_numeric_factor(void) {
*
* Parse a complete string (sub-)expression.
*/
-static void
-expr_parse_string_expr(void) {
+static void expr_parse_string_expr(void) {
/*
* Parse a string factor, then all repeated concatenations. Because the '+'
* and '&' are context sensitive, we have to invent/translate them into the
@@ -1386,8 +1364,7 @@ expr_parse_string_expr(void) {
*
* Parse a string expression factor.
*/
-static void
-expr_parse_string_factor(void) {
+static void expr_parse_string_factor(void) {
/* Handle factors based on lookahead token. */
switch (expr_parse_lookahead) {
/* Handle straightforward factors first. */
@@ -1499,9 +1476,8 @@ expr_parse_string_factor(void) {
* Parse a string expression into a runtime values stack. Return the
* value of the expression.
*/
-static sc_bool
-expr_evaluate_expression(const sc_char *expression, sc_var_setref_t vars,
- sc_int assign_type, sc_vartype_t *vt_rvalue) {
+static sc_bool expr_evaluate_expression(const sc_char *expression, sc_var_setref_t vars,
+ sc_int assign_type, sc_vartype_t *vt_rvalue) {
assert(assign_type == VAR_INTEGER || assign_type == VAR_STRING);
/* Reset values stack and start tokenizer. */
@@ -1540,9 +1516,7 @@ expr_evaluate_expression(const sc_char *expression, sc_var_setref_t vars,
* the return value is malloc'ed, and the caller is responsible for freeing
* it.
*/
-sc_bool
-expr_eval_numeric_expression(const sc_char *expression,
- sc_var_setref_t vars, sc_int *rvalue) {
+sc_bool expr_eval_numeric_expression(const sc_char *expression, sc_var_setref_t vars, sc_int *rvalue) {
sc_vartype_t vt_rvalue;
sc_bool status;
assert(expression && vars && rvalue);
@@ -1554,9 +1528,7 @@ expr_eval_numeric_expression(const sc_char *expression,
return status;
}
-sc_bool
-expr_eval_string_expression(const sc_char *expression,
- sc_var_setref_t vars, sc_char **rvalue) {
+sc_bool expr_eval_string_expression(const sc_char *expression, sc_var_setref_t vars, sc_char **rvalue) {
sc_vartype_t vt_rvalue;
sc_bool status;
assert(expression && vars && rvalue);
diff --git a/engines/glk/adrift/scgamest.cpp b/engines/glk/adrift/scgamest.cpp
index f2af6b8..84abf6b 100644
--- a/engines/glk/adrift/scgamest.cpp
+++ b/engines/glk/adrift/scgamest.cpp
@@ -36,8 +36,7 @@ static const sc_uint GAME_MAGIC = 0x35aed26e;
*
* Move the player to a given room, and check presence in a given room.
*/
-void
-gs_move_player_to_room(sc_gameref_t game, sc_int room) {
+void gs_move_player_to_room(sc_gameref_t game, sc_int room) {
assert(gs_is_game_valid(game));
if (room < 0) {
@@ -53,8 +52,7 @@ gs_move_player_to_room(sc_gameref_t game, sc_int room) {
game->playerposition = 0;
}
-sc_bool
-gs_player_in_room(sc_gameref_t game, sc_int room) {
+sc_bool gs_player_in_room(sc_gameref_t game, sc_int room) {
assert(gs_is_game_valid(game));
return game->playerroom == room;
}
@@ -65,8 +63,7 @@ gs_player_in_room(sc_gameref_t game, sc_int room) {
*
* Helper for event, room, object, and npc range assertions.
*/
-static sc_bool
-gs_in_range(sc_int value, sc_int limit) {
+static sc_bool gs_in_range(sc_int value, sc_int limit) {
return value >= 0 && value < limit;
}
@@ -76,26 +73,22 @@ gs_in_range(sc_int value, sc_int limit) {
*
* Game accessors and mutators.
*/
-sc_var_setref_t
-gs_get_vars(sc_gameref_t gs) {
+sc_var_setref_t gs_get_vars(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->vars;
}
-sc_prop_setref_t
-gs_get_bundle(sc_gameref_t gs) {
+sc_prop_setref_t gs_get_bundle(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->bundle;
}
-sc_filterref_t
-gs_get_filter(sc_gameref_t gs) {
+sc_filterref_t gs_get_filter(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->filter;
}
-sc_memo_setref_t
-gs_get_memento(sc_gameref_t gs) {
+sc_memo_setref_t gs_get_memento(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->memento;
}
@@ -104,38 +97,32 @@ gs_get_memento(sc_gameref_t gs) {
/*
* Game accessors and mutators for the player.
*/
-void
-gs_set_playerroom(sc_gameref_t gs, sc_int room) {
+void gs_set_playerroom(sc_gameref_t gs, sc_int room) {
assert(gs_is_game_valid(gs));
gs->playerroom = room;
}
-void
-gs_set_playerposition(sc_gameref_t gs, sc_int position) {
+void gs_set_playerposition(sc_gameref_t gs, sc_int position) {
assert(gs_is_game_valid(gs));
gs->playerposition = position;
}
-void
-gs_set_playerparent(sc_gameref_t gs, sc_int parent) {
+void gs_set_playerparent(sc_gameref_t gs, sc_int parent) {
assert(gs_is_game_valid(gs));
gs->playerparent = parent;
}
-sc_int
-gs_playerroom(sc_gameref_t gs) {
+sc_int gs_playerroom(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->playerroom;
}
-sc_int
-gs_playerposition(sc_gameref_t gs) {
+sc_int gs_playerposition(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->playerposition;
}
-sc_int
-gs_playerparent(sc_gameref_t gs) {
+sc_int gs_playerparent(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->playerparent;
}
@@ -144,38 +131,32 @@ gs_playerparent(sc_gameref_t gs) {
/*
* Game accessors and mutators for events.
*/
-sc_int
-gs_event_count(sc_gameref_t gs) {
+sc_int gs_event_count(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->event_count;
}
-void
-gs_set_event_state(sc_gameref_t gs, sc_int event, sc_int state) {
+void gs_set_event_state(sc_gameref_t gs, sc_int event, sc_int state) {
assert(gs_is_game_valid(gs) && gs_in_range(event, gs->event_count));
gs->events[event].state = state;
}
-void
-gs_set_event_time(sc_gameref_t gs, sc_int event, sc_int etime) {
+void gs_set_event_time(sc_gameref_t gs, sc_int event, sc_int etime) {
assert(gs_is_game_valid(gs) && gs_in_range(event, gs->event_count));
gs->events[event].time = etime;
}
-sc_int
-gs_event_state(sc_gameref_t gs, sc_int event) {
+sc_int gs_event_state(sc_gameref_t gs, sc_int event) {
assert(gs_is_game_valid(gs) && gs_in_range(event, gs->event_count));
return gs->events[event].state;
}
-sc_int
-gs_event_time(sc_gameref_t gs, sc_int event) {
+sc_int gs_event_time(sc_gameref_t gs, sc_int event) {
assert(gs_is_game_valid(gs) && gs_in_range(event, gs->event_count));
return gs->events[event].time;
}
-void
-gs_decrement_event_time(sc_gameref_t gs, sc_int event) {
+void gs_decrement_event_time(sc_gameref_t gs, sc_int event) {
assert(gs_is_game_valid(gs) && gs_in_range(event, gs->event_count));
gs->events[event].time--;
}
@@ -184,20 +165,17 @@ gs_decrement_event_time(sc_gameref_t gs, sc_int event) {
/*
* Game accessors and mutators for rooms.
*/
-sc_int
-gs_room_count(sc_gameref_t gs) {
+sc_int gs_room_count(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->room_count;
}
-void
-gs_set_room_seen(sc_gameref_t gs, sc_int room, sc_bool seen) {
+void gs_set_room_seen(sc_gameref_t gs, sc_int room, sc_bool seen) {
assert(gs_is_game_valid(gs) && gs_in_range(room, gs->room_count));
gs->rooms[room].visited = seen;
}
-sc_bool
-gs_room_seen(sc_gameref_t gs, sc_int room) {
+sc_bool gs_room_seen(sc_gameref_t gs, sc_int room) {
assert(gs_is_game_valid(gs) && gs_in_range(room, gs->room_count));
return gs->rooms[room].visited;
}
@@ -206,32 +184,27 @@ gs_room_seen(sc_gameref_t gs, sc_int room) {
/*
* Game accessors and mutators for tasks.
*/
-sc_int
-gs_task_count(sc_gameref_t gs) {
+sc_int gs_task_count(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->task_count;
}
-void
-gs_set_task_done(sc_gameref_t gs, sc_int task, sc_bool done) {
+void gs_set_task_done(sc_gameref_t gs, sc_int task, sc_bool done) {
assert(gs_is_game_valid(gs) && gs_in_range(task, gs->task_count));
gs->tasks[task].done = done;
}
-void
-gs_set_task_scored(sc_gameref_t gs, sc_int task, sc_bool scored) {
+void gs_set_task_scored(sc_gameref_t gs, sc_int task, sc_bool scored) {
assert(gs_is_game_valid(gs) && gs_in_range(task, gs->task_count));
gs->tasks[task].scored = scored;
}
-sc_bool
-gs_task_done(sc_gameref_t gs, sc_int task) {
+sc_bool gs_task_done(sc_gameref_t gs, sc_int task) {
assert(gs_is_game_valid(gs) && gs_in_range(task, gs->task_count));
return gs->tasks[task].done;
}
-sc_bool
-gs_task_scored(sc_gameref_t gs, sc_int task) {
+sc_bool gs_task_scored(sc_gameref_t gs, sc_int task) {
assert(gs_is_game_valid(gs) && gs_in_range(task, gs->task_count));
return gs->tasks[task].scored;
}
@@ -240,142 +213,120 @@ gs_task_scored(sc_gameref_t gs, sc_int task) {
/*
* Game accessors and mutators for objects.
*/
-sc_int
-gs_object_count(sc_gameref_t gs) {
+sc_int gs_object_count(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->object_count;
}
-void
-gs_set_object_openness(sc_gameref_t gs, sc_int object, sc_int openness) {
+void gs_set_object_openness(sc_gameref_t gs, sc_int object, sc_int openness) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].openness = openness;
}
-void
-gs_set_object_state(sc_gameref_t gs, sc_int object, sc_int state) {
+void gs_set_object_state(sc_gameref_t gs, sc_int object, sc_int state) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].state = state;
}
-void
-gs_set_object_seen(sc_gameref_t gs, sc_int object, sc_bool seen) {
+void gs_set_object_seen(sc_gameref_t gs, sc_int object, sc_bool seen) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].seen = seen;
}
-void
-gs_set_object_unmoved(sc_gameref_t gs, sc_int object, sc_bool unmoved) {
+void gs_set_object_unmoved(sc_gameref_t gs, sc_int object, sc_bool unmoved) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].unmoved = unmoved;
}
-void
-gs_set_object_static_unmoved(sc_gameref_t gs, sc_int object, sc_bool unmoved) {
+void gs_set_object_static_unmoved(sc_gameref_t gs, sc_int object, sc_bool unmoved) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].static_unmoved = unmoved;
}
-sc_int
-gs_object_openness(sc_gameref_t gs, sc_int object) {
+sc_int gs_object_openness(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
return gs->objects[object].openness;
}
-sc_int
-gs_object_state(sc_gameref_t gs, sc_int object) {
+sc_int gs_object_state(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
return gs->objects[object].state;
}
-sc_bool
-gs_object_seen(sc_gameref_t gs, sc_int object) {
+sc_bool gs_object_seen(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
return gs->objects[object].seen;
}
-sc_bool
-gs_object_unmoved(sc_gameref_t gs, sc_int object) {
+sc_bool gs_object_unmoved(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
return gs->objects[object].unmoved;
}
-sc_bool
-gs_object_static_unmoved(sc_gameref_t gs, sc_int object) {
+sc_bool gs_object_static_unmoved(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
return gs->objects[object].static_unmoved;
}
-sc_int
-gs_object_position(sc_gameref_t gs, sc_int object) {
+sc_int gs_object_position(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
return gs->objects[object].position;
}
-sc_int
-gs_object_parent(sc_gameref_t gs, sc_int object) {
+sc_int gs_object_parent(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
return gs->objects[object].parent;
}
-static void
-gs_object_move_onto_unchecked(sc_gameref_t gs, sc_int object, sc_int onto) {
+static void gs_object_move_onto_unchecked(sc_gameref_t gs, sc_int object, sc_int onto) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = OBJ_ON_OBJECT;
gs->objects[object].parent = onto;
}
-static void
-gs_object_move_into_unchecked(sc_gameref_t gs, sc_int object, sc_int into) {
+static void gs_object_move_into_unchecked(sc_gameref_t gs, sc_int object, sc_int into) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = OBJ_IN_OBJECT;
gs->objects[object].parent = into;
}
-static void
-gs_object_make_hidden_unchecked(sc_gameref_t gs, sc_int object) {
+static void gs_object_make_hidden_unchecked(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = OBJ_HIDDEN;
gs->objects[object].parent = -1;
}
-static void
-gs_object_player_get_unchecked(sc_gameref_t gs, sc_int object) {
+static void gs_object_player_get_unchecked(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = OBJ_HELD_PLAYER;
gs->objects[object].parent = -1;
}
-static void
-gs_object_npc_get_unchecked(sc_gameref_t gs, sc_int object, sc_int npc) {
+static void gs_object_npc_get_unchecked(sc_gameref_t gs, sc_int object, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = OBJ_HELD_NPC;
gs->objects[object].parent = npc;
}
-static void
-gs_object_player_wear_unchecked(sc_gameref_t gs, sc_int object) {
+static void gs_object_player_wear_unchecked(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = OBJ_WORN_PLAYER;
gs->objects[object].parent = 0;
}
-static void
-gs_object_npc_wear_unchecked(sc_gameref_t gs, sc_int object, sc_int npc) {
+static void gs_object_npc_wear_unchecked(sc_gameref_t gs, sc_int object, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = OBJ_WORN_NPC;
gs->objects[object].parent = npc;
}
-static void
-gs_object_to_room_unchecked(sc_gameref_t gs, sc_int object, sc_int room) {
+static void gs_object_to_room_unchecked(sc_gameref_t gs, sc_int object, sc_int room) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
gs->objects[object].position = room + 1;
gs->objects[object].parent = -1;
}
-void
-gs_object_move_onto(sc_gameref_t gs, sc_int object, sc_int onto) {
+void gs_object_move_onto(sc_gameref_t gs, sc_int object, sc_int onto) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != OBJ_ON_OBJECT
|| gs->objects[object].parent != onto) {
@@ -384,8 +335,7 @@ gs_object_move_onto(sc_gameref_t gs, sc_int object, sc_int onto) {
}
}
-void
-gs_object_move_into(sc_gameref_t gs, sc_int object, sc_int into) {
+void gs_object_move_into(sc_gameref_t gs, sc_int object, sc_int into) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != OBJ_IN_OBJECT
|| gs->objects[object].parent != into) {
@@ -394,8 +344,7 @@ gs_object_move_into(sc_gameref_t gs, sc_int object, sc_int into) {
}
}
-void
-gs_object_make_hidden(sc_gameref_t gs, sc_int object) {
+void gs_object_make_hidden(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != OBJ_HIDDEN) {
gs_object_make_hidden_unchecked(gs, object);
@@ -403,8 +352,7 @@ gs_object_make_hidden(sc_gameref_t gs, sc_int object) {
}
}
-void
-gs_object_player_get(sc_gameref_t gs, sc_int object) {
+void gs_object_player_get(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != OBJ_HELD_PLAYER) {
gs_object_player_get_unchecked(gs, object);
@@ -412,8 +360,7 @@ gs_object_player_get(sc_gameref_t gs, sc_int object) {
}
}
-void
-gs_object_npc_get(sc_gameref_t gs, sc_int object, sc_int npc) {
+void gs_object_npc_get(sc_gameref_t gs, sc_int object, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != OBJ_HELD_NPC
|| gs->objects[object].parent != npc) {
@@ -422,8 +369,7 @@ gs_object_npc_get(sc_gameref_t gs, sc_int object, sc_int npc) {
}
}
-void
-gs_object_player_wear(sc_gameref_t gs, sc_int object) {
+void gs_object_player_wear(sc_gameref_t gs, sc_int object) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != OBJ_WORN_PLAYER) {
gs_object_player_wear_unchecked(gs, object);
@@ -431,8 +377,7 @@ gs_object_player_wear(sc_gameref_t gs, sc_int object) {
}
}
-void
-gs_object_npc_wear(sc_gameref_t gs, sc_int object, sc_int npc) {
+void gs_object_npc_wear(sc_gameref_t gs, sc_int object, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != OBJ_WORN_NPC
|| gs->objects[object].parent != npc) {
@@ -441,8 +386,7 @@ gs_object_npc_wear(sc_gameref_t gs, sc_int object, sc_int npc) {
}
}
-void
-gs_object_to_room(sc_gameref_t gs, sc_int object, sc_int room) {
+void gs_object_to_room(sc_gameref_t gs, sc_int object, sc_int room) {
assert(gs_is_game_valid(gs) && gs_in_range(object, gs->object_count));
if (gs->objects[object].position != room + 1) {
gs_object_to_room_unchecked(gs, object, room);
@@ -454,83 +398,70 @@ gs_object_to_room(sc_gameref_t gs, sc_int object, sc_int room) {
/*
* Game accessors and mutators for NPCs.
*/
-sc_int
-gs_npc_count(sc_gameref_t gs) {
+sc_int gs_npc_count(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
return gs->npc_count;
}
-void
-gs_set_npc_location(sc_gameref_t gs, sc_int npc, sc_int location) {
+void gs_set_npc_location(sc_gameref_t gs, sc_int npc, sc_int location) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
gs->npcs[npc].location = location;
}
-sc_int
-gs_npc_location(sc_gameref_t gs, sc_int npc) {
+sc_int gs_npc_location(sc_gameref_t gs, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
return gs->npcs[npc].location;
}
-void
-gs_set_npc_position(sc_gameref_t gs, sc_int npc, sc_int position) {
+void gs_set_npc_position(sc_gameref_t gs, sc_int npc, sc_int position) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
gs->npcs[npc].position = position;
}
-sc_int
-gs_npc_position(sc_gameref_t gs, sc_int npc) {
+sc_int gs_npc_position(sc_gameref_t gs, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
return gs->npcs[npc].position;
}
-void
-gs_set_npc_parent(sc_gameref_t gs, sc_int npc, sc_int parent) {
+void gs_set_npc_parent(sc_gameref_t gs, sc_int npc, sc_int parent) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
gs->npcs[npc].parent = parent;
}
-sc_int
-gs_npc_parent(sc_gameref_t gs, sc_int npc) {
+sc_int gs_npc_parent(sc_gameref_t gs, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
return gs->npcs[npc].parent;
}
-void
-gs_set_npc_seen(sc_gameref_t gs, sc_int npc, sc_bool seen) {
+void gs_set_npc_seen(sc_gameref_t gs, sc_int npc, sc_bool seen) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
gs->npcs[npc].seen = seen;
}
-sc_bool
-gs_npc_seen(sc_gameref_t gs, sc_int npc) {
+sc_bool gs_npc_seen(sc_gameref_t gs, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
return gs->npcs[npc].seen;
}
-sc_int
-gs_npc_walkstep_count(sc_gameref_t gs, sc_int npc) {
+sc_int gs_npc_walkstep_count(sc_gameref_t gs, sc_int npc) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count));
return gs->npcs[npc].walkstep_count;
}
-void
-gs_set_npc_walkstep(sc_gameref_t gs,
+void gs_set_npc_walkstep(sc_gameref_t gs,
sc_int npc, sc_int walk, sc_int walkstep) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count)
&& gs_in_range(walk, gs->npcs[npc].walkstep_count));
gs->npcs[npc].walksteps[walk] = walkstep;
}
-sc_int
-gs_npc_walkstep(sc_gameref_t gs, sc_int npc, sc_int walk) {
+sc_int gs_npc_walkstep(sc_gameref_t gs, sc_int npc, sc_int walk) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count)
&& gs_in_range(walk, gs->npcs[npc].walkstep_count));
return gs->npcs[npc].walksteps[walk];
}
-void
-gs_decrement_npc_walkstep(sc_gameref_t gs, sc_int npc, sc_int walk) {
+void gs_decrement_npc_walkstep(sc_gameref_t gs, sc_int npc, sc_int walk) {
assert(gs_is_game_valid(gs) && gs_in_range(npc, gs->npc_count)
&& gs_in_range(walk, gs->npcs[npc].walkstep_count));
gs->npcs[npc].walksteps[walk]--;
@@ -540,29 +471,25 @@ gs_decrement_npc_walkstep(sc_gameref_t gs, sc_int npc, sc_int walk) {
/*
* Convenience functions for bulk clearance of references.
*/
-void
-gs_clear_npc_references(sc_gameref_t gs) {
+void gs_clear_npc_references(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
memset(gs->npc_references,
FALSE, gs->npc_count * sizeof(*gs->npc_references));
}
-void
-gs_clear_object_references(sc_gameref_t gs) {
+void gs_clear_object_references(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
memset(gs->object_references,
FALSE, gs->object_count * sizeof(*gs->object_references));
}
-void
-gs_set_multiple_references(sc_gameref_t gs) {
+void gs_set_multiple_references(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
memset(gs->multiple_references,
TRUE, gs->object_count * sizeof(*gs->multiple_references));
}
-void
-gs_clear_multiple_references(sc_gameref_t gs) {
+void gs_clear_multiple_references(sc_gameref_t gs) {
assert(gs_is_game_valid(gs));
memset(gs->multiple_references,
FALSE, gs->object_count * sizeof(*gs->multiple_references));
@@ -574,9 +501,7 @@ gs_clear_multiple_references(sc_gameref_t gs) {
*
* Create and initialize a game state.
*/
-sc_gameref_t
-gs_create(sc_var_setref_t vars,
- sc_prop_setref_t bundle, sc_filterref_t filter) {
+sc_gameref_t gs_create(sc_var_setref_t vars, sc_prop_setref_t bundle, sc_filterref_t filter) {
sc_gameref_t game;
sc_vartype_t vt_key[4];
sc_int index_, bytes;
@@ -871,8 +796,7 @@ gs_create(sc_var_setref_t vars,
*
* Return TRUE if pointer is a valid game, FALSE otherwise.
*/
-sc_bool
-gs_is_game_valid(sc_gameref_t game) {
+sc_bool gs_is_game_valid(sc_gameref_t game) {
return game && game->magic == GAME_MAGIC;
}
@@ -883,8 +807,7 @@ gs_is_game_valid(sc_gameref_t game) {
* Helper for gs_copy(), copies one malloc'ed string to another, or NULL
* if from is NULL, taking care not to leak memory.
*/
-static void
-gs_string_copy(sc_char **to_string, const sc_char *from_string) {
+static void gs_string_copy(sc_char **to_string, const sc_char *from_string) {
/* Free any current contents of to_string. */
sc_free(*to_string);
@@ -903,8 +826,7 @@ gs_string_copy(sc_char **to_string, const sc_char *from_string) {
* Deep-copy the dynamic parts of a game onto another existing
* game structure.
*/
-void
-gs_copy(sc_gameref_t to, sc_gameref_t from) {
+void gs_copy(sc_gameref_t to, sc_gameref_t from) {
const sc_prop_setref_t bundle = from->bundle;
sc_vartype_t vt_key[3];
sc_int var_count, var, npc;
@@ -1048,8 +970,7 @@ gs_copy(sc_gameref_t to, sc_gameref_t from) {
*
* Free all the memory associated with a game state.
*/
-void
-gs_destroy(sc_gameref_t game) {
+void gs_destroy(sc_gameref_t game) {
sc_int npc;
assert(gs_is_game_valid(game));
diff --git a/engines/glk/adrift/scinterf.cpp b/engines/glk/adrift/scinterf.cpp
index c5e53e9..ff7456b 100644
--- a/engines/glk/adrift/scinterf.cpp
+++ b/engines/glk/adrift/scinterf.cpp
@@ -45,8 +45,7 @@ static sc_uint if_trace_flags = 0;
* First-time runtime checks for the overall interpreter. This function
* tries to ensure correct compile options.
*/
-static void
-if_initialize(void) {
+static void if_initialize(void) {
static sc_bool initialized = FALSE;
/* Only do checks on the first call. */
@@ -79,13 +78,11 @@ if_initialize(void) {
* Set and retrieve tracing flags. Setting new values propagates the new
* tracing setting to all modules that support it.
*/
-static sc_bool
-if_bool(sc_uint flag) {
+static sc_bool if_bool(sc_uint flag) {
return flag ? TRUE : FALSE;
}
-void
-sc_set_trace_flags(sc_uint trace_flags) {
+void sc_set_trace_flags(sc_uint trace_flags) {
if_initialize();
/* Save the value for queries. */
@@ -105,8 +102,7 @@ sc_set_trace_flags(sc_uint trace_flags) {
pf_debug_trace(if_bool(trace_flags & SC_TRACE_PRINTFILTER));
}
-sc_bool
-if_get_trace_flag(sc_uint bitmask) {
+sc_bool if_get_trace_flag(sc_uint bitmask) {
return if_bool(if_trace_flags & bitmask);
}
@@ -122,28 +118,22 @@ if_get_trace_flag(sc_uint bitmask) {
*
* Call OS-specific print function for the given arguments.
*/
-static void
-if_print_string_common(const sc_char *string,
- void (*print_string_function)(const sc_char *)) {
+static void if_print_string_common(const sc_char *string, void (*print_string_function)(const sc_char *)) {
assert(string);
if (string[0] != NUL)
print_string_function(string);
}
-void
-if_print_string(const sc_char *string) {
+void if_print_string(const sc_char *string) {
if_print_string_common(string, os_print_string);
}
-void
-if_print_debug(const sc_char *string) {
+void if_print_debug(const sc_char *string) {
if_print_string_common(string, os_print_string_debug);
}
-static void
-if_print_character_common(sc_char character,
- void (*print_string_function)(const sc_char *)) {
+static void if_print_character_common(sc_char character, void (*print_string_function)(const sc_char *)) {
if (character != NUL) {
sc_char buffer[2];
@@ -153,18 +143,15 @@ if_print_character_common(sc_char character,
}
}
-void
-if_print_character(sc_char character) {
+void if_print_character(sc_char character) {
if_print_character_common(character, os_print_string);
}
-void
-if_print_debug_character(sc_char character) {
+void if_print_debug_character(sc_char character) {
if_print_character_common(character, os_print_string_debug);
}
-void
-if_print_tag(sc_int tag, const sc_char *arg) {
+void if_print_tag(sc_int tag, const sc_char *arg) {
assert(arg);
os_print_tag(tag, arg);
@@ -179,9 +166,8 @@ if_print_tag(sc_int tag, const sc_char *arg) {
* Call OS-specific line read function. Clean up any read data a little
* before returning it to the caller.
*/
-static void
-if_read_line_common(sc_char *buffer, sc_int length,
- sc_bool(*read_line_function)(sc_char *, sc_int)) {
+static void if_read_line_common(sc_char *buffer, sc_int length,
+ sc_bool(*read_line_function)(sc_char *, sc_int)) {
sc_bool is_line_available;
sc_int last;
assert(buffer && length > 0);
@@ -204,13 +190,11 @@ if_read_line_common(sc_char *buffer, sc_int length,
buffer[last--] = NUL;
}
-void
-if_read_line(sc_char *buffer, sc_int length) {
+void if_read_line(sc_char *buffer, sc_int length) {
if_read_line_common(buffer, length, os_read_line);
}
-void
-if_read_debug(sc_char *buffer, sc_int length) {
+void if_read_debug(sc_char *buffer, sc_int length) {
if_read_line_common(buffer, length, os_read_line_debug);
}
@@ -220,8 +204,7 @@ if_read_debug(sc_char *buffer, sc_int length) {
*
* Call OS-specific confirm function.
*/
-sc_bool
-if_confirm(sc_int type) {
+sc_bool if_confirm(sc_int type) {
return os_confirm(type);
}
@@ -234,27 +217,23 @@ if_confirm(sc_int type) {
*
* Call OS-specific functions for saving and restoring games.
*/
-void *
-if_open_saved_game(sc_bool is_save) {
+void *if_open_saved_game(sc_bool is_save) {
return os_open_file(is_save);
}
-void
-if_write_saved_game(void *opaque, const sc_byte *buffer, sc_int length) {
+void if_write_saved_game(void *opaque, const sc_byte *buffer, sc_int length) {
assert(buffer);
os_write_file(opaque, buffer, length);
}
-sc_int
-if_read_saved_game(void *opaque, sc_byte *buffer, sc_int length) {
+sc_int if_read_saved_game(void *opaque, sc_byte *buffer, sc_int length) {
assert(buffer);
return os_read_file(opaque, buffer, length);
}
-void
-if_close_saved_game(void *opaque) {
+void if_close_saved_game(void *opaque) {
os_close_file(opaque);
}
@@ -264,8 +243,7 @@ if_close_saved_game(void *opaque) {
*
* Call OS-specific hint display function.
*/
-void
-if_display_hints(sc_gameref_t game) {
+void if_display_hints(sc_gameref_t game) {
assert(gs_is_game_valid(game));
os_display_hints((sc_game) game);
@@ -278,18 +256,15 @@ if_display_hints(sc_gameref_t game) {
*
* Call OS-specific sound and graphic handler functions.
*/
-void
-if_update_sound(const sc_char *filename,
- sc_int sound_offset, sc_int sound_length,
- sc_bool is_looping) {
+void if_update_sound(const sc_char *filename, sc_int sound_offset, sc_int sound_length,
+ sc_bool is_looping) {
if (strlen(filename) > 0)
os_play_sound(filename, sound_offset, sound_length, is_looping);
else
os_stop_sound();
}
-void
-if_update_graphic(const sc_char *filename,
+void if_update_graphic(const sc_char *filename,
sc_int graphic_offset, sc_int graphic_length) {
os_show_graphic(filename, graphic_offset, graphic_length);
}
@@ -301,14 +276,12 @@ if_update_graphic(const sc_char *filename,
*
* Return a version string and Adrift emulation level.
*/
-const sc_char *
-sc_scare_version(void) {
+const sc_char *sc_scare_version(void) {
if_initialize();
return "SCARE " SCARE_VERSION SCARE_PATCH_LEVEL;
}
-sc_int
-sc_scare_emulation(void) {
+sc_int sc_scare_emulation(void) {
if_initialize();
return SCARE_EMULATION;
}
@@ -321,8 +294,7 @@ sc_scare_emulation(void) {
* Standard FILE* reader and writer callback for constructing callback-style
* calls from filename and stream variants.
*/
-static sc_int
-if_file_read_callback(void *opaque, sc_byte *buffer, sc_int length) {
+static sc_int if_file_read_callback(void *opaque, sc_byte *buffer, sc_int length) {
Common::SeekableReadStream *stream = (Common::SeekableReadStream *)opaque;
sc_int bytes;
@@ -350,8 +322,7 @@ static void if_file_write_callback(void *opaque, const sc_byte *buffer, sc_int l
* Called by the OS-specific layer to create a run context. The _filename()
* and _stream() variants are adapters for run_create().
*/
-sc_game
-sc_game_from_filename(const sc_char *filename) {
+sc_game sc_game_from_filename(const sc_char *filename) {
Common::File *stream;
sc_game game;
@@ -384,9 +355,7 @@ sc_game sc_game_from_stream(Common::SeekableReadStream *stream) {
return run_create(if_file_read_callback, stream);
}
-sc_game
-sc_game_from_callback(sc_int(*callback)(void *, sc_byte *, sc_int),
- void *opaque) {
+sc_game sc_game_from_callback(sc_int(*callback)(void *, sc_byte *, sc_int), void *opaque) {
if_initialize();
if (!callback) {
sc_error("sc_game_from_callback: nullptr callback\n");
@@ -403,8 +372,7 @@ sc_game_from_callback(sc_int(*callback)(void *, sc_byte *, sc_int),
* Common function to verify that the game passed in to functions below
* is a valid game. Returns TRUE on game error, FALSE if okay.
*/
-static sc_bool
-if_game_error(sc_gameref_t game, const sc_char *function_name) {
+static sc_bool if_game_error(sc_gameref_t game, const sc_char *function_name) {
/* Check for invalid game -- null pointer or bad magic. */
if (!gs_is_game_valid(game)) {
if (game)
@@ -435,8 +403,7 @@ if_game_error(sc_gameref_t game, const sc_char *function_name) {
* behaving like sc_restart_game()), but will return if the game could not
* be restored. sc_undo_game_turn() behaves like sc_load_game().
*/
-void
-sc_interpret_game(sc_game game) {
+void sc_interpret_game(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_interpret_game"))
@@ -445,8 +412,7 @@ sc_interpret_game(sc_game game) {
run_interpret(game_);
}
-void
-sc_restart_game(sc_game game) {
+void sc_restart_game(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_restart_game"))
@@ -455,8 +421,7 @@ sc_restart_game(sc_game game) {
run_restart(game_);
}
-sc_bool
-sc_save_game(sc_game game) {
+sc_bool sc_save_game(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_save_game"))
@@ -465,8 +430,7 @@ sc_save_game(sc_game game) {
return run_save_prompted(game_);
}
-sc_bool
-sc_load_game(sc_game game) {
+sc_bool sc_load_game(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_load_game"))
@@ -475,8 +439,7 @@ sc_load_game(sc_game game) {
return run_restore_prompted(game_);
}
-sc_bool
-sc_undo_game_turn(sc_game game) {
+sc_bool sc_undo_game_turn(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_undo_game_turn"))
@@ -485,8 +448,7 @@ sc_undo_game_turn(sc_game game) {
return run_undo(game_);
}
-void
-sc_quit_game(sc_game game) {
+void sc_quit_game(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_quit_game"))
@@ -510,8 +472,7 @@ sc_quit_game(sc_game game) {
* These alternative forms allow the caller to directly specify the data
* streams.
*/
-sc_bool
-sc_save_game_to_filename(sc_game game, const sc_char *filename) {
+sc_bool sc_save_game_to_filename(sc_game game, const sc_char *filename) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
Common::OutSaveFile *sf;
@@ -536,8 +497,7 @@ sc_save_game_to_filename(sc_game game, const sc_char *filename) {
return TRUE;
}
-void
-sc_save_game_to_stream(sc_game game, Common::SeekableReadStream *stream) {
+void sc_save_game_to_stream(sc_game game, Common::SeekableReadStream *stream) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_save_game_to_stream"))
@@ -551,10 +511,8 @@ sc_save_game_to_stream(sc_game game, Common::SeekableReadStream *stream) {
run_save(game_, if_file_write_callback, stream);
}
-void
-sc_save_game_to_callback(sc_game game,
- void (*callback)(void *, const sc_byte *, sc_int),
- void *opaque) {
+void sc_save_game_to_callback(sc_game game,
+ void (*callback)(void *, const sc_byte *, sc_int), void *opaque) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_save_game_to_callback"))
@@ -568,8 +526,7 @@ sc_save_game_to_callback(sc_game game,
run_save(game_, callback, opaque);
}
-sc_bool
-sc_load_game_from_filename(sc_game game, const sc_char *filename) {
+sc_bool sc_load_game_from_filename(sc_game game, const sc_char *filename) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
Common::InSaveFile *sf;
sc_bool status;
@@ -594,8 +551,7 @@ sc_load_game_from_filename(sc_game game, const sc_char *filename) {
return status;
}
-sc_bool
-sc_load_game_from_stream(sc_game game, Common::SeekableReadStream *stream) {
+sc_bool sc_load_game_from_stream(sc_game game, Common::SeekableReadStream *stream) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_load_game_from_stream"))
@@ -609,10 +565,8 @@ sc_load_game_from_stream(sc_game game, Common::SeekableReadStream *stream) {
return run_restore(game_, if_file_read_callback, stream);
}
-sc_bool
-sc_load_game_from_callback(sc_game game,
- sc_int(*callback)(void *, sc_byte *, sc_int),
- void *opaque) {
+sc_bool sc_load_game_from_callback(sc_game game,
+ sc_int(*callback)(void *, sc_byte *, sc_int), void *opaque) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_load_game_from_callback"))
@@ -632,8 +586,7 @@ sc_load_game_from_callback(sc_game game,
*
* Called by the OS-specific layer to free run context memory.
*/
-void
-sc_free_game(sc_game game) {
+void sc_free_game(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_free_game"))
@@ -662,8 +615,7 @@ sc_free_game(sc_game game) {
*
* Return a few attributes of a game.
*/
-sc_bool
-sc_is_game_running(sc_game game) {
+sc_bool sc_is_game_running(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_is_game_running"))
@@ -672,8 +624,7 @@ sc_is_game_running(sc_game game) {
return run_is_running(game_);
}
-const sc_char *
-sc_get_game_name(sc_game game) {
+const sc_char *sc_get_game_name(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_char *retval;
@@ -700,8 +651,7 @@ sc_get_game_author(sc_game game) {
return retval;
}
-const sc_char *
-sc_get_game_compile_date(sc_game game) {
+const sc_char *sc_get_game_compile_date(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_char *retval;
@@ -713,8 +663,7 @@ sc_get_game_compile_date(sc_game game) {
return retval;
}
-sc_int
-sc_get_game_turns(sc_game game) {
+sc_int sc_get_game_turns(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_int retval;
@@ -726,8 +675,7 @@ sc_get_game_turns(sc_game game) {
return retval;
}
-sc_int
-sc_get_game_score(sc_game game) {
+sc_int sc_get_game_score(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_int retval;
@@ -739,8 +687,7 @@ sc_get_game_score(sc_game game) {
return retval;
}
-sc_int
-sc_get_game_max_score(sc_game game) {
+sc_int sc_get_game_max_score(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_int retval;
@@ -752,8 +699,7 @@ sc_get_game_max_score(sc_game game) {
return retval;
}
-const sc_char *
-sc_get_game_room(sc_game game) {
+const sc_char *sc_get_game_room(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_char *retval;
@@ -765,8 +711,7 @@ sc_get_game_room(sc_game game) {
return retval;
}
-const sc_char *
-sc_get_game_status_line(sc_game game) {
+const sc_char *sc_get_game_status_line(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_char *retval;
@@ -778,8 +723,7 @@ sc_get_game_status_line(sc_game game) {
return retval;
}
-const sc_char *
-sc_get_game_preferred_font(sc_game game) {
+const sc_char *sc_get_game_preferred_font(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_char *retval;
@@ -791,8 +735,7 @@ sc_get_game_preferred_font(sc_game game) {
return retval;
}
-sc_bool
-sc_get_game_bold_room_names(sc_game game) {
+sc_bool sc_get_game_bold_room_names(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_bool retval;
@@ -804,8 +747,7 @@ sc_get_game_bold_room_names(sc_game game) {
return retval;
}
-sc_bool
-sc_get_game_verbose(sc_game game) {
+sc_bool sc_get_game_verbose(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_bool retval;
@@ -817,8 +759,7 @@ sc_get_game_verbose(sc_game game) {
return retval;
}
-sc_bool
-sc_get_game_notify_score_change(sc_game game) {
+sc_bool sc_get_game_notify_score_change(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_bool retval;
@@ -830,8 +771,7 @@ sc_get_game_notify_score_change(sc_game game) {
return retval;
}
-sc_bool
-sc_has_game_completed(sc_game game) {
+sc_bool sc_has_game_completed(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_has_game_completed"))
@@ -840,8 +780,7 @@ sc_has_game_completed(sc_game game) {
return run_has_completed(game_);
}
-sc_bool
-sc_is_game_undo_available(sc_game game) {
+sc_bool sc_is_game_undo_available(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_is_game_undo_available"))
@@ -858,8 +797,7 @@ sc_is_game_undo_available(sc_game game) {
*
* Set a few attributes of a game.
*/
-void
-sc_set_game_bold_room_names(sc_game game, sc_bool flag) {
+void sc_set_game_bold_room_names(sc_game game, sc_bool flag) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_bool bold, verbose, notify;
@@ -871,8 +809,7 @@ sc_set_game_bold_room_names(sc_game game, sc_bool flag) {
run_set_attributes(game_, flag, verbose, notify);
}
-void
-sc_set_game_verbose(sc_game game, sc_bool flag) {
+void sc_set_game_verbose(sc_game game, sc_bool flag) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_bool bold, verbose, notify;
@@ -884,8 +821,7 @@ sc_set_game_verbose(sc_game game, sc_bool flag) {
run_set_attributes(game_, bold, flag, notify);
}
-void
-sc_set_game_notify_score_change(sc_game game, sc_bool flag) {
+void sc_set_game_notify_score_change(sc_game game, sc_bool flag) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
sc_bool bold, verbose, notify;
@@ -904,8 +840,7 @@ sc_set_game_notify_score_change(sc_game game, sc_bool flag) {
*
* Indicate the game's use of resources.
*/
-sc_bool
-sc_does_game_use_sounds(sc_game game) {
+sc_bool sc_does_game_use_sounds(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_does_game_use_sounds"))
@@ -914,8 +849,7 @@ sc_does_game_use_sounds(sc_game game) {
return res_has_sound(game_);
}
-sc_bool
-sc_does_game_use_graphics(sc_game game) {
+sc_bool sc_does_game_use_graphics(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_does_game_use_graphics"))
@@ -934,8 +868,7 @@ sc_does_game_use_graphics(sc_game game) {
*
* Iterate currently available hints, and return strings for a hint.
*/
-sc_game_hint
-sc_get_first_game_hint(sc_game game) {
+sc_game_hint sc_get_first_game_hint(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_get_first_game_hint"))
@@ -944,8 +877,7 @@ sc_get_first_game_hint(sc_game game) {
return run_hint_iterate(game_, nullptr);
}
-sc_game_hint
-sc_get_next_game_hint(sc_game game, sc_game_hint hint) {
+sc_game_hint sc_get_next_game_hint(sc_game game, sc_game_hint hint) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_hintref_t hint_ = (const sc_hintref_t)hint;
@@ -959,8 +891,7 @@ sc_get_next_game_hint(sc_game game, sc_game_hint hint) {
return run_hint_iterate(game_, hint_);
}
-const sc_char *
-sc_get_game_hint_question(sc_game game, sc_game_hint hint) {
+const sc_char *sc_get_game_hint_question(sc_game game, sc_game_hint hint) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_hintref_t hint_ = (const sc_hintref_t)hint;
@@ -974,8 +905,7 @@ sc_get_game_hint_question(sc_game game, sc_game_hint hint) {
return run_get_hint_question(game_, hint_);
}
-const sc_char *
-sc_get_game_subtle_hint(sc_game game, sc_game_hint hint) {
+const sc_char *sc_get_game_subtle_hint(sc_game game, sc_game_hint hint) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_hintref_t hint_ = (const sc_hintref_t)hint;
@@ -989,8 +919,7 @@ sc_get_game_subtle_hint(sc_game game, sc_game_hint hint) {
return run_get_subtle_hint(game_, hint_);
}
-const sc_char *
-sc_get_game_unsubtle_hint(sc_game game, sc_game_hint hint) {
+const sc_char *sc_get_game_unsubtle_hint(sc_game game, sc_game_hint hint) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
const sc_hintref_t hint_ = (const sc_hintref_t)hint;
@@ -1012,8 +941,7 @@ sc_get_game_unsubtle_hint(sc_game game, sc_game_hint hint) {
*
* Enable, disable, and query game debugging, and run a single debug command.
*/
-void
-sc_set_game_debugger_enabled(sc_game game, sc_bool flag) {
+void sc_set_game_debugger_enabled(sc_game game, sc_bool flag) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_set_game_debugger_enabled"))
@@ -1022,8 +950,7 @@ sc_set_game_debugger_enabled(sc_game game, sc_bool flag) {
debug_set_enabled(game_, flag);
}
-sc_bool
-sc_get_game_debugger_enabled(sc_game game) {
+sc_bool sc_get_game_debugger_enabled(sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_get_game_debugger_enabled"))
@@ -1032,8 +959,7 @@ sc_get_game_debugger_enabled(sc_game game) {
return debug_get_enabled(game_);
}
-sc_bool
-sc_run_game_debugger_command(sc_game game, const sc_char *debug_command) {
+sc_bool sc_run_game_debugger_command(sc_game game, const sc_char *debug_command) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_run_game_debugger_command"))
@@ -1049,8 +975,7 @@ sc_run_game_debugger_command(sc_game game, const sc_char *debug_command) {
*
* Set the interpreter locale, and get the currently set locale.
*/
-sc_bool
-sc_set_locale(const sc_char *name) {
+sc_bool sc_set_locale(const sc_char *name) {
if (!name) {
sc_error("sc_set_locale: nullptr name\n");
return FALSE;
@@ -1059,8 +984,7 @@ sc_set_locale(const sc_char *name) {
return loc_set_locale(name);
}
-const sc_char *
-sc_get_locale(void) {
+const sc_char *sc_get_locale(void) {
return loc_get_locale();
}
@@ -1072,16 +996,14 @@ sc_get_locale(void) {
* Turn portable random number generation on and off, and supply a new seed
* for random number generators.
*/
-void
-sc_set_portable_random(sc_bool flag) {
+void sc_set_portable_random(sc_bool flag) {
if (flag)
sc_set_congruential_random();
else
sc_set_platform_random();
}
-void
-sc_reseed_random_sequence(sc_uint new_seed) {
+void sc_reseed_random_sequence(sc_uint new_seed) {
if (new_seed == 0) {
sc_error("sc_reseed_random_sequence: new_seed may not be 0\n");
return;
diff --git a/engines/glk/adrift/sclibrar.cpp b/engines/glk/adrift/sclibrar.cpp
index bfa1711..51e4224 100644
--- a/engines/glk/adrift/sclibrar.cpp
+++ b/engines/glk/adrift/sclibrar.cpp
@@ -58,8 +58,7 @@ static sc_bool lib_trace = FALSE;
* directly rather than using the printfilter to avoid possible clashes
* with ALRs.
*/
-void
-lib_warn_battle_system(void) {
+void lib_warn_battle_system(void) {
if_print_tag(SC_TAG_FONT, "size=16");
if_print_string("SCARE WARNING");
if_print_tag(SC_TAG_ENDFONT, "");
@@ -85,8 +84,7 @@ lib_warn_battle_system(void) {
*
* Return a random member of a roomgroup.
*/
-sc_int
-lib_random_roomgroup_member(sc_gameref_t game, sc_int roomgroup) {
+sc_int lib_random_roomgroup_member(sc_gameref_t game, sc_int roomgroup) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
sc_int count, room;
@@ -119,8 +117,7 @@ lib_random_roomgroup_member(sc_gameref_t game, sc_int roomgroup) {
*
* Return TRUE if a particular alternate room description should be used.
*/
-static sc_bool
-lib_use_room_alt(sc_gameref_t game, sc_int room, sc_int alt) {
+static sc_bool lib_use_room_alt(sc_gameref_t game, sc_int room, sc_int alt) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int type;
@@ -247,8 +244,7 @@ lib_use_room_alt(sc_gameref_t game, sc_int room, sc_int alt) {
* the alts list when generating room names or descriptions. Returns -1 if
* no alt overrides the default room long description.
*/
-static sc_int
-lib_find_starting_alt(sc_gameref_t game, sc_int room) {
+static sc_int lib_find_starting_alt(sc_gameref_t game, sc_int room) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int alt_count, alt, retval;
@@ -305,8 +301,7 @@ lib_find_starting_alt(sc_gameref_t game, sc_int room) {
*
* Get/print out the name for a given room.
*/
-const sc_char *
-lib_get_room_name(sc_gameref_t game, sc_int room) {
+const sc_char *lib_get_room_name(sc_gameref_t game, sc_int room) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int alt_count, alt, start;
@@ -357,8 +352,7 @@ lib_get_room_name(sc_gameref_t game, sc_int room) {
return name;
}
-void
-lib_print_room_name(sc_gameref_t game, sc_int room) {
+void lib_print_room_name(sc_gameref_t game, sc_int room) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_char *name;
@@ -382,8 +376,7 @@ lib_print_room_name(sc_gameref_t game, sc_int room) {
* prefix -- any "a"/"an"/"some" is replaced by "the" -- and with the full
* prefix.
*/
-static void
-lib_print_object_np(sc_gameref_t game, sc_int object) {
+static void lib_print_object_np(sc_gameref_t game, sc_int object) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -448,8 +441,7 @@ lib_print_object_np(sc_gameref_t game, sc_int object) {
pf_buffer_string(filter, name);
}
-static void
-lib_print_object(sc_gameref_t game, sc_int object) {
+static void lib_print_object(sc_gameref_t game, sc_int object) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -483,8 +475,7 @@ lib_print_object(sc_gameref_t game, sc_int object) {
* Convenience functions to print out an NPC's name, with and without
* any prefix.
*/
-static void
-lib_print_npc_np(sc_gameref_t game, sc_int npc) {
+static void lib_print_npc_np(sc_gameref_t game, sc_int npc) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -500,8 +491,7 @@ lib_print_npc_np(sc_gameref_t game, sc_int npc) {
}
#if 0
-static void
-lib_print_npc(sc_gameref_t game, sc_int npc) {
+static void lib_print_npc(sc_gameref_t game, sc_int npc) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -530,11 +520,8 @@ lib_print_npc(sc_gameref_t game, sc_int npc) {
* Convenience functions for multiple handlers. Returns the appropriate
* response string for a game, based on perspective or object plurality.
*/
-static const sc_char *
-lib_select_response(sc_gameref_t game,
- const sc_char *second_person,
- const sc_char *first_person,
- const sc_char *third_person) {
+static const sc_char *lib_select_response(sc_gameref_t game,
+ const sc_char *second_person, const sc_char *first_person, const sc_char *third_person) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
sc_int perspective;
@@ -564,9 +551,8 @@ lib_select_response(sc_gameref_t game,
return response;
}
-static const sc_char *
-lib_select_plurality(sc_gameref_t game, sc_int object,
- const sc_char *singular, const sc_char *plural) {
+static const sc_char *lib_select_plurality(sc_gameref_t game, sc_int object,
+ const sc_char *singular, const sc_char *plural) {
return obj_appears_plural(game, object) ? plural : singular;
}
@@ -578,8 +564,7 @@ lib_select_plurality(sc_gameref_t game, sc_int object,
* gone walkabout and offers a changed description, return that; otherwise
* return the standard inroom text.
*/
-static const sc_char *
-lib_get_npc_inroom_text(sc_gameref_t game, sc_int npc) {
+static const sc_char *lib_get_npc_inroom_text(sc_gameref_t game, sc_int npc) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int walk_count, walk;
@@ -617,8 +602,7 @@ lib_get_npc_inroom_text(sc_gameref_t game, sc_int npc) {
*
* Print a list of the contents of a room.
*/
-static void
-lib_print_room_contents(sc_gameref_t game, sc_int room) {
+static void lib_print_room_contents(sc_gameref_t game, sc_int room) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
@@ -775,8 +759,7 @@ lib_print_room_contents(sc_gameref_t game, sc_int room) {
*
* Print out the long description for a given room.
*/
-void
-lib_print_room_description(sc_gameref_t game, sc_int room) {
+void lib_print_room_description(sc_gameref_t game, sc_int room) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
@@ -917,8 +900,7 @@ lib_print_room_description(sc_gameref_t game, sc_int room) {
*
* Return TRUE if the player can move in the given direction.
*/
-static sc_bool
-lib_can_go(sc_gameref_t game, sc_int room, sc_int direction) {
+static sc_bool lib_can_go(sc_gameref_t game, sc_int room, sc_int direction) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int restriction;
@@ -1036,8 +1018,7 @@ static const sc_char *const DIRNAMES_8[] = {
*
* Print a list of exits from the player room.
*/
-sc_bool
-lib_cmd_print_room_exits(sc_gameref_t game) {
+sc_bool lib_cmd_print_room_exits(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
@@ -1115,8 +1096,7 @@ lib_cmd_print_room_exits(sc_gameref_t game) {
* Print out details of the player room, in brief if verbose not set and the
* room has already been visited.
*/
-static void
-lib_describe_player_room(sc_gameref_t game, sc_bool force_verbose) {
+static void lib_describe_player_room(sc_gameref_t game, sc_bool force_verbose) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
@@ -1149,8 +1129,7 @@ lib_describe_player_room(sc_gameref_t game, sc_bool force_verbose) {
*
* Command handler for "look" command.
*/
-sc_bool
-lib_cmd_look(sc_gameref_t game) {
+sc_bool lib_cmd_look(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_character(filter, '\n');
@@ -1164,8 +1143,7 @@ lib_cmd_look(sc_gameref_t game) {
*
* Called on "quit". Exits from the game main loop.
*/
-sc_bool
-lib_cmd_quit(sc_gameref_t game) {
+sc_bool lib_cmd_quit(sc_gameref_t game) {
if (if_confirm(SC_CONF_QUIT))
game->is_running = FALSE;
@@ -1180,8 +1158,7 @@ lib_cmd_quit(sc_gameref_t game) {
* Called on "restart". Exits from the game main loop with restart
* request set.
*/
-sc_bool
-lib_cmd_restart(sc_gameref_t game) {
+sc_bool lib_cmd_restart(sc_gameref_t game) {
if (if_confirm(SC_CONF_RESTART)) {
game->is_running = FALSE;
game->do_restart = TRUE;
@@ -1197,8 +1174,7 @@ lib_cmd_restart(sc_gameref_t game) {
*
* Called on "undo". Restores any undo game or memo to the main game.
*/
-sc_bool
-lib_cmd_undo(sc_gameref_t game) {
+sc_bool lib_cmd_undo(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_memo_setref_t memento = gs_get_memento(game);
@@ -1246,8 +1222,7 @@ lib_cmd_undo(sc_gameref_t game) {
* Prints a history of saved commands for the game. Print directly rather
* than using the printfilter to avoid possible clashes with ALRs.
*/
-static sc_bool
-lib_cmd_history_common(sc_gameref_t game, sc_int limit) {
+static sc_bool lib_cmd_history_common(sc_gameref_t game, sc_int limit) {
const sc_var_setref_t vars = gs_get_vars(game);
const sc_memo_setref_t memento = gs_get_memento(game);
sc_int first, count, timestamp;
@@ -1319,8 +1294,7 @@ lib_cmd_history_common(sc_gameref_t game, sc_int limit) {
return TRUE;
}
-sc_bool
-lib_cmd_history_number(sc_gameref_t game) {
+sc_bool lib_cmd_history_number(sc_gameref_t game) {
const sc_var_setref_t vars = gs_get_vars(game);
sc_int limit;
@@ -1336,8 +1310,7 @@ lib_cmd_history_number(sc_gameref_t game) {
return lib_cmd_history_common(game, limit);
}
-sc_bool
-lib_cmd_history(sc_gameref_t game) {
+sc_bool lib_cmd_history(sc_gameref_t game) {
return lib_cmd_history_common(game, 0);
}
@@ -1353,8 +1326,7 @@ lib_cmd_history(sc_gameref_t game) {
* flag. The others allow the user to select a command from the history list
* to re-run.
*/
-sc_bool
-lib_cmd_again(sc_gameref_t game) {
+sc_bool lib_cmd_again(sc_gameref_t game) {
game->do_again = TRUE;
game->redo_sequence = 0;
@@ -1362,8 +1334,7 @@ lib_cmd_again(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_redo_number(sc_gameref_t game) {
+sc_bool lib_cmd_redo_number(sc_gameref_t game) {
const sc_var_setref_t vars = gs_get_vars(game);
const sc_memo_setref_t memento = gs_get_memento(game);
sc_int sequence;
@@ -1398,8 +1369,7 @@ lib_cmd_redo_number(sc_gameref_t game) {
return TRUE;
}
-static sc_bool
-lib_cmd_redo_text_last_common(sc_gameref_t game, const sc_char *target) {
+static sc_bool lib_cmd_redo_text_last_common(sc_gameref_t game, const sc_char *target) {
const sc_memo_setref_t memento = gs_get_memento(game);
sc_bool is_do_last, is_contains;
sc_int length, matched_sequence;
@@ -1486,16 +1456,14 @@ lib_cmd_redo_text_last_common(sc_gameref_t game, const sc_char *target) {
return TRUE;
}
-sc_bool
-lib_cmd_redo_text(sc_gameref_t game) {
+sc_bool lib_cmd_redo_text(sc_gameref_t game) {
const sc_var_setref_t vars = gs_get_vars(game);
/* Call the common redo with the referenced text from %text%. */
return lib_cmd_redo_text_last_common(game, var_get_ref_text(vars));
}
-sc_bool
-lib_cmd_redo_last(sc_gameref_t game) {
+sc_bool lib_cmd_redo_last(sc_gameref_t game) {
/* Call the common redo with, literally, "!", forming "!!" . */
return lib_cmd_redo_text_last_common(game, "!");
}
@@ -1506,8 +1474,7 @@ lib_cmd_redo_last(sc_gameref_t game) {
*
* Called on "hints". Requests the interface to display any available hints.
*/
-sc_bool
-lib_cmd_hints(sc_gameref_t game) {
+sc_bool lib_cmd_hints(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int task;
sc_bool game_has_hints;
@@ -1550,15 +1517,13 @@ lib_cmd_hints(sc_gameref_t game) {
*
* Convenience helpers for printing licensing and game information.
*/
-static void
-lib_print_string_bold(const sc_char *string) {
+static void lib_print_string_bold(const sc_char *string) {
if_print_tag(SC_TAG_BOLD, "");
if_print_string(string);
if_print_tag(SC_TAG_ENDBOLD, "");
}
-static void
-lib_print_string_italics(const sc_char *string) {
+static void lib_print_string_italics(const sc_char *string) {
if_print_tag(SC_TAG_ITALICS, "");
if_print_string(string);
if_print_tag(SC_TAG_ENDITALICS, "");
@@ -1573,8 +1538,7 @@ lib_print_string_italics(const sc_char *string) {
* and the GPL licensing. Print directly rather than using the printfilter
* to avoid possible clashes with ALRs.
*/
-sc_bool
-lib_cmd_help(sc_gameref_t game) {
+sc_bool lib_cmd_help(sc_gameref_t game) {
if_print_string(
"These are some of the typical commands used in this adventure:\n\n");
@@ -1626,8 +1590,7 @@ lib_cmd_help(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_license(sc_gameref_t game) {
+sc_bool lib_cmd_license(sc_gameref_t game) {
lib_print_string_bold("SCARE");
if_print_string(" is ");
lib_print_string_italics(
@@ -1671,8 +1634,7 @@ lib_cmd_license(sc_gameref_t game) {
* in real Adrift. Prints directly rather than using the printfilter to
* avoid possible clashes with ALRs.
*/
-sc_bool
-lib_cmd_information(sc_gameref_t game) {
+sc_bool lib_cmd_information(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[2];
@@ -1718,8 +1680,7 @@ lib_cmd_information(sc_gameref_t game) {
*
* Clear the main game window (almost).
*/
-sc_bool
-lib_cmd_clear(sc_gameref_t game) {
+sc_bool lib_cmd_clear(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_tag(filter, SC_TAG_CLS);
@@ -1736,8 +1697,7 @@ lib_cmd_clear(sc_gameref_t game) {
* interpreter builds that can't offer a true status line. Prints directly
* rather than using the printfilter to avoid possible clashes with ALRs.
*/
-sc_bool
-lib_cmd_statusline(sc_gameref_t game) {
+sc_bool lib_cmd_statusline(sc_gameref_t game) {
const sc_char *name, *author, *room, *status;
sc_int score;
@@ -1782,8 +1742,7 @@ lib_cmd_statusline(sc_gameref_t game) {
* Display the "Runner version". Prints directly rather than using the
* printfilter to avoid possible clashes with ALRs.
*/
-sc_bool
-lib_cmd_version(sc_gameref_t game) {
+sc_bool lib_cmd_version(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key;
sc_char buffer[64];
@@ -1822,8 +1781,7 @@ lib_cmd_version(sc_gameref_t game) {
* the game's setting. The latter prints directly rather than using the
* printfilter to avoid possible clashes with ALRs.
*/
-sc_bool
-lib_cmd_wait(sc_gameref_t game) {
+sc_bool lib_cmd_wait(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
@@ -1850,8 +1808,7 @@ lib_cmd_wait(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_wait_number(sc_gameref_t game) {
+sc_bool lib_cmd_wait_number(sc_gameref_t game) {
const sc_var_setref_t vars = gs_get_vars(game);
sc_int waitturns;
sc_char buffer[32];
@@ -1885,8 +1842,7 @@ lib_cmd_wait_number(sc_gameref_t game) {
* Set/clear game verbose flag. Print directly rather than using the
* printfilter to avoid possible clashes with ALRs.
*/
-sc_bool
-lib_cmd_verbose(sc_gameref_t game) {
+sc_bool lib_cmd_verbose(sc_gameref_t game) {
/* Set game verbose flag and return. */
game->verbose = TRUE;
if_print_string("The game is now in its ");
@@ -1900,8 +1856,7 @@ lib_cmd_verbose(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_brief(sc_gameref_t game) {
+sc_bool lib_cmd_brief(sc_gameref_t game) {
/* Clear game verbose flag and return. */
game->verbose = FALSE;
if_print_string("The game is now in its ");
@@ -1923,8 +1878,7 @@ lib_cmd_brief(sc_gameref_t game) {
* Set/clear/query game score change notification flag. Print directly
* rather than using the printfilter to avoid possible clashes with ALRs.
*/
-sc_bool
-lib_cmd_notify_on_off(sc_gameref_t game) {
+sc_bool lib_cmd_notify_on_off(sc_gameref_t game) {
const sc_var_setref_t vars = gs_get_vars(game);
const sc_char *control;
@@ -1957,8 +1911,7 @@ lib_cmd_notify_on_off(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_notify(sc_gameref_t game) {
+sc_bool lib_cmd_notify(sc_gameref_t game) {
/* Report the current state of notification. */
if_print_string("Game score change notification is ");
if_print_tag(SC_TAG_ITALICS, "");
@@ -1986,8 +1939,7 @@ lib_cmd_notify(sc_gameref_t game) {
* Runner responds here with the system time and date, but we'll do something
* different.
*/
-sc_bool
-lib_cmd_time(sc_gameref_t game) {
+sc_bool lib_cmd_time(sc_gameref_t game) {
const sc_var_setref_t vars = gs_get_vars(game);
sc_uint timestamp;
sc_int hr, min, sec;
@@ -2012,8 +1964,7 @@ lib_cmd_time(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_date(sc_gameref_t game) {
+sc_bool lib_cmd_date(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "Maybe we should just be good friends.\n");
@@ -2038,8 +1989,7 @@ enum {
*
* Central movement command, called by all movement handlers.
*/
-static sc_bool
-lib_go(sc_gameref_t game, sc_int direction) {
+static sc_bool lib_go(sc_gameref_t game, sc_int direction) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5], vt_rvalue;
@@ -2164,63 +2114,51 @@ lib_go(sc_gameref_t game, sc_int direction) {
*
* Direction-specific movement commands.
*/
-sc_bool
-lib_cmd_go_north(sc_gameref_t game) {
+sc_bool lib_cmd_go_north(sc_gameref_t game) {
return lib_go(game, DIR_NORTH);
}
-sc_bool
-lib_cmd_go_east(sc_gameref_t game) {
+sc_bool lib_cmd_go_east(sc_gameref_t game) {
return lib_go(game, DIR_EAST);
}
-sc_bool
-lib_cmd_go_south(sc_gameref_t game) {
+sc_bool lib_cmd_go_south(sc_gameref_t game) {
return lib_go(game, DIR_SOUTH);
}
-sc_bool
-lib_cmd_go_west(sc_gameref_t game) {
+sc_bool lib_cmd_go_west(sc_gameref_t game) {
return lib_go(game, DIR_WEST);
}
-sc_bool
-lib_cmd_go_up(sc_gameref_t game) {
+sc_bool lib_cmd_go_up(sc_gameref_t game) {
return lib_go(game, DIR_UP);
}
-sc_bool
-lib_cmd_go_down(sc_gameref_t game) {
+sc_bool lib_cmd_go_down(sc_gameref_t game) {
return lib_go(game, DIR_DOWN);
}
-sc_bool
-lib_cmd_go_in(sc_gameref_t game) {
+sc_bool lib_cmd_go_in(sc_gameref_t game) {
return lib_go(game, DIR_IN);
}
-sc_bool
-lib_cmd_go_out(sc_gameref_t game) {
+sc_bool lib_cmd_go_out(sc_gameref_t game) {
return lib_go(game, DIR_OUT);
}
-sc_bool
-lib_cmd_go_northeast(sc_gameref_t game) {
+sc_bool lib_cmd_go_northeast(sc_gameref_t game) {
return lib_go(game, DIR_NORTHEAST);
}
-sc_bool
-lib_cmd_go_southeast(sc_gameref_t game) {
+sc_bool lib_cmd_go_southeast(sc_gameref_t game) {
return lib_go(game, DIR_SOUTHEAST);
}
-sc_bool
-lib_cmd_go_northwest(sc_gameref_t game) {
+sc_bool lib_cmd_go_northwest(sc_gameref_t game) {
return lib_go(game, DIR_NORTHWEST);
}
-sc_bool
-lib_cmd_go_southwest(sc_gameref_t game) {
+sc_bool lib_cmd_go_southwest(sc_gameref_t game) {
return lib_go(game, DIR_SOUTHWEST);
}
@@ -2232,8 +2170,7 @@ lib_cmd_go_southwest(sc_gameref_t game) {
* with the string passed in, and return TRUE if they match. The routine
* requires that string is filtered, stripped, trimmed and normalized.
*/
-static sc_bool
-lib_compare_rooms(sc_gameref_t game, sc_int room, const sc_char *string) {
+static sc_bool lib_compare_rooms(sc_gameref_t game, sc_int room, const sc_char *string) {
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_char *name, *compare_name;
@@ -2275,8 +2212,7 @@ lib_compare_rooms(sc_gameref_t game, sc_int room, const sc_char *string) {
* text comparisons, for example, two "Manor Grounds" at the start of Humbug,
* differentiated within the game with trailing "<some_tag>" components.
*/
-sc_bool
-lib_cmd_go_room(sc_gameref_t game) {
+sc_bool lib_cmd_go_room(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
@@ -2386,8 +2322,7 @@ lib_cmd_go_room(sc_gameref_t game) {
*
* Show the long description of a player.
*/
-sc_bool
-lib_cmd_examine_self(sc_gameref_t game) {
+sc_bool lib_cmd_examine_self(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
@@ -2501,9 +2436,7 @@ lib_cmd_examine_self(sc_gameref_t game) {
* -1 with *is_ambiguous FALSE if requested, otherwise print a message then
* return -1.
*/
-static sc_int
-lib_disambiguate_npc(sc_gameref_t game,
- const sc_char *verb, sc_bool *is_ambiguous) {
+static sc_int lib_disambiguate_npc(sc_gameref_t game, const sc_char *verb, sc_bool *is_ambiguous) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int count, index_, npc, listed;
@@ -2590,12 +2523,9 @@ lib_disambiguate_npc(sc_gameref_t game,
* just one object. The resolver function can normally be the same as the
* function used to filter objects for multiple references.
*/
-static sc_int
-lib_disambiguate_object_common(sc_gameref_t game, const sc_char *verb,
- sc_bool(*resolver)
- (sc_gameref_t, sc_int, sc_int),
- sc_int resolver_arg,
- sc_bool *is_ambiguous) {
+static sc_int lib_disambiguate_object_common(sc_gameref_t game, const sc_char *verb,
+ sc_bool(*resolver)(sc_gameref_t, sc_int, sc_int),
+ sc_int resolver_arg, sc_bool *is_ambiguous) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int count, index_, object, listed;
@@ -2712,18 +2642,12 @@ lib_disambiguate_object_common(sc_gameref_t game, const sc_char *verb,
return -1;
}
-static sc_int
-lib_disambiguate_object(sc_gameref_t game,
- const sc_char *verb, sc_bool *is_ambiguous) {
+static sc_int lib_disambiguate_object(sc_gameref_t game, const sc_char *verb, sc_bool *is_ambiguous) {
return lib_disambiguate_object_common(game, verb, NULL, -1, is_ambiguous);
}
-static sc_int
-lib_disambiguate_object_extended(sc_gameref_t game, const sc_char *verb,
- sc_bool(*resolver)
- (sc_gameref_t, sc_int, sc_int),
- sc_int resolver_arg,
- sc_bool *is_ambiguous) {
+static sc_int lib_disambiguate_object_extended(sc_gameref_t game, const sc_char *verb,
+ sc_bool(*resolver)(sc_gameref_t, sc_int, sc_int), sc_int resolver_arg, sc_bool *is_ambiguous) {
return lib_disambiguate_object_common(game, verb,
resolver, resolver_arg, is_ambiguous);
}
@@ -2734,8 +2658,7 @@ lib_disambiguate_object_extended(sc_gameref_t game, const sc_char *verb,
*
* List objects carried and worn by an NPC.
*/
-static sc_bool
-lib_list_npc_inventory(sc_gameref_t game, sc_int npc, sc_bool is_described) {
+static sc_bool lib_list_npc_inventory(sc_gameref_t game, sc_int npc, sc_bool is_described) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, count, trail;
sc_bool wearing;
@@ -2831,8 +2754,7 @@ lib_list_npc_inventory(sc_gameref_t game, sc_int npc, sc_bool is_described) {
* Show the long description of the most recently referenced NPC, and a
* list of what they're wearing and carrying.
*/
-sc_bool
-lib_cmd_examine_npc(sc_gameref_t game) {
+sc_bool lib_cmd_examine_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
@@ -2888,9 +2810,7 @@ lib_cmd_examine_npc(sc_gameref_t game) {
*
* List the objects in a given container object, normal format listing.
*/
-static sc_bool
-lib_list_in_object_normal(sc_gameref_t game,
- sc_int container, sc_bool is_described) {
+static sc_bool lib_list_in_object_normal(sc_gameref_t game, sc_int container, sc_bool is_described) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, count, trail;
@@ -2948,9 +2868,7 @@ lib_list_in_object_normal(sc_gameref_t game,
*
* List the objects in a given container object, alternate format listing.
*/
-static sc_bool
-lib_list_in_object_alternate(sc_gameref_t game,
- sc_int container, sc_bool is_described) {
+static sc_bool lib_list_in_object_alternate(sc_gameref_t game,sc_int container, sc_bool is_described) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, count, trail;
@@ -3014,8 +2932,7 @@ lib_list_in_object_alternate(sc_gameref_t game,
* this, and in particular works with the ALR magic in "To Hell in a Hamper",
* but it's almost certainly wrong. Or, at minimum, incomplete.
*/
-static sc_bool
-lib_list_in_object(sc_gameref_t game, sc_int container, sc_bool is_described) {
+static sc_bool lib_list_in_object(sc_gameref_t game, sc_int container, sc_bool is_described) {
sc_bool use_alternate_format = FALSE;
/*
@@ -3057,8 +2974,7 @@ lib_list_in_object(sc_gameref_t game, sc_int container, sc_bool is_described) {
*
* List the objects on a given surface object.
*/
-static sc_bool
-lib_list_on_object(sc_gameref_t game, sc_int supporter, sc_bool is_described) {
+static sc_bool lib_list_on_object(sc_gameref_t game, sc_int supporter, sc_bool is_described) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, count, trail;
@@ -3116,8 +3032,7 @@ lib_list_on_object(sc_gameref_t game, sc_int supporter, sc_bool is_described) {
*
* Describe the state of a stateful object.
*/
-static sc_bool
-lib_list_object_state(sc_gameref_t game, sc_int object, sc_bool is_described) {
+static sc_bool lib_list_object_state(sc_gameref_t game, sc_int object, sc_bool is_described) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -3161,8 +3076,7 @@ lib_list_object_state(sc_gameref_t game, sc_int object, sc_bool is_described) {
*
* Show the long description of the most recently referenced object.
*/
-sc_bool
-lib_cmd_examine_object(sc_gameref_t game) {
+sc_bool lib_cmd_examine_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -3294,8 +3208,7 @@ lib_cmd_examine_object(sc_gameref_t game) {
* references uses the buffer passed in if possible, otherwise allocates
* its own buffer; testing the return value shows which happened.
*/
-static sc_bool *
-lib_save_object_references(sc_gameref_t game, sc_bool buffer[], sc_int length) {
+static sc_bool *lib_save_object_references(sc_gameref_t game, sc_bool buffer[], sc_int length) {
sc_int required, available;
sc_bool *references;
@@ -3312,8 +3225,7 @@ lib_save_object_references(sc_gameref_t game, sc_bool buffer[], sc_int length) {
return references;
}
-static void
-lib_restore_object_references(sc_gameref_t game, const sc_bool references[]) {
+static void lib_restore_object_references(sc_gameref_t game, const sc_bool references[]) {
sc_int bytes;
/* Calculate the bytes in the references array, and copy back to the game. */
@@ -3332,13 +3244,9 @@ lib_restore_object_references(sc_gameref_t game, const sc_bool references[]) {
* to retry game commands using standard "get " and "drop " commands. This
* makes "take/pick up/put down" work with a game's overridden get/drop.
*/
-static sc_bool
-lib_try_game_command_common(sc_gameref_t game,
- const sc_char *verb, sc_int object,
- const sc_char *preposition,
- sc_int associate,
- sc_bool is_associate_object,
- sc_bool is_associate_npc) {
+static sc_bool lib_try_game_command_common(sc_gameref_t game, const sc_char *verb, sc_int object,
+ const sc_char *preposition, sc_int associate, sc_bool is_associate_object,
+ sc_bool is_associate_npc) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_char buffer[LIB_ALLOCATION_AVOIDANCE_SIZE];
@@ -3439,26 +3347,18 @@ lib_try_game_command_common(sc_gameref_t game,
return status;
}
-static sc_bool
-lib_try_game_command_short(sc_gameref_t game,
- const sc_char *verb, sc_int object) {
- return lib_try_game_command_common(game, verb, object,
- NULL, -1, FALSE, FALSE);
+static sc_bool lib_try_game_command_short(sc_gameref_t game, const sc_char *verb, sc_int object) {
+ return lib_try_game_command_common(game, verb, object, NULL, -1, FALSE, FALSE);
}
-static sc_bool
-lib_try_game_command_with_object(sc_gameref_t game,
- const sc_char *verb, sc_int object,
- const sc_char *preposition,
- sc_int other_object) {
+static sc_bool lib_try_game_command_with_object(sc_gameref_t game, const sc_char *verb,
+ sc_int object, const sc_char *preposition, sc_int other_object) {
return lib_try_game_command_common(game, verb, object,
preposition, other_object, TRUE, FALSE);
}
-static sc_bool
-lib_try_game_command_with_npc(sc_gameref_t game,
- const sc_char *verb, sc_int object,
- const sc_char *preposition, sc_int npc) {
+static sc_bool lib_try_game_command_with_npc(sc_gameref_t game, const sc_char *verb,
+ sc_int object, const sc_char *preposition, sc_int npc) {
return lib_try_game_command_common(game, verb, object,
preposition, npc, FALSE, TRUE);
}
@@ -3472,12 +3372,9 @@ lib_try_game_command_with_npc(sc_gameref_t game,
* using the verb supplied, and sets are_more_objects if we found an object
* but there appear to be more following it.
*/
-static sc_bool
-lib_parse_next_object(sc_gameref_t game, const sc_char *verb,
- sc_bool(*resolver)(sc_gameref_t, sc_int, sc_int),
- sc_int resolver_arg,
- sc_int *object,
- sc_bool *are_more_objects, sc_bool *is_ambiguous) {
+static sc_bool lib_parse_next_object(sc_gameref_t game, const sc_char *verb,
+ sc_bool(*resolver)(sc_gameref_t, sc_int, sc_int), sc_int resolver_arg,
+ sc_int *object, sc_bool *are_more_objects, sc_bool *is_ambiguous) {
const sc_var_setref_t vars = gs_get_vars(game);
const sc_char *list;
sc_bool is_matched;
@@ -3513,11 +3410,9 @@ lib_parse_next_object(sc_gameref_t game, const sc_char *verb,
* Parses object lists such as "object" and "object and object" and returns
* the multiple objects in the game's multiple_references.
*/
-static sc_bool
-lib_parse_multiple_objects(sc_gameref_t game, const sc_char *verb,
- sc_bool(*resolver)(sc_gameref_t, sc_int, sc_int),
- sc_int resolver_arg,
- sc_int *count) {
+static sc_bool lib_parse_multiple_objects(sc_gameref_t game, const sc_char *verb,
+ sc_bool(*resolver)(sc_gameref_t, sc_int, sc_int),
+ sc_int resolver_arg, sc_int *count) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int count_, object;
sc_bool are_more_objects, is_ambiguous;
@@ -3612,10 +3507,9 @@ lib_parse_multiple_objects(sc_gameref_t game, const sc_char *verb,
* references into standard object references, using the supplied filter.
* The first is inclusive, the second exclusive.
*/
-static sc_int
-lib_apply_multiple_filter(sc_gameref_t game,
- sc_bool(*filter)(sc_gameref_t, sc_int, sc_int),
- sc_int filter_arg, sc_int *references) {
+static sc_int lib_apply_multiple_filter(sc_gameref_t game,
+ sc_bool(*filter)(sc_gameref_t, sc_int, sc_int),
+ sc_int filter_arg, sc_int *references) {
sc_int count, object, references_;
/* Clear all object references initially. */
@@ -3645,10 +3539,9 @@ lib_apply_multiple_filter(sc_gameref_t game,
return count;
}
-static sc_int
-lib_apply_except_filter(sc_gameref_t game,
- sc_bool(*filter)(sc_gameref_t, sc_int, sc_int),
- sc_int filter_arg, sc_int *references) {
+static sc_int lib_apply_except_filter(sc_gameref_t game,
+ sc_bool(*filter)(sc_gameref_t, sc_int, sc_int),
+ sc_int filter_arg, sc_int *references) {
sc_int count, object, references_;
/* Clear all object references initially. */
@@ -3685,8 +3578,7 @@ lib_apply_except_filter(sc_gameref_t game,
*
* Display player weight and size limits and amounts currently carried.
*/
-sc_bool
-lib_cmd_count(sc_gameref_t game) {
+sc_bool lib_cmd_count(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int index_, size, weight;
sc_char buffer[32];
@@ -3734,8 +3626,7 @@ lib_cmd_count(sc_gameref_t game) {
*
* Return TRUE if the given object is too heavy for the player to carry.
*/
-static sc_bool
-lib_object_too_heavy(sc_gameref_t game, sc_int object, sc_bool *is_portable) {
+static sc_bool lib_object_too_heavy(sc_gameref_t game, sc_int object, sc_bool *is_portable) {
sc_int player_limit, index_, weight, object_weight;
/* Get the player limit and the given object weight. */
@@ -3764,8 +3655,7 @@ lib_object_too_heavy(sc_gameref_t game, sc_int object, sc_bool *is_portable) {
*
* Return TRUE if the given object is too large for the player to carry.
*/
-static sc_bool
-lib_object_too_large(sc_gameref_t game, sc_int object, sc_bool *is_portable) {
+static sc_bool lib_object_too_large(sc_gameref_t game, sc_int object, sc_bool *is_portable) {
sc_int player_limit, index_, size, object_size;
/* Get the player limit and the given object size. */
@@ -3794,8 +3684,7 @@ lib_object_too_large(sc_gameref_t game, sc_int object, sc_bool *is_portable) {
*
* Reject attempts to take an npc.
*/
-sc_bool
-lib_cmd_take_npc(sc_gameref_t game) {
+sc_bool lib_cmd_take_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int npc;
sc_bool is_ambiguous;
@@ -3823,9 +3712,8 @@ lib_cmd_take_npc(sc_gameref_t game) {
* Objects to action are flagged in object_references; objects requested but
* deemed not actionable are flagged in multiple_references.
*/
-static void
-lib_take_backend_common(sc_gameref_t game, sc_int associate,
- sc_bool is_associate_object, sc_bool is_associate_npc) {
+static void lib_take_backend_common(sc_gameref_t game, sc_int associate,
+ sc_bool is_associate_object, sc_bool is_associate_npc) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object_count, object, count, trail, total, npc;
sc_int too_heavy, too_large;
@@ -4374,18 +4262,15 @@ lib_take_backend_common(sc_gameref_t game, sc_int associate,
* Facets of lib_take_backend_common(). Provide backend handling for either
* the plain "take" handlers, or the "take from <something>" handlers.
*/
-static void
-lib_take_backend(sc_gameref_t game) {
+static void lib_take_backend(sc_gameref_t game) {
lib_take_backend_common(game, -1, FALSE, FALSE);
}
-static void
-lib_take_from_object_backend(sc_gameref_t game, sc_int associate) {
+static void lib_take_from_object_backend(sc_gameref_t game, sc_int associate) {
lib_take_backend_common(game, associate, TRUE, FALSE);
}
-static void
-lib_take_from_npc_backend(sc_gameref_t game, sc_int associate) {
+static void lib_take_from_npc_backend(sc_gameref_t game, sc_int associate) {
lib_take_backend_common(game, associate, FALSE, TRUE);
}
@@ -4397,8 +4282,7 @@ lib_take_from_npc_backend(sc_gameref_t game, sc_int associate) {
* Helper functions for deciding if an object may be acquired in this context.
* Returns TRUE if an object may be acquired, FALSE otherwise.
*/
-static sc_bool
-lib_take_filter(sc_gameref_t game, sc_int object, sc_int unused) {
+static sc_bool lib_take_filter(sc_gameref_t game, sc_int object, sc_int unused) {
assert(unused == -1);
/*
@@ -4413,9 +4297,7 @@ lib_take_filter(sc_gameref_t game, sc_int object, sc_int unused) {
|| gs_object_position(game, object) == OBJ_WORN_NPC);
}
-static sc_bool
-lib_take_not_associated_filter(sc_gameref_t game,
- sc_int object, sc_int unused) {
+static sc_bool lib_take_not_associated_filter(sc_gameref_t game, sc_int object, sc_int unused) {
assert(unused == -1);
/* In addition to other checks, the object may not be in or on an object. */
@@ -4430,8 +4312,7 @@ lib_take_not_associated_filter(sc_gameref_t game,
*
* Attempt to take all objects currently visible to the player.
*/
-sc_bool
-lib_cmd_take_all(sc_gameref_t game) {
+sc_bool lib_cmd_take_all(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects;
@@ -4457,8 +4338,7 @@ lib_cmd_take_all(sc_gameref_t game) {
* Take all objects currently available to the player, excepting those listed
* in %text%.
*/
-sc_bool
-lib_cmd_take_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_take_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -4493,8 +4373,7 @@ lib_cmd_take_except_multiple(sc_gameref_t game) {
*
* Take all objects currently available to the player and listed in %text%.
*/
-sc_bool
-lib_cmd_take_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_take_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -4526,8 +4405,7 @@ lib_cmd_take_multiple(sc_gameref_t game) {
* Helper function for deciding if an object may be acquired in this context.
* Returns TRUE if an object may be acquired, FALSE otherwise.
*/
-static sc_bool
-lib_take_from_filter(sc_gameref_t game, sc_int object, sc_int associate) {
+static sc_bool lib_take_from_filter(sc_gameref_t game, sc_int object, sc_int associate) {
/*
* To be take-able, an object must be either inside or on the specified
* object.
@@ -4545,8 +4423,7 @@ lib_take_from_filter(sc_gameref_t game, sc_int object, sc_int associate) {
* Common error handling for when nothing is taken from a container or
* supporter object.
*/
-static void
-lib_take_from_empty(sc_gameref_t game, sc_int associate, sc_bool is_except) {
+static void lib_take_from_empty(sc_gameref_t game, sc_int associate, sc_bool is_except) {
const sc_filterref_t filter = gs_get_filter(game);
if (obj_is_container(game, associate) && obj_is_surface(game, associate)) {
@@ -4605,8 +4482,7 @@ lib_take_from_empty(sc_gameref_t game, sc_int associate, sc_bool is_except) {
*
* Validate the supporter requested in "take from" commands.
*/
-static sc_bool
-lib_take_from_is_valid(sc_gameref_t game, sc_int associate) {
+static sc_bool lib_take_from_is_valid(sc_gameref_t game, sc_int associate) {
const sc_filterref_t filter = gs_get_filter(game);
/* Disallow emptying non-container/non-surface objects. */
@@ -4644,8 +4520,7 @@ lib_take_from_is_valid(sc_gameref_t game, sc_int associate) {
*
* Attempt to take all objects contained in or supported by a given object.
*/
-sc_bool
-lib_cmd_take_all_from(sc_gameref_t game) {
+sc_bool lib_cmd_take_all_from(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int associate, objects;
sc_bool is_ambiguous;
@@ -4681,8 +4556,7 @@ lib_cmd_take_all_from(sc_gameref_t game) {
* Take all objects contained in or supported by a given object, excepting
* those listed in %text%.
*/
-sc_bool
-lib_cmd_take_from_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_take_from_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int associate, objects, references;
sc_bool is_ambiguous;
@@ -4734,8 +4608,7 @@ lib_cmd_take_from_except_multiple(sc_gameref_t game) {
* function isn't mandatory -- plain "take <object>" works fine with contain-
* ers and surfaces, but it's a standard in Adrift so here it is.
*/
-sc_bool
-lib_cmd_take_from_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_take_from_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int associate, objects, references;
sc_bool is_ambiguous;
@@ -4777,8 +4650,7 @@ lib_cmd_take_from_multiple(sc_gameref_t game) {
* Helper function for deciding if an object may be acquired in this context.
* Returns TRUE if an object may be acquired, FALSE otherwise.
*/
-static sc_bool
-lib_take_from_npc_filter(sc_gameref_t game, sc_int object, sc_int associate) {
+static sc_bool lib_take_from_npc_filter(sc_gameref_t game, sc_int object, sc_int associate) {
/*
* To be take-able, an object must be either held or worn by the specified
* NPC.
@@ -4795,8 +4667,7 @@ lib_take_from_npc_filter(sc_gameref_t game, sc_int object, sc_int associate) {
*
* Attempt to take all objects held or worn by a given NPC.
*/
-sc_bool
-lib_cmd_take_all_from_npc(sc_gameref_t game) {
+sc_bool lib_cmd_take_all_from_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int associate, objects;
sc_bool is_ambiguous;
@@ -4831,8 +4702,7 @@ lib_cmd_take_all_from_npc(sc_gameref_t game) {
* Attempt to take all objects held or worn by a given NPC, excepting those
* listed in %text%.
*/
-sc_bool
-lib_cmd_take_from_npc_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_take_from_npc_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int associate, objects, references;
sc_bool is_ambiguous;
@@ -4873,8 +4743,7 @@ lib_cmd_take_from_npc_except_multiple(sc_gameref_t game) {
* Attempt to take the objects currently held or worn by an NPC and listed
* in %text%.
*/
-sc_bool
-lib_cmd_take_from_npc_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_take_from_npc_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int associate, objects, references;
sc_bool is_ambiguous;
@@ -4919,8 +4788,7 @@ lib_cmd_take_from_npc_multiple(sc_gameref_t game) {
* Objects to action are flagged in object_references; objects requested but
* deemed not actionable are flagged in multiple_references.
*/
-static void
-lib_drop_backend(sc_gameref_t game) {
+static void lib_drop_backend(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object_count, object, count, trail;
sc_bool has_printed;
@@ -5032,8 +4900,7 @@ lib_drop_backend(sc_gameref_t game) {
* Helper function for deciding if an object may be dropped in this context.
* Returns TRUE if an object may be dropped, FALSE otherwise.
*/
-static sc_bool
-lib_drop_filter(sc_gameref_t game, sc_int object, sc_int unused) {
+static sc_bool lib_drop_filter(sc_gameref_t game, sc_int object, sc_int unused) {
assert(unused == -1);
return !obj_is_static(game, object)
@@ -5046,8 +4913,7 @@ lib_drop_filter(sc_gameref_t game, sc_int object, sc_int unused) {
*
* Drop all objects currently held by the player.
*/
-sc_bool
-lib_cmd_drop_all(sc_gameref_t game) {
+sc_bool lib_cmd_drop_all(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects;
@@ -5078,8 +4944,7 @@ lib_cmd_drop_all(sc_gameref_t game) {
* Drop all objects currently held by the player, excepting those listed in
* %text%.
*/
-sc_bool
-lib_cmd_drop_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_drop_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -5118,8 +4983,7 @@ lib_cmd_drop_except_multiple(sc_gameref_t game) {
*
* Drop all objects currently held by the player and listed in %text%.
*/
-sc_bool
-lib_cmd_drop_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_drop_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -5156,8 +5020,7 @@ lib_cmd_drop_multiple(sc_gameref_t game) {
*
* Attempt to give an object to an NPC.
*/
-sc_bool
-lib_cmd_give_object_npc(sc_gameref_t game) {
+sc_bool lib_cmd_give_object_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, npc;
sc_bool is_ambiguous;
@@ -5193,8 +5056,7 @@ lib_cmd_give_object_npc(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_give_object(sc_gameref_t game) {
+sc_bool lib_cmd_give_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -5233,8 +5095,7 @@ lib_cmd_give_object(sc_gameref_t game) {
* Objects to action are flagged in object_references; objects requested but
* deemed not actionable are flagged in multiple_references.
*/
-static void
-lib_wear_backend(sc_gameref_t game) {
+static void lib_wear_backend(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object_count, object, count, trail;
sc_bool has_printed;
@@ -5434,8 +5295,7 @@ lib_wear_backend(sc_gameref_t game) {
* Helper function for deciding if an object may be worn in this context.
* Returns TRUE if an object may be worn, FALSE otherwise.
*/
-static sc_bool
-lib_wear_filter(sc_gameref_t game, sc_int object, sc_int unused) {
+static sc_bool lib_wear_filter(sc_gameref_t game, sc_int object, sc_int unused) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
assert(unused == -1);
@@ -5464,8 +5324,7 @@ lib_wear_filter(sc_gameref_t game, sc_int object, sc_int unused) {
*
* Wear all wearable objects currently held by the player.
*/
-sc_bool
-lib_cmd_wear_all(sc_gameref_t game) {
+sc_bool lib_cmd_wear_all(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects;
@@ -5497,8 +5356,7 @@ lib_cmd_wear_all(sc_gameref_t game) {
* Wear all wearable objects currently held by the player, excepting those
* listed in %text%.
*/
-sc_bool
-lib_cmd_wear_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_wear_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -5538,8 +5396,7 @@ lib_cmd_wear_except_multiple(sc_gameref_t game) {
* Wear all objects currently held by the player, wearable, and listed
* in %text%.
*/
-sc_bool
-lib_cmd_wear_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_wear_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -5580,8 +5437,7 @@ lib_cmd_wear_multiple(sc_gameref_t game) {
* Objects to action are flagged in object_references; objects requested but
* deemed not actionable are flagged in multiple_references.
*/
-static void
-lib_remove_backend(sc_gameref_t game) {
+static void lib_remove_backend(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object_count, object, count, trail;
sc_bool has_printed;
@@ -5693,8 +5549,7 @@ lib_remove_backend(sc_gameref_t game) {
* Helper function for deciding if an object may be removed in this context.
* Returns TRUE if an object is currently being worn, FALSE otherwise.
*/
-static sc_bool
-lib_remove_filter(sc_gameref_t game, sc_int object, sc_int unused) {
+static sc_bool lib_remove_filter(sc_gameref_t game, sc_int object, sc_int unused) {
assert(unused == -1);
return !obj_is_static(game, object)
@@ -5707,8 +5562,7 @@ lib_remove_filter(sc_gameref_t game, sc_int object, sc_int unused) {
*
* Remove all objects currently held by the player.
*/
-sc_bool
-lib_cmd_remove_all(sc_gameref_t game) {
+sc_bool lib_cmd_remove_all(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects;
@@ -5740,8 +5594,7 @@ lib_cmd_remove_all(sc_gameref_t game) {
* Remove all objects currently worn by the player, excepting those listed
* in %text%.
*/
-sc_bool
-lib_cmd_remove_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_remove_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -5780,8 +5633,7 @@ lib_cmd_remove_except_multiple(sc_gameref_t game) {
*
* Remove all objects currently worn by the player, and listed in %text%.
*/
-sc_bool
-lib_cmd_remove_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_remove_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int objects, references;
@@ -5818,8 +5670,7 @@ lib_cmd_remove_multiple(sc_gameref_t game) {
*
* List objects carried and worn by the player.
*/
-sc_bool
-lib_cmd_inventory(sc_gameref_t game) {
+sc_bool lib_cmd_inventory(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, count, trail;
sc_bool wearing;
@@ -5946,8 +5797,7 @@ lib_cmd_inventory(sc_gameref_t game) {
*
* Attempt to open the referenced object.
*/
-sc_bool
-lib_cmd_open_object(sc_gameref_t game) {
+sc_bool lib_cmd_open_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, openness;
sc_bool is_ambiguous;
@@ -6017,8 +5867,7 @@ lib_cmd_open_object(sc_gameref_t game) {
*
* Attempt to close the referenced object.
*/
-sc_bool
-lib_cmd_close_object(sc_gameref_t game) {
+sc_bool lib_cmd_close_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object, openness;
sc_bool is_ambiguous;
@@ -6077,8 +5926,7 @@ lib_cmd_close_object(sc_gameref_t game) {
*
* Automatically get an object being used as a key, if possible.
*/
-static void
-lib_attempt_key_acquisition(sc_gameref_t game, sc_int object) {
+static void lib_attempt_key_acquisition(sc_gameref_t game, sc_int object) {
const sc_filterref_t filter = gs_get_filter(game);
/* Disallow getting static objects. */
@@ -6139,8 +5987,7 @@ lib_attempt_key_acquisition(sc_gameref_t game, sc_int object) {
*
* Attempt to unlock the referenced object.
*/
-sc_bool
-lib_cmd_unlock_object_with(sc_gameref_t game) {
+sc_bool lib_cmd_unlock_object_with(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
@@ -6246,8 +6093,7 @@ lib_cmd_unlock_object_with(sc_gameref_t game) {
*
* Attempt to unlock the referenced object, automatically selecting key.
*/
-sc_bool
-lib_cmd_unlock_object(sc_gameref_t game) {
+sc_bool lib_cmd_unlock_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, openness;
@@ -6330,8 +6176,7 @@ lib_cmd_unlock_object(sc_gameref_t game) {
*
* Attempt to lock the referenced object.
*/
-sc_bool
-lib_cmd_lock_object_with(sc_gameref_t game) {
+sc_bool lib_cmd_lock_object_with(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
@@ -6445,8 +6290,7 @@ lib_cmd_lock_object_with(sc_gameref_t game) {
*
* Attempt to lock the referenced object, automatically selecting key.
*/
-sc_bool
-lib_cmd_lock_object(sc_gameref_t game) {
+sc_bool lib_cmd_lock_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, openness;
@@ -6538,9 +6382,7 @@ lib_cmd_lock_object(sc_gameref_t game) {
*
* Compare a subject, comma or NUL terminated. Helper for ask.
*/
-static sc_bool
-lib_compare_subject(const sc_char *subject, sc_int posn,
- const sc_char *string) {
+static sc_bool lib_compare_subject(const sc_char *subject, sc_int posn, const sc_char *string) {
sc_int word_posn, string_posn;
/* Skip any leading subject spaces. */
@@ -6596,8 +6438,7 @@ lib_compare_subject(const sc_char *subject, sc_int posn,
*
* Reply for an NPC on a given topic. Helper for ask.
*/
-static sc_bool
-lib_npc_reply_to(sc_gameref_t game, sc_int npc, sc_int topic) {
+static sc_bool lib_npc_reply_to(sc_gameref_t game, sc_int npc, sc_int topic) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
@@ -6634,8 +6475,7 @@ lib_npc_reply_to(sc_gameref_t game, sc_int npc, sc_int topic) {
*
* Converse with NPC.
*/
-sc_bool
-lib_cmd_ask_npc_about(sc_gameref_t game) {
+sc_bool lib_cmd_ask_npc_about(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
@@ -6724,9 +6564,8 @@ lib_cmd_ask_npc_about(sc_gameref_t game) {
* Checks for infinite recursion when placing an object in an object. Returns
* TRUE if no recursion detected.
*/
-static sc_bool
-lib_check_put_in_recursion(sc_gameref_t game,
- sc_int object, sc_int container, sc_bool report) {
+static sc_bool lib_check_put_in_recursion(sc_gameref_t game, sc_int object,
+ sc_int container, sc_bool report) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int check;
@@ -6775,8 +6614,7 @@ lib_check_put_in_recursion(sc_gameref_t game,
* Objects to action are flagged in object_references; objects requested but
* deemed not actionable are flagged in multiple_references.
*/
-static void
-lib_put_in_backend(sc_gameref_t game, sc_int container) {
+static void lib_put_in_backend(sc_gameref_t game, sc_int container) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object_count, object, count, trail, capacity, maxsize;
sc_bool has_printed;
@@ -7013,17 +6851,14 @@ lib_put_in_backend(sc_gameref_t game, sc_int container) {
* Helper functions for deciding if an object may be put in another this
* context. Returns TRUE if an object may be manipulated, FALSE otherwise.
*/
-static sc_bool
-lib_put_in_filter(sc_gameref_t game, sc_int object, sc_int unused) {
+static sc_bool lib_put_in_filter(sc_gameref_t game, sc_int object, sc_int unused) {
assert(unused == -1);
return !obj_is_static(game, object)
&& gs_object_position(game, object) == OBJ_HELD_PLAYER;
}
-static sc_bool
-lib_put_in_not_container_filter(sc_gameref_t game,
- sc_int object, sc_int container) {
+static sc_bool lib_put_in_not_container_filter(sc_gameref_t game, sc_int object, sc_int container) {
return lib_put_in_filter(game, object, -1) && object != container;
}
@@ -7033,8 +6868,7 @@ lib_put_in_not_container_filter(sc_gameref_t game,
*
* Validate the container requested in "put in" commands.
*/
-static sc_bool
-lib_put_in_is_valid(sc_gameref_t game, sc_int container) {
+static sc_bool lib_put_in_is_valid(sc_gameref_t game, sc_int container) {
const sc_filterref_t filter = gs_get_filter(game);
/* Verify that the container object is a container. */
@@ -7072,8 +6906,7 @@ lib_put_in_is_valid(sc_gameref_t game, sc_int container) {
*
* Put all objects currently held by the player into a container.
*/
-sc_bool
-lib_cmd_put_all_in(sc_gameref_t game) {
+sc_bool lib_cmd_put_all_in(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int container, objects;
sc_bool is_ambiguous;
@@ -7117,8 +6950,7 @@ lib_cmd_put_all_in(sc_gameref_t game) {
* Put all objects currently held by the player into an object, excepting
* those listed in %text%.
*/
-sc_bool
-lib_cmd_put_in_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_put_in_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int container, objects, references;
sc_bool is_ambiguous;
@@ -7177,8 +7009,7 @@ lib_cmd_put_in_except_multiple(sc_gameref_t game) {
* Put all objects currently held by the player and listed in %text% into an
* object.
*/
-sc_bool
-lib_cmd_put_in_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_put_in_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int container, objects, references;
sc_bool is_ambiguous;
@@ -7225,9 +7056,8 @@ lib_cmd_put_in_multiple(sc_gameref_t game) {
* Checks for infinite recursion when placing an object on an object. Returns
* TRUE if no recursion detected.
*/
-static sc_bool
-lib_check_put_on_recursion(sc_gameref_t game,
- sc_int object, sc_int supporter, sc_bool report) {
+static sc_bool lib_check_put_on_recursion(sc_gameref_t game, sc_int object,
+ sc_int supporter, sc_bool report) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int check;
@@ -7276,8 +7106,7 @@ lib_check_put_on_recursion(sc_gameref_t game,
* Objects to action are flagged in object_references; objects requested but
* deemed not actionable are flagged in multiple_references.
*/
-static void
-lib_put_on_backend(sc_gameref_t game, sc_int supporter) {
+static void lib_put_on_backend(sc_gameref_t game, sc_int supporter) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object_count, object, count, trail;
sc_bool has_printed;
@@ -7401,8 +7230,7 @@ lib_put_on_backend(sc_gameref_t game, sc_int supporter) {
* Helper functions for deciding if an object may be put on another this
* context. Returns TRUE if an object may be manipulated, FALSE otherwise.
*/
-static sc_bool
-lib_put_on_filter(sc_gameref_t game, sc_int object, sc_int unused) {
+static sc_bool lib_put_on_filter(sc_gameref_t game, sc_int object, sc_int unused) {
assert(unused == -1);
return !obj_is_static(game, object)
@@ -7421,8 +7249,7 @@ lib_put_on_not_supporter_filter(sc_gameref_t game,
*
* Validate the supporter requested in "put on" commands.
*/
-static sc_bool
-lib_put_on_is_valid(sc_gameref_t game, sc_int supporter) {
+static sc_bool lib_put_on_is_valid(sc_gameref_t game, sc_int supporter) {
const sc_filterref_t filter = gs_get_filter(game);
/* Verify that the supporter object is a supporter. */
@@ -7447,8 +7274,7 @@ lib_put_on_is_valid(sc_gameref_t game, sc_int supporter) {
*
* Put all objects currently held by the player onto a supporter.
*/
-sc_bool
-lib_cmd_put_all_on(sc_gameref_t game) {
+sc_bool lib_cmd_put_all_on(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int supporter, objects;
sc_bool is_ambiguous;
@@ -7492,8 +7318,7 @@ lib_cmd_put_all_on(sc_gameref_t game) {
* Put all objects currently held by the player onto an object, excepting
* those listed in %text%.
*/
-sc_bool
-lib_cmd_put_on_except_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_put_on_except_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int supporter, objects, references;
sc_bool is_ambiguous;
@@ -7552,8 +7377,7 @@ lib_cmd_put_on_except_multiple(sc_gameref_t game) {
* Put all objects currently held by the player and listed in %text% onto an
* object.
*/
-sc_bool
-lib_cmd_put_on_multiple(sc_gameref_t game) {
+sc_bool lib_cmd_put_on_multiple(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int supporter, objects, references;
sc_bool is_ambiguous;
@@ -7600,8 +7424,7 @@ lib_cmd_put_on_multiple(sc_gameref_t game) {
*
* Attempt to read the referenced object, or something else.
*/
-sc_bool
-lib_cmd_read_object(sc_gameref_t game) {
+sc_bool lib_cmd_read_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -7663,8 +7486,7 @@ lib_cmd_read_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_read_other(sc_gameref_t game) {
+sc_bool lib_cmd_read_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
/* Reject the attempt. */
@@ -7683,8 +7505,7 @@ lib_cmd_read_other(sc_gameref_t game) {
*
* Attempt to attack an NPC, with and without weaponry.
*/
-sc_bool
-lib_cmd_attack_npc(sc_gameref_t game) {
+sc_bool lib_cmd_attack_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int npc;
sc_bool is_ambiguous;
@@ -7705,8 +7526,7 @@ lib_cmd_attack_npc(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_attack_npc_with(sc_gameref_t game) {
+sc_bool lib_cmd_attack_npc_with(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, npc;
@@ -7784,8 +7604,7 @@ lib_cmd_attack_npc_with(sc_gameref_t game) {
*
* Reject romantic advances in all cases.
*/
-sc_bool
-lib_cmd_kiss_npc(sc_gameref_t game) {
+sc_bool lib_cmd_kiss_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -7822,8 +7641,7 @@ lib_cmd_kiss_npc(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_kiss_object(sc_gameref_t game) {
+sc_bool lib_cmd_kiss_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -7840,8 +7658,7 @@ lib_cmd_kiss_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_kiss_other(sc_gameref_t game) {
+sc_bool lib_cmd_kiss_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
/* Reject this attempt. */
@@ -7856,8 +7673,7 @@ lib_cmd_kiss_other(sc_gameref_t game) {
*
* Standard responses to attempts to buy something.
*/
-sc_bool
-lib_cmd_buy_object(sc_gameref_t game) {
+sc_bool lib_cmd_buy_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -7876,8 +7692,7 @@ lib_cmd_buy_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_buy_other(sc_gameref_t game) {
+sc_bool lib_cmd_buy_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
/* Reject this attempt. */
@@ -7892,8 +7707,7 @@ lib_cmd_buy_other(sc_gameref_t game) {
*
* Standard responses to attempts to break something.
*/
-sc_bool
-lib_cmd_break_object(sc_gameref_t game) {
+sc_bool lib_cmd_break_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -7914,8 +7728,7 @@ lib_cmd_break_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_break_other(sc_gameref_t game) {
+sc_bool lib_cmd_break_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
/* Reject this attempt. */
@@ -7934,8 +7747,7 @@ lib_cmd_break_other(sc_gameref_t game) {
*
* Standard responses to attempts to smell something.
*/
-sc_bool
-lib_cmd_smell_object(sc_gameref_t game) {
+sc_bool lib_cmd_smell_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -7952,8 +7764,7 @@ lib_cmd_smell_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_smell_other(sc_gameref_t game) {
+sc_bool lib_cmd_smell_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
/* Reject this attempt. */
@@ -7968,8 +7779,7 @@ lib_cmd_smell_other(sc_gameref_t game) {
*
* Standard responses to attempts to sell something.
*/
-sc_bool
-lib_cmd_sell_object(sc_gameref_t game) {
+sc_bool lib_cmd_sell_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -7986,8 +7796,7 @@ lib_cmd_sell_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_sell_other(sc_gameref_t game) {
+sc_bool lib_cmd_sell_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "No-one is interested in buying that.\n");
@@ -8000,8 +7809,7 @@ lib_cmd_sell_other(sc_gameref_t game) {
*
* Consume edible objects.
*/
-sc_bool
-lib_cmd_eat_object(sc_gameref_t game) {
+sc_bool lib_cmd_eat_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -8081,8 +7889,7 @@ enum {
*
* Central handler for stand, sit, and lie commands.
*/
-static sc_bool
-lib_stand_sit_lie(sc_gameref_t game, sc_int movement) {
+static sc_bool lib_stand_sit_lie(sc_gameref_t game, sc_int movement) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, position;
@@ -8295,33 +8102,27 @@ lib_stand_sit_lie(sc_gameref_t game, sc_int movement) {
*
* Stand, sit, or lie on an object, or on the floor.
*/
-sc_bool
-lib_cmd_stand_on_object(sc_gameref_t game) {
+sc_bool lib_cmd_stand_on_object(sc_gameref_t game) {
return lib_stand_sit_lie(game, MOVE_STAND);
}
-sc_bool
-lib_cmd_stand_on_floor(sc_gameref_t game) {
+sc_bool lib_cmd_stand_on_floor(sc_gameref_t game) {
return lib_stand_sit_lie(game, MOVE_STAND_FLOOR);
}
-sc_bool
-lib_cmd_sit_on_object(sc_gameref_t game) {
+sc_bool lib_cmd_sit_on_object(sc_gameref_t game) {
return lib_stand_sit_lie(game, MOVE_SIT);
}
-sc_bool
-lib_cmd_sit_on_floor(sc_gameref_t game) {
+sc_bool lib_cmd_sit_on_floor(sc_gameref_t game) {
return lib_stand_sit_lie(game, MOVE_SIT_FLOOR);
}
-sc_bool
-lib_cmd_lie_on_object(sc_gameref_t game) {
+sc_bool lib_cmd_lie_on_object(sc_gameref_t game) {
return lib_stand_sit_lie(game, MOVE_LIE);
}
-sc_bool
-lib_cmd_lie_on_floor(sc_gameref_t game) {
+sc_bool lib_cmd_lie_on_floor(sc_gameref_t game) {
return lib_stand_sit_lie(game, MOVE_LIE_FLOOR);
}
@@ -8332,8 +8133,7 @@ lib_cmd_lie_on_floor(sc_gameref_t game) {
*
* Get off whatever supporter the player rests on.
*/
-sc_bool
-lib_cmd_get_off_object(sc_gameref_t game) {
+sc_bool lib_cmd_get_off_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -8369,8 +8169,7 @@ lib_cmd_get_off_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_get_off(sc_gameref_t game) {
+sc_bool lib_cmd_get_off(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
/* Reject the attempt if the player is not on anything. */
@@ -8404,8 +8203,7 @@ lib_cmd_get_off(sc_gameref_t game) {
*
* Save/restore a game.
*/
-sc_bool
-lib_cmd_save(sc_gameref_t game) {
+sc_bool lib_cmd_save(sc_gameref_t game) {
if (if_confirm(SC_CONF_SAVE)) {
if (ser_save_game_prompted(game))
if_print_string("Ok.\n");
@@ -8417,8 +8215,7 @@ lib_cmd_save(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_restore(sc_gameref_t game) {
+sc_bool lib_cmd_restore(sc_gameref_t game) {
if (if_confirm(SC_CONF_RESTORE)) {
if (ser_load_game_prompted(game)) {
if_print_string("Ok.\n");
@@ -8439,8 +8236,7 @@ lib_cmd_restore(sc_gameref_t game) {
*
* Display the location of a selected object, and selected NPC.
*/
-sc_bool
-lib_cmd_locate_object(sc_gameref_t game) {
+sc_bool lib_cmd_locate_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int index_, count, object, room, position, parent;
@@ -8612,8 +8408,7 @@ lib_cmd_locate_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_locate_npc(sc_gameref_t game) {
+sc_bool lib_cmd_locate_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int index_, count, npc, room;
@@ -8711,8 +8506,7 @@ lib_cmd_locate_npc(sc_gameref_t game) {
*
* Display turns taken and score so far.
*/
-sc_bool
-lib_cmd_turns(sc_gameref_t game) {
+sc_bool lib_cmd_turns(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_char buffer[32];
@@ -8728,8 +8522,7 @@ lib_cmd_turns(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_score(sc_gameref_t game) {
+sc_bool lib_cmd_score(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
@@ -8772,8 +8565,7 @@ lib_cmd_score(sc_gameref_t game) {
* Standard response commands. These are uninteresting catch-all cases,
* but it's good to make then right as game ALRs may look for them.
*/
-sc_bool
-lib_cmd_profanity(sc_gameref_t game) {
+sc_bool lib_cmd_profanity(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8782,16 +8574,14 @@ lib_cmd_profanity(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_examine_all(sc_gameref_t game) {
+sc_bool lib_cmd_examine_all(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "Please examine one object at a time.\n");
return TRUE;
}
-sc_bool
-lib_cmd_examine_other(sc_gameref_t game) {
+sc_bool lib_cmd_examine_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8802,8 +8592,7 @@ lib_cmd_examine_other(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_locate_other(sc_gameref_t game) {
+sc_bool lib_cmd_locate_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "I don't know where that is!\n");
@@ -8811,32 +8600,28 @@ lib_cmd_locate_other(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_unix_like(sc_gameref_t game) {
+sc_bool lib_cmd_unix_like(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "This isn't Unix you know!\n");
return TRUE;
}
-sc_bool
-lib_cmd_dos_like(sc_gameref_t game) {
+sc_bool lib_cmd_dos_like(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "This isn't Dos you know!\n");
return TRUE;
}
-sc_bool
-lib_cmd_cry(sc_gameref_t game) {
+sc_bool lib_cmd_cry(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "There's no need for that!\n");
return TRUE;
}
-sc_bool
-lib_cmd_dance(sc_gameref_t game) {
+sc_bool lib_cmd_dance(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8847,32 +8632,28 @@ lib_cmd_dance(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_eat_other(sc_gameref_t game) {
+sc_bool lib_cmd_eat_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "I don't understand what you are trying to eat.\n");
return TRUE;
}
-sc_bool
-lib_cmd_fight(sc_gameref_t game) {
+sc_bool lib_cmd_fight(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "There is nothing worth fighting here.\n");
return TRUE;
}
-sc_bool
-lib_cmd_feed(sc_gameref_t game) {
+sc_bool lib_cmd_feed(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "There is nothing worth feeding here.\n");
return TRUE;
}
-sc_bool
-lib_cmd_feel(sc_gameref_t game) {
+sc_bool lib_cmd_feel(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8883,8 +8664,7 @@ lib_cmd_feel(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_fly(sc_gameref_t game) {
+sc_bool lib_cmd_fly(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8895,8 +8675,7 @@ lib_cmd_fly(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_hint(sc_gameref_t game) {
+sc_bool lib_cmd_hint(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8905,8 +8684,7 @@ lib_cmd_hint(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_hum(sc_gameref_t game) {
+sc_bool lib_cmd_hum(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8917,16 +8695,14 @@ lib_cmd_hum(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_jump(sc_gameref_t game) {
+sc_bool lib_cmd_jump(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "Wheee-boinng.\n");
return TRUE;
}
-sc_bool
-lib_cmd_listen(sc_gameref_t game) {
+sc_bool lib_cmd_listen(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8937,8 +8713,7 @@ lib_cmd_listen(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_please(sc_gameref_t game) {
+sc_bool lib_cmd_please(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8949,16 +8724,14 @@ lib_cmd_please(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_punch(sc_gameref_t game) {
+sc_bool lib_cmd_punch(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "Who do you think you are, Mike Tyson?\n");
return TRUE;
}
-sc_bool
-lib_cmd_run(sc_gameref_t game) {
+sc_bool lib_cmd_run(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -8969,16 +8742,14 @@ lib_cmd_run(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_shout(sc_gameref_t game) {
+sc_bool lib_cmd_shout(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "Aaarrrrgggghhhhhh!\n");
return TRUE;
}
-sc_bool
-lib_cmd_say(sc_gameref_t game) {
+sc_bool lib_cmd_say(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_char *string = NULL;
@@ -9010,8 +8781,7 @@ lib_cmd_say(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_sing(sc_gameref_t game) {
+sc_bool lib_cmd_sing(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -9022,16 +8792,14 @@ lib_cmd_sing(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_sleep(sc_gameref_t game) {
+sc_bool lib_cmd_sleep(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "Zzzzz. Bored are you?\n");
return TRUE;
}
-sc_bool
-lib_cmd_talk(sc_gameref_t game) {
+sc_bool lib_cmd_talk(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -9042,16 +8810,14 @@ lib_cmd_talk(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_thank(sc_gameref_t game) {
+sc_bool lib_cmd_thank(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "You're welcome.\n");
return TRUE;
}
-sc_bool
-lib_cmd_whistle(sc_gameref_t game) {
+sc_bool lib_cmd_whistle(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -9062,8 +8828,7 @@ lib_cmd_whistle(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_interrogation(sc_gameref_t game) {
+sc_bool lib_cmd_interrogation(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_char *string = NULL;
@@ -9125,8 +8890,7 @@ lib_cmd_interrogation(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_xyzzy(sc_gameref_t game) {
+sc_bool lib_cmd_xyzzy(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -9135,8 +8899,7 @@ lib_cmd_xyzzy(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_egotistic(sc_gameref_t game) {
+sc_bool lib_cmd_egotistic(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
#if 0
@@ -9150,8 +8913,7 @@ lib_cmd_egotistic(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_yes_or_no(sc_gameref_t game) {
+sc_bool lib_cmd_yes_or_no(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter,
@@ -9167,8 +8929,7 @@ lib_cmd_yes_or_no(sc_gameref_t game) {
*
* Malformed and rhetorical question responses.
*/
-sc_bool
-lib_cmd_ask_npc(sc_gameref_t game) {
+sc_bool lib_cmd_ask_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int npc;
sc_bool is_ambiguous;
@@ -9185,8 +8946,7 @@ lib_cmd_ask_npc(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_ask_object(sc_gameref_t game) {
+sc_bool lib_cmd_ask_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -9207,8 +8967,7 @@ lib_cmd_ask_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_ask_other(sc_gameref_t game) {
+sc_bool lib_cmd_ask_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
/* Incomplete ask command, so offer help and return. */
@@ -9223,8 +8982,7 @@ lib_cmd_ask_other(sc_gameref_t game) {
*
* Uninteresting kill message when no weaponry is involved.
*/
-sc_bool
-lib_cmd_kill_other(sc_gameref_t game) {
+sc_bool lib_cmd_kill_other(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, "Now that isn't very nice.\n");
@@ -9240,11 +8998,8 @@ lib_cmd_kill_other(sc_gameref_t game) {
* Central handler for a range of nothing-happens messages. More
* uninteresting responses.
*/
-static sc_bool
-lib_nothing_happens_common(sc_gameref_t game,
- const sc_char *verb_general,
- const sc_char *verb_third_person,
- sc_bool is_object) {
+static sc_bool lib_nothing_happens_common(sc_gameref_t game, const sc_char *verb_general,
+ const sc_char *verb_third_person, sc_bool is_object) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
@@ -9298,18 +9053,14 @@ lib_nothing_happens_common(sc_gameref_t game,
return TRUE;
}
-static sc_bool
-lib_nothing_happens_object(sc_gameref_t game,
- const sc_char *verb_general,
- const sc_char *verb_third_person) {
+static sc_bool lib_nothing_happens_object(sc_gameref_t game,
+ const sc_char *verb_general, const sc_char *verb_third_person) {
return lib_nothing_happens_common(game,
verb_general, verb_third_person, TRUE);
}
-static sc_bool
-lib_nothing_happens_other(sc_gameref_t game,
- const sc_char *verb_general,
- const sc_char *verb_third_person) {
+static sc_bool lib_nothing_happens_other(sc_gameref_t game,
+ const sc_char *verb_general, const sc_char *verb_third_person) {
return lib_nothing_happens_common(game,
verb_general, verb_third_person, FALSE);
}
@@ -9320,63 +9071,51 @@ lib_nothing_happens_other(sc_gameref_t game,
*
* Shake, rattle and roll, and assorted nothing-happens handlers.
*/
-sc_bool
-lib_cmd_hit_object(sc_gameref_t game) {
+sc_bool lib_cmd_hit_object(sc_gameref_t game) {
return lib_nothing_happens_object(game, "hit", "hits");
}
-sc_bool
-lib_cmd_kick_object(sc_gameref_t game) {
+sc_bool lib_cmd_kick_object(sc_gameref_t game) {
return lib_nothing_happens_object(game, "kick", "kicks");
}
-sc_bool
-lib_cmd_press_object(sc_gameref_t game) {
+sc_bool lib_cmd_press_object(sc_gameref_t game) {
return lib_nothing_happens_object(game, "press", "presses");
}
-sc_bool
-lib_cmd_push_object(sc_gameref_t game) {
+sc_bool lib_cmd_push_object(sc_gameref_t game) {
return lib_nothing_happens_object(game, "push", "pushes");
}
-sc_bool
-lib_cmd_pull_object(sc_gameref_t game) {
+sc_bool lib_cmd_pull_object(sc_gameref_t game) {
return lib_nothing_happens_object(game, "pull", "pulls");
}
-sc_bool
-lib_cmd_shake_object(sc_gameref_t game) {
+sc_bool lib_cmd_shake_object(sc_gameref_t game) {
return lib_nothing_happens_object(game, "shake", "shakes");
}
-sc_bool
-lib_cmd_hit_other(sc_gameref_t game) {
+sc_bool lib_cmd_hit_other(sc_gameref_t game) {
return lib_nothing_happens_other(game, "hit", "hits");
}
-sc_bool
-lib_cmd_kick_other(sc_gameref_t game) {
+sc_bool lib_cmd_kick_other(sc_gameref_t game) {
return lib_nothing_happens_other(game, "kick", "kicks");
}
-sc_bool
-lib_cmd_press_other(sc_gameref_t game) {
+sc_bool lib_cmd_press_other(sc_gameref_t game) {
return lib_nothing_happens_other(game, "press", "presses");
}
-sc_bool
-lib_cmd_push_other(sc_gameref_t game) {
+sc_bool lib_cmd_push_other(sc_gameref_t game) {
return lib_nothing_happens_other(game, "push", "pushes");
}
-sc_bool
-lib_cmd_pull_other(sc_gameref_t game) {
+sc_bool lib_cmd_pull_other(sc_gameref_t game) {
return lib_nothing_happens_other(game, "pull", "pulls");
}
-sc_bool
-lib_cmd_shake_other(sc_gameref_t game) {
+sc_bool lib_cmd_shake_other(sc_gameref_t game) {
return lib_nothing_happens_other(game, "shake", "shakes");
}
@@ -9389,9 +9128,7 @@ lib_cmd_shake_other(sc_gameref_t game) {
* Central handler for a range of can't-do messages. Yet more uninterest-
* ing responses.
*/
-static sc_bool
-lib_cant_do_common(sc_gameref_t game,
- const sc_char *verb, sc_bool is_object) {
+static sc_bool lib_cant_do_common(sc_gameref_t game, const sc_char *verb, sc_bool is_object) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
sc_bool is_ambiguous;
@@ -9424,13 +9161,11 @@ lib_cant_do_common(sc_gameref_t game,
return TRUE;
}
-static sc_bool
-lib_cant_do_object(sc_gameref_t game, const sc_char *verb) {
+static sc_bool lib_cant_do_object(sc_gameref_t game, const sc_char *verb) {
return lib_cant_do_common(game, verb, TRUE);
}
-static sc_bool
-lib_cant_do_other(sc_gameref_t game, const sc_char *verb) {
+static sc_bool lib_cant_do_other(sc_gameref_t game, const sc_char *verb) {
return lib_cant_do_common(game, verb, FALSE);
}
@@ -9440,183 +9175,147 @@ lib_cant_do_other(sc_gameref_t game, const sc_char *verb) {
*
* Assorted can't-do messages.
*/
-sc_bool
-lib_cmd_block_object(sc_gameref_t game) {
+sc_bool lib_cmd_block_object(sc_gameref_t game) {
return lib_cant_do_object(game, "block");
}
-sc_bool
-lib_cmd_climb_object(sc_gameref_t game) {
+sc_bool lib_cmd_climb_object(sc_gameref_t game) {
return lib_cant_do_object(game, "climb");
}
-sc_bool
-lib_cmd_clean_object(sc_gameref_t game) {
+sc_bool lib_cmd_clean_object(sc_gameref_t game) {
return lib_cant_do_object(game, "clean");
}
-sc_bool
-lib_cmd_cut_object(sc_gameref_t game) {
+sc_bool lib_cmd_cut_object(sc_gameref_t game) {
return lib_cant_do_object(game, "cut");
}
-sc_bool
-lib_cmd_drink_object(sc_gameref_t game) {
+sc_bool lib_cmd_drink_object(sc_gameref_t game) {
return lib_cant_do_object(game, "drink");
}
-sc_bool
-lib_cmd_light_object(sc_gameref_t game) {
+sc_bool lib_cmd_light_object(sc_gameref_t game) {
return lib_cant_do_object(game, "light");
}
-sc_bool
-lib_cmd_lift_object(sc_gameref_t game) {
+sc_bool lib_cmd_lift_object(sc_gameref_t game) {
return lib_cant_do_object(game, "lift");
}
-sc_bool
-lib_cmd_move_object(sc_gameref_t game) {
+sc_bool lib_cmd_move_object(sc_gameref_t game) {
return lib_cant_do_object(game, "move");
}
-sc_bool
-lib_cmd_rub_object(sc_gameref_t game) {
+sc_bool lib_cmd_rub_object(sc_gameref_t game) {
return lib_cant_do_object(game, "rub");
}
-sc_bool
-lib_cmd_stop_object(sc_gameref_t game) {
+sc_bool lib_cmd_stop_object(sc_gameref_t game) {
return lib_cant_do_object(game, "stop");
}
-sc_bool
-lib_cmd_suck_object(sc_gameref_t game) {
+sc_bool lib_cmd_suck_object(sc_gameref_t game) {
return lib_cant_do_object(game, "suck");
}
-sc_bool
-lib_cmd_touch_object(sc_gameref_t game) {
+sc_bool lib_cmd_touch_object(sc_gameref_t game) {
return lib_cant_do_object(game, "touch");
}
-sc_bool
-lib_cmd_turn_object(sc_gameref_t game) {
+sc_bool lib_cmd_turn_object(sc_gameref_t game) {
return lib_cant_do_object(game, "turn");
}
-sc_bool
-lib_cmd_unblock_object(sc_gameref_t game) {
+sc_bool lib_cmd_unblock_object(sc_gameref_t game) {
return lib_cant_do_object(game, "unblock");
}
-sc_bool
-lib_cmd_wash_object(sc_gameref_t game) {
+sc_bool lib_cmd_wash_object(sc_gameref_t game) {
return lib_cant_do_object(game, "wash");
}
-sc_bool
-lib_cmd_block_other(sc_gameref_t game) {
+sc_bool lib_cmd_block_other(sc_gameref_t game) {
return lib_cant_do_other(game, "block");
}
-sc_bool
-lib_cmd_climb_other(sc_gameref_t game) {
+sc_bool lib_cmd_climb_other(sc_gameref_t game) {
return lib_cant_do_other(game, "climb");
}
-sc_bool
-lib_cmd_clean_other(sc_gameref_t game) {
+sc_bool lib_cmd_clean_other(sc_gameref_t game) {
return lib_cant_do_other(game, "clean");
}
-sc_bool
-lib_cmd_close_other(sc_gameref_t game) {
+sc_bool lib_cmd_close_other(sc_gameref_t game) {
return lib_cant_do_other(game, "close");
}
-sc_bool
-lib_cmd_lock_other(sc_gameref_t game) {
+sc_bool lib_cmd_lock_other(sc_gameref_t game) {
return lib_cant_do_other(game, "lock");
}
-sc_bool
-lib_cmd_unlock_other(sc_gameref_t game) {
+sc_bool lib_cmd_unlock_other(sc_gameref_t game) {
return lib_cant_do_other(game, "unlock");
}
-sc_bool
-lib_cmd_stand_other(sc_gameref_t game) {
+sc_bool lib_cmd_stand_other(sc_gameref_t game) {
return lib_cant_do_other(game, "stand on");
}
-sc_bool
-lib_cmd_sit_other(sc_gameref_t game) {
+sc_bool lib_cmd_sit_other(sc_gameref_t game) {
return lib_cant_do_other(game, "sit on");
}
-sc_bool
-lib_cmd_lie_other(sc_gameref_t game) {
+sc_bool lib_cmd_lie_other(sc_gameref_t game) {
return lib_cant_do_other(game, "lie on");
}
-sc_bool
-lib_cmd_cut_other(sc_gameref_t game) {
+sc_bool lib_cmd_cut_other(sc_gameref_t game) {
return lib_cant_do_other(game, "cut");
}
-sc_bool
-lib_cmd_drink_other(sc_gameref_t game) {
+sc_bool lib_cmd_drink_other(sc_gameref_t game) {
return lib_cant_do_other(game, "drink");
}
-sc_bool
-lib_cmd_lift_other(sc_gameref_t game) {
+sc_bool lib_cmd_lift_other(sc_gameref_t game) {
return lib_cant_do_other(game, "lift");
}
-sc_bool
-lib_cmd_light_other(sc_gameref_t game) {
+sc_bool lib_cmd_light_other(sc_gameref_t game) {
return lib_cant_do_other(game, "light");
}
-sc_bool
-lib_cmd_move_other(sc_gameref_t game) {
+sc_bool lib_cmd_move_other(sc_gameref_t game) {
return lib_cant_do_other(game, "move");
}
-sc_bool
-lib_cmd_stop_other(sc_gameref_t game) {
+sc_bool lib_cmd_stop_other(sc_gameref_t game) {
return lib_cant_do_other(game, "stop");
}
-sc_bool
-lib_cmd_rub_other(sc_gameref_t game) {
+sc_bool lib_cmd_rub_other(sc_gameref_t game) {
return lib_cant_do_other(game, "rub");
}
-sc_bool
-lib_cmd_suck_other(sc_gameref_t game) {
+sc_bool lib_cmd_suck_other(sc_gameref_t game) {
return lib_cant_do_other(game, "suck");
}
-sc_bool
-lib_cmd_turn_other(sc_gameref_t game) {
+sc_bool lib_cmd_turn_other(sc_gameref_t game) {
return lib_cant_do_other(game, "turn");
}
-sc_bool
-lib_cmd_touch_other(sc_gameref_t game) {
+sc_bool lib_cmd_touch_other(sc_gameref_t game) {
return lib_cant_do_other(game, "touch");
}
-sc_bool
-lib_cmd_unblock_other(sc_gameref_t game) {
+sc_bool lib_cmd_unblock_other(sc_gameref_t game) {
return lib_cant_do_other(game, "unblock");
}
-sc_bool
-lib_cmd_wash_other(sc_gameref_t game) {
+sc_bool lib_cmd_wash_other(sc_gameref_t game) {
return lib_cant_do_other(game, "wash");
}
@@ -9629,8 +9328,7 @@ lib_cmd_wash_other(sc_gameref_t game) {
* Central handler for a range of don't_think messages. Still more
* uninteresting responses.
*/
-static sc_bool
-lib_dont_think_common(sc_gameref_t game,
+static sc_bool lib_dont_think_common(sc_gameref_t game,
const sc_char *verb, sc_bool is_object) {
const sc_filterref_t filter = gs_get_filter(game);
sc_int object;
@@ -9662,13 +9360,11 @@ lib_dont_think_common(sc_gameref_t game,
return TRUE;
}
-static sc_bool
-lib_dont_think_object(sc_gameref_t game, const sc_char *verb) {
+static sc_bool lib_dont_think_object(sc_gameref_t game, const sc_char *verb) {
return lib_dont_think_common(game, verb, TRUE);
}
-static sc_bool
-lib_dont_think_other(sc_gameref_t game, const sc_char *verb) {
+static sc_bool lib_dont_think_other(sc_gameref_t game, const sc_char *verb) {
return lib_dont_think_common(game, verb, FALSE);
}
@@ -9678,33 +9374,27 @@ lib_dont_think_other(sc_gameref_t game, const sc_char *verb) {
*
* Assorted don't-think messages.
*/
-sc_bool
-lib_cmd_fix_object(sc_gameref_t game) {
+sc_bool lib_cmd_fix_object(sc_gameref_t game) {
return lib_dont_think_object(game, "fix");
}
-sc_bool
-lib_cmd_mend_object(sc_gameref_t game) {
+sc_bool lib_cmd_mend_object(sc_gameref_t game) {
return lib_dont_think_object(game, "mend");
}
-sc_bool
-lib_cmd_repair_object(sc_gameref_t game) {
+sc_bool lib_cmd_repair_object(sc_gameref_t game) {
return lib_dont_think_object(game, "repair");
}
-sc_bool
-lib_cmd_fix_other(sc_gameref_t game) {
+sc_bool lib_cmd_fix_other(sc_gameref_t game) {
return lib_dont_think_other(game, "fix");
}
-sc_bool
-lib_cmd_mend_other(sc_gameref_t game) {
+sc_bool lib_cmd_mend_other(sc_gameref_t game) {
return lib_dont_think_other(game, "mend");
}
-sc_bool
-lib_cmd_repair_other(sc_gameref_t game) {
+sc_bool lib_cmd_repair_other(sc_gameref_t game) {
return lib_dont_think_other(game, "repair");
}
@@ -9714,8 +9404,7 @@ lib_cmd_repair_other(sc_gameref_t game) {
*
* Central handler for doing something, but unsure to what.
*/
-static sc_bool
-lib_what(sc_gameref_t game, const sc_char *verb) {
+static sc_bool lib_what(sc_gameref_t game, const sc_char *verb) {
const sc_filterref_t filter = gs_get_filter(game);
pf_buffer_string(filter, verb);
@@ -9729,188 +9418,151 @@ lib_what(sc_gameref_t game, const sc_char *verb) {
*
* Assorted "what?" messages.
*/
-sc_bool
-lib_cmd_block_what(sc_gameref_t game) {
+sc_bool lib_cmd_block_what(sc_gameref_t game) {
return lib_what(game, "Block");
}
-sc_bool
-lib_cmd_break_what(sc_gameref_t game) {
+sc_bool lib_cmd_break_what(sc_gameref_t game) {
return lib_what(game, "Break");
}
-sc_bool
-lib_cmd_destroy_what(sc_gameref_t game) {
+sc_bool lib_cmd_destroy_what(sc_gameref_t game) {
return lib_what(game, "Destroy");
}
-sc_bool
-lib_cmd_smash_what(sc_gameref_t game) {
+sc_bool lib_cmd_smash_what(sc_gameref_t game) {
return lib_what(game, "Smash");
}
-sc_bool
-lib_cmd_buy_what(sc_gameref_t game) {
+sc_bool lib_cmd_buy_what(sc_gameref_t game) {
return lib_what(game, "Buy");
}
-sc_bool
-lib_cmd_clean_what(sc_gameref_t game) {
+sc_bool lib_cmd_clean_what(sc_gameref_t game) {
return lib_what(game, "Clean");
}
-sc_bool
-lib_cmd_climb_what(sc_gameref_t game) {
+sc_bool lib_cmd_climb_what(sc_gameref_t game) {
return lib_what(game, "Climb");
}
-sc_bool
-lib_cmd_cut_what(sc_gameref_t game) {
+sc_bool lib_cmd_cut_what(sc_gameref_t game) {
return lib_what(game, "Cut");
}
-sc_bool
-lib_cmd_drink_what(sc_gameref_t game) {
+sc_bool lib_cmd_drink_what(sc_gameref_t game) {
return lib_what(game, "Drink");
}
-sc_bool
-lib_cmd_fix_what(sc_gameref_t game) {
+sc_bool lib_cmd_fix_what(sc_gameref_t game) {
return lib_what(game, "Fix");
}
-sc_bool
-lib_cmd_hit_what(sc_gameref_t game) {
+sc_bool lib_cmd_hit_what(sc_gameref_t game) {
return lib_what(game, "Hit");
}
-sc_bool
-lib_cmd_kick_what(sc_gameref_t game) {
+sc_bool lib_cmd_kick_what(sc_gameref_t game) {
return lib_what(game, "Kick");
}
-sc_bool
-lib_cmd_light_what(sc_gameref_t game) {
+sc_bool lib_cmd_light_what(sc_gameref_t game) {
return lib_what(game, "Light");
}
-sc_bool
-lib_cmd_lift_what(sc_gameref_t game) {
+sc_bool lib_cmd_lift_what(sc_gameref_t game) {
return lib_what(game, "Lift");
}
-sc_bool
-lib_cmd_mend_what(sc_gameref_t game) {
+sc_bool lib_cmd_mend_what(sc_gameref_t game) {
return lib_what(game, "Mend");
}
-sc_bool
-lib_cmd_move_what(sc_gameref_t game) {
+sc_bool lib_cmd_move_what(sc_gameref_t game) {
return lib_what(game, "Move");
}
-sc_bool
-lib_cmd_press_what(sc_gameref_t game) {
+sc_bool lib_cmd_press_what(sc_gameref_t game) {
return lib_what(game, "Press");
}
-sc_bool
-lib_cmd_pull_what(sc_gameref_t game) {
+sc_bool lib_cmd_pull_what(sc_gameref_t game) {
return lib_what(game, "Pull");
}
-sc_bool
-lib_cmd_push_what(sc_gameref_t game) {
+sc_bool lib_cmd_push_what(sc_gameref_t game) {
return lib_what(game, "Push");
}
-sc_bool
-lib_cmd_repair_what(sc_gameref_t game) {
+sc_bool lib_cmd_repair_what(sc_gameref_t game) {
return lib_what(game, "Repair");
}
-sc_bool
-lib_cmd_sell_what(sc_gameref_t game) {
+sc_bool lib_cmd_sell_what(sc_gameref_t game) {
return lib_what(game, "Sell");
}
-sc_bool
-lib_cmd_shake_what(sc_gameref_t game) {
+sc_bool lib_cmd_shake_what(sc_gameref_t game) {
return lib_what(game, "Shake");
}
-sc_bool
-lib_cmd_rub_what(sc_gameref_t game) {
+sc_bool lib_cmd_rub_what(sc_gameref_t game) {
return lib_what(game, "Rub");
}
-sc_bool
-lib_cmd_stop_what(sc_gameref_t game) {
+sc_bool lib_cmd_stop_what(sc_gameref_t game) {
return lib_what(game, "Stop");
}
-sc_bool
-lib_cmd_suck_what(sc_gameref_t game) {
+sc_bool lib_cmd_suck_what(sc_gameref_t game) {
return lib_what(game, "Suck");
}
-sc_bool
-lib_cmd_touch_what(sc_gameref_t game) {
+sc_bool lib_cmd_touch_what(sc_gameref_t game) {
return lib_what(game, "Touch");
}
-sc_bool
-lib_cmd_turn_what(sc_gameref_t game) {
+sc_bool lib_cmd_turn_what(sc_gameref_t game) {
return lib_what(game, "Turn");
}
-sc_bool
-lib_cmd_unblock_what(sc_gameref_t game) {
+sc_bool lib_cmd_unblock_what(sc_gameref_t game) {
return lib_what(game, "Unblock");
}
-sc_bool
-lib_cmd_wash_what(sc_gameref_t game) {
+sc_bool lib_cmd_wash_what(sc_gameref_t game) {
return lib_what(game, "Wash");
}
-sc_bool
-lib_cmd_drop_what(sc_gameref_t game) {
+sc_bool lib_cmd_drop_what(sc_gameref_t game) {
return lib_what(game, "Drop");
}
-sc_bool
-lib_cmd_get_what(sc_gameref_t game) {
+sc_bool lib_cmd_get_what(sc_gameref_t game) {
return lib_what(game, "Take");
}
-sc_bool
-lib_cmd_give_what(sc_gameref_t game) {
+sc_bool lib_cmd_give_what(sc_gameref_t game) {
return lib_what(game, "Give");
}
-sc_bool
-lib_cmd_open_what(sc_gameref_t game) {
+sc_bool lib_cmd_open_what(sc_gameref_t game) {
return lib_what(game, "Open");
}
-sc_bool
-lib_cmd_remove_what(sc_gameref_t game) {
+sc_bool lib_cmd_remove_what(sc_gameref_t game) {
return lib_what(game, "Remove");
}
-sc_bool
-lib_cmd_wear_what(sc_gameref_t game) {
+sc_bool lib_cmd_wear_what(sc_gameref_t game) {
return lib_what(game, "Wear");
}
-sc_bool
-lib_cmd_lock_what(sc_gameref_t game) {
+sc_bool lib_cmd_lock_what(sc_gameref_t game) {
return lib_what(game, "Lock");
}
-sc_bool
-lib_cmd_unlock_what(sc_gameref_t game) {
+sc_bool lib_cmd_unlock_what(sc_gameref_t game) {
return lib_what(game, "Unlock");
}
@@ -9921,8 +9573,7 @@ lib_cmd_unlock_what(sc_gameref_t game) {
*
* Handlers for unrecognized verbs with known object/NPC.
*/
-sc_bool
-lib_cmd_verb_object(sc_gameref_t game) {
+sc_bool lib_cmd_verb_object(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int count, object, index_;
@@ -9951,8 +9602,7 @@ lib_cmd_verb_object(sc_gameref_t game) {
return TRUE;
}
-sc_bool
-lib_cmd_verb_npc(sc_gameref_t game) {
+sc_bool lib_cmd_verb_npc(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int count, npc, index_;
@@ -9987,8 +9637,7 @@ lib_cmd_verb_npc(sc_gameref_t game) {
*
* Set library tracing on/off.
*/
-void
-lib_debug_trace(sc_bool flag) {
+void lib_debug_trace(sc_bool flag) {
lib_trace = flag;
}
diff --git a/engines/glk/adrift/sclocale.cpp b/engines/glk/adrift/sclocale.cpp
index b201b7f..140e9c9 100644
--- a/engines/glk/adrift/sclocale.cpp
+++ b/engines/glk/adrift/sclocale.cpp
@@ -50,8 +50,7 @@ enum { TABLE_SIZE = 256 };
* Helpers for building ctype tables. Sets all elements from start to end
* inclusive to TRUE, and iterate this on a ranges array.
*/
-static void
-loc_setrange_bool(sc_int start, sc_int end, sc_bool table[]) {
+static void loc_setrange_bool(sc_int start, sc_int end, sc_bool table[]) {
sc_int index_;
for (index_ = start; index_ <= end; index_++) {
@@ -60,8 +59,7 @@ loc_setrange_bool(sc_int start, sc_int end, sc_bool table[]) {
}
}
-static void
-loc_setranges_bool(const sc_int ranges[], sc_bool table[]) {
+static void loc_setranges_bool(const sc_int ranges[], sc_bool table[]) {
sc_int index_;
for (index_ = 0; ranges[index_] > -1; index_ += 2) {
@@ -79,8 +77,7 @@ loc_setranges_bool(const sc_int ranges[], sc_bool table[]) {
* to end inclusive to their index value plus the given offset, and iterate
* this on a ranges array.
*/
-static void
-loc_setrange_char(sc_int start, sc_int end, sc_int offset, sc_char table[]) {
+static void loc_setrange_char(sc_int start, sc_int end, sc_int offset, sc_char table[]) {
sc_int index_;
for (index_ = start; index_ <= end; index_++) {
@@ -90,8 +87,7 @@ loc_setrange_char(sc_int start, sc_int end, sc_int offset, sc_char table[]) {
}
}
-static void
-loc_setranges_char(const sc_int ranges[], sc_char table[]) {
+static void loc_setranges_char(const sc_int ranges[], sc_char table[]) {
sc_int index_;
for (index_ = 0; ranges[index_] > -1; index_ += 3) {
@@ -109,7 +105,7 @@ loc_setranges_char(const sc_int ranges[], sc_char table[]) {
*/
enum { RANGES_LENGTH = 32 };
enum { SIGNATURE_COUNT = 24, SIGNATURE_LENGTH = 3 };
-typedef struct {
+struct sc_locale_t {
const sc_char *const name;
const sc_int isspace_ranges[RANGES_LENGTH];
const sc_int isdigit_ranges[RANGES_LENGTH];
@@ -117,7 +113,7 @@ typedef struct {
const sc_int toupper_ranges[RANGES_LENGTH];
const sc_int tolower_ranges[RANGES_LENGTH];
const sc_byte signature[SIGNATURE_COUNT][SIGNATURE_LENGTH];
-} sc_locale_t;
+};
/*
@@ -126,14 +122,14 @@ typedef struct {
* table, for synchronization with changed locales. This is the dynamic data
* portion of a locale.
*/
-typedef struct {
+struct sc_locale_table_t {
const sc_locale_t *locale;
sc_bool isspace[TABLE_SIZE];
sc_bool isdigit[TABLE_SIZE];
sc_bool isalpha[TABLE_SIZE];
sc_char toupper[TABLE_SIZE];
sc_char tolower[TABLE_SIZE];
-} sc_locale_table_t;
+};
/*
* Define a single static locale table set. This set re-initializes if it
@@ -149,8 +145,7 @@ static sc_locale_table_t loc_locale_tables = {NULL, {0}, {0}, {0}, {0}, {0}};
* Initialize tables for a locale. And compare the locale tables to a locale
* and if not for the same locale, (re-)initialize.
*/
-static void
-loc_synchronize_tables(const sc_locale_t *locale) {
+static void loc_synchronize_tables(const sc_locale_t *locale) {
/* Clear all tables and the locale pointer. */
memset(&loc_locale_tables, 0, sizeof(loc_locale_tables));
@@ -164,8 +159,7 @@ loc_synchronize_tables(const sc_locale_t *locale) {
loc_locale_tables.locale = locale;
}
-static void
-loc_check_tables_synchronized(const sc_locale_t *locale) {
+static void loc_check_tables_synchronized(const sc_locale_t *locale) {
if (locale != loc_locale_tables.locale)
loc_synchronize_tables(locale);
}
@@ -250,8 +244,7 @@ static sc_bool loc_is_autodetect_enabled = TRUE;
* "dd [Mm]mm yyyy". Returns the address of the month part of the string, or
* NULL if it doesn't match the expected format.
*/
-static const sc_char *
-loc_locate_signature_in_date(const sc_char *date) {
+static const sc_char *loc_locate_signature_in_date(const sc_char *date) {
sc_int day, year, converted;
sc_char signature[SIGNATURE_LENGTH + 1];
@@ -275,8 +268,7 @@ loc_locate_signature_in_date(const sc_char *date) {
* any strcasecmp() variant because the signatures are in the locale's
* codepage, but the locale is not yet (by definition) set.
*/
-static sc_bool
-loc_compare_locale_signatures(const char *signature, const sc_locale_t *locale) {
+static sc_bool loc_compare_locale_signatures(const char *signature, const sc_locale_t *locale) {
sc_int index_;
sc_bool is_matched;
@@ -302,9 +294,8 @@ loc_compare_locale_signatures(const char *signature, const sc_locale_t *locale)
* Generator was run. Match this with locale signatures, and return the
* first locale that matches, or NULL if none match.
*/
-static const sc_locale_t *
-loc_find_matching_locale(const sc_char *date,
- const sc_locale_t *const *locales) {
+static const sc_locale_t *loc_find_matching_locale(const sc_char *date,
+ const sc_locale_t *const *locales) {
const sc_char *signature;
const sc_locale_t *matched = NULL;
@@ -333,8 +324,7 @@ loc_find_matching_locale(const sc_char *date,
* Set an autodetected value for the locale based on looking at a game's
* compilation date.
*/
-void
-loc_detect_game_locale(sc_prop_setref_t bundle) {
+void loc_detect_game_locale(sc_prop_setref_t bundle) {
assert(bundle);
/* If an explicit locale has already been set, ignore the call. */
@@ -367,13 +357,11 @@ loc_detect_game_locale(sc_prop_setref_t bundle) {
* be in ascii anyway, it's slightly safer to just use an ascii-only version
* of this function.
*/
-static sc_char
-loc_ascii_tolower(sc_char ch) {
+static sc_char loc_ascii_tolower(sc_char ch) {
return (ch >= 'A' && ch <= 'Z') ? ch - 'A' + 'a' : ch;
}
-static sc_int
-loc_ascii_strncasecmp(const sc_char *s1, const sc_char *s2, sc_int n) {
+static sc_int loc_ascii_strncasecmp(const sc_char *s1, const sc_char *s2, sc_int n) {
sc_int index_;
for (index_ = 0; index_ < n; index_++) {
@@ -396,8 +384,7 @@ loc_ascii_strncasecmp(const sc_char *s1, const sc_char *s2, sc_int n) {
* matched the name. Get the current locale, which may be the default locale
* if none yet set.
*/
-sc_bool
-loc_set_locale(const sc_char *name) {
+sc_bool loc_set_locale(const sc_char *name) {
const sc_locale_t *matched = NULL;
const sc_locale_t *const *iterator;
assert(name);
@@ -424,8 +411,7 @@ loc_set_locale(const sc_char *name) {
return matched ? TRUE : FALSE;
}
-const sc_char *
-loc_get_locale(void) {
+const sc_char *loc_get_locale(void) {
return loc_locale->name;
}
@@ -438,14 +424,11 @@ loc_get_locale(void) {
*
* Print out locale tables.
*/
-static int
-loc_debug_dump_new_line(sc_int index_, sc_int count) {
+static int loc_debug_dump_new_line(sc_int index_, sc_int count) {
return index_ < TABLE_SIZE - 1 && index_ % count == count - 1;
}
-static void
-loc_debug_dump_bool_table(const sc_char *label,
- sc_int count, const sc_bool table[]) {
+static void loc_debug_dump_bool_table(const sc_char *label, sc_int count, const sc_bool table[]) {
sc_int index_;
sc_trace("loc_locale_tables.%s = {\n ", label);
@@ -456,9 +439,7 @@ loc_debug_dump_bool_table(const sc_char *label,
sc_trace("\n}\n");
}
-static void
-loc_debug_dump_char_table(const sc_char *label,
- sc_int count, const sc_char table[]) {
+static void loc_debug_dump_char_table(const sc_char *label, sc_int count, const sc_char table[]) {
sc_int index_;
sc_trace("loc_locale_tables.%s = {\n ", label);
@@ -469,8 +450,7 @@ loc_debug_dump_char_table(const sc_char *label,
sc_trace("\n}\n");
}
-void
-loc_debug_dump(void) {
+void loc_debug_dump(void) {
sc_trace("Locale: debug dump follows...\n");
loc_check_tables_synchronized(loc_locale);
@@ -492,14 +472,12 @@ loc_debug_dump(void) {
* "Template" functions for locale variant ctype functions. Synchronize
* tables to the currently set locale, and return the value from the table.
*/
-static sc_bool
-loc_bool_template(sc_char character, const sc_bool table[]) {
+static sc_bool loc_bool_template(sc_char character, const sc_bool table[]) {
loc_check_tables_synchronized(loc_locale);
return table[(sc_byte) character];
}
-static sc_char
-loc_char_template(sc_char character, const sc_char table[]) {
+static sc_char loc_char_template(sc_char character, const sc_char table[]) {
loc_check_tables_synchronized(loc_locale);
return table[(sc_byte) character];
}
@@ -514,28 +492,23 @@ loc_char_template(sc_char character, const sc_char table[]) {
*
* Public entry points into locale variant ctype functions.
*/
-sc_bool
-sc_isspace(sc_char character) {
+sc_bool sc_isspace(sc_char character) {
return loc_bool_template(character, loc_locale_tables.isspace);
}
-sc_bool
-sc_isalpha(sc_char character) {
+sc_bool sc_isalpha(sc_char character) {
return loc_bool_template(character, loc_locale_tables.isalpha);
}
-sc_bool
-sc_isdigit(sc_char character) {
+sc_bool sc_isdigit(sc_char character) {
return loc_bool_template(character, loc_locale_tables.isdigit);
}
-sc_char
-sc_toupper(sc_char character) {
+sc_char sc_toupper(sc_char character) {
return loc_char_template(character, loc_locale_tables.toupper);
}
-sc_char
-sc_tolower(sc_char character) {
+sc_char sc_tolower(sc_char character) {
return loc_char_template(character, loc_locale_tables.tolower);
}
diff --git a/engines/glk/adrift/scmemos.cpp b/engines/glk/adrift/scmemos.cpp
index 9179783..88720f2 100644
--- a/engines/glk/adrift/scmemos.cpp
+++ b/engines/glk/adrift/scmemos.cpp
@@ -34,25 +34,27 @@ enum { MEMO_ALLOCATION_BLOCK = 32 };
* Game memo structure, saves a serialized game. Allocation is preserved so
* that structures can be reused without requiring reallocation.
*/
-typedef struct sc_memo_s {
+struct sc_memo_s {
sc_byte *serialized_game;
sc_int allocation;
sc_int length;
-} sc_memo_t;
+};
+typedef sc_memo_s sc_memo_t;
typedef sc_memo_t *sc_memoref_t;
/*
* Game command history structure, similar to a memo. Saves a player input
* command to create a history, reusing allocation where possible.
*/
-typedef struct sc_history_s {
+struct sc_history_s {
sc_char *command;
sc_int sequence;
sc_int timestamp;
sc_int turns;
sc_int allocation;
sc_int length;
-} sc_history_t;
+};
+typedef sc_history_s sc_history_t;
typedef sc_history_t *sc_historyref_t;
/*
@@ -64,7 +66,7 @@ typedef sc_history_t *sc_historyref_t;
* also a ring with limited capacity.
*/
enum { MEMO_UNDO_TABLE_SIZE = 16, MEMO_HISTORY_TABLE_SIZE = 64 };
-typedef struct sc_memo_set_s {
+struct sc_memo_set_s {
sc_uint magic;
sc_memo_t memo[MEMO_UNDO_TABLE_SIZE];
sc_int memo_cursor;
@@ -73,7 +75,8 @@ typedef struct sc_memo_set_s {
sc_int history_count;
sc_int current_history;
sc_bool is_at_start;
-} sc_memo_set_t;
+};
+typedef sc_memo_set_s sc_memo_set_t;
/*
@@ -81,8 +84,7 @@ typedef struct sc_memo_set_s {
*
* Return TRUE if pointer is a valid memo set, FALSE otherwise.
*/
-static sc_bool
-memo_is_valid(sc_memo_setref_t memento) {
+static sc_bool memo_is_valid(sc_memo_setref_t memento) {
return memento && memento->magic == MEMENTO_MAGIC;
}
@@ -92,8 +94,7 @@ memo_is_valid(sc_memo_setref_t memento) {
*
* Round up an allocation in bytes to the next allocation block.
*/
-static sc_int
-memo_round_up(sc_int allocation) {
+static sc_int memo_round_up(sc_int allocation) {
sc_int extended;
extended = allocation + MEMO_ALLOCATION_BLOCK - 1;
@@ -106,8 +107,7 @@ memo_round_up(sc_int allocation) {
*
* Create and return a new set of memos.
*/
-sc_memo_setref_t
-memo_create(void) {
+sc_memo_setref_t memo_create(void) {
sc_memo_setref_t memento;
/* Create and initialize a clean set of memos. */
@@ -131,8 +131,7 @@ memo_create(void) {
*
* Destroy a memo set, and free its heap memory.
*/
-void
-memo_destroy(sc_memo_setref_t memento) {
+void memo_destroy(sc_memo_setref_t memento) {
sc_int index_;
assert(memo_is_valid(memento));
@@ -162,8 +161,7 @@ memo_destroy(sc_memo_setref_t memento) {
* Callback function for game serialization. Appends the data passed in to
* that already stored in the memo.
*/
-static void
-memo_save_game_callback(void *opaque, const sc_byte *buffer, sc_int length) {
+static void memo_save_game_callback(void *opaque, const sc_byte *buffer, sc_int length) {
sc_memoref_t memo = (sc_memoref_t)opaque;
sc_int required;
assert(opaque && buffer && length > 0);
@@ -191,8 +189,7 @@ memo_save_game_callback(void *opaque, const sc_byte *buffer, sc_int length) {
*
* Store a game in the next memo slot.
*/
-void
-memo_save_game(sc_memo_setref_t memento, sc_gameref_t game) {
+void memo_save_game(sc_memo_setref_t memento, sc_gameref_t game) {
sc_memoref_t memo;
assert(memo_is_valid(memento));
@@ -224,8 +221,7 @@ memo_save_game(sc_memo_setref_t memento, sc_gameref_t game) {
* Callback function for game deserialization. Returns data from the memo
* until it's drained.
*/
-static sc_int
-memo_load_game_callback(void *opaque, sc_byte *buffer, sc_int length) {
+static sc_int memo_load_game_callback(void *opaque, sc_byte *buffer, sc_int length) {
sc_memoref_t memo = (sc_memoref_t)opaque;
sc_int bytes;
assert(opaque && buffer && length > 0);
@@ -249,8 +245,7 @@ memo_load_game_callback(void *opaque, sc_byte *buffer, sc_int length) {
*
* Restore a game from the last memo slot used, if possible.
*/
-sc_bool
-memo_load_game(sc_memo_setref_t memento, sc_gameref_t game) {
+sc_bool memo_load_game(sc_memo_setref_t memento, sc_gameref_t game) {
sc_int cursor;
sc_memoref_t memo;
assert(memo_is_valid(memento));
@@ -298,8 +293,7 @@ memo_load_game(sc_memo_setref_t memento, sc_gameref_t game) {
* Returns TRUE if a memo restore is likely to succeed if called, FALSE
* otherwise.
*/
-sc_bool
-memo_is_load_available(sc_memo_setref_t memento) {
+sc_bool memo_is_load_available(sc_memo_setref_t memento) {
sc_int cursor;
sc_memoref_t memo;
assert(memo_is_valid(memento));
@@ -320,8 +314,7 @@ memo_is_load_available(sc_memo_setref_t memento) {
*
* Forget the memos of saved games.
*/
-void
-memo_clear_games(sc_memo_setref_t memento) {
+void memo_clear_games(sc_memo_setref_t memento) {
sc_int index_;
assert(memo_is_valid(memento));
@@ -345,9 +338,7 @@ memo_clear_games(sc_memo_setref_t memento) {
* Store a player command in the command history, evicting any least recently
* used item if necessary.
*/
-void
-memo_save_command(sc_memo_setref_t memento,
- const sc_char *command, sc_int timestamp, sc_int turns) {
+void memo_save_command(sc_memo_setref_t memento, const sc_char *command, sc_int timestamp, sc_int turns) {
sc_historyref_t history;
sc_int length;
assert(memo_is_valid(memento));
@@ -390,8 +381,7 @@ memo_save_command(sc_memo_setref_t memento,
* to "invent" a history item at the end of the list before listing, then
* remove it again as the main runner loop will add the real thing.
*/
-void
-memo_unsave_command(sc_memo_setref_t memento) {
+void memo_unsave_command(sc_memo_setref_t memento) {
assert(memo_is_valid(memento));
/* Do nothing if for some reason there's no history to unsave. */
@@ -415,8 +405,7 @@ memo_unsave_command(sc_memo_setref_t memento) {
*
* Return a count of available saved commands.
*/
-sc_int
-memo_get_command_count(sc_memo_setref_t memento) {
+sc_int memo_get_command_count(sc_memo_setref_t memento) {
assert(memo_is_valid(memento));
/* Return the lesser of the history count and the history table size. */
@@ -432,8 +421,7 @@ memo_get_command_count(sc_memo_setref_t memento) {
*
* Iterator rewind function, reset current location to the first command.
*/
-void
-memo_first_command(sc_memo_setref_t memento) {
+void memo_first_command(sc_memo_setref_t memento) {
sc_int cursor;
sc_historyref_t history;
assert(memo_is_valid(memento));
@@ -458,10 +446,8 @@ memo_first_command(sc_memo_setref_t memento) {
* Iterator function, return the next saved command and its sequence id
* starting at 1, and the timestamp and turns when the command was saved.
*/
-void
-memo_next_command(sc_memo_setref_t memento,
- const sc_char **command, sc_int *sequence,
- sc_int *timestamp, sc_int *turns) {
+void memo_next_command(sc_memo_setref_t memento, const sc_char **command,
+ sc_int *sequence, sc_int *timestamp, sc_int *turns) {
assert(memo_is_valid(memento));
/* If valid, return the current command and advance. */
@@ -494,8 +480,7 @@ memo_next_command(sc_memo_setref_t memento,
*
* Iterator end function, returns TRUE if more commands are readable.
*/
-sc_bool
-memo_more_commands(sc_memo_setref_t memento) {
+sc_bool memo_more_commands(sc_memo_setref_t memento) {
sc_int cursor;
sc_historyref_t history;
assert(memo_is_valid(memento));
@@ -522,8 +507,7 @@ memo_more_commands(sc_memo_setref_t memento) {
* Find and return the command string for the given sequence number (-ve
* indicates an offset from the last defined), or NULL if not found.
*/
-const sc_char *
-memo_find_command(sc_memo_setref_t memento, sc_int sequence) {
+const sc_char *memo_find_command(sc_memo_setref_t memento, sc_int sequence) {
sc_int target, index_;
sc_historyref_t matched;
assert(memo_is_valid(memento));
@@ -561,8 +545,7 @@ memo_find_command(sc_memo_setref_t memento, sc_int sequence) {
*
* Forget all saved commands.
*/
-void
-memo_clear_commands(sc_memo_setref_t memento) {
+void memo_clear_commands(sc_memo_setref_t memento) {
sc_int index_;
assert(memo_is_valid(memento));
diff --git a/engines/glk/adrift/scnpcs.cpp b/engines/glk/adrift/scnpcs.cpp
index b9b60d5..d3567f6 100644
--- a/engines/glk/adrift/scnpcs.cpp
+++ b/engines/glk/adrift/scnpcs.cpp
@@ -36,8 +36,7 @@ static sc_bool npc_trace = FALSE;
*
* Return TRUE if a given NPC is currently in a given room.
*/
-sc_bool
-npc_in_room(sc_gameref_t game, sc_int npc, sc_int room) {
+sc_bool npc_in_room(sc_gameref_t game, sc_int npc, sc_int room) {
if (npc_trace) {
sc_trace("NPC: checking NPC %ld in room %ld (NPC is in %ld)\n",
npc, room, gs_npc_location(game, npc));
@@ -52,8 +51,7 @@ npc_in_room(sc_gameref_t game, sc_int npc, sc_int room) {
*
* Return the count of characters in the room, including the player.
*/
-sc_int
-npc_count_in_room(sc_gameref_t game, sc_int room) {
+sc_int npc_count_in_room(sc_gameref_t game, sc_int room) {
sc_int count, npc;
/* Start with the player. */
@@ -73,8 +71,7 @@ npc_count_in_room(sc_gameref_t game, sc_int room) {
*
* Start the given walk for the given NPC.
*/
-void
-npc_start_npc_walk(sc_gameref_t game, sc_int npc, sc_int walk) {
+void npc_start_npc_walk(sc_gameref_t game, sc_int npc, sc_int walk) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[6];
sc_int movetime;
@@ -99,8 +96,7 @@ npc_start_npc_walk(sc_gameref_t game, sc_int npc, sc_int walk) {
*
* Set initial values for NPC states, and update on turns.
*/
-void
-npc_turn_update(sc_gameref_t game) {
+void npc_turn_update(sc_gameref_t game) {
sc_int index_;
/* Set current values for NPC seen states. */
@@ -111,8 +107,7 @@ npc_turn_update(sc_gameref_t game) {
}
}
-void
-npc_setup_initial(sc_gameref_t game) {
+void npc_setup_initial(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int index_;
@@ -149,8 +144,7 @@ npc_setup_initial(sc_gameref_t game) {
*
* Return TRUE if a given room is in a given group.
*/
-static sc_bool
-npc_room_in_roomgroup(sc_gameref_t game, sc_int room, sc_int group) {
+static sc_bool npc_room_in_roomgroup(sc_gameref_t game, sc_int room, sc_int group) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
sc_int member;
@@ -183,9 +177,7 @@ static const sc_char *const DIRNAMES_8[] = {
*
* Return a random member of group adjacent to given room.
*/
-static sc_int
-npc_random_adjacent_roomgroup_member(sc_gameref_t game,
- sc_int room, sc_int group) {
+static sc_int npc_random_adjacent_roomgroup_member(sc_gameref_t game, sc_int room, sc_int group) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_bool eightpointcompass;
@@ -232,9 +224,7 @@ npc_random_adjacent_roomgroup_member(sc_gameref_t game,
*
* Helper for npc_tick_npc().
*/
-static void
-npc_announce(sc_gameref_t game, sc_int npc,
- sc_int room, sc_bool is_exit, sc_int npc_room) {
+static void npc_announce(sc_gameref_t game, sc_int npc, sc_int room, sc_bool is_exit, sc_int npc_room) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5], vt_rvalue;
@@ -312,8 +302,7 @@ npc_announce(sc_gameref_t game, sc_int npc,
*
* Helper for npc_tick_npc().
*/
-static void
-npc_tick_npc_walk(sc_gameref_t game, sc_int npc, sc_int walk) {
+static void npc_tick_npc_walk(sc_gameref_t game, sc_int npc, sc_int walk) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[6];
sc_int roomgroups, movetimes, walkstep, start, dest, destnum;
@@ -428,8 +417,7 @@ npc_tick_npc_walk(sc_gameref_t game, sc_int npc, sc_int walk) {
*
* Move an NPC one step along current walk.
*/
-static void
-npc_tick_npc(sc_gameref_t game, sc_int npc) {
+static void npc_tick_npc(sc_gameref_t game, sc_int npc) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[6];
sc_int walk;
@@ -522,8 +510,7 @@ npc_tick_npc(sc_gameref_t game, sc_int npc) {
*
* Move each NPC one step along current walk.
*/
-void
-npc_tick_npcs(sc_gameref_t game) {
+void npc_tick_npcs(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_gameref_t undo = game->undo;
sc_int npc;
@@ -587,8 +574,7 @@ npc_tick_npcs(sc_gameref_t game) {
*
* Set NPC tracing on/off.
*/
-void
-npc_debug_trace(sc_bool flag) {
+void npc_debug_trace(sc_bool flag) {
npc_trace = flag;
}
diff --git a/engines/glk/adrift/scobjcts.cpp b/engines/glk/adrift/scobjcts.cpp
index 28a89ab..50abfa1 100644
--- a/engines/glk/adrift/scobjcts.cpp
+++ b/engines/glk/adrift/scobjcts.cpp
@@ -41,8 +41,7 @@ static sc_bool obj_trace = FALSE;
*
* Convenience functions to return TRUE for given object attributes.
*/
-sc_bool
-obj_is_static(sc_gameref_t game, sc_int object) {
+sc_bool obj_is_static(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_bool bstatic;
@@ -54,8 +53,7 @@ obj_is_static(sc_gameref_t game, sc_int object) {
return bstatic;
}
-sc_bool
-obj_is_container(sc_gameref_t game, sc_int object) {
+sc_bool obj_is_container(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_bool is_container;
@@ -67,8 +65,7 @@ obj_is_container(sc_gameref_t game, sc_int object) {
return is_container;
}
-sc_bool
-obj_is_surface(sc_gameref_t game, sc_int object) {
+sc_bool obj_is_surface(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_bool is_surface;
@@ -86,8 +83,7 @@ obj_is_surface(sc_gameref_t game, sc_int object) {
*
* Return the index of the n'th container object found.
*/
-sc_int
-obj_container_object(sc_gameref_t game, sc_int n) {
+sc_int obj_container_object(sc_gameref_t game, sc_int n) {
sc_int object, count;
/* Progress through objects until n containers found. */
@@ -105,8 +101,7 @@ obj_container_object(sc_gameref_t game, sc_int n) {
*
* Return index such that obj_container_object(index) == objnum.
*/
-sc_int
-obj_container_index(sc_gameref_t game, sc_int objnum) {
+sc_int obj_container_index(sc_gameref_t game, sc_int objnum) {
sc_int object, count;
/* Progress through objects up to objnum. */
@@ -124,8 +119,7 @@ obj_container_index(sc_gameref_t game, sc_int objnum) {
*
* Return the index of the n'th surface object found.
*/
-sc_int
-obj_surface_object(sc_gameref_t game, sc_int n) {
+sc_int obj_surface_object(sc_gameref_t game, sc_int n) {
sc_int object, count;
/* Progress through objects until n surfaces found. */
@@ -143,8 +137,7 @@ obj_surface_object(sc_gameref_t game, sc_int n) {
*
* Return index such that obj_surface_object(index) == objnum.
*/
-sc_int
-obj_surface_index(sc_gameref_t game, sc_int objnum) {
+sc_int obj_surface_index(sc_gameref_t game, sc_int objnum) {
sc_int object, count;
/* Progress through objects up to objnum. */
@@ -162,8 +155,7 @@ obj_surface_index(sc_gameref_t game, sc_int objnum) {
*
* Return the index of the n'th openable or statussed object found.
*/
-sc_int
-obj_stateful_object(sc_gameref_t game, sc_int n) {
+sc_int obj_stateful_object(sc_gameref_t game, sc_int n) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, count;
@@ -191,8 +183,7 @@ obj_stateful_object(sc_gameref_t game, sc_int n) {
*
* Return index such that obj_stateful_object(index) == objnum.
*/
-sc_int
-obj_stateful_index(sc_gameref_t game, sc_int objnum) {
+sc_int obj_stateful_index(sc_gameref_t game, sc_int objnum) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, count;
@@ -222,8 +213,7 @@ obj_stateful_index(sc_gameref_t game, sc_int objnum) {
* string is malloc'ed, and needs to be freed by the caller. Returns NULL
* if no valid state string found.
*/
-sc_char *
-obj_state_name(sc_gameref_t game, sc_int objnum) {
+sc_char *obj_state_name(sc_gameref_t game, sc_int objnum) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
const sc_char *states;
@@ -266,8 +256,7 @@ obj_state_name(sc_gameref_t game, sc_int objnum) {
*
* Return the index of the n'th non-static object found.
*/
-sc_int
-obj_dynamic_object(sc_gameref_t game, sc_int n) {
+sc_int obj_dynamic_object(sc_gameref_t game, sc_int n) {
sc_int object, count;
/* Progress through objects until n matches found. */
@@ -285,8 +274,7 @@ obj_dynamic_object(sc_gameref_t game, sc_int n) {
*
* Return the index of the n'th wearable object found.
*/
-sc_int
-obj_wearable_object(sc_gameref_t game, sc_int n) {
+sc_int obj_wearable_object(sc_gameref_t game, sc_int n) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, count;
@@ -329,8 +317,7 @@ enum {
* TODO It's possible to have static objects in the player inventory, moved
* by events -- how should these be handled, as they have no SizeWeight?
*/
-sc_int
-obj_get_size(sc_gameref_t game, sc_int object) {
+sc_int obj_get_size(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int size, count;
@@ -362,8 +349,7 @@ obj_get_size(sc_gameref_t game, sc_int object) {
return size;
}
-sc_int
-obj_get_weight(sc_gameref_t game, sc_int object) {
+sc_int obj_get_weight(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int weight, count;
@@ -413,8 +399,7 @@ obj_get_weight(sc_gameref_t game, sc_int object) {
* Return the limits set on the sizes and weights a player can handle. Not
* really object-related except that they deal with sizing multiples.
*/
-static sc_int
-obj_convert_player_limit(sc_int value) {
+static sc_int obj_convert_player_limit(sc_int value) {
sc_int retval, index_;
/* 'Tens' of value multiplied by 3 to the power 'units' of value. */
@@ -425,8 +410,7 @@ obj_convert_player_limit(sc_int value) {
return retval;
}
-sc_int
-obj_get_player_size_limit(sc_gameref_t game) {
+sc_int obj_get_player_size_limit(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
sc_int max_size;
@@ -438,8 +422,7 @@ obj_get_player_size_limit(sc_gameref_t game) {
return obj_convert_player_limit(max_size);
}
-sc_int
-obj_get_player_weight_limit(sc_gameref_t game) {
+sc_int obj_get_player_weight_limit(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
sc_int max_weight;
@@ -459,8 +442,7 @@ obj_get_player_weight_limit(sc_gameref_t game) {
* Return the maximum size of an object that can be placed in a container,
* and the number that will fit.
*/
-sc_int
-obj_get_container_maxsize(sc_gameref_t game, sc_int object) {
+sc_int obj_get_container_maxsize(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int maxsize, count;
@@ -482,8 +464,7 @@ obj_get_container_maxsize(sc_gameref_t game, sc_int object) {
return maxsize;
}
-sc_int
-obj_get_container_capacity(sc_gameref_t game, sc_int object) {
+sc_int obj_get_container_capacity(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int capacity;
@@ -513,8 +494,7 @@ enum {
*
* Return the index of the n'th standable object found.
*/
-sc_int
-obj_standable_object(sc_gameref_t game, sc_int n) {
+sc_int obj_standable_object(sc_gameref_t game, sc_int n) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, count;
@@ -540,8 +520,7 @@ obj_standable_object(sc_gameref_t game, sc_int n) {
*
* Return the index of the n'th lieable object found.
*/
-sc_int
-obj_lieable_object(sc_gameref_t game, sc_int n) {
+sc_int obj_lieable_object(sc_gameref_t game, sc_int n) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int object, count;
@@ -571,8 +550,7 @@ obj_lieable_object(sc_gameref_t game, sc_int n) {
* or ""; plural if prefix is "the" or "some" and short name ends with 's'
* that is not preceded by 'u'.
*/
-sc_bool
-obj_appears_plural(sc_gameref_t game, sc_int object) {
+sc_bool obj_appears_plural(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
const sc_char *prefix, *name;
@@ -610,8 +588,7 @@ obj_appears_plural(sc_gameref_t game, sc_int object) {
*
* Return TRUE if a given object is currently on the floor of a given room.
*/
-static sc_bool
-obj_directly_in_room_internal(sc_gameref_t game, sc_int object, sc_int room) {
+static sc_bool obj_directly_in_room_internal(sc_gameref_t game, sc_int object, sc_int room) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
/* See if the object is static or dynamic. */
@@ -658,8 +635,7 @@ obj_directly_in_room_internal(sc_gameref_t game, sc_int object, sc_int room) {
return gs_object_position(game, object) == room + 1;
}
-sc_bool
-obj_directly_in_room(sc_gameref_t game, sc_int object, sc_int room) {
+sc_bool obj_directly_in_room(sc_gameref_t game, sc_int object, sc_int room) {
sc_bool result;
/* Check, trace result, and return. */
@@ -682,8 +658,7 @@ obj_directly_in_room(sc_gameref_t game, sc_int object, sc_int room) {
* directly, on an object indirectly, in an open object indirectly, or
* carried by an NPC in the room.
*/
-static sc_bool
-obj_indirectly_in_room_internal(sc_gameref_t game, sc_int object, sc_int room) {
+static sc_bool obj_indirectly_in_room_internal(sc_gameref_t game, sc_int object, sc_int room) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
/* See if the object is static or dynamic. */
@@ -782,9 +757,7 @@ obj_indirectly_in_room_internal(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 obj_indirectly_in_room(sc_gameref_t game, sc_int object, sc_int room) {
sc_bool result;
/* Check, trace result, and return. */
@@ -806,9 +779,7 @@ obj_indirectly_in_room(sc_gameref_t game,
* Return TRUE if a given object is currently held by the player, either
* directly, on an object indirectly, or in an open object indirectly.
*/
-static sc_bool
-obj_indirectly_held_by_player_internal(sc_gameref_t game,
- sc_int object) {
+static sc_bool obj_indirectly_held_by_player_internal(sc_gameref_t game, sc_int object) {
/* See if the object is static or dynamic. */
if (obj_is_static(game, object)) {
/* Static object moved to player or room by event? */
@@ -863,8 +834,7 @@ obj_indirectly_held_by_player_internal(sc_gameref_t game,
}
}
-sc_bool
-obj_indirectly_held_by_player(sc_gameref_t game, sc_int object) {
+sc_bool obj_indirectly_held_by_player(sc_gameref_t game, sc_int object) {
sc_bool result;
/* Check, trace result, and return. */
@@ -884,8 +854,7 @@ obj_indirectly_held_by_player(sc_gameref_t game, sc_int object) {
*
* Return TRUE if this object should be listed as room content.
*/
-sc_bool
-obj_shows_initial_description(sc_gameref_t game, sc_int object) {
+sc_bool obj_shows_initial_description(sc_gameref_t game, sc_int object) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int onlywhennotmoved;
@@ -927,8 +896,7 @@ obj_shows_initial_description(sc_gameref_t game, sc_int object) {
*
* Set initial values for object states, and update after a turn.
*/
-void
-obj_turn_update(sc_gameref_t game) {
+void obj_turn_update(sc_gameref_t game) {
sc_int index_;
/* Update object seen flag to current state. */
@@ -939,8 +907,7 @@ obj_turn_update(sc_gameref_t game) {
}
}
-void
-obj_setup_initial(sc_gameref_t game) {
+void obj_setup_initial(sc_gameref_t game) {
/* Set initial seen states for objects. */
obj_turn_update(game);
}
@@ -951,8 +918,7 @@ obj_setup_initial(sc_gameref_t game) {
*
* Set object tracing on/off.
*/
-void
-obj_debug_trace(sc_bool flag) {
+void obj_debug_trace(sc_bool flag) {
obj_trace = flag;
}
diff --git a/engines/glk/adrift/scparser.cpp b/engines/glk/adrift/scparser.cpp
index 9372b5e..7b49693 100644
--- a/engines/glk/adrift/scparser.cpp
+++ b/engines/glk/adrift/scparser.cpp
@@ -48,24 +48,24 @@ static const sc_char *const WHITESPACE = "\t\n\v\f\r ";
static sc_bool uip_trace = FALSE;
/* Enumeration of tokens. TOK_NONE represents a non-occurring token. */
-typedef enum {
+enum sc_uip_tok_t {
TOK_NONE = 0,
TOK_CHOICE, TOK_CHOICE_END, TOK_OPTIONAL, TOK_OPTIONAL_END,
TOK_ALTERNATES_SEPARATOR,
TOK_WILDCARD, TOK_WHITESPACE, TOK_WORD, TOK_VARIABLE,
TOK_CHARACTER_REFERENCE, TOK_OBJECT_REFERENCE, TOK_NUMBER_REFERENCE,
TOK_TEXT_REFERENCE, TOK_EOS
-} sc_uip_tok_t;
+};
/*
* Small table tying token strings to tokens. Anything not whitespace and
* not caught by the table is a plain TOK_WORD.
*/
-typedef struct {
+struct sc_uip_token_entry_t {
const sc_char *const name;
const sc_int length;
const sc_uip_tok_t token;
-} sc_uip_token_entry_t;
+};
static const sc_uip_token_entry_t UIP_TOKENS[] = {
{"[", 1, TOK_CHOICE}, {"]", 1, TOK_CHOICE_END},
@@ -98,8 +98,7 @@ static sc_char *uip_temporary = NULL;
*
* Start and wrap up pattern string tokenization.
*/
-static void
-uip_tokenize_start(const sc_char *pattern) {
+static void uip_tokenize_start(const sc_char *pattern) {
static sc_bool initialized = FALSE;
sc_int required;
@@ -129,8 +128,7 @@ uip_tokenize_start(const sc_char *pattern) {
? (sc_char *)sc_malloc(required) : uip_static_temporary;
}
-static void
-uip_tokenize_end(void) {
+static void uip_tokenize_end(void) {
/* Deallocate temporary if required, and clear pattern and index. */
if (uip_temporary != uip_static_temporary)
sc_free(uip_temporary);
@@ -145,8 +143,7 @@ uip_tokenize_end(void) {
*
* Return the next token from the current pattern.
*/
-static sc_uip_tok_t
-uip_next_token(void) {
+static sc_uip_tok_t uip_next_token(void) {
const sc_uip_token_entry_t *entry;
sc_char close;
assert(uip_pattern);
@@ -211,8 +208,7 @@ uip_next_token(void) {
* Return the token value of the current token. It is an error to call
* here if the current token is not a TOK_WORD or TOK_VARIABLE.
*/
-static const sc_char *
-uip_current_token_value(void) {
+static const sc_char *uip_current_token_value(void) {
/* If the token value is NULL, the current token isn't a word. */
if (!uip_token_value) {
sc_fatal("uip_current_token_value:"
@@ -230,20 +226,21 @@ uip_current_token_value(void) {
* NODE_UNUSED must be zero to ensure that the statically allocated array that
* forms the node pool appears initially as containing only unused nodes.
*/
-typedef enum {
+enum sc_pttype_t {
NODE_UNUSED = 0,
NODE_CHOICE, NODE_OPTIONAL, NODE_WILDCARD, NODE_WHITESPACE,
NODE_CHARACTER_REFERENCE, NODE_OBJECT_REFERENCE, NODE_TEXT_REFERENCE,
NODE_NUMBER_REFERENCE, NODE_WORD, NODE_VARIABLE, NODE_LIST, NODE_EOS
-} sc_pttype_t;
-typedef struct sc_ptnode_s {
+};
+struct sc_ptnode_s {
struct sc_ptnode_s *left_child;
struct sc_ptnode_s *right_sibling;
sc_pttype_t type;
sc_char *word;
sc_bool is_allocated;
-} sc_ptnode_t;
+};
+typedef sc_ptnode_s sc_ptnode_t;
typedef sc_ptnode_t *sc_ptnoderef_t;
/* Predictive parser lookahead token. */
@@ -273,10 +270,10 @@ static sc_int uip_node_pool_available = UIP_NODE_POOL_SIZE;
* first, then by straight malloc() should the pool empty.
*/
enum { UIP_WORD_POOL_SIZE = 64, UIP_SHORT_WORD_SIZE = 16 };
-typedef struct {
+struct sc_ptshortword_t {
sc_bool is_in_use;
sc_char word[UIP_SHORT_WORD_SIZE];
-} sc_ptshortword_t;
+};
typedef sc_ptshortword_t *sc_ptshortwordref_t;
static sc_ptshortword_t uip_word_pool[UIP_WORD_POOL_SIZE];
static sc_int uip_word_pool_cursor = 0;
@@ -287,8 +284,7 @@ static sc_int uip_word_pool_available = UIP_WORD_POOL_SIZE;
*
* Match a token to the lookahead, then advance lookahead.
*/
-static void
-uip_parse_match(sc_uip_tok_t token) {
+static void uip_parse_match(sc_uip_tok_t token) {
if (uip_parse_lookahead == token)
uip_parse_lookahead = uip_next_token();
else {
@@ -307,8 +303,7 @@ uip_parse_match(sc_uip_tok_t token) {
* allocate initially from static storage, for performance. If this is
* exhausted, backs off to standard allocation.
*/
-static sc_char *
-uip_new_word(const sc_char *word) {
+static sc_char *uip_new_word(const sc_char *word) {
sc_int required;
/*
@@ -357,8 +352,7 @@ uip_new_word(const sc_char *word) {
* If the word was allocated, free its memory; if not, find its short word
* pool entry and return it to the pool.
*/
-static void
-uip_free_word(sc_char *word) {
+static void uip_free_word(sc_char *word) {
const sc_char *first_in_pool, *last_in_pool;
/* Obtain the range of valid addresses for words from the word pool. */
@@ -392,8 +386,7 @@ uip_free_word(sc_char *word) {
* to allocate initially from static storage, for performance. If this is
* exhausted, backs off to standard allocation.
*/
-static sc_ptnoderef_t
-uip_new_node(sc_pttype_t type) {
+static sc_ptnoderef_t uip_new_node(sc_pttype_t type) {
sc_ptnoderef_t node;
/*
@@ -441,8 +434,7 @@ uip_new_node(sc_pttype_t type) {
* Destroy a node, and any allocated word memory. If the node was allocated,
* free its memory; if not, return it to the pool.
*/
-static void
-uip_destroy_node(sc_ptnoderef_t node) {
+static void uip_destroy_node(sc_ptnoderef_t node) {
/* Free any word contained at this node. */
if (node->word)
uip_free_word(node->word);
@@ -469,8 +461,7 @@ uip_destroy_node(sc_ptnoderef_t node) {
* Parse a set of .../.../... alternatives for choices and optionals. The
* first function is a helper, returning a newly constructed parsed list.
*/
-static sc_ptnoderef_t
-uip_parse_new_list(void) {
+static sc_ptnoderef_t uip_parse_new_list(void) {
sc_ptnoderef_t list;
/* Create a new list node, parse into it, and return it. */
@@ -479,8 +470,7 @@ uip_parse_new_list(void) {
return list;
}
-static void
-uip_parse_alternatives(sc_ptnoderef_t node) {
+static void uip_parse_alternatives(sc_ptnoderef_t node) {
sc_ptnoderef_t child;
/* Parse initial alternative, then add other listed alternatives. */
@@ -499,8 +489,7 @@ uip_parse_alternatives(sc_ptnoderef_t node) {
*
* Parse a single pattern element.
*/
-static sc_ptnoderef_t
-uip_parse_element(void) {
+static sc_ptnoderef_t uip_parse_element(void) {
sc_ptnoderef_t node = NULL;
sc_uip_tok_t token;
@@ -604,8 +593,7 @@ uip_parse_element(void) {
*
* Parse a list of pattern elements.
*/
-static void
-uip_parse_list(sc_ptnoderef_t list) {
+static void uip_parse_list(sc_ptnoderef_t list) {
sc_ptnoderef_t child, node;
/* Add elements until a list terminator token is encountered. */
@@ -663,8 +651,7 @@ uip_parse_list(sc_ptnoderef_t list) {
*
* Free and destroy a parsed pattern tree.
*/
-static void
-uip_destroy_tree(sc_ptnoderef_t node) {
+static void uip_destroy_tree(sc_ptnoderef_t node) {
if (node) {
/* Recursively destroy siblings, then left child. */
uip_destroy_tree(node->right_sibling);
@@ -682,8 +669,7 @@ uip_destroy_tree(sc_ptnoderef_t node) {
*
* Print out a pattern match tree.
*/
-static void
-uip_debug_dump_node(sc_ptnoderef_t node, sc_int depth) {
+static void uip_debug_dump_node(sc_ptnoderef_t node, sc_int depth) {
/* End recursion on null node. */
if (node) {
sc_int index_;
@@ -746,8 +732,7 @@ uip_debug_dump_node(sc_ptnoderef_t node, sc_int depth) {
}
}
-static void
-uip_debug_dump(void) {
+static void uip_debug_dump(void) {
sc_trace("UIParser: debug dump follows...\n");
if (uip_parse_tree) {
sc_trace("uip_parse_tree = {\n");
@@ -769,8 +754,7 @@ static sc_gameref_t uip_game = NULL;
*
* Set up a string for matching to a pattern tree, and wrap up matching.
*/
-static void
-uip_match_start(const sc_char *string, sc_gameref_t game) {
+static void uip_match_start(const sc_char *string, sc_gameref_t game) {
/* Save string, and restart index. */
uip_string = string;
uip_posn = 0;
@@ -779,8 +763,7 @@ uip_match_start(const sc_char *string, sc_gameref_t game) {
uip_game = game;
}
-static void
-uip_match_end(void) {
+static void uip_match_end(void) {
/* Clear match target string, and variable set. */
uip_string = NULL;
uip_posn = 0;
@@ -794,8 +777,7 @@ uip_match_end(void) {
* Safety wrapper to ensure module code sees a valid game when it requires
* one.
*/
-static sc_gameref_t
-uip_get_game(void) {
+static sc_gameref_t uip_get_game(void) {
assert(gs_is_game_valid(uip_game));
return uip_game;
}
@@ -819,14 +801,12 @@ static sc_bool uip_match_node(sc_ptnoderef_t node);
* advance position if necessary, on match, FALSE on no match, with position
* unchanged.
*/
-static sc_bool
-uip_match_eos(void) {
+static sc_bool uip_match_eos(void) {
/* Check that we hit the string's end. */
return uip_string[uip_posn] == NUL;
}
-static sc_bool
-uip_match_word(sc_ptnoderef_t node) {
+static sc_bool uip_match_word(sc_ptnoderef_t node) {
sc_int length;
const sc_char *word;
@@ -846,8 +826,7 @@ uip_match_word(sc_ptnoderef_t node) {
return FALSE;
}
-static sc_bool
-uip_match_variable(sc_ptnoderef_t node) {
+static sc_bool uip_match_variable(sc_ptnoderef_t node) {
const sc_gameref_t game = uip_get_game();
const sc_var_setref_t vars = gs_get_vars(game);
sc_int type;
@@ -898,8 +877,7 @@ uip_match_variable(sc_ptnoderef_t node) {
return FALSE;
}
-static sc_bool
-uip_match_whitespace(void) {
+static sc_bool uip_match_whitespace(void) {
/* If next character is space, read whitespace and return. */
if (sc_isspace(uip_string[uip_posn])) {
/* Space match, advance position and return. */
@@ -934,8 +912,7 @@ uip_match_whitespace(void) {
return FALSE;
}
-static sc_bool
-uip_match_list(sc_ptnoderef_t node) {
+static sc_bool uip_match_list(sc_ptnoderef_t node) {
sc_ptnoderef_t child;
/*
@@ -958,8 +935,7 @@ uip_match_list(sc_ptnoderef_t node) {
return TRUE;
}
-static sc_bool
-uip_match_alternatives(sc_ptnoderef_t node) {
+static sc_bool uip_match_alternatives(sc_ptnoderef_t node) {
sc_ptnoderef_t child;
sc_int start_posn, extent;
sc_bool matched;
@@ -990,8 +966,7 @@ uip_match_alternatives(sc_ptnoderef_t node) {
return matched;
}
-static sc_bool
-uip_match_choice(sc_ptnoderef_t node) {
+static sc_bool uip_match_choice(sc_ptnoderef_t node) {
/*
* Return the result of matching alternatives. The choice will therefore
* fail if none of the alternatives match.
@@ -999,8 +974,7 @@ uip_match_choice(sc_ptnoderef_t node) {
return uip_match_alternatives(node);
}
-static sc_bool
-uip_match_optional(sc_ptnoderef_t node) {
+static sc_bool uip_match_optional(sc_ptnoderef_t node) {
sc_int start_posn;
sc_ptnoderef_t list;
sc_bool matched;
@@ -1036,8 +1010,7 @@ uip_match_optional(sc_ptnoderef_t node) {
return TRUE;
}
-static sc_bool
-uip_match_wildcard(sc_ptnoderef_t node) {
+static sc_bool uip_match_wildcard(sc_ptnoderef_t node) {
sc_int start_posn, limit, index_;
sc_bool matched;
sc_ptnoderef_t list;
@@ -1099,8 +1072,7 @@ uip_match_wildcard(sc_ptnoderef_t node) {
*
* Attempt to match a number, or a word, from the string.
*/
-static sc_bool
-uip_match_number(void) {
+static sc_bool uip_match_number(void) {
const sc_gameref_t game = uip_get_game();
const sc_var_setref_t vars = gs_get_vars(game);
sc_int number;
@@ -1122,8 +1094,7 @@ uip_match_number(void) {
return FALSE;
}
-static sc_bool
-uip_match_text(sc_ptnoderef_t node) {
+static sc_bool uip_match_text(sc_ptnoderef_t node) {
const sc_gameref_t game = uip_get_game();
const sc_var_setref_t vars = gs_get_vars(game);
sc_int start_posn, limit, index_;
@@ -1195,8 +1166,7 @@ uip_match_text(sc_ptnoderef_t node) {
* Skip over any "a"/"an"/"the"/"some" at the head of a string. Helper for
* %character% and %object% matchers. Returns the revised string position.
*/
-static sc_int
-uip_skip_article(const sc_char *string, sc_int start) {
+static sc_int uip_skip_article(const sc_char *string, sc_int start) {
sc_int posn;
/* Skip over articles. */
@@ -1225,8 +1195,7 @@ uip_skip_article(const sc_char *string, sc_int start) {
* didn't match, otherwise the length of the current position that matched
* the words passed in (the new value of uip_posn on match).
*/
-static sc_int
-uip_compare_reference(const sc_char *words) {
+static sc_int uip_compare_reference(const sc_char *words) {
sc_int wpos, posn;
/* Skip articles and lead in space on words and string. */
@@ -1279,8 +1248,7 @@ uip_compare_reference(const sc_char *words) {
* match against both the prefixed name, and if that fails, the plain name.
* Returns the extent of the match, or zero if no match.
*/
-static sc_int
-uip_compare_prefixed_name(const sc_char *prefix, const sc_char *name) {
+static sc_int uip_compare_prefixed_name(const sc_char *prefix, const sc_char *name) {
sc_char buffer[UIP_SHORT_WORD_SIZE + UIP_SHORT_WORD_SIZE + 1];
sc_char *string;
sc_int required, extent;
@@ -1311,8 +1279,7 @@ uip_compare_prefixed_name(const sc_char *prefix, const sc_char *name) {
* of a pattern, to resolve the difference between, say, "table leg" and
* "table".
*/
-static sc_bool
-uip_match_remainder(sc_ptnoderef_t node, sc_int extent) {
+static sc_bool uip_match_remainder(sc_ptnoderef_t node, sc_int extent) {
sc_ptnoderef_t list;
sc_int start_posn;
sc_bool matched;
@@ -1347,8 +1314,7 @@ uip_match_remainder(sc_ptnoderef_t node, sc_int extent) {
* aliases for possible matches, and sets the game npc_references flag
* for any that match. The final one to match is also stored in variables.
*/
-static sc_bool
-uip_match_character(sc_ptnoderef_t node) {
+static sc_bool uip_match_character(sc_ptnoderef_t node) {
const sc_gameref_t game = uip_get_game();
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
@@ -1446,8 +1412,7 @@ uip_match_character(sc_ptnoderef_t node) {
* aliases for possible matches, and sets the game object_references flag
* for any that match. The final one to match is also stored in variables.
*/
-static sc_bool
-uip_match_object(sc_ptnoderef_t node) {
+static sc_bool uip_match_object(sc_ptnoderef_t node) {
const sc_gameref_t game = uip_get_game();
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
@@ -1545,8 +1510,7 @@ uip_match_object(sc_ptnoderef_t node) {
* Return TRUE, with position advanced, on match, FALSE on fail with the
* position unchanged.
*/
-static sc_bool
-uip_match_node(sc_ptnoderef_t node) {
+static sc_bool uip_match_node(sc_ptnoderef_t node) {
sc_bool match = FALSE;
/* Match depending on node type. */
@@ -1605,8 +1569,7 @@ uip_match_node(sc_ptnoderef_t node) {
* allocation if it happens (detectable by comparing the return value to the
* buffer passed in), or call uip_free_cleansed_string.
*/
-static sc_char *
-uip_cleanse_string(const sc_char *original, sc_char *buffer, sc_int length) {
+static sc_char *uip_cleanse_string(const sc_char *original, sc_char *buffer, sc_int length) {
sc_int required;
sc_char *string;
@@ -1623,8 +1586,7 @@ uip_cleanse_string(const sc_char *original, sc_char *buffer, sc_int length) {
return string;
}
-static sc_char *
-uip_free_cleansed_string(sc_char *string, const sc_char *buffer) {
+static sc_char *uip_free_cleansed_string(sc_char *string, const sc_char *buffer) {
/* Free if the string was allocated by the function above. */
if (string != buffer)
sc_free(string);
@@ -1639,8 +1601,7 @@ uip_free_cleansed_string(sc_char *string, const sc_char *buffer) {
*
* Set pattern match tracing on/off.
*/
-void
-uip_debug_trace(sc_bool flag) {
+void uip_debug_trace(sc_bool flag) {
uip_trace = flag;
}
@@ -1652,8 +1613,7 @@ uip_debug_trace(sc_bool flag) {
* For performance, this function uses a local buffer to try to avoid the
* need to copy each of the pattern and match strings passed in.
*/
-sc_bool
-uip_match(const sc_char *pattern, const sc_char *string, sc_gameref_t game) {
+sc_bool uip_match(const sc_char *pattern, const sc_char *string, sc_gameref_t game) {
static sc_char *cleansed; /* For setjmp safety. */
sc_char buffer[UIP_ALLOCATION_AVOIDANCE_SIZE];
sc_bool match;
@@ -1713,8 +1673,7 @@ uip_match(const sc_char *pattern, const sc_char *string, sc_gameref_t game) {
* resulting string to the caller, or NULL if no pronouns were replaced. The
* return string is malloc'ed, so the caller needs to remember to free it.
*/
-sc_char *
-uip_replace_pronouns(sc_gameref_t game, const sc_char *string) {
+sc_char *uip_replace_pronouns(sc_gameref_t game, const sc_char *string) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_int buffer_allocation;
sc_char *buffer;
@@ -1856,8 +1815,7 @@ uip_replace_pronouns(sc_gameref_t game, const sc_char *string) {
* pronouns for objects or NPC names as found. Later ones will overwrite
* earlier ones if there is more than one in the string.
*/
-void
-uip_assign_pronouns(sc_gameref_t game, const sc_char *string) {
+void uip_assign_pronouns(sc_gameref_t game, const sc_char *string) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_char *current;
diff --git a/engines/glk/adrift/scprintf.cpp b/engines/glk/adrift/scprintf.cpp
index 1ea93e8..90c4130 100644
--- a/engines/glk/adrift/scprintf.cpp
+++ b/engines/glk/adrift/scprintf.cpp
@@ -65,11 +65,11 @@ static sc_bool pf_trace = FALSE;
* come before shorter ones. The <br> tag is missing because this is
* handled separately, as a simple put of '\n'.
*/
-typedef struct {
+struct sc_html_tags_t {
const sc_char *const name;
const sc_int length;
const sc_int tag;
-} sc_html_tags_t;
+};
static const sc_html_tags_t HTML_TAGS_TABLE[] = {
{"bgcolour", 8, SC_TAG_BGCOLOR}, {"bgcolor", 7, SC_TAG_BGCOLOR},
@@ -91,7 +91,7 @@ static const sc_html_tags_t HTML_TAGS_TABLE[] = {
* associated size and length, a note of any conversion to apply to the next
* buffered character, and a flag to let the filter ignore incoming text.
*/
-typedef struct sc_filter_s {
+struct sc_filter_s {
sc_uint magic;
sc_int buffer_length;
sc_int buffer_allocation;
@@ -99,7 +99,8 @@ typedef struct sc_filter_s {
sc_bool new_sentence;
sc_bool is_muted;
sc_bool needs_filtering;
-} sc_filter_t;
+};
+typedef sc_filter_s sc_filter_t;
/*
@@ -107,8 +108,7 @@ typedef struct sc_filter_s {
*
* Return TRUE if pointer is a valid printfilter, FALSE otherwise.
*/
-static sc_bool
-pf_is_valid(sc_filterref_t filter) {
+static sc_bool pf_is_valid(sc_filterref_t filter) {
return filter && filter->magic == PRINTFILTER_MAGIC;
}
@@ -118,8 +118,7 @@ pf_is_valid(sc_filterref_t filter) {
*
* Create and return a new printfilter.
*/
-sc_filterref_t
-pf_create(void) {
+sc_filterref_t pf_create(void) {
static sc_bool initialized = FALSE;
sc_filterref_t filter;
@@ -159,8 +158,7 @@ pf_create(void) {
*
* Destroy a printfilter and free its allocated memory.
*/
-void
-pf_destroy(sc_filterref_t filter) {
+void pf_destroy(sc_filterref_t filter) {
assert(pf_is_valid(filter));
/* Free buffer space, and poison and free the printfilter. */
@@ -183,8 +181,7 @@ pf_destroy(sc_filterref_t filter) {
* characters, and since some games have strings with this character in them,
* this is probably all that can be done.
*/
-static sc_char *
-pf_interpolate_vars(const sc_char *string, sc_var_setref_t vars) {
+static sc_char *pf_interpolate_vars(const sc_char *string, sc_var_setref_t vars) {
sc_char *buffer, *name;
const sc_char *cursor;
const sc_char *marker;
@@ -291,9 +288,7 @@ pf_interpolate_vars(const sc_char *string, sc_var_setref_t vars) {
* its equivalent, updating the buffer at the address passed in, including
* reallocating if necessary. Return TRUE if the buffer was changed.
*/
-static sc_bool
-pf_replace_alr(const sc_char *string,
- sc_char **buffer, sc_int alr, sc_prop_setref_t bundle) {
+static sc_bool pf_replace_alr(const sc_char *string, sc_char **buffer, sc_int alr, sc_prop_setref_t bundle) {
sc_vartype_t vt_key[3];
const sc_char *marker, *cursor, *original, *replacement;
sc_char *buffer_ = *buffer;
@@ -358,9 +353,8 @@ pf_replace_alr(const sc_char *string,
* ALRs were replaced, returns an allocated string with replacements done,
* otherwise returns NULL.
*/
-static sc_char *
-pf_replace_alrs(const sc_char *string, sc_prop_setref_t bundle,
- sc_bool alr_applied[], sc_int alr_count) {
+static sc_char *pf_replace_alrs(const sc_char *string, sc_prop_setref_t bundle,
+ sc_bool alr_applied[], sc_int alr_count) {
sc_int index_;
sc_char *buffer1, *buffer2, **buffer;
const sc_char *marker;
@@ -437,8 +431,7 @@ pf_replace_alrs(const sc_char *string, sc_prop_setref_t bundle,
* Edit the tag-stripped text element passed in, substituting < >
* +percent+ with < > %, then send to the OS-specific output functions.
*/
-static void
-pf_output_text(const sc_char *string) {
+static void pf_output_text(const sc_char *string) {
sc_int index_, b_index;
sc_char *buffer;
@@ -487,8 +480,7 @@ pf_output_text(const sc_char *string) {
*
* Output an HTML-like tag element to the OS-specific tag handling function.
*/
-static void
-pf_output_tag(const sc_char *contents) {
+static void pf_output_tag(const sc_char *contents) {
const sc_html_tags_t *entry;
const sc_char *argument;
@@ -539,8 +531,7 @@ pf_output_tag(const sc_char *contents) {
* Break apart HTML-like string into normal text elements, and HTML-like
* tags.
*/
-static void
-pf_output_untagged(const sc_char *string) {
+static void pf_output_untagged(const sc_char *string) {
sc_char *temporary, *untagged, *contents;
const sc_char *cursor;
const sc_char *marker;
@@ -636,9 +627,7 @@ pf_output_untagged(const sc_char *string) {
* until no more changes in the current string
*
*/
-static sc_char *
-pf_filter_internal(const sc_char *string,
- sc_var_setref_t vars, sc_prop_setref_t bundle) {
+static sc_char *pf_filter_internal(const sc_char *string, sc_var_setref_t vars, sc_prop_setref_t bundle) {
sc_int alr_count, iteration;
sc_char *current;
sc_bool *alr_applied;
@@ -743,9 +732,7 @@ pf_filter_internal(const sc_char *string,
* variables and replacing ALR's. Returns an allocated string that the caller
* needs to free.
*/
-sc_char *
-pf_filter(const sc_char *string,
- sc_var_setref_t vars, sc_prop_setref_t bundle) {
+sc_char *pf_filter(const sc_char *string, sc_var_setref_t vars, sc_prop_setref_t bundle) {
sc_char *current;
/* Filter this string, including ALRs replacements. */
@@ -769,8 +756,7 @@ pf_filter(const sc_char *string,
* Used on informational strings such as the game title and author. Returns
* an allocated string that the caller needs to free.
*/
-sc_char *
-pf_filter_for_info(const sc_char *string, sc_var_setref_t vars) {
+sc_char *pf_filter_for_info(const sc_char *string, sc_var_setref_t vars) {
sc_char *current;
/* Filter this string, excluding ALRs replacements. */
@@ -792,9 +778,7 @@ pf_filter_for_info(const sc_char *string, sc_var_setref_t vars) {
* Filter buffered data, interpolating variables and replacing ALR's, and
* send the resulting string to the output channel.
*/
-void
-pf_flush(sc_filterref_t filter,
- sc_var_setref_t vars, sc_prop_setref_t bundle) {
+void pf_flush(sc_filterref_t filter, sc_var_setref_t vars, sc_prop_setref_t bundle) {
assert(pf_is_valid(filter));
assert(vars && bundle);
@@ -834,8 +818,7 @@ pf_flush(sc_filterref_t filter,
*
* Append a string to the filter buffer.
*/
-static void
-pf_append_string(sc_filterref_t filter, const sc_char *string) {
+static void pf_append_string(sc_filterref_t filter, const sc_char *string) {
sc_int length, required;
/*
@@ -876,9 +859,7 @@ pf_append_string(sc_filterref_t filter, const sc_char *string) {
* polated in between main flushes; used to update buffered text with variable
* values before those values are updated by task actions.
*/
-void
-pf_checkpoint(sc_filterref_t filter,
- sc_var_setref_t vars, sc_prop_setref_t bundle) {
+void pf_checkpoint(sc_filterref_t filter, sc_var_setref_t vars, sc_prop_setref_t bundle) {
assert(pf_is_valid(filter));
assert(vars && bundle);
@@ -918,8 +899,7 @@ pf_checkpoint(sc_filterref_t filter,
* The second function is an optimization to avoid allocations and copying
* in client code.
*/
-const sc_char *
-pf_get_buffer(sc_filterref_t filter) {
+const sc_char *pf_get_buffer(sc_filterref_t filter) {
assert(pf_is_valid(filter));
/*
@@ -933,8 +913,7 @@ pf_get_buffer(sc_filterref_t filter) {
return NULL;
}
-sc_char *
-pf_transfer_buffer(sc_filterref_t filter) {
+sc_char *pf_transfer_buffer(sc_filterref_t filter) {
assert(pf_is_valid(filter));
/*
@@ -969,8 +948,7 @@ pf_transfer_buffer(sc_filterref_t filter) {
*
* Empty any text currently buffered in the filter.
*/
-void
-pf_empty(sc_filterref_t filter) {
+void pf_empty(sc_filterref_t filter) {
assert(pf_is_valid(filter));
/* Free any allocation, and return the filter to initialization state. */
@@ -991,8 +969,7 @@ pf_empty(sc_filterref_t filter) {
* Add a string, and a single character, to the printfilter buffer. If muted,
* these functions do nothing.
*/
-void
-pf_buffer_string(sc_filterref_t filter, const sc_char *string) {
+void pf_buffer_string(sc_filterref_t filter, const sc_char *string) {
assert(pf_is_valid(filter));
assert(string);
@@ -1014,8 +991,7 @@ pf_buffer_string(sc_filterref_t filter, const sc_char *string) {
}
}
-void
-pf_buffer_character(sc_filterref_t filter, sc_char character) {
+void pf_buffer_character(sc_filterref_t filter, sc_char character) {
sc_char buffer[2];
assert(pf_is_valid(filter));
@@ -1033,8 +1009,7 @@ pf_buffer_character(sc_filterref_t filter, sc_char character) {
* running code, which needs to run task actions and then prepend the task's
* completion text. If muted, this function does nothing.
*/
-void
-pf_prepend_string(sc_filterref_t filter, const sc_char *string) {
+void pf_prepend_string(sc_filterref_t filter, const sc_char *string) {
assert(pf_is_valid(filter));
assert(string);
@@ -1080,8 +1055,7 @@ pf_prepend_string(sc_filterref_t filter, const sc_char *string) {
* Tells the printfilter to force the next non-space character to uppercase.
* Ignored if the printfilter is muted.
*/
-void
-pf_new_sentence(sc_filterref_t filter) {
+void pf_new_sentence(sc_filterref_t filter) {
assert(pf_is_valid(filter));
if (!filter->is_muted)
@@ -1095,15 +1069,13 @@ pf_new_sentence(sc_filterref_t filter) {
*
* A muted printfilter ignores all new text additions.
*/
-void
-pf_mute(sc_filterref_t filter) {
+void pf_mute(sc_filterref_t filter) {
assert(pf_is_valid(filter));
filter->is_muted = TRUE;
}
-void
-pf_clear_mute(sc_filterref_t filter) {
+void pf_clear_mute(sc_filterref_t filter) {
assert(pf_is_valid(filter));
filter->is_muted = FALSE;
@@ -1116,8 +1088,7 @@ pf_clear_mute(sc_filterref_t filter) {
* Insert an HTML-like tag into the buffered output data. The call is ignored
* if the printfilter is muted.
*/
-void
-pf_buffer_tag(sc_filterref_t filter, sc_int tag) {
+void pf_buffer_tag(sc_filterref_t filter, sc_int tag) {
const sc_html_tags_t *entry;
assert(pf_is_valid(filter));
@@ -1145,8 +1116,7 @@ pf_buffer_tag(sc_filterref_t filter, sc_int tag) {
* status lines. It ignores all tags except <br>, which it replaces with
* a newline if requested by allow_newlines.
*/
-static void
-pf_strip_tags_common(sc_char *string, sc_bool allow_newlines) {
+static void pf_strip_tags_common(sc_char *string, sc_bool allow_newlines) {
sc_char *marker, *cursor;
/* Run through the string looking for <...> tags. */
@@ -1181,13 +1151,11 @@ pf_strip_tags_common(sc_char *string, sc_bool allow_newlines) {
* Public interfaces to pf_strip_tags_common(). The hints version will
* allow <br> tags to map into newlines in hints strings.
*/
-void
-pf_strip_tags(sc_char *string) {
+void pf_strip_tags(sc_char *string) {
pf_strip_tags_common(string, FALSE);
}
-void
-pf_strip_tags_for_hints(sc_char *string) {
+void pf_strip_tags_for_hints(sc_char *string) {
pf_strip_tags_common(string, TRUE);
}
@@ -1202,8 +1170,7 @@ pf_strip_tags_for_hints(sc_char *string) {
* the character itself followed by a space. The return string is malloc'ed,
* so the caller needs to remember to free it.
*/
-sc_char *
-pf_escape(const sc_char *string) {
+sc_char *pf_escape(const sc_char *string) {
const sc_char *marker, *cursor;
sc_char *buffer;
@@ -1277,8 +1244,7 @@ pf_escape(const sc_char *string) {
* Matches multiple words from words in string. Returns the extent of
* the match if the string matched, 0 otherwise.
*/
-static sc_int
-pf_compare_words(const sc_char *string, const sc_char *words) {
+static sc_int pf_compare_words(const sc_char *string, const sc_char *words) {
sc_int word_posn, posn;
/* None expected, but skip leading space. */
@@ -1332,8 +1298,7 @@ pf_compare_words(const sc_char *string, const sc_char *words) {
* string to the caller, or NULL if no synonym changes were needed. The
* return string is malloc'ed, so the caller needs to remember to free it.
*/
-sc_char *
-pf_filter_input(const sc_char *string, sc_prop_setref_t bundle) {
+sc_char *pf_filter_input(const sc_char *string, sc_prop_setref_t bundle) {
sc_vartype_t vt_key[3];
sc_int synonym_count, buffer_allocation;
sc_char *buffer;
@@ -1448,8 +1413,7 @@ pf_filter_input(const sc_char *string, sc_prop_setref_t bundle) {
*
* Set filter tracing on/off.
*/
-void
-pf_debug_trace(sc_bool flag) {
+void pf_debug_trace(sc_bool flag) {
pf_trace = flag;
}
diff --git a/engines/glk/adrift/scprops.cpp b/engines/glk/adrift/scprops.cpp
index aeb0d24..0888173 100644
--- a/engines/glk/adrift/scprops.cpp
+++ b/engines/glk/adrift/scprops.cpp
@@ -80,8 +80,7 @@ typedef sc_prop_set_s sc_prop_set_t;
*
* Return TRUE if pointer is a valid properties set, FALSE otherwise.
*/
-static sc_bool
-prop_is_valid(sc_prop_setref_t bundle) {
+static sc_bool prop_is_valid(sc_prop_setref_t bundle) {
return bundle && bundle->magic == PROP_MAGIC;
}
@@ -91,8 +90,7 @@ prop_is_valid(sc_prop_setref_t bundle) {
*
* Round up a count of elements to the next block of grow increments.
*/
-static sc_int
-prop_round_up(sc_int elements) {
+static sc_int prop_round_up(sc_int elements) {
sc_int extended;
extended = elements + PROP_GROW_INCREMENT - 1;
@@ -111,9 +109,7 @@ prop_round_up(sc_int elements) {
* realloc() in blocks of elements, and thus need to realloc() much less
* frequently.
*/
-static void *
-prop_ensure_capacity(void *array,
- sc_int old_size, sc_int new_size, sc_int element_size) {
+static void *prop_ensure_capacity(void *array, sc_int old_size, sc_int new_size, sc_int element_size) {
sc_int current, required;
/*
@@ -145,8 +141,7 @@ prop_ensure_capacity(void *array,
* "unblock" the allocations of prop_ensure_capacity(). Once trimmed,
* the array cannot ever be grown safely again.
*/
-static void *
-prop_trim_capacity(void *array, sc_int size, sc_int element_size) {
+static void *prop_trim_capacity(void *array, sc_int size, sc_int element_size) {
if (prop_round_up(size) > size)
return sc_realloc(array, size * element_size);
else
@@ -161,8 +156,7 @@ prop_trim_capacity(void *array, sc_int size, sc_int element_size) {
* The function has return type "int" to match the libc implementations of
* bsearch() and qsort().
*/
-static int
-prop_compare(const void *string1, const void *string2) {
+static int prop_compare(const void *string1, const void *string2) {
return strcmp(*(sc_char * const *) string1, *(sc_char * const *) string2);
}
@@ -175,8 +169,7 @@ prop_compare(const void *string1, const void *string2) {
* either added or already present. Any new dictionary entry will
* contain a malloced copy of the string passed in.
*/
-static const sc_char *
-prop_dictionary_lookup(sc_prop_setref_t bundle, const sc_char *string) {
+static const sc_char *prop_dictionary_lookup(sc_prop_setref_t bundle, const sc_char *string) {
sc_char *dict_string;
/*
@@ -223,8 +216,7 @@ prop_dictionary_lookup(sc_prop_setref_t bundle, const sc_char *string) {
* for even a small game is large, and preallocating pools avoids excessive
* malloc's of small individual nodes.
*/
-static sc_prop_noderef_t
-prop_new_node(sc_prop_setref_t bundle) {
+static sc_prop_noderef_t prop_new_node(sc_prop_setref_t bundle) {
sc_int node_index;
sc_prop_noderef_t node;
@@ -260,8 +252,7 @@ prop_new_node(sc_prop_setref_t bundle) {
*
* Find a child node of the given parent whose name matches that passed in.
*/
-static sc_prop_noderef_t
-prop_find_child(sc_prop_noderef_t parent, sc_int type, sc_vartype_t name) {
+static sc_prop_noderef_t prop_find_child(sc_prop_noderef_t parent, sc_int type, sc_vartype_t name) {
/* See if this node has any children. */
if (parent->child_list) {
sc_int index_;
@@ -330,9 +321,8 @@ prop_find_child(sc_prop_noderef_t parent, sc_int type, sc_vartype_t name) {
* Add a new child node to the given parent. Return its reference. Set
* needs to be passed so that string names can be added to the dictionary.
*/
-static sc_prop_noderef_t
-prop_add_child(sc_prop_noderef_t parent,
- sc_int type, sc_vartype_t name, sc_prop_setref_t bundle) {
+static sc_prop_noderef_t prop_add_child(sc_prop_noderef_t parent, sc_int type,
+ sc_vartype_t name, sc_prop_setref_t bundle) {
sc_prop_noderef_t child;
/* Not possible if growable allocations have been trimmed. */
@@ -422,9 +412,8 @@ prop_add_child(sc_prop_noderef_t parent,
* "I->sssis", stores an integer, with a key composed of three strings, an
* integer, and another string.
*/
-void
-prop_put(sc_prop_setref_t bundle, const sc_char *format,
- sc_vartype_t vt_value, const sc_vartype_t vt_key[]) {
+void prop_put(sc_prop_setref_t bundle, const sc_char *format,
+ sc_vartype_t vt_value, const sc_vartype_t vt_key[]) {
sc_prop_noderef_t node;
sc_int index_;
assert(prop_is_valid(bundle));
@@ -523,9 +512,8 @@ prop_put(sc_prop_setref_t bundle, const sc_char *format,
* Retrieve a property from a properties set. Format stuff as above, except
* with "->" replaced with "<-". Returns FALSE if no such property exists.
*/
-sc_bool
-prop_get(sc_prop_setref_t bundle, const sc_char *format,
- sc_vartype_t *vt_rvalue, const sc_vartype_t vt_key[]) {
+sc_bool prop_get(sc_prop_setref_t bundle, const sc_char *format, sc_vartype_t *vt_rvalue,
+ const sc_vartype_t vt_key[]) {
sc_prop_noderef_t node;
sc_int index_;
assert(prop_is_valid(bundle));
@@ -633,8 +621,7 @@ prop_get(sc_prop_setref_t bundle, const sc_char *format,
* Trim excess allocation from growable arrays, and fix the properties set
* so that no further property insertions are allowed.
*/
-static void
-prop_trim_node(sc_prop_noderef_t node) {
+static void prop_trim_node(sc_prop_noderef_t node) {
/* End recursion on null or childless node. */
if (node && node->child_list) {
sc_int index_;
@@ -650,8 +637,7 @@ prop_trim_node(sc_prop_noderef_t node) {
}
}
-void
-prop_solidify(sc_prop_setref_t bundle) {
+void prop_solidify(sc_prop_setref_t bundle) {
assert(prop_is_valid(bundle));
/*
@@ -685,9 +671,7 @@ prop_solidify(sc_prop_setref_t bundle) {
* Convenience functions to retrieve a property of a known type directly.
* It is an error for the property not to exist on retrieval.
*/
-sc_int
-prop_get_integer(sc_prop_setref_t bundle,
- const sc_char *format, const sc_vartype_t vt_key[]) {
+sc_int prop_get_integer(sc_prop_setref_t bundle, const sc_char *format, const sc_vartype_t vt_key[]) {
sc_vartype_t vt_rvalue;
assert(format[0] == PROP_INTEGER);
@@ -697,9 +681,7 @@ prop_get_integer(sc_prop_setref_t bundle,
return vt_rvalue.integer;
}
-sc_bool
-prop_get_boolean(sc_prop_setref_t bundle,
- const sc_char *format, const sc_vartype_t vt_key[]) {
+sc_bool prop_get_boolean(sc_prop_setref_t bundle, const sc_char *format, const sc_vartype_t vt_key[]) {
sc_vartype_t vt_rvalue;
assert(format[0] == PROP_BOOLEAN);
@@ -709,9 +691,7 @@ prop_get_boolean(sc_prop_setref_t bundle,
return vt_rvalue.boolean;
}
-const sc_char *
-prop_get_string(sc_prop_setref_t bundle,
- const sc_char *format, const sc_vartype_t vt_key[]) {
+const sc_char *prop_get_string(sc_prop_setref_t bundle, const sc_char *format, const sc_vartype_t vt_key[]) {
sc_vartype_t vt_rvalue;
assert(format[0] == PROP_STRING);
@@ -728,9 +708,7 @@ prop_get_string(sc_prop_setref_t bundle,
* Convenience function to retrieve a count of child properties available
* for a given property. Returns zero if the property does not exist.
*/
-sc_int
-prop_get_child_count(sc_prop_setref_t bundle,
- const sc_char *format, const sc_vartype_t vt_key[]) {
+sc_int prop_get_child_count(sc_prop_setref_t bundle, const sc_char *format, const sc_vartype_t vt_key[]) {
sc_vartype_t vt_rvalue;
assert(format[0] == PROP_INTEGER);
@@ -747,8 +725,7 @@ prop_get_child_count(sc_prop_setref_t bundle,
*
* Create a new, empty properties set, and return it.
*/
-static sc_prop_setref_t
-prop_create_empty() {
+static sc_prop_setref_t prop_create_empty() {
sc_prop_setref_t bundle;
/* Create a new, empty set. */
@@ -793,8 +770,7 @@ prop_create_empty() {
*
* Free set memory, and destroy a properties set structure.
*/
-static void
-prop_destroy_child_list(sc_prop_noderef_t node) {
+static void prop_destroy_child_list(sc_prop_noderef_t node) {
/* End recursion on null or childless node. */
if (node && node->child_list) {
sc_int index_;
@@ -808,8 +784,7 @@ prop_destroy_child_list(sc_prop_noderef_t node) {
}
}
-void
-prop_destroy(sc_prop_setref_t bundle) {
+void prop_destroy(sc_prop_setref_t bundle) {
sc_int index_;
assert(prop_is_valid(bundle));
@@ -853,8 +828,7 @@ prop_destroy(sc_prop_setref_t bundle) {
*
* Create a new properties set based on a taf, and return it.
*/
-sc_prop_setref_t
-prop_create(const sc_tafref_t taf) {
+sc_prop_setref_t prop_create(const sc_tafref_t taf) {
sc_prop_setref_t bundle;
/* Create a new, empty set. */
@@ -877,8 +851,7 @@ prop_create(const sc_tafref_t taf) {
*
* Adopt a memory address for free'ing on destroy.
*/
-void
-prop_adopt(sc_prop_setref_t bundle, void *addr) {
+void prop_adopt(sc_prop_setref_t bundle, void *addr) {
assert(prop_is_valid(bundle));
/* Extend the orphans array if necessary. */
@@ -899,8 +872,7 @@ prop_adopt(sc_prop_setref_t bundle, void *addr) {
*
* Print out a complete properties set.
*/
-static sc_bool
-prop_debug_is_dictionary_string(sc_prop_setref_t bundle, const void *pointer) {
+static sc_bool prop_debug_is_dictionary_string(sc_prop_setref_t bundle, const void *pointer) {
const sc_char *const pointer_ = (const sc_char * const)pointer;
sc_int index_;
@@ -913,9 +885,8 @@ prop_debug_is_dictionary_string(sc_prop_setref_t bundle, const void *pointer) {
return FALSE;
}
-static void
-prop_debug_dump_node(sc_prop_setref_t bundle,
- sc_int depth, sc_int child_index, sc_prop_noderef_t node) {
+static void prop_debug_dump_node(sc_prop_setref_t bundle, sc_int depth,
+ sc_int child_index, sc_prop_noderef_t node) {
sc_int index_;
/* Write node preamble, indented two spaces for each depth count. */
@@ -953,8 +924,7 @@ prop_debug_dump_node(sc_prop_setref_t bundle,
sc_trace("\n");
}
-void
-prop_debug_dump(sc_prop_setref_t bundle) {
+void prop_debug_dump(sc_prop_setref_t bundle) {
sc_int index_;
assert(prop_is_valid(bundle));
@@ -988,8 +958,7 @@ prop_debug_dump(sc_prop_setref_t bundle) {
*
* Set property tracing on/off.
*/
-void
-prop_debug_trace(sc_bool flag) {
+void prop_debug_trace(sc_bool flag) {
prop_trace = flag;
}
diff --git a/engines/glk/adrift/scprotos.h b/engines/glk/adrift/scprotos.h
index 24103b9..9601f06 100644
--- a/engines/glk/adrift/scprotos.h
+++ b/engines/glk/adrift/scprotos.h
@@ -779,18 +779,13 @@ extern void if_read_line(sc_char *buffer, sc_int length);
extern void if_read_debug(sc_char *buffer, sc_int length);
extern sc_bool if_confirm(sc_int type);
extern void *if_open_saved_game(sc_bool is_save);
-extern void if_write_saved_game(void *opaque,
- const sc_byte *buffer, sc_int length);
-extern sc_int if_read_saved_game(void *opaque,
- sc_byte *buffer, sc_int length);
+extern void if_write_saved_game(void *opaque, const sc_byte *buffer, sc_int length);
+extern sc_int if_read_saved_game(void *opaque, sc_byte *buffer, sc_int length);
extern void if_close_saved_game(void *opaque);
extern void if_display_hints(sc_gameref_t game);
-extern void if_update_sound(const sc_char *filepath,
- sc_int sound_offset,
- sc_int sound_length, sc_bool is_looping);
-extern void if_update_graphic(const sc_char *filepath,
- sc_int graphic_offset,
- sc_int graphic_length);
+extern void if_update_sound(const sc_char *filepath, sc_int sound_offset,
+ sc_int sound_length, sc_bool is_looping);
+extern void if_update_graphic(const sc_char *filepath, sc_int graphic_offset, sc_int graphic_length);
#endif
diff --git a/engines/glk/adrift/scresour.cpp b/engines/glk/adrift/scresour.cpp
index 739c3d7..c09a5c8 100644
--- a/engines/glk/adrift/scresour.cpp
+++ b/engines/glk/adrift/scresour.cpp
@@ -37,8 +37,7 @@ static const sc_char NUL = '\0';
*
* Return TRUE if the game uses sound or graphics.
*/
-sc_bool
-res_has_sound(sc_gameref_t game) {
+sc_bool res_has_sound(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
sc_bool has_sound;
@@ -50,8 +49,7 @@ res_has_sound(sc_gameref_t game) {
return has_sound;
}
-sc_bool
-res_has_graphics(sc_gameref_t game) {
+sc_bool res_has_graphics(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
sc_bool has_graphics;
@@ -71,21 +69,18 @@ res_has_graphics(sc_gameref_t game) {
*
* Convenience functions to set, clear, and compare resource fields.
*/
-static void
-res_set_resource(sc_resourceref_t resource, const sc_char *name,
+static void res_set_resource(sc_resourceref_t resource, const sc_char *name,
sc_int offset, sc_int length) {
resource->name = name;
resource->offset = offset;
resource->length = length;
}
-void
-res_clear_resource(sc_resourceref_t resource) {
+void res_clear_resource(sc_resourceref_t resource) {
res_set_resource(resource, "", 0, 0);
}
-sc_bool
-res_compare_resource(sc_resourceref_t from, sc_resourceref_t with) {
+sc_bool res_compare_resource(sc_resourceref_t from, sc_resourceref_t with) {
return strcmp(from->name, with->name) == 0
&& from->offset == with->offset && from->length == with->length;
}
@@ -103,10 +98,8 @@ res_compare_resource(sc_resourceref_t from, sc_resourceref_t with) {
* in prop_get), and the partial key is guaranteed to contain at least
* strlen(partial_format) elements.
*/
-void
-res_handle_resource(sc_gameref_t game,
- const sc_char *partial_format,
- const sc_vartype_t vt_partial[]) {
+void res_handle_resource(sc_gameref_t game, const sc_char *partial_format,
+ const sc_vartype_t vt_partial[]) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2], *vt_full;
sc_int partial_length, resource_start_offset;
@@ -250,8 +243,7 @@ res_handle_resource(sc_gameref_t game,
* Bring resources into line with the game; called on undo, restart,
* restore, and so on.
*/
-void
-res_sync_resources(sc_gameref_t game) {
+void res_sync_resources(sc_gameref_t game) {
assert(gs_is_game_valid(game));
/* Deal with any latched sound stop first. */
@@ -307,8 +299,7 @@ res_sync_resources(sc_gameref_t game) {
* Turn off sound and graphics, and reset the game's tracking of resources in
* use to match. Called on game restart or restore.
*/
-void
-res_cancel_resources(sc_gameref_t game) {
+void res_cancel_resources(sc_gameref_t game) {
assert(gs_is_game_valid(game));
/* Request that everything stops and clears. */
diff --git a/engines/glk/adrift/screstrs.cpp b/engines/glk/adrift/screstrs.cpp
index 3f1db88..c808129 100644
--- a/engines/glk/adrift/screstrs.cpp
+++ b/engines/glk/adrift/screstrs.cpp
@@ -40,8 +40,7 @@ static sc_bool restr_trace = FALSE;
*
* Return the index of the n'th integer found.
*/
-static sc_int
-restr_integer_variable(sc_gameref_t game, sc_int n) {
+static sc_int restr_integer_variable(sc_gameref_t game, sc_int n) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int var_count, var, count;
@@ -70,9 +69,7 @@ restr_integer_variable(sc_gameref_t game, sc_int n) {
*
* Is object in a certain place, state, or condition.
*/
-static sc_bool
-restr_object_in_place(sc_gameref_t game,
- sc_int object, sc_int var2, sc_int var3) {
+static sc_bool restr_object_in_place(sc_gameref_t game, sc_int object, sc_int var2, sc_int var3) {
const sc_var_setref_t vars = gs_get_vars(game);
sc_int npc;
@@ -157,9 +154,8 @@ restr_object_in_place(sc_gameref_t game,
*
* Evaluate restrictions relating to object location.
*/
-static sc_bool
-restr_pass_task_object_location(sc_gameref_t game,
- sc_int var1, sc_int var2, sc_int var3) {
+static sc_bool restr_pass_task_object_location(sc_gameref_t game,
+ sc_int var1, sc_int var2, sc_int var3) {
const sc_var_setref_t vars = gs_get_vars(game);
sc_bool should_be;
sc_int object;
@@ -231,8 +227,7 @@ restr_pass_task_object_location(sc_gameref_t game,
* Evaluate restrictions relating to object states. This function is called
* from the library by lib_pass_alt_room(), so cannot be static.
*/
-sc_bool
-restr_pass_task_object_state(sc_gameref_t game, sc_int var1, sc_int var2) {
+sc_bool restr_pass_task_object_state(sc_gameref_t game, sc_int var1, sc_int var2) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[3];
@@ -279,8 +274,7 @@ restr_pass_task_object_state(sc_gameref_t game, sc_int var1, sc_int var2) {
*
* Evaluate restrictions relating to task states.
*/
-static sc_bool
-restr_pass_task_task_state(sc_gameref_t game, sc_int var1, sc_int var2) {
+static sc_bool restr_pass_task_task_state(sc_gameref_t game, sc_int var1, sc_int var2) {
sc_bool should_be;
if (restr_trace)
@@ -318,8 +312,7 @@ restr_pass_task_task_state(sc_gameref_t game, sc_int var1, sc_int var2) {
*
* Evaluate restrictions relating to player and NPCs.
*/
-static sc_bool
-restr_pass_task_char(sc_gameref_t game, sc_int var1, sc_int var2, sc_int var3) {
+static sc_bool restr_pass_task_char(sc_gameref_t game, sc_int var1, sc_int var2, sc_int var3) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int npc1, npc2;
@@ -437,9 +430,7 @@ restr_pass_task_char(sc_gameref_t game, sc_int var1, sc_int var2, sc_int var3) {
*
* Helper for restr_pass_task_var(), handles integer variable restrictions.
*/
-static sc_bool
-restr_pass_task_int_var(sc_gameref_t game,
- sc_int var2, sc_int var3, sc_int value) {
+static sc_bool restr_pass_task_int_var(sc_gameref_t game, sc_int var2, sc_int var3, sc_int value) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[3];
@@ -522,9 +513,7 @@ restr_pass_task_int_var(sc_gameref_t game,
*
* Helper for restr_pass_task_var(), handles string variable restrictions.
*/
-static sc_bool
-restr_pass_task_string_var(sc_int var2,
- const sc_char *var4, const sc_char *value) {
+static sc_bool restr_pass_task_string_var(sc_int var2, const sc_char *var4, const sc_char *value) {
if (restr_trace) {
sc_trace("Restr: running string"
" var restriction, %ld, \"%s\", \"%s\"\n", var2, var4, value);
@@ -550,10 +539,8 @@ restr_pass_task_string_var(sc_int var2,
*
* Evaluate restrictions relating to variables.
*/
-static sc_bool
-restr_pass_task_var(sc_gameref_t game,
- sc_int var1, sc_int var2, sc_int var3,
- const sc_char *var4) {
+static sc_bool restr_pass_task_var(sc_gameref_t game, sc_int var1, sc_int var2, sc_int var3,
+ const sc_char *var4) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[3];
@@ -607,8 +594,7 @@ restr_pass_task_var(sc_gameref_t game,
*
* Demultiplexer for task restrictions.
*/
-static sc_bool
-restr_pass_task_restriction(sc_gameref_t game, sc_int task, sc_int restriction) {
+static sc_bool restr_pass_task_restriction(sc_gameref_t game, sc_int task, sc_int restriction) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int type, var1, var2, var3;
@@ -712,15 +698,13 @@ static sc_int restr_index = 0;
*
* Start and wrap up restrictions combinations string tokenization.
*/
-static void
-restr_tokenize_start(const sc_char *expression) {
+static void restr_tokenize_start(const sc_char *expression) {
/* Save expression, and restart index. */
restr_expression = expression;
restr_index = 0;
}
-static void
-restr_tokenize_end(void) {
+static void restr_tokenize_end(void) {
restr_expression = NULL;
restr_index = 0;
}
@@ -731,8 +715,7 @@ restr_tokenize_end(void) {
*
* Simple tokenizer for restrictions combination expressions.
*/
-static sc_char
-restr_next_token(void) {
+static sc_char restr_next_token(void) {
assert(restr_expression);
/* Find the next non-space, and return it. */
@@ -775,8 +758,7 @@ static sc_int restr_lowest_fail = -1;
* Reset the evaluation stack to an empty state, and note the things we have
* to note for when we need to evaluate a restriction.
*/
-static void
-restr_eval_start(sc_gameref_t game, sc_int task) {
+static void restr_eval_start(sc_gameref_t game, sc_int task) {
/* Clear stack. */
restr_eval_stack = 0;
restr_eval_restriction = 0;
@@ -795,8 +777,7 @@ restr_eval_start(sc_gameref_t game, sc_int task) {
*
* Push a value onto the values stack.
*/
-static void
-restr_eval_push(sc_bool value) {
+static void restr_eval_push(sc_bool value) {
if (restr_eval_stack >= MAX_NESTING_DEPTH)
sc_fatal("restr_eval_push: stack overflow\n");
@@ -809,8 +790,7 @@ restr_eval_push(sc_bool value) {
*
* Evaluate the effect of an and/or into the values stack.
*/
-static void
-restr_eval_action(sc_char token) {
+static void restr_eval_action(sc_char token) {
/* Select action based on parsed token. */
switch (token) {
/* Handle evaluating and pushing a restriction result. */
@@ -875,8 +855,7 @@ restr_eval_action(sc_char token) {
*
* Return the top of the values stack as the evaluation result.
*/
-static sc_int
-restr_eval_result(sc_int *lowest_fail) {
+static sc_int restr_eval_result(sc_int *lowest_fail) {
if (restr_eval_stack != 1)
sc_fatal("restr_eval_result: values stack not completed\n");
@@ -896,8 +875,7 @@ static sc_char restr_lookahead = '\0';
*
* Match a token with an expectation.
*/
-static void
-restr_match(sc_char c) {
+static void restr_match(sc_char c) {
if (restr_lookahead == c)
restr_lookahead = restr_next_token();
else {
@@ -918,8 +896,7 @@ static void restr_bexpr(void);
*
* Expression parsers. Here we go again...
*/
-static void
-restr_andexpr(void) {
+static void restr_andexpr(void) {
restr_bexpr();
while (restr_lookahead == TOK_AND) {
restr_match(TOK_AND);
@@ -928,8 +905,7 @@ restr_andexpr(void) {
}
}
-static void
-restr_orexpr(void) {
+static void restr_orexpr(void) {
restr_andexpr();
while (restr_lookahead == TOK_OR) {
restr_match(TOK_OR);
@@ -938,8 +914,7 @@ restr_orexpr(void) {
}
}
-static void
-restr_bexpr(void) {
+static void restr_bexpr(void) {
switch (restr_lookahead) {
case TOK_RESTRICTION:
restr_match(TOK_RESTRICTION);
@@ -964,8 +939,7 @@ restr_bexpr(void) {
*
* Get the FailMessage for the given task restriction; NULL if none.
*/
-static const sc_char *
-restr_get_fail_message(sc_gameref_t game, sc_int task, sc_int restriction) {
+static const sc_char *restr_get_fail_message(sc_gameref_t game, sc_int task, sc_int restriction) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
const sc_char *message;
@@ -988,8 +962,7 @@ restr_get_fail_message(sc_gameref_t game, sc_int task, sc_int restriction) {
*
* Set restrictions tracing on/off.
*/
-void
-restr_debug_trace(sc_bool flag) {
+void restr_debug_trace(sc_bool flag) {
restr_trace = flag;
}
@@ -1004,10 +977,8 @@ restr_debug_trace(sc_bool flag) {
* if no failing restriction has a FailMessage. The function's main return
* value is TRUE if restrictions parsed successfully, FALSE otherwise.
*/
-sc_bool
-restr_eval_task_restrictions(sc_gameref_t game,
- sc_int task, sc_bool *pass,
- const sc_char **fail_message) {
+sc_bool restr_eval_task_restrictions(sc_gameref_t game, sc_int task, sc_bool *pass,
+ const sc_char **fail_message) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int restr_count, lowest_fail;
diff --git a/engines/glk/adrift/scrunner.cpp b/engines/glk/adrift/scrunner.cpp
index 9e979d1..95c8f19 100644
--- a/engines/glk/adrift/scrunner.cpp
+++ b/engines/glk/adrift/scrunner.cpp
@@ -44,8 +44,7 @@ static const sc_char *const SEPARATORS = ".,";
* present, only getdynfromroom() exists. Returns TRUE if function found
* and handled.
*/
-static sc_bool
-run_is_task_function(const sc_char *pattern, sc_gameref_t game) {
+static sc_bool run_is_task_function(const sc_char *pattern, sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[3];
@@ -107,10 +106,11 @@ run_is_task_function(const sc_char *pattern, sc_gameref_t game) {
/* Structure used to associate a pattern with a handler function. */
-typedef struct sc_commands_s {
+struct sc_commands_s {
const sc_char *const command;
sc_bool(*const handler)(sc_gameref_t game);
-} sc_commands_t;
+};
+typedef sc_commands_s sc_commands_t;
typedef sc_commands_t *sc_commandsref_t;
/* Movement commands for the four point compass. */
@@ -487,8 +487,7 @@ static sc_commands_t STANDARD_COMMANDS[] = {
* For now, I can't find any better way to try to handle it than to make
* object acquisition take precedence over game commands.
*/
-static sc_bool
-run_priority_commands(sc_gameref_t game, const sc_char *string) {
+static sc_bool run_priority_commands(sc_gameref_t game, const sc_char *string) {
sc_commandsref_t command;
for (command = PRIORITY_COMMANDS; command->command; command++) {
@@ -502,8 +501,7 @@ run_priority_commands(sc_gameref_t game, const sc_char *string) {
return FALSE;
}
-static sc_bool
-run_standard_commands(sc_gameref_t game, const sc_char *string) {
+static sc_bool run_standard_commands(sc_gameref_t game, const sc_char *string) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[2];
sc_bool eightpointcompass;
@@ -543,8 +541,7 @@ run_standard_commands(sc_gameref_t game, const sc_char *string) {
*
* Update the game's current room and status line strings.
*/
-static void
-run_update_status(sc_gameref_t game) {
+static void run_update_status(sc_gameref_t game) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[2];
@@ -589,8 +586,7 @@ run_update_status(sc_gameref_t game) {
* directly for printing, rather than the filter, so that it can place its
* output ahead of buffered printfilter text.
*/
-static void
-run_notify_score_change(sc_gameref_t game) {
+static void run_notify_score_change(sc_gameref_t game) {
const sc_gameref_t undo = game->undo;
sc_char buffer[32];
assert(gs_is_game_valid(undo));
@@ -630,10 +626,8 @@ run_notify_score_change(sc_gameref_t game) {
* if a task command matches, FALSE otherwise. Ordinary or reverse commands
* are selected by 'forwards'.
*/
-static sc_bool
-run_match_task_common(sc_gameref_t game,
- sc_int task, const sc_char *string, sc_bool forwards,
- sc_bool is_library, sc_bool is_normal) {
+static sc_bool run_match_task_common(sc_gameref_t game, sc_int task, const sc_char *string,
+ sc_bool forwards, sc_bool is_library, sc_bool is_normal) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
sc_int command_count, command;
@@ -682,10 +676,8 @@ run_match_task_common(sc_gameref_t game,
return is_matched;
}
-static sc_bool
-run_match_task_commands(sc_gameref_t game,
- sc_int task, const sc_char *string,
- sc_bool forwards, sc_bool is_library) {
+static sc_bool run_match_task_commands(sc_gameref_t game, sc_int task,
+ const sc_char *string, sc_bool forwards, sc_bool is_library) {
/*
* Match tasks using the normal pattern matcher, with or without any note
* about whether the call is from the library.
@@ -693,9 +685,8 @@ run_match_task_commands(sc_gameref_t game,
return run_match_task_common(game, task, string, forwards, is_library, TRUE);
}
-static sc_bool
-run_match_task_functions(sc_gameref_t game,
- sc_int task, const sc_char *string, sc_bool forwards) {
+static sc_bool run_match_task_functions(sc_gameref_t game, sc_int task,
+ const sc_char *string, sc_bool forwards) {
/* Match tasks against "task command functions". */
return run_match_task_common(game, task, string, forwards, FALSE, FALSE);
}
@@ -713,8 +704,7 @@ run_match_task_functions(sc_gameref_t game,
* indicates why it fails; such tasks, if run, produce their failure message
* and don't change state.
*/
-static sc_bool
-run_task_is_unrestricted(sc_gameref_t game, sc_int task) {
+static sc_bool run_task_is_unrestricted(sc_gameref_t game, sc_int task) {
sc_bool restrictions_passed;
const sc_char *fail_message;
@@ -732,8 +722,7 @@ run_task_is_unrestricted(sc_gameref_t game, sc_int task) {
return restrictions_passed;
}
-static sc_bool
-run_task_is_loudly_restricted(sc_gameref_t game, sc_int task) {
+static sc_bool run_task_is_loudly_restricted(sc_gameref_t game, sc_int task) {
sc_bool restrictions_passed;
const sc_char *fail_message;
@@ -788,9 +777,8 @@ run_task_is_loudly_restricted(sc_gameref_t game, sc_int task) {
* library to try to run "get " and "drop " game commands for standard get/drop
* handlers and get_all/drop_all handlers. No pressure, then.
*/
-static sc_bool
-run_game_commands_common(sc_gameref_t game, const sc_char *string,
- sc_bool include_restrictions, sc_bool is_library) {
+static sc_bool run_game_commands_common(sc_gameref_t game, const sc_char *string,
+ sc_bool include_restrictions, sc_bool is_library) {
sc_bool is_matched = FALSE, is_handled = FALSE;
sc_bool *is_matching;
sc_int task_count, task, direction;
@@ -883,9 +871,8 @@ run_game_commands_common(sc_gameref_t game, const sc_char *string,
return is_handled;
}
-static sc_bool
-run_game_commands_in_parser_context(sc_gameref_t game, const sc_char *string,
- sc_bool include_restrictions) {
+static sc_bool run_game_commands_in_parser_context(sc_gameref_t game,
+ const sc_char *string, sc_bool include_restrictions) {
/*
* Try game commands, either with or without restrictions, and all full and
* complete parse matching (no special case for game commands that begin
@@ -894,8 +881,7 @@ run_game_commands_in_parser_context(sc_gameref_t game, const sc_char *string,
return run_game_commands_common(game, string, include_restrictions, FALSE);
}
-static sc_bool
-run_game_commands_in_library_context(sc_gameref_t game, const sc_char *string) {
+static sc_bool run_game_commands_in_library_context(sc_gameref_t game, const sc_char *string) {
/*
* Try game commands, including restrictions, and noting that this is a
* library call so that the parse matcher can exclude game commands that
@@ -912,8 +898,7 @@ run_game_commands_in_library_context(sc_gameref_t game, const sc_char *string) {
* "task command functions". These seem to happen in addition to any regular
* command matches, so we try them as a separate action.
*/
-static void
-run_game_functions(sc_gameref_t game, const sc_char *string) {
+static void run_game_functions(sc_gameref_t game, const sc_char *string) {
sc_int task_count, task, direction;
/* Iterate over every task, ignoring those not runnable. */
@@ -947,8 +932,7 @@ run_game_functions(sc_gameref_t game, const sc_char *string) {
* main user input handling loop; the latter by the library when looking for
* game commands that override standard actions.
*/
-static sc_bool
-run_all_commands(sc_gameref_t game, const sc_char *string) {
+static sc_bool run_all_commands(sc_gameref_t game, const sc_char *string) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_bool status;
@@ -1009,8 +993,7 @@ run_all_commands(sc_gameref_t game, const sc_char *string) {
return status;
}
-sc_bool
-run_game_task_commands(sc_gameref_t game, const sc_char *string) {
+sc_bool run_game_task_commands(sc_gameref_t game, const sc_char *string) {
return run_game_commands_in_library_context(game, string);
}
@@ -1032,8 +1015,7 @@ run_game_task_commands(sc_gameref_t game, const sc_char *string) {
* this is a signal to reset all noted line input to initial conditions, and
* just return. Sorry about the ugliness.
*/
-static sc_bool
-run_player_input(sc_gameref_t game) {
+static sc_bool run_player_input(sc_gameref_t game) {
static sc_char line_buffer[LINE_BUFFER_SIZE];
static sc_char prior_element[LINE_BUFFER_SIZE];
static sc_char line_element[LINE_BUFFER_SIZE];
@@ -1254,8 +1236,7 @@ run_player_input(sc_gameref_t game) {
*
* Main interpreter loop.
*/
-static void
-run_main_loop(sc_gameref_t game) {
+static void run_main_loop(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
@@ -1436,8 +1417,7 @@ run_main_loop(sc_gameref_t game) {
*
* Create a game context from a callback.
*/
-sc_gameref_t
-run_create(sc_read_callbackref_t callback, void *opaque) {
+sc_gameref_t run_create(sc_read_callbackref_t callback, void *opaque) {
sc_tafref_t taf;
sc_prop_setref_t bundle;
sc_var_setref_t vars, temporary_vars, undo_vars;
@@ -1502,8 +1482,7 @@ run_create(sc_read_callbackref_t callback, void *opaque) {
*
* Return a game context to initial states to restart a game.
*/
-static void
-run_restart_handler(sc_gameref_t game) {
+static void run_restart_handler(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_gameref_t new_game;
@@ -1548,8 +1527,7 @@ run_restart_handler(sc_gameref_t game) {
*
* Adjust a game context for continuation after restoring a game.
*/
-static void
-run_restore_handler(sc_gameref_t game) {
+static void run_restore_handler(sc_gameref_t game) {
/* Invalidate the undo buffer. */
game->undo_available = FALSE;
@@ -1570,8 +1548,7 @@ run_restore_handler(sc_gameref_t game) {
*
* Tidy up printfilter and input statics on game quit.
*/
-static void
-run_quit_handler(sc_gameref_t game) {
+static void run_quit_handler(sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
@@ -1597,8 +1574,7 @@ run_quit_handler(sc_gameref_t game) {
*
* Intepret the game in a game context.
*/
-void
-run_interpret(sc_gameref_t game) {
+void run_interpret(sc_gameref_t game) {
assert(gs_is_game_valid(game));
/* Verify the game is not already running, and is runnable. */
@@ -1652,8 +1628,7 @@ run_interpret(sc_gameref_t game) {
*
* Destroy a game context, and free all resources.
*/
-void
-run_destroy(sc_gameref_t game) {
+void run_destroy(sc_gameref_t game) {
assert(gs_is_game_valid(game));
/* Can't destroy the context of a running game. */
@@ -1706,8 +1681,7 @@ run_destroy(sc_gameref_t game) {
* Quits a running game. This function calls a longjump to act as if
* run_main_loop() returned, and so never returns to its caller.
*/
-void
-run_quit(sc_gameref_t game) {
+void run_quit(sc_gameref_t game) {
assert(gs_is_game_valid(game));
/* Disallow quitting a non-running game. */
@@ -1730,8 +1704,7 @@ run_quit(sc_gameref_t game) {
* function calls a longjump to act as if run_main_loop() returned, and so
* never returns to its caller. For stopped games, it returns.
*/
-void
-run_restart(sc_gameref_t game) {
+void run_restart(sc_gameref_t game) {
assert(gs_is_game_valid(game));
/*
@@ -1757,16 +1730,14 @@ run_restart(sc_gameref_t game) {
*
* Saves either a running or a stopped game.
*/
-void
-run_save(sc_gameref_t game, sc_write_callbackref_t callback, void *opaque) {
+void run_save(sc_gameref_t game, sc_write_callbackref_t callback, void *opaque) {
assert(gs_is_game_valid(game));
assert(callback);
ser_save_game(game, callback, opaque);
}
-sc_bool
-run_save_prompted(sc_gameref_t game) {
+sc_bool run_save_prompted(sc_gameref_t game) {
assert(gs_is_game_valid(game));
return ser_save_game_prompted(game);
@@ -1784,9 +1755,7 @@ run_save_prompted(sc_gameref_t game) {
* restore, and for stopped games, they will return, with TRUE if successful,
* FALSE if restore failed.
*/
-static sc_bool
-run_restore_common(sc_gameref_t game,
- sc_read_callbackref_t callback, void *opaque) {
+static sc_bool run_restore_common(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
sc_bool is_running, status;
/*
@@ -1817,16 +1786,14 @@ run_restore_common(sc_gameref_t game,
return status;
}
-sc_bool
-run_restore(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
+sc_bool run_restore(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
assert(gs_is_game_valid(game));
assert(callback);
return run_restore_common(game, callback, opaque);
}
-sc_bool
-run_restore_prompted(sc_gameref_t game) {
+sc_bool run_restore_prompted(sc_gameref_t game) {
assert(gs_is_game_valid(game));
return run_restore_common(game, NULL, NULL);
@@ -1839,8 +1806,7 @@ run_restore_prompted(sc_gameref_t game) {
* Undo a turn in either a running or a stopped game. Returns TRUE on
* successful undo, FALSE if no undo buffer is available.
*/
-sc_bool
-run_undo(sc_gameref_t game) {
+sc_bool run_undo(sc_gameref_t game) {
const sc_memo_setref_t memento = gs_get_memento(game);
sc_bool is_running;
assert(gs_is_game_valid(game));
@@ -1896,8 +1862,7 @@ run_undo(sc_gameref_t game) {
*
* Query the game running state.
*/
-sc_bool
-run_is_running(sc_gameref_t game) {
+sc_bool run_is_running(sc_gameref_t game) {
assert(gs_is_game_valid(game));
return game->is_running;
@@ -1910,8 +1875,7 @@ run_is_running(sc_gameref_t game) {
* Query the game completion state. Completed games cannot be resumed,
* since they've run the exit task and thus have nowhere to go.
*/
-sc_bool
-run_has_completed(sc_gameref_t game) {
+sc_bool run_has_completed(sc_gameref_t game) {
assert(gs_is_game_valid(game));
return game->has_completed;
@@ -1923,8 +1887,7 @@ run_has_completed(sc_gameref_t game) {
*
* Query the game turn undo buffer and memo availability.
*/
-sc_bool
-run_is_undo_available(sc_gameref_t game) {
+sc_bool run_is_undo_available(sc_gameref_t game) {
const sc_memo_setref_t memento = gs_get_memento(game);
assert(gs_is_game_valid(game));
@@ -1938,15 +1901,10 @@ run_is_undo_available(sc_gameref_t game) {
*
* Get and set selected game attributes.
*/
-void
-run_get_attributes(sc_gameref_t game,
- const sc_char **game_name, const sc_char **game_author,
- const sc_char **game_compile_date,
- sc_int *turns, sc_int *score, sc_int *max_score,
- const sc_char **current_room_name,
- const sc_char **status_line, const sc_char **preferred_font,
- sc_bool *bold_room_names, sc_bool *verbose,
- sc_bool *notify_score_change) {
+void run_get_attributes(sc_gameref_t game, const sc_char **game_name, const sc_char **game_author,
+ const sc_char **game_compile_date, sc_int *turns, sc_int *score, sc_int *max_score,
+ const sc_char **current_room_name, const sc_char **status_line, const sc_char **preferred_font,
+ sc_bool *bold_room_names, sc_bool *verbose, sc_bool *notify_score_change) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_vartype_t vt_key[2];
@@ -2022,10 +1980,8 @@ run_get_attributes(sc_gameref_t game,
*notify_score_change = game->notify_score_change;
}
-void
-run_set_attributes(sc_gameref_t game,
- sc_bool bold_room_names, sc_bool verbose,
- sc_bool notify_score_change) {
+void run_set_attributes(sc_gameref_t game, sc_bool bold_room_names, sc_bool verbose,
+ sc_bool notify_score_change) {
assert(gs_is_game_valid(game));
/* Set game options. */
@@ -2044,8 +2000,7 @@ run_set_attributes(sc_gameref_t game,
* the token passed in and out is a pointer, and readily made opaque to
* the client as a void*.
*/
-sc_hintref_t
-run_hint_iterate(sc_gameref_t game, sc_hintref_t hint) {
+sc_hintref_t run_hint_iterate(sc_gameref_t game, sc_hintref_t hint) {
sc_int task;
assert(gs_is_game_valid(game));
@@ -2091,9 +2046,8 @@ run_hint_iterate(sc_gameref_t game, sc_hintref_t hint) {
*
* Hint strings are NULL if empty (not defined by the game).
*/
-static const sc_char *
-run_get_hint_common(sc_gameref_t game, sc_hintref_t hint,
- const sc_char * (*handler)(sc_gameref_t, sc_int)) {
+static const sc_char *run_get_hint_common(sc_gameref_t game, sc_hintref_t hint,
+ const sc_char * (*handler)(sc_gameref_t, sc_int)) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
sc_int task;
@@ -2129,18 +2083,15 @@ run_get_hint_common(sc_gameref_t game, sc_hintref_t hint,
return game->hint_text;
}
-const sc_char *
-run_get_hint_question(sc_gameref_t game, sc_hintref_t hint) {
+const sc_char *run_get_hint_question(sc_gameref_t game, sc_hintref_t hint) {
return run_get_hint_common(game, hint, task_get_hint_question);
}
-const sc_char *
-run_get_subtle_hint(sc_gameref_t game, sc_hintref_t hint) {
+const sc_char *run_get_subtle_hint(sc_gameref_t game, sc_hintref_t hint) {
return run_get_hint_common(game, hint, task_get_hint_subtle);
}
-const sc_char *
-run_get_unsubtle_hint(sc_gameref_t game, sc_hintref_t hint) {
+const sc_char *run_get_unsubtle_hint(sc_gameref_t game, sc_hintref_t hint) {
return run_get_hint_common(game, hint, task_get_hint_unsubtle);
}
diff --git a/engines/glk/adrift/scserial.cpp b/engines/glk/adrift/scserial.cpp
index 9c41db2..f069347 100644
--- a/engines/glk/adrift/scserial.cpp
+++ b/engines/glk/adrift/scserial.cpp
@@ -177,8 +177,7 @@ static void ser_flush(sc_bool is_final) {
#endif
}
-static void
-ser_buffer_character(sc_char character) {
+static void ser_buffer_character(sc_char character) {
/* Allocate the buffer if not yet done. */
if (!ser_buffer) {
assert(ser_buffer_length == 0);
@@ -202,8 +201,7 @@ ser_buffer_character(sc_char character) {
*
* Buffer a buffer, a string, an unsigned and signed integer, and a boolean.
*/
-static void
-ser_buffer_buffer(const sc_char *buffer, sc_int length) {
+static void ser_buffer_buffer(const sc_char *buffer, sc_int length) {
sc_int index_;
/* Add each character to the buffer. */
@@ -211,16 +209,14 @@ ser_buffer_buffer(const sc_char *buffer, sc_int length) {
ser_buffer_character(buffer[index_]);
}
-static void
-ser_buffer_string(const sc_char *string) {
+static void ser_buffer_string(const sc_char *string) {
/* Buffer string, followed by DOS style end-of-line. */
ser_buffer_buffer(string, strlen(string));
ser_buffer_character(CARRIAGE_RETURN);
ser_buffer_character(NEWLINE);
}
-static void
-ser_buffer_int(sc_int value) {
+static void ser_buffer_int(sc_int value) {
sc_char buffer[32];
/* Convert to a string and buffer that. */
@@ -228,8 +224,7 @@ ser_buffer_int(sc_int value) {
ser_buffer_string(buffer);
}
-static void
-ser_buffer_int_special(sc_int value) {
+static void ser_buffer_int_special(sc_int value) {
sc_char buffer[32];
/* Weirdo formatting for compatibility. */
@@ -237,8 +232,7 @@ ser_buffer_int_special(sc_int value) {
ser_buffer_string(buffer);
}
-static void
-ser_buffer_uint(sc_uint value) {
+static void ser_buffer_uint(sc_uint value) {
sc_char buffer[32];
/* Convert to a string and buffer that. */
@@ -246,8 +240,7 @@ ser_buffer_uint(sc_uint value) {
ser_buffer_string(buffer);
}
-static void
-ser_buffer_boolean(sc_bool boolean) {
+static void ser_buffer_boolean(sc_bool boolean) {
/* Write a 1 for TRUE, 0 for FALSE. */
ser_buffer_string(boolean ? "1" : "0");
}
@@ -258,9 +251,7 @@ ser_buffer_boolean(sc_bool boolean) {
*
* Serialize a game and save its state using the given callback and opaque.
*/
-void
-ser_save_game(sc_gameref_t game,
- sc_write_callbackref_t callback, void *opaque) {
+void ser_save_game(sc_gameref_t game, sc_write_callbackref_t callback, void *opaque) {
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -418,8 +409,7 @@ ser_save_game(sc_gameref_t game,
* Serialize a game and save its state, requesting a save stream from
* the user.
*/
-sc_bool
-ser_save_game_prompted(sc_gameref_t game) {
+sc_bool ser_save_game_prompted(sc_gameref_t game) {
void *opaque;
/*
@@ -453,8 +443,7 @@ static jmp_buf ser_tas_error;
* Wrapper round obtaining the next TAS file line, with variants to convert
* the line content into an appropriate type.
*/
-static const sc_char *
-ser_get_string(void) {
+static const sc_char *ser_get_string(void) {
const sc_char *string;
/* Get the next line, and complain if absent. */
@@ -468,8 +457,7 @@ ser_get_string(void) {
return string;
}
-static sc_int
-ser_get_int(void) {
+static sc_int ser_get_int(void) {
const sc_char *string;
sc_int value;
@@ -484,8 +472,7 @@ ser_get_int(void) {
return value;
}
-static sc_uint
-ser_get_uint(void) {
+static sc_uint ser_get_uint(void) {
const sc_char *string;
sc_uint value;
@@ -500,8 +487,7 @@ ser_get_uint(void) {
return value;
}
-static sc_bool
-ser_get_boolean(void) {
+static sc_bool ser_get_boolean(void) {
const sc_char *string;
sc_uint value;
@@ -530,9 +516,7 @@ ser_get_boolean(void) {
* Load a serialized game into the given game by repeated calls to the
* callback() function.
*/
-sc_bool
-ser_load_game(sc_gameref_t game,
- sc_read_callbackref_t callback, void *opaque) {
+sc_bool ser_load_game(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
static sc_var_setref_t new_vars; /* For setjmp safety */
static sc_gameref_t new_game; /* For setjmp safety */
@@ -753,8 +737,7 @@ ser_load_game(sc_gameref_t game,
* Load a serialized game into the given game, requesting a restore
* stream from the user.
*/
-sc_bool
-ser_load_game_prompted(sc_gameref_t game) {
+sc_bool ser_load_game_prompted(sc_gameref_t game) {
void *opaque;
/*
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index f365a7f..4bee769 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -94,7 +94,7 @@ struct sc_slabdesc_t {
sc_int size;
};
typedef sc_slabdesc_t *sc_slabdescref_t;
-typedef struct sc_taf_s {
+struct sc_taf_s {
sc_uint magic;
sc_byte header[VERSION_HEADER_SIZE + V400_HEADER_EXTRA];
sc_int version;
@@ -105,7 +105,8 @@ typedef struct sc_taf_s {
sc_bool is_unterminated;
sc_int current_slab;
sc_int current_offset;
-} sc_taf_t;
+};
+typedef sc_taf_s sc_taf_t;
/* Microsoft Visual Basic PRNG magic numbers, initial and current state. */
@@ -125,15 +126,13 @@ static sc_int taf_random_state = 0x00a09e86;
* we multiply by 255 and then divide by prng_cst3 + 1 to get output in the
* range 0..254. Thanks to Rik Snel for uncovering this obfuscation.
*/
-static sc_byte
-taf_random(void) {
+static sc_byte taf_random(void) {
/* Generate and return the next pseudo-random number. */
taf_random_state = (taf_random_state * PRNG_CST1 + PRNG_CST2) & PRNG_CST3;
return (UCHAR_MAX * (sc_uint) taf_random_state) / (sc_uint)(PRNG_CST3 + 1);
}
-static void
-taf_random_reset(void) {
+static void taf_random_reset(void) {
/* Reset PRNG to initial conditions. */
taf_random_state = PRNG_INITIAL_STATE;
}
@@ -144,8 +143,7 @@ taf_random_reset(void) {
*
* Return TRUE if pointer is a valid TAF structure, FALSE otherwise.
*/
-static sc_bool
-taf_is_valid(sc_tafref_t taf) {
+static sc_bool taf_is_valid(sc_tafref_t taf) {
return taf && taf->magic == TAF_MAGIC;
}
@@ -155,8 +153,7 @@ taf_is_valid(sc_tafref_t taf) {
*
* Allocate and return a new, empty TAF structure.
*/
-static sc_tafref_t
-taf_create_empty(void) {
+static sc_tafref_t taf_create_empty(void) {
sc_tafref_t taf;
/* Create an empty TAF structure. */
@@ -182,8 +179,7 @@ taf_create_empty(void) {
*
* Free TAF memory, and destroy a TAF structure.
*/
-void
-taf_destroy(sc_tafref_t taf) {
+void taf_destroy(sc_tafref_t taf) {
sc_int index_;
assert(taf_is_valid(taf));
@@ -207,8 +203,7 @@ taf_destroy(sc_tafref_t taf) {
* Insert nul's into slab data so that it turns into a series of nul-terminated
* strings. Nul's are used to replace carriage return and newline pairs.
*/
-static void
-taf_finalize_last_slab(sc_tafref_t taf) {
+static void taf_finalize_last_slab(sc_tafref_t taf) {
sc_slabdescref_t slab;
sc_int index_;
@@ -244,9 +239,7 @@ taf_finalize_last_slab(sc_tafref_t taf) {
* line feed. If none, found, return length and set is_unterminated to TRUE.
* Otherwise, return the count of usable bytes found in the buffer.
*/
-static sc_int
-taf_find_buffer_extent(const sc_byte *buffer,
- sc_int length, sc_bool *is_unterminated) {
+static sc_int taf_find_buffer_extent(const sc_byte *buffer, sc_int length, sc_bool *is_unterminated) {
sc_int bytes;
/* Search backwards from the buffer end for the final line feed. */
@@ -271,8 +264,7 @@ taf_find_buffer_extent(const sc_byte *buffer,
* Append a buffer of TAF lines to an existing TAF structure. Returns the
* number of characters consumed from the buffer.
*/
-static sc_int
-taf_append_buffer(sc_tafref_t taf, const sc_byte *buffer, sc_int length) {
+static sc_int taf_append_buffer(sc_tafref_t taf, const sc_byte *buffer, sc_int length) {
sc_int bytes;
sc_bool is_unterminated;
@@ -347,9 +339,8 @@ taf_append_buffer(sc_tafref_t taf, const sc_byte *buffer, sc_int length) {
* count of bytes placed in the buffer, or 0 if no more (end of file).
* Assumes that the file has been read past the header.
*/
-static sc_bool
-taf_unobfuscate(sc_tafref_t taf, sc_read_callbackref_t callback,
- void *opaque, sc_bool is_gamefile) {
+static sc_bool taf_unobfuscate(sc_tafref_t taf, sc_read_callbackref_t callback,
+ void *opaque, sc_bool is_gamefile) {
sc_byte *buffer;
sc_int bytes, used_bytes, total_bytes, index_;
@@ -427,7 +418,7 @@ taf_unobfuscate(sc_tafref_t taf, sc_read_callbackref_t callback,
* Decompress a version 4.0 TAF
*/
static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
- void *opaque, sc_bool is_gamefile) {
+ void *opaque, sc_bool is_gamefile) {
#if USE_ZLIB
Common::SeekableReadStream *src = (Common::SeekableReadStream *)opaque;
assert(src);
@@ -462,9 +453,8 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
* callback() function. Callback() should return the count of bytes placed
* in the buffer, or 0 if no more (end of file).
*/
-static sc_tafref_t
-taf_create_from_callback(sc_read_callbackref_t callback,
- void *opaque, sc_bool is_gamefile) {
+static sc_tafref_t taf_create_from_callback(sc_read_callbackref_t callback,
+ void *opaque, sc_bool is_gamefile) {
sc_tafref_t taf;
sc_bool status = FALSE;
assert(callback);
@@ -555,13 +545,11 @@ taf_create_from_callback(sc_read_callbackref_t callback,
* Public entry points for taf_create_from_callback(). Return a taf object
* constructed from either *.TAF (game) or *.TAS (saved game state) file data.
*/
-sc_tafref_t
-taf_create(sc_read_callbackref_t callback, void *opaque) {
+sc_tafref_t taf_create(sc_read_callbackref_t callback, void *opaque) {
return taf_create_from_callback(callback, opaque, TRUE);
}
-sc_tafref_t
-taf_create_tas(sc_read_callbackref_t callback, void *opaque) {
+sc_tafref_t taf_create_tas(sc_read_callbackref_t callback, void *opaque) {
return taf_create_from_callback(callback, opaque, FALSE);
}
@@ -571,8 +559,7 @@ taf_create_tas(sc_read_callbackref_t callback, void *opaque) {
*
* Iterator rewind function, reset current slab location to TAF data start.
*/
-void
-taf_first_line(sc_tafref_t taf) {
+void taf_first_line(sc_tafref_t taf) {
assert(taf_is_valid(taf));
/* Set current locations to TAF start. */
@@ -587,8 +574,7 @@ taf_first_line(sc_tafref_t taf) {
* Iterator function, return the next line of data from a TAF, or NULL
* if no more lines.
*/
-const sc_char *
-taf_next_line(sc_tafref_t taf) {
+const sc_char *taf_next_line(sc_tafref_t taf) {
assert(taf_is_valid(taf));
/* If there is a next line, return it and advance current. */
@@ -622,8 +608,7 @@ taf_next_line(sc_tafref_t taf) {
*
* Iterator end function, returns TRUE if more TAF lines are readable.
*/
-sc_bool
-taf_more_lines(sc_tafref_t taf) {
+sc_bool taf_more_lines(sc_tafref_t taf) {
assert(taf_is_valid(taf));
/* Return TRUE if not at TAF data end. */
@@ -638,8 +623,7 @@ taf_more_lines(sc_tafref_t taf) {
* appended to the TAF file after the game, so this value allows them to
* be located.
*/
-sc_int
-taf_get_game_data_length(sc_tafref_t taf) {
+sc_int taf_get_game_data_length(sc_tafref_t taf) {
assert(taf_is_valid(taf));
/*
@@ -656,8 +640,7 @@ taf_get_game_data_length(sc_tafref_t taf) {
*
* Return the version number of the TAF file, 400, 390, or 380.
*/
-sc_int
-taf_get_version(sc_tafref_t taf) {
+sc_int taf_get_version(sc_tafref_t taf) {
assert(taf_is_valid(taf));
assert(taf->version != TAF_VERSION_NONE);
@@ -673,8 +656,7 @@ taf_get_version(sc_tafref_t taf) {
* properties debugging, indicating if a given address is a string in a TAF
* slab, and therefore safe to print.
*/
-sc_bool
-taf_debug_is_taf_string(sc_tafref_t taf, const void *addr) {
+sc_bool taf_debug_is_taf_string(sc_tafref_t taf, const void *addr) {
const sc_byte *const addr_ = (const sc_byte * const)addr;
sc_int index_;
@@ -691,8 +673,7 @@ taf_debug_is_taf_string(sc_tafref_t taf, const void *addr) {
return FALSE;
}
-void
-taf_debug_dump(sc_tafref_t taf) {
+void taf_debug_dump(sc_tafref_t taf) {
sc_int index_, current_slab, current_offset;
assert(taf_is_valid(taf));
diff --git a/engines/glk/adrift/sctafpar.cpp b/engines/glk/adrift/sctafpar.cpp
index 9880603..6c2dcda 100644
--- a/engines/glk/adrift/sctafpar.cpp
+++ b/engines/glk/adrift/sctafpar.cpp
@@ -71,10 +71,10 @@ static const sc_byte V380_SEPARATOR[SEPARATOR_SIZE] = {0x2a, 0x2a, 0x00};
* |...| - fixup specials for versions < 4
* {special} - because some things just defy description
*/
-typedef struct {
+struct sc_parse_schema_t {
const sc_char *const class_name;
const sc_char *const descriptor;
-} sc_parse_schema_t;
+};
/* Version 4.0 TAF file properties descriptor table. */
static const sc_parse_schema_t V400_PARSE_SCHEMA[] = {
@@ -455,8 +455,7 @@ static const sc_parse_schema_t V380_PARSE_SCHEMA[] = {
*
* Select one of the parse schemata based on a TAF file.
*/
-static const sc_parse_schema_t *
-parse_select_schema(sc_tafref_t taf) {
+static const sc_parse_schema_t *parse_select_schema(sc_tafref_t taf) {
/* Switch based on the TAF file version. */
switch (taf_get_version(taf)) {
case TAF_VERSION_400:
@@ -499,8 +498,7 @@ static sc_int parse_depth = 0;
* Push a key of the given type onto the property key stack, and pop a key
* off on unwind.
*/
-static void
-parse_push_key(sc_vartype_t vt_key, sc_char type) {
+static void parse_push_key(sc_vartype_t vt_key, sc_char type) {
if (parse_depth == PARSE_MAX_DEPTH)
sc_fatal("parse_push_key: stack overrun\n");
@@ -510,8 +508,7 @@ parse_push_key(sc_vartype_t vt_key, sc_char type) {
parse_depth++;
}
-static void
-parse_pop_key(void) {
+static void parse_pop_key(void) {
/* Check the stack has something to pop, then pop it. */
if (parse_depth == 0)
sc_fatal("parse_pop_key: stack underrun\n");
@@ -526,8 +523,7 @@ parse_pop_key(void) {
* index. An expedient fix is to switch i-s keys before storing a property
* value
*/
-static void
-parse_retrieve_stack(sc_char format[], sc_vartype_t vt_key[], sc_int *depth) {
+static void parse_retrieve_stack(sc_char format[], sc_vartype_t vt_key[], sc_int *depth) {
sc_int index_;
/* Switch index-string key pairs. */
@@ -560,8 +556,7 @@ parse_retrieve_stack(sc_char format[], sc_vartype_t vt_key[], sc_int *depth) {
* Dump the parse stack. Used for diagnostics on finding what we think may
* be a bad game.
*/
-static void
-parse_stack_backtrace(void) {
+static void parse_stack_backtrace(void) {
sc_vartype_t vt_key[PARSE_MAX_DEPTH];
sc_char format[PARSE_MAX_DEPTH];
sc_int depth, index_;
@@ -595,8 +590,7 @@ parse_stack_backtrace(void) {
*
* Write or read a property based on the keys amassed so far.
*/
-static void
-parse_put_property(sc_vartype_t vt_value, sc_char type) {
+static void parse_put_property(sc_vartype_t vt_value, sc_char type) {
sc_vartype_t vt_key[PARSE_MAX_DEPTH];
sc_char format[PARSE_MAX_DEPTH + 4];
sc_int depth;
@@ -615,8 +609,7 @@ parse_put_property(sc_vartype_t vt_value, sc_char type) {
prop_put(parse_bundle, format, vt_value, vt_key);
}
-static sc_bool
-parse_get_property(sc_vartype_t *vt_rvalue, sc_char type) {
+static sc_bool parse_get_property(sc_vartype_t *vt_rvalue, sc_char type) {
sc_vartype_t vt_key[PARSE_MAX_DEPTH];
sc_char format[PARSE_MAX_DEPTH + 4];
sc_int depth;
@@ -646,8 +639,7 @@ parse_get_property(sc_vartype_t *vt_rvalue, sc_char type) {
* indicating the child count of the effectively stacked node, or zero if
* no such node exists.
*/
-static sc_int
-parse_get_child_count(void) {
+static sc_int parse_get_child_count(void) {
sc_vartype_t vt_rvalue;
if (!parse_get_property(&vt_rvalue, PROP_INTEGER))
@@ -665,8 +657,7 @@ parse_get_child_count(void) {
* Convenience forms of parse_get_property(), retrieve directly, and report
* a fatal error if the property does not exist.
*/
-static sc_int
-parse_get_integer_property(void) {
+static sc_int parse_get_integer_property(void) {
sc_vartype_t vt_rvalue;
if (!parse_get_property(&vt_rvalue, PROP_INTEGER))
@@ -675,8 +666,7 @@ parse_get_integer_property(void) {
return vt_rvalue.integer;
}
-static sc_bool
-parse_get_boolean_property(void) {
+static sc_bool parse_get_boolean_property(void) {
sc_vartype_t vt_rvalue;
if (!parse_get_property(&vt_rvalue, PROP_BOOLEAN))
@@ -685,8 +675,7 @@ parse_get_boolean_property(void) {
return vt_rvalue.boolean;
}
-static const sc_char *
-parse_get_string_property(void) {
+static const sc_char *parse_get_string_property(void) {
sc_vartype_t vt_rvalue;
if (!parse_get_property(&vt_rvalue, PROP_STRING))
@@ -713,8 +702,7 @@ static sc_bool parse_use_pushback = FALSE;
* the line content into an integer or boolean, and a function for effective
* TAF line pushback.
*/
-static const sc_char *
-parse_get_taf_string(void) {
+static const sc_char *parse_get_taf_string(void) {
const sc_char *line;
/* If pushback requested, use that instead of reading. */
@@ -745,8 +733,7 @@ parse_get_taf_string(void) {
return line;
}
-static sc_int
-parse_get_taf_integer(void) {
+static sc_int parse_get_taf_integer(void) {
const sc_char *line;
sc_int integer;
@@ -762,8 +749,7 @@ parse_get_taf_integer(void) {
return integer;
}
-static sc_bool
-parse_get_taf_boolean(void) {
+static sc_bool parse_get_taf_boolean(void) {
const sc_char *line;
sc_uint boolean;
@@ -786,8 +772,7 @@ parse_get_taf_boolean(void) {
return boolean != 0;
}
-static void
-parse_taf_pushback(void) {
+static void parse_taf_pushback(void) {
if (parse_use_pushback || !parse_pushback_line)
sc_fatal("parse_taf_pushback: too much pushback requested\n");
@@ -835,8 +820,7 @@ static void parse_descriptor(const sc_char *descriptor);
*
* Parse a descriptor [] array.
*/
-static void
-parse_array(const sc_char *array) {
+static void parse_array(const sc_char *array) {
sc_int count, index_;
sc_char element[PARSE_TEMP_LENGTH];
@@ -871,8 +855,7 @@ parse_array(const sc_char *array) {
*
* Parse a variable-length vector of properties.
*/
-static void
-parse_vector_common(const sc_char *vector, sc_int count) {
+static void parse_vector_common(const sc_char *vector, sc_int count) {
sc_int index_;
/* Parse the vector property count times, pushing a key on each. */
@@ -888,8 +871,7 @@ parse_vector_common(const sc_char *vector, sc_int count) {
}
}
-static void
-parse_vector(const sc_char *vector) {
+static void parse_vector(const sc_char *vector) {
sc_int count;
if (parse_trace)
@@ -903,8 +885,7 @@ parse_vector(const sc_char *vector) {
sc_trace("Parse: leaving vector %s\n", vector);
}
-static void
-parse_vector_alternate(const sc_char *vector) {
+static void parse_vector_alternate(const sc_char *vector) {
sc_int count;
if (parse_trace)
@@ -925,8 +906,7 @@ parse_vector_alternate(const sc_char *vector) {
*
* Parse a conditional field definition, with runtime test.
*/
-static sc_bool
-parse_test_expression(const sc_char *test_expression) {
+static sc_bool parse_test_expression(const sc_char *test_expression) {
sc_vartype_t vt_key;
sc_char plhs[PARSE_TEMP_LENGTH];
sc_int rhs;
@@ -985,8 +965,7 @@ parse_test_expression(const sc_char *test_expression) {
return retval;
}
-static void
-parse_expression(const sc_char *expression) {
+static void parse_expression(const sc_char *expression) {
sc_char test_expression[PARSE_TEMP_LENGTH];
sc_bool is_present;
@@ -1034,8 +1013,7 @@ parse_expression(const sc_char *expression) {
* Helper for parse_terminal(), reads in a multiline string. The return
* string is malloc'ed, and the caller needs to handle that.
*/
-static sc_char *
-parse_read_multiline(void) {
+static sc_char *parse_read_multiline(void) {
const sc_byte *separator = NULL;
const sc_char *line;
sc_char *multiline;
@@ -1080,8 +1058,7 @@ parse_read_multiline(void) {
*
* Common handler for string, integer, boolean, and multiline parse terminals.
*/
-static void
-parse_terminal(const sc_char *terminal) {
+static void parse_terminal(const sc_char *terminal) {
sc_vartype_t vt_key, vt_value;
if (parse_trace)
@@ -1157,12 +1134,12 @@ parse_terminal(const sc_char *terminal) {
* for the various sound and graphic resources encountered on parsing
* version 4.0 games. It's unused if the version is not 4.0.
*/
-typedef struct {
+struct sc_parse_resource_t {
sc_char *name;
sc_uint hash;
sc_int length;
sc_int offset;
-} sc_parse_resource_t;
+};
enum { RESOURCE_GROW_INCREMENT = 32 };
static sc_int parse_resources_length = 0;
@@ -1175,8 +1152,7 @@ static sc_parse_resource_t *parse_resources = NULL;
*
* Free and clear down the version 4.0 resources table.
*/
-static void
-parse_clear_v400_resources_table(void) {
+static void parse_clear_v400_resources_table(void) {
/* Free allocated memory and return to initial values. */
if (parse_resources) {
sc_int index_;
@@ -1205,9 +1181,8 @@ parse_clear_v400_resources_table(void) {
* lengths; this function needs to handle that. The caller needs to compare
* length with real_length to see if that happened.
*/
-static sc_int
-parse_get_v400_resource_offset(const sc_char *name,
- sc_int length, sc_int *real_length) {
+static sc_int parse_get_v400_resource_offset(const sc_char *name,
+ sc_int length, sc_int *real_length) {
sc_char *clean_name;
sc_uint hash;
sc_int index_, offset;
@@ -1290,8 +1265,7 @@ parse_get_v400_resource_offset(const sc_char *name,
* 'resource number'; -(length+2) is tantalizingly close to the index into
* our parse_resources table, but not always...
*/
-static void
-parse_handle_v400_resources(sc_bool has_sound, sc_bool has_graphics) {
+static void parse_handle_v400_resources(sc_bool has_sound, sc_bool has_graphics) {
sc_vartype_t vt_key, vt_value;
const sc_char *file;
sc_int length, offset;
@@ -1391,8 +1365,7 @@ parse_handle_v400_resources(sc_bool has_sound, sc_bool has_graphics) {
* Handler for special items that can't be described accurately, and
* therefore need careful treatment.
*/
-static void
-parse_special(const sc_char *special) {
+static void parse_special(const sc_char *special) {
if (parse_trace)
sc_trace("Parse: entering special %s\n", special);
@@ -1617,14 +1590,9 @@ parse_special(const sc_char *special) {
* Helper for parse_fixup_v390_v380_room_alts(). Handles creation of
* version 4.0 room alts for version 3.9 and version 3.8 games.
*/
-static void
-parse_fixup_v390_v380_room_alt(const sc_char *m1, sc_int type,
- const sc_char *resource1,
- const sc_char *m2, sc_int var2,
- const sc_char *resource2,
- sc_int hide_objects,
- const sc_char *changed,
- sc_int var3, sc_int display_room) {
+static void parse_fixup_v390_v380_room_alt(const sc_char *m1, sc_int type,
+ const sc_char *resource1, const sc_char *m2, sc_int var2, const sc_char *resource2,
+ sc_int hide_objects, const sc_char *changed, sc_int var3, sc_int display_room) {
sc_vartype_t vt_key, vt_value, vt_gkey[2];
sc_bool has_sound, has_graphics;
sc_int alt_count;
@@ -1830,8 +1798,7 @@ enum { V390_V380_ALT_TYPEHIDE_MULT = 10 };
* converts version 3.9 and version 3.8 fixed room description alts into
* an equivalent array of version 4.0 style room alts.
*/
-static void
-parse_fixup_v390_v380_room_alts(void) {
+static void parse_fixup_v390_v380_room_alts(void) {
sc_vartype_t vt_key;
const sc_char *m1, *m2, *changed;
sc_int type, var2, hide_objects, var3, display_room;
@@ -1956,8 +1923,7 @@ parse_fixup_v390_v380_room_alts(void) {
* Handler for fixup special items to help with conversions from TAF version
* 3.9 format into version 4.0.
*/
-static void
-parse_fixup_v390(const sc_char *fixup) {
+static void parse_fixup_v390(const sc_char *fixup) {
if (parse_trace)
sc_trace("Parse: entering version 3.9 fixup %s\n", fixup);
@@ -2106,9 +2072,8 @@ enum { V380_TASK_MOVEMENTS = 6 };
*
* Helper for parse_fixup_v380(), adds a task action.
*/
-static void
-parse_fixup_v380_action(sc_int type, sc_int var_count,
- sc_int var1, sc_int var2, sc_int var3) {
+static void parse_fixup_v380_action(sc_int type, sc_int var_count,
+ sc_int var1, sc_int var2, sc_int var3) {
sc_vartype_t vt_key, vt_value;
sc_int action_count;
@@ -2163,8 +2128,7 @@ parse_fixup_v380_action(sc_int type, sc_int var_count,
*
* Helper for parse_fixup_v380(), converts a task movement into an action.
*/
-static void
-parse_fixup_v380_movement(sc_int mvar1, sc_int mvar2, sc_int mvar3) {
+static void parse_fixup_v380_movement(sc_int mvar1, sc_int mvar2, sc_int mvar3) {
sc_int var1;
/* If nothing was selected to move, ignore the call. */
@@ -2245,10 +2209,8 @@ parse_fixup_v380_movement(sc_int mvar1, sc_int mvar2, sc_int mvar3) {
*
* Helper for parse_fixup_v380(), adds a task restriction.
*/
-static void
-parse_fixup_v380_restr(sc_int type, sc_int var_count,
- sc_int var1, sc_int var2, sc_int var3,
- const sc_char *failmessage) {
+static void parse_fixup_v380_restr(sc_int type, sc_int var_count,
+ sc_int var1, sc_int var2, sc_int var3, const sc_char *failmessage) {
sc_vartype_t vt_key, vt_value;
sc_int restriction_count;
@@ -2314,9 +2276,7 @@ parse_fixup_v380_restr(sc_int type, sc_int var_count,
*
* Helper handlers for parse_fixup_v380(); create task restrictions.
*/
-static void
-parse_fixup_v380_obj_restr(sc_bool holding,
- sc_int holdobj, const sc_char *failmessage) {
+static void parse_fixup_v380_obj_restr(sc_bool holding, sc_int holdobj, const sc_char *failmessage) {
/* Ignore if no object selected. */
if (holdobj > 0) {
sc_int var1, var2;
@@ -2332,9 +2292,7 @@ parse_fixup_v380_obj_restr(sc_bool holding,
}
}
-static void
-parse_fixup_v380_task_restr(sc_bool tasknotdone, sc_int task,
- const sc_char *failmessage) {
+static void parse_fixup_v380_task_restr(sc_bool tasknotdone, sc_int task, const sc_char *failmessage) {
/* Ignore if no task selected. */
if (task > 0) {
sc_int var2;
@@ -2345,8 +2303,7 @@ parse_fixup_v380_task_restr(sc_bool tasknotdone, sc_int task,
}
}
-static void
-parse_fixup_v380_wear_restr(sc_int wearobj, const sc_char *failmessage) {
+static void parse_fixup_v380_wear_restr(sc_int wearobj, const sc_char *failmessage) {
/* Ignore if no object selected. */
if (wearobj > 0) {
sc_vartype_t vt_key[3];
@@ -2403,9 +2360,8 @@ parse_fixup_v380_wear_restr(sc_int wearobj, const sc_char *failmessage) {
}
}
-static void
-parse_fixup_v380_npc_restr(sc_bool notinsameroom, sc_int npc,
- const sc_char *failmessage) {
+static void parse_fixup_v380_npc_restr(sc_bool notinsameroom, sc_int npc,
+ const sc_char *failmessage) {
/* Ignore if no NPC selected. */
if (npc > 0) {
sc_int var2;
@@ -2423,9 +2379,7 @@ parse_fixup_v380_npc_restr(sc_bool notinsameroom, sc_int npc,
}
}
-static void
-parse_fixup_v380_objroom_restr(sc_int obj, sc_int objroom,
- const sc_char *failmessage) {
+static void parse_fixup_v380_objroom_restr(sc_int obj, sc_int objroom, const sc_char *failmessage) {
/* Ignore if no object selected. */
if (obj > 0) {
/* Create version 4.0 restriction to check object in room. */
@@ -2433,9 +2387,8 @@ parse_fixup_v380_objroom_restr(sc_int obj, sc_int objroom,
}
}
-static void
-parse_fixup_v380_objstate_restr(sc_int obj, sc_int ivar1, sc_int ivar2,
- const sc_char *failmessage) {
+static void parse_fixup_v380_objstate_restr(sc_int obj, sc_int ivar1, sc_int ivar2,
+ const sc_char *failmessage) {
sc_vartype_t vt_key[3];
sc_int object, dynamic, var2, var3;
@@ -2519,8 +2472,7 @@ parse_fixup_v380_objstate_restr(sc_int obj, sc_int ivar1, sc_int ivar2,
* Handler for fixup special items to help with conversions from TAF version
* 3.8 format into version 4.0.
*/
-static void
-parse_fixup_v380(const sc_char *fixup) {
+static void parse_fixup_v380(const sc_char *fixup) {
if (parse_trace)
sc_trace("Parse: entering version 3.8 fixup %s\n", fixup);
@@ -3012,8 +2964,7 @@ parse_fixup_v380(const sc_char *fixup) {
* Handler for fixup special items to help with conversions from TAF version
* 3.9 and version 3.8 formats into version 4.0.
*/
-static void
-parse_fixup(const sc_char *fixup) {
+static void parse_fixup(const sc_char *fixup) {
/*
* Pick a fixup handler specific to the TAF version. This helps keep
* fixup code separate, rather than glommed into one large function.
@@ -3040,8 +2991,7 @@ parse_fixup(const sc_char *fixup) {
*
* Parse a class descriptor element.
*/
-static void
-parse_element(const sc_char *element) {
+static void parse_element(const sc_char *element) {
if (parse_trace)
sc_trace("Parse: entering element %s\n", element);
@@ -3096,8 +3046,7 @@ parse_element(const sc_char *element) {
*
* Parse a class's properties descriptor list.
*/
-static void
-parse_descriptor(const sc_char *descriptor) {
+static void parse_descriptor(const sc_char *descriptor) {
sc_int next;
/* Find and parse each element in the descriptor. */
@@ -3123,8 +3072,7 @@ parse_descriptor(const sc_char *descriptor) {
*
* Parse a class of properties.
*/
-static void
-parse_class(const sc_char *class_) {
+static void parse_class(const sc_char *class_) {
sc_char class_name[PARSE_TEMP_LENGTH];
sc_int index_;
sc_vartype_t vt_key;
@@ -3171,8 +3119,7 @@ parse_class(const sc_char *class_) {
* Add a list of all NPC walks started by each task. This is post-processing
* that occurs after the TAF file has been successfully parsed.
*/
-static void
-parse_add_walkalerts(sc_prop_setref_t bundle) {
+static void parse_add_walkalerts(sc_prop_setref_t bundle) {
sc_vartype_t vt_key[5];
sc_int npcs_count, npc;
@@ -3225,8 +3172,7 @@ parse_add_walkalerts(sc_prop_setref_t bundle) {
* Add a list of move times to all NPC walks. This is post-processing that
* occurs after the TAF file has been successfully parsed.
*/
-static void
-parse_add_movetimes(sc_prop_setref_t bundle) {
+static void parse_add_movetimes(sc_prop_setref_t bundle) {
sc_vartype_t vt_key[6];
sc_int npcs_count, npc;
@@ -3280,8 +3226,7 @@ parse_add_movetimes(sc_prop_setref_t bundle) {
* Sort ALRs by original string length and store an indexer property, so
* that ALR replacements look at longer strings before shorter ones.
*/
-static void
-parse_add_alrs_index(sc_prop_setref_t bundle) {
+static void parse_add_alrs_index(sc_prop_setref_t bundle) {
sc_vartype_t vt_key[3];
sc_int alr_count, index_, alr;
sc_int *alr_lengths, longest, shortest, length;
@@ -3345,8 +3290,7 @@ parse_add_alrs_index(sc_prop_setref_t bundle) {
* for version 4.0 games. For version 3.9 and version 3.8 games, write
* zero; only version 4.0 games can embed their resources into the TAF file.
*/
-static void
-parse_add_resources_offset(sc_prop_setref_t bundle, sc_tafref_t taf) {
+static void parse_add_resources_offset(sc_prop_setref_t bundle, sc_tafref_t taf) {
sc_vartype_t vt_key[2], vt_value;
sc_bool embedded;
sc_int offset;
@@ -3373,8 +3317,7 @@ parse_add_resources_offset(sc_prop_setref_t bundle, sc_tafref_t taf) {
* Add the TAF version to the properties, both integer and character forms
* for convenience.
*/
-static void
-parse_add_version(sc_prop_setref_t bundle, sc_tafref_t taf) {
+static void parse_add_version(sc_prop_setref_t bundle, sc_tafref_t taf) {
sc_vartype_t vt_key, vt_value;
/* Add the version integer to the properties. */
@@ -3469,8 +3412,7 @@ sc_bool parse_game(sc_tafref_t taf, sc_prop_setref_t bundle) {
*
* Set parse tracing on/off.
*/
-void
-parse_debug_trace(sc_bool flag) {
+void parse_debug_trace(sc_bool flag) {
parse_trace = flag;
}
diff --git a/engines/glk/adrift/sctasks.cpp b/engines/glk/adrift/sctasks.cpp
index 8273aff..cab6fcb 100644
--- a/engines/glk/adrift/sctasks.cpp
+++ b/engines/glk/adrift/sctasks.cpp
@@ -56,8 +56,7 @@ static sc_bool task_trace = FALSE;
* Return the assorted hint text strings, and TRUE if the given task offers
* hints.
*/
-static const sc_char *
-task_get_hint_common(sc_gameref_t game, sc_int task, const sc_char *hint) {
+static const sc_char *task_get_hint_common(sc_gameref_t game, sc_int task, const sc_char *hint) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
const sc_char *retval;
@@ -70,23 +69,19 @@ task_get_hint_common(sc_gameref_t game, sc_int task, const sc_char *hint) {
return retval;
}
-const sc_char *
-task_get_hint_question(sc_gameref_t game, sc_int task) {
+const sc_char *task_get_hint_question(sc_gameref_t game, sc_int task) {
return task_get_hint_common(game, task, "Question");
}
-const sc_char *
-task_get_hint_subtle(sc_gameref_t game, sc_int task) {
+const sc_char *task_get_hint_subtle(sc_gameref_t game, sc_int task) {
return task_get_hint_common(game, task, "Hint1");
}
-const sc_char *
-task_get_hint_unsubtle(sc_gameref_t game, sc_int task) {
+const sc_char *task_get_hint_unsubtle(sc_gameref_t game, sc_int task) {
return task_get_hint_common(game, task, "Hint2");
}
-sc_bool
-task_has_hints(sc_gameref_t game, sc_int task) {
+sc_bool task_has_hints(sc_gameref_t game, sc_int task) {
/* A non-empty question implies hints available. */
return !sc_strempty(task_get_hint_question(game, task));
}
@@ -98,9 +93,7 @@ task_has_hints(sc_gameref_t game, sc_int task) {
* Return TRUE if player is in a room where the task can be run and the task
* is runnable in the given direction.
*/
-sc_bool
-task_can_run_task_directional(sc_gameref_t game,
- sc_int task, sc_bool forwards) {
+sc_bool task_can_run_task_directional(sc_gameref_t game, sc_int task, sc_bool forwards) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int type;
@@ -169,8 +162,7 @@ task_can_run_task_directional(sc_gameref_t game,
*
* Returns TRUE if the task can be run in either direction.
*/
-sc_bool
-task_can_run_task(sc_gameref_t game, sc_int task) {
+sc_bool task_can_run_task(sc_gameref_t game, sc_int task) {
/*
* Testing reversible tasks first may be a little more efficient if they
* aren't common in games. There is, though, probably a little bit of
@@ -186,8 +178,7 @@ task_can_run_task(sc_gameref_t game, sc_int task) {
*
* Move an object to a place.
*/
-static void
-task_move_object(sc_gameref_t game, sc_int object, sc_int var2, sc_int var3) {
+static void task_move_object(sc_gameref_t game, sc_int object, sc_int var2, sc_int var3) {
const sc_var_setref_t vars = gs_get_vars(game);
/* Select action depending on var2. */
@@ -291,9 +282,7 @@ task_move_object(sc_gameref_t game, sc_int object, sc_int var2, sc_int var3) {
*
* Demultiplex an object move action and execute it.
*/
-static void
-task_run_move_object_action(sc_gameref_t game,
- sc_int var1, sc_int var2, sc_int var3) {
+static void task_run_move_object_action(sc_gameref_t game, sc_int var1, sc_int var2, sc_int var3) {
const sc_var_setref_t vars = gs_get_vars(game);
sc_int object;
@@ -331,8 +320,7 @@ task_run_move_object_action(sc_gameref_t game,
*
* Move an NPC to a given room.
*/
-static void
-task_move_npc_to_room(sc_gameref_t game, sc_int npc, sc_int room) {
+static void task_move_npc_to_room(sc_gameref_t game, sc_int npc, sc_int room) {
if (task_trace)
sc_trace("Task: moving NPC %ld to room %ld\n", npc, room);
@@ -354,9 +342,7 @@ task_move_npc_to_room(sc_gameref_t game, sc_int npc, sc_int room) {
*
* Move player or NPC.
*/
-static void
-task_run_move_npc_action(sc_gameref_t game,
- sc_int var1, sc_int var2, sc_int var3) {
+static void task_run_move_npc_action(sc_gameref_t game, sc_int var1, sc_int var2, sc_int var3) {
const sc_var_setref_t vars = gs_get_vars(game);
sc_int npc, room, ref_npc = -1;
@@ -506,8 +492,7 @@ task_run_move_npc_action(sc_gameref_t game,
*
* Change the status of an object.
*/
-static void
-task_run_change_object_status(sc_gameref_t game, sc_int var1, sc_int var2) {
+static void task_run_change_object_status(sc_gameref_t game, sc_int var1, sc_int var2) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
sc_int object, openable, lockable;
@@ -560,10 +545,8 @@ task_run_change_object_status(sc_gameref_t game, sc_int var1, sc_int var2) {
*
* Change a variable's value in inscrutable ways.
*/
-static void
-task_run_change_variable_action(sc_gameref_t game,
- sc_int var1, sc_int var2, sc_int var3,
- const sc_char *expr, sc_int var5) {
+static void task_run_change_variable_action(sc_gameref_t game,
+ sc_int var1, sc_int var2, sc_int var3, const sc_char *expr, sc_int var5) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
const sc_var_setref_t vars = gs_get_vars(game);
@@ -714,8 +697,7 @@ task_run_change_variable_action(sc_gameref_t game,
*
* Change game score.
*/
-static void
-task_run_change_score_action(sc_gameref_t game, sc_int task, sc_int var1) {
+static void task_run_change_score_action(sc_gameref_t game, sc_int task, sc_int var1) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
/* Increasing or decreasing the score? */
@@ -773,8 +755,7 @@ task_run_change_score_action(sc_gameref_t game, sc_int task, sc_int var1) {
*
* Redirect to another task.
*/
-static sc_bool
-task_run_set_task_action(sc_gameref_t game, sc_int var1, sc_int var2) {
+static sc_bool task_run_set_task_action(sc_gameref_t game, sc_int var1, sc_int var2) {
sc_bool status = FALSE;
/* Select based on var1. */
@@ -805,8 +786,7 @@ task_run_set_task_action(sc_gameref_t game, sc_int var1, sc_int var2) {
*
* End of game task action.
*/
-static sc_bool
-task_run_end_game_action(sc_gameref_t game, sc_int var1) {
+static sc_bool task_run_end_game_action(sc_gameref_t game, sc_int var1) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_bool status = FALSE;
@@ -868,8 +848,7 @@ task_run_end_game_action(sc_gameref_t game, sc_int var1) {
*
* Demultiplexer for task actions.
*/
-static sc_bool
-task_run_task_action(sc_gameref_t game, sc_int task, sc_int action) {
+static sc_bool task_run_task_action(sc_gameref_t game, sc_int task, sc_int action) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[5];
sc_int type, var1, var2, var3, var5;
@@ -966,8 +945,7 @@ task_run_task_action(sc_gameref_t game, sc_int task, sc_int action) {
* game, return immediately. Returns TRUE if any action ran and itself
* returned TRUE.
*/
-static sc_bool
-task_run_task_actions(sc_gameref_t game, sc_int task) {
+static sc_bool task_run_task_actions(sc_gameref_t game, sc_int task) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -1031,8 +1009,7 @@ task_run_task_actions(sc_gameref_t game, sc_int task) {
*
* Start NPC walks based on alerts.
*/
-static void
-task_start_npc_walks(sc_gameref_t game, sc_int task) {
+static void task_start_npc_walks(sc_gameref_t game, sc_int task) {
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[4];
sc_int alert_count, alert;
@@ -1064,8 +1041,7 @@ task_start_npc_walks(sc_gameref_t game, sc_int task) {
* outputting a message describing what prevented it, or why it couldn't be
* done.
*/
-static sc_bool
-task_run_task_unrestricted(sc_gameref_t game, sc_int task, sc_bool forwards) {
+static sc_bool task_run_task_unrestricted(sc_gameref_t game, sc_int task, sc_bool forwards) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
sc_vartype_t vt_key[3];
@@ -1221,8 +1197,7 @@ task_run_task_unrestricted(sc_gameref_t game, sc_int task, sc_bool forwards) {
* task with an error message if we seem to be in one. Checked by counting
* the call depth.
*/
-sc_bool
-task_run_task(sc_gameref_t game, sc_int task, sc_bool forwards) {
+sc_bool task_run_task(sc_gameref_t game, sc_int task, sc_bool forwards) {
static sc_int recursion_depth = 0;
const sc_filterref_t filter = gs_get_filter(game);
@@ -1288,8 +1263,7 @@ task_run_task(sc_gameref_t game, sc_int task, sc_bool forwards) {
*
* Set task tracing on/off.
Commit: 60c23ffaaf867777bde2001626d198cc4cce7d4b
https://github.com/scummvm/scummvm/commit/60c23ffaaf867777bde2001626d198cc4cce7d4b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Fix save serialization to memos
Changed paths:
engines/glk/adrift/scserial.cpp
diff --git a/engines/glk/adrift/scserial.cpp b/engines/glk/adrift/scserial.cpp
index f069347..7b9a161 100644
--- a/engines/glk/adrift/scserial.cpp
+++ b/engines/glk/adrift/scserial.cpp
@@ -51,130 +51,13 @@ static void *ser_opaque = NULL;
* Flush pending buffer contents; add a character to the buffer.
*/
static void ser_flush(sc_bool is_final) {
- error("TODO");
-#ifdef TODO
- static sc_bool initialized = FALSE;
- static sc_byte *out_buffer = NULL;
- static sc_int out_buffer_size = 0;
- static z_stream stream;
-
- sc_int status;
-
- /* If this is an initial call, initialize deflation. */
- if (!initialized) {
- /* Allocate an initial output buffer. */
- out_buffer_size = BUFFER_SIZE;
- out_buffer = sc_malloc(out_buffer_size);
-
- /* Initialize Zlib deflation functions. */
- stream.next_out = out_buffer;
- stream.avail_out = out_buffer_size;
- stream.next_in = ser_buffer;
- stream.avail_in = 0;
-
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- status = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
- if (status != Z_OK) {
- sc_error("ser_flush: deflateInit: error %ld\n", status);
- ser_buffer_length = 0;
-
- sc_free(out_buffer);
- out_buffer = NULL;
- out_buffer_size = 0;
- return;
- }
-
- initialized = TRUE;
- }
-
- /* Deflate data from the current output buffer. */
- stream.next_in = ser_buffer;
- stream.avail_in = ser_buffer_length;
-
- /* Loop while deflate output is pending and buffer not emptied. */
- while (TRUE) {
- sc_int in_bytes, out_bytes;
-
- /* Compress stream data, with finish if this is the final flush. */
- if (is_final)
- status = deflate(&stream, Z_FINISH);
- else
- status = deflate(&stream, Z_NO_FLUSH);
- if (status != Z_STREAM_END && status != Z_OK) {
- sc_error("ser_flush: deflate: error %ld\n", status);
- ser_buffer_length = 0;
-
- sc_free(out_buffer);
- out_buffer = NULL;
- out_buffer_size = 0;
- initialized = FALSE;
- return;
- }
-
- /* Calculate bytes used, and output. */
- in_bytes = ser_buffer_length - stream.avail_in;
- out_bytes = out_buffer_size - stream.avail_out;
-
- /* See if compressed data is available. */
- if (out_bytes > 0) {
- /* Write it to save file output through the callback. */
- ser_callback(ser_opaque, out_buffer, out_bytes);
-
- /* Reset deflation stream for available space. */
- stream.next_out = out_buffer;
- stream.avail_out = out_buffer_size;
- }
-
- /* Remove consumed data from the input buffer. */
- if (in_bytes > 0) {
- /* Move any unused data, and reduce length. */
- memmove(ser_buffer,
- ser_buffer + in_bytes, ser_buffer_length - in_bytes);
- ser_buffer_length -= in_bytes;
-
- /* Reset deflation stream for consumed data. */
- stream.next_in = ser_buffer;
- stream.avail_in = ser_buffer_length;
- }
-
- /* If final flush, wait until deflate indicates finished. */
- if (is_final && status == Z_OK)
- continue;
-
- /* If data was consumed or produced, break. */
- if (out_bytes > 0 || in_bytes > 0)
- break;
- }
-
- /* If this was a final call, clean up. */
if (is_final) {
- /* Compression completed. */
- status = deflateEnd(&stream);
- if (status != Z_OK)
- sc_error("ser_flush: warning: deflateEnd: error %ld\n", status);
-
- if (ser_buffer_length != 0) {
- sc_error("ser_flush: warning: deflate missed data\n");
- ser_buffer_length = 0;
- }
+ ser_callback(ser_opaque, ser_buffer, ser_buffer_length);
- /* Free the allocated compression buffer. */
sc_free(ser_buffer);
- ser_buffer = NULL;
-
- /*
- * Free output buffer, and reset flag for reinitialization on the next
- * call.
- */
- sc_free(out_buffer);
- out_buffer = NULL;
- out_buffer_size = 0;
- initialized = FALSE;
+ ser_buffer = nullptr;
+ ser_buffer_length = 0;
}
-#endif
}
static void ser_buffer_character(sc_char character) {
@@ -187,7 +70,7 @@ static void ser_buffer_character(sc_char character) {
/* Add to the buffer, with intermediate flush if filled. */
ser_buffer[ser_buffer_length++] = character;
if (ser_buffer_length == BUFFER_SIZE)
- ser_flush(FALSE);
+ error("Ran out of serialization buffer");
}
Commit: 0026f9ab5e18bc8eebcd6b7dc1973bcfab39e1dd
https://github.com/scummvm/scummvm/commit/0026f9ab5e18bc8eebcd6b7dc1973bcfab39e1dd
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: In progress implementing savegames
Changed paths:
engines/glk/adrift/adrift.cpp
engines/glk/adrift/adrift.h
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/os_glk.h
engines/glk/adrift/scprotos.h
engines/glk/adrift/scserial.cpp
engines/glk/quetzal.cpp
diff --git a/engines/glk/adrift/adrift.cpp b/engines/glk/adrift/adrift.cpp
index 9ba4e1c..b376864 100644
--- a/engines/glk/adrift/adrift.cpp
+++ b/engines/glk/adrift/adrift.cpp
@@ -22,6 +22,7 @@
#include "glk/adrift/adrift.h"
#include "glk/adrift/os_glk.h"
+#include "glk/adrift/scprotos.h"
namespace Glk {
namespace Adrift {
@@ -38,12 +39,23 @@ void Adrift::runGame() {
}
Common::Error Adrift::readSaveData(Common::SeekableReadStream *rs) {
- return Common::kNoError;
+ return ser_load_game((sc_gameref_t)gsc_game, if_read_saved_game, rs) ? Common::kNoError : Common::kReadingFailed;
}
Common::Error Adrift::writeGameData(Common::WriteStream *ws) {
+ ser_save_game((sc_gameref_t)gsc_game, if_write_saved_game, ws);
return Common::kNoError;
}
+sc_int Adrift::if_read_saved_game(void *opaque, sc_byte *buffer, sc_int length) {
+ Common::SeekableReadStream *rs = (Common::SeekableReadStream *)opaque;
+ return rs->read(buffer, length);
+}
+
+void Adrift::if_write_saved_game(void *opaque, const sc_byte *buffer, sc_int length) {
+ Common::WriteStream *ws = (Common::WriteStream *)opaque;
+ ws->write(buffer, length);
+}
+
} // End of namespace Adrift
} // End of namespace Glk
diff --git a/engines/glk/adrift/adrift.h b/engines/glk/adrift/adrift.h
index 81d7d30..006293a 100644
--- a/engines/glk/adrift/adrift.h
+++ b/engines/glk/adrift/adrift.h
@@ -27,6 +27,7 @@
#include "common/serializer.h"
#include "common/stack.h"
#include "glk/glk_api.h"
+#include "glk/adrift/scare.h"
namespace Glk {
namespace Adrift {
@@ -45,6 +46,9 @@ private:
* Deinitialization
*/
void deinitialize();
+
+ static void if_write_saved_game(void *opaque, const sc_byte *buffer, sc_int length);
+ static sc_int if_read_saved_game(void *opaque, sc_byte *buffer, sc_int length);
public:
/**
* Constructor
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index cfe61ac..c9c9c0c 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -78,7 +78,7 @@ static int gsc_commands_enabled = TRUE, gsc_abbreviations_enabled = TRUE,
gsc_unicode_enabled = TRUE;
/* Adrift game to interpret. */
-static sc_game gsc_game = nullptr;
+sc_game gsc_game = nullptr;
/* Special out-of-band os_confirm() options used locally with os_glk. */
static const sc_int GSC_CONF_SUBTLE_HINT = INT_MAX,
diff --git a/engines/glk/adrift/os_glk.h b/engines/glk/adrift/os_glk.h
index 52c7d89..7772b8f 100644
--- a/engines/glk/adrift/os_glk.h
+++ b/engines/glk/adrift/os_glk.h
@@ -29,6 +29,8 @@
namespace Glk {
namespace Adrift {
+extern sc_game gsc_game;
+
extern bool adrift_startup_code(Common::SeekableReadStream *gameFile);
extern void adrift_main();
diff --git a/engines/glk/adrift/scprotos.h b/engines/glk/adrift/scprotos.h
index 9601f06..4172cfe 100644
--- a/engines/glk/adrift/scprotos.h
+++ b/engines/glk/adrift/scprotos.h
@@ -779,8 +779,6 @@ extern void if_read_line(sc_char *buffer, sc_int length);
extern void if_read_debug(sc_char *buffer, sc_int length);
extern sc_bool if_confirm(sc_int type);
extern void *if_open_saved_game(sc_bool is_save);
-extern void if_write_saved_game(void *opaque, const sc_byte *buffer, sc_int length);
-extern sc_int if_read_saved_game(void *opaque, sc_byte *buffer, sc_int length);
extern void if_close_saved_game(void *opaque);
extern void if_display_hints(sc_gameref_t game);
extern void if_update_sound(const sc_char *filepath, sc_int sound_offset,
diff --git a/engines/glk/adrift/scserial.cpp b/engines/glk/adrift/scserial.cpp
index 7b9a161..fb771de 100644
--- a/engines/glk/adrift/scserial.cpp
+++ b/engines/glk/adrift/scserial.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "glk/adrift/scare.h"
+#include "glk/adrift/adrift.h"
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
#include "common/textconsole.h"
@@ -293,20 +293,7 @@ void ser_save_game(sc_gameref_t game, sc_write_callbackref_t callback, void *opa
* the user.
*/
sc_bool ser_save_game_prompted(sc_gameref_t game) {
- void *opaque;
-
- /*
- * Open an output stream, and if successful, save a game using the opaque
- * value returned.
- */
- opaque = if_open_saved_game(TRUE);
- if (opaque) {
- ser_save_game(game, if_write_saved_game, opaque);
- if_close_saved_game(opaque);
- return TRUE;
- }
-
- return FALSE;
+ return g_vm->saveGame().getCode() == Common::kNoError;
}
@@ -621,22 +608,7 @@ sc_bool ser_load_game(sc_gameref_t game, sc_read_callbackref_t callback, void *o
* stream from the user.
*/
sc_bool ser_load_game_prompted(sc_gameref_t game) {
- void *opaque;
-
- /*
- * Open an input stream, and if successful, try to load a game using
- * the opaque value returned and the saved game callback.
- */
- opaque = if_open_saved_game(FALSE);
- if (opaque) {
- sc_bool status;
-
- status = ser_load_game(game, if_read_saved_game, opaque);
- if_close_saved_game(opaque);
- return status;
- }
-
- return FALSE;
+ return g_vm->loadGame().getCode() == Common::kNoError;
}
} // End of namespace Adrift
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
index b83d855..e604602 100644
--- a/engines/glk/quetzal.cpp
+++ b/engines/glk/quetzal.cpp
@@ -31,10 +31,12 @@
namespace Glk {
const uint32 INTERPRETER_IDS[INTERPRETER_TADS3 + 1] = {
+ MKTAG('A', 'D', 'R', 'I'),
MKTAG('A', 'S', 'Y', 'S'),
MKTAG('A', 'G', 'I', 'L'),
MKTAG('A', 'L', 'N', '2'),
MKTAG('A', 'L', 'N', '3'),
+ MKTAG('B', 'O', 'C', 'F'),
MKTAG('Z', 'C', 'O', 'D'),
MKTAG('G', 'E', 'A', 'S'),
MKTAG('G', 'L', 'U', 'L'),
Commit: 994afedd33de0e298425933945a47e6dacb3a138
https://github.com/scummvm/scummvm/commit/994afedd33de0e298425933945a47e6dacb3a138
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Encapsulation serialization code into their own classes
Changed paths:
A engines/glk/adrift/serialization.cpp
A engines/glk/adrift/serialization.h
R engines/glk/adrift/scserial.cpp
engines/glk/adrift/adrift.cpp
engines/glk/adrift/sclibrar.cpp
engines/glk/adrift/scmemos.cpp
engines/glk/adrift/scprotos.h
engines/glk/adrift/scrunner.cpp
engines/glk/module.mk
diff --git a/engines/glk/adrift/adrift.cpp b/engines/glk/adrift/adrift.cpp
index b376864..ed83944 100644
--- a/engines/glk/adrift/adrift.cpp
+++ b/engines/glk/adrift/adrift.cpp
@@ -23,6 +23,7 @@
#include "glk/adrift/adrift.h"
#include "glk/adrift/os_glk.h"
#include "glk/adrift/scprotos.h"
+#include "glk/adrift/serialization.h"
namespace Glk {
namespace Adrift {
@@ -39,11 +40,12 @@ void Adrift::runGame() {
}
Common::Error Adrift::readSaveData(Common::SeekableReadStream *rs) {
- return ser_load_game((sc_gameref_t)gsc_game, if_read_saved_game, rs) ? Common::kNoError : Common::kReadingFailed;
+ LoadSerializer ser((sc_gameref_t)gsc_game, if_read_saved_game, rs);
+ return ser.load() ? Common::kNoError : Common::kReadingFailed;
}
Common::Error Adrift::writeGameData(Common::WriteStream *ws) {
- ser_save_game((sc_gameref_t)gsc_game, if_write_saved_game, ws);
+ SaveSerializer ser((sc_gameref_t)gsc_game, if_write_saved_game, ws);
return Common::kNoError;
}
diff --git a/engines/glk/adrift/sclibrar.cpp b/engines/glk/adrift/sclibrar.cpp
index 51e4224..c17a3a7 100644
--- a/engines/glk/adrift/sclibrar.cpp
+++ b/engines/glk/adrift/sclibrar.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "glk/adrift/scare.h"
+#include "glk/adrift/adrift.h"
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
+#include "glk/adrift/serialization.h"
namespace Glk {
namespace Adrift {
@@ -8205,7 +8206,7 @@ sc_bool lib_cmd_get_off(sc_gameref_t game) {
*/
sc_bool lib_cmd_save(sc_gameref_t game) {
if (if_confirm(SC_CONF_SAVE)) {
- if (ser_save_game_prompted(game))
+ if (g_vm->saveGame().getCode() == Common::kNoError)
if_print_string("Ok.\n");
else
if_print_string("Save failed.\n");
@@ -8217,12 +8218,13 @@ sc_bool lib_cmd_save(sc_gameref_t game) {
sc_bool lib_cmd_restore(sc_gameref_t game) {
if (if_confirm(SC_CONF_RESTORE)) {
- if (ser_load_game_prompted(game)) {
+ if (g_vm->loadGame().getCode() == Common::kNoError) {
if_print_string("Ok.\n");
game->is_running = FALSE;
game->do_restore = TRUE;
- } else
+ } else {
if_print_string("Restore failed.\n");
+ }
}
game->is_admin = TRUE;
diff --git a/engines/glk/adrift/scmemos.cpp b/engines/glk/adrift/scmemos.cpp
index 88720f2..c26f684 100644
--- a/engines/glk/adrift/scmemos.cpp
+++ b/engines/glk/adrift/scmemos.cpp
@@ -22,6 +22,7 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
+#include "glk/adrift/serialization.h"
namespace Glk {
namespace Adrift {
@@ -201,7 +202,8 @@ void memo_save_game(sc_memo_setref_t memento, sc_gameref_t game) {
memo->length = 0;
/* Serialize the given game into this memo. */
- ser_save_game(game, memo_save_game_callback, memo);
+ SaveSerializer ser(game, memo_save_game_callback, memo);
+ ser.save();
/*
* If serialization worked (failure would be a surprise), advance the
@@ -263,7 +265,8 @@ sc_bool memo_load_game(sc_memo_setref_t memento, sc_gameref_t game) {
* Deserialize the given game from this memo; failure would be somewhat
* of a surprise here.
*/
- status = ser_load_game(game, memo_load_game_callback, memo);
+ LoadSerializer ser(game, memo_load_game_callback, memo);
+ status = ser.load();
if (!status)
sc_error("memo_load_game: warning: game load failed\n");
diff --git a/engines/glk/adrift/scprotos.h b/engines/glk/adrift/scprotos.h
index 4172cfe..37d2bdc 100644
--- a/engines/glk/adrift/scprotos.h
+++ b/engines/glk/adrift/scprotos.h
@@ -738,14 +738,6 @@ extern sc_bool obj_shows_initial_description(sc_gameref_t game, sc_int object);
extern void obj_turn_update(sc_gameref_t game);
extern void obj_debug_trace(sc_bool flag);
-/* Game serialization functions. */
-extern void ser_save_game(sc_gameref_t game,
- sc_write_callbackref_t callback, void *opaque);
-extern sc_bool ser_save_game_prompted(sc_gameref_t game);
-extern sc_bool ser_load_game(sc_gameref_t game,
- sc_read_callbackref_t callback, void *opaque);
-extern sc_bool ser_load_game_prompted(sc_gameref_t game);
-
/* Locale support, and locale-sensitive functions. */
extern void loc_detect_game_locale(sc_prop_setref_t bundle);
extern sc_bool loc_set_locale(const sc_char *name);
diff --git a/engines/glk/adrift/scrunner.cpp b/engines/glk/adrift/scrunner.cpp
index 95c8f19..288ca83 100644
--- a/engines/glk/adrift/scrunner.cpp
+++ b/engines/glk/adrift/scrunner.cpp
@@ -23,6 +23,7 @@
#include "glk/adrift/adrift.h"
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
+#include "glk/adrift/serialization.h"
namespace Glk {
namespace Adrift {
@@ -1734,16 +1735,16 @@ void run_save(sc_gameref_t game, sc_write_callbackref_t callback, void *opaque)
assert(gs_is_game_valid(game));
assert(callback);
- ser_save_game(game, callback, opaque);
+ SaveSerializer ser(game, callback, opaque);
+ ser.save();
}
sc_bool run_save_prompted(sc_gameref_t game) {
assert(gs_is_game_valid(game));
- return ser_save_game_prompted(game);
+ return g_vm->saveGame().getCode() == Common::kNoError;
}
-
/*
* run_restore_common()
* run_restore()
@@ -1764,8 +1765,8 @@ static sc_bool run_restore_common(sc_gameref_t game, sc_read_callbackref_t callb
* callback of NULL; callback cannot be NULL for run_restore() calls.
*/
is_running = game->is_running;
- status = callback ? ser_load_game(game, callback, opaque)
- : ser_load_game_prompted(game);
+ LoadSerializer ser(game, callback, opaque);
+ status = ser.load();
if (status) {
/* Loading a game clears is_running -- restore it here. */
game->is_running = is_running;
diff --git a/engines/glk/adrift/scserial.cpp b/engines/glk/adrift/scserial.cpp
deleted file mode 100644
index fb771de..0000000
--- a/engines/glk/adrift/scserial.cpp
+++ /dev/null
@@ -1,615 +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/adrift/adrift.h"
-#include "glk/adrift/scprotos.h"
-#include "glk/adrift/scgamest.h"
-#include "common/textconsole.h"
-
-namespace Glk {
-namespace Adrift {
-
-/* Assorted definitions and constants. */
-static const sc_char NEWLINE = '\n';
-static const sc_char CARRIAGE_RETURN = '\r';
-static const sc_char NUL = '\0';
-
-enum { BUFFER_SIZE = 4096 };
-
-/* Output buffer. */
-static sc_byte *ser_buffer = NULL;
-static sc_int ser_buffer_length = 0;
-
-/* Callback and opaque pointer for use by output functions. */
-static sc_write_callbackref_t ser_callback = NULL;
-static void *ser_opaque = NULL;
-
-
-/*
- * ser_flush()
- * ser_buffer_character()
- *
- * Flush pending buffer contents; add a character to the buffer.
- */
-static void ser_flush(sc_bool is_final) {
- if (is_final) {
- ser_callback(ser_opaque, ser_buffer, ser_buffer_length);
-
- sc_free(ser_buffer);
- ser_buffer = nullptr;
- ser_buffer_length = 0;
- }
-}
-
-static void ser_buffer_character(sc_char character) {
- /* Allocate the buffer if not yet done. */
- if (!ser_buffer) {
- assert(ser_buffer_length == 0);
- ser_buffer = (sc_byte *)sc_malloc(BUFFER_SIZE);
- }
-
- /* Add to the buffer, with intermediate flush if filled. */
- ser_buffer[ser_buffer_length++] = character;
- if (ser_buffer_length == BUFFER_SIZE)
- error("Ran out of serialization buffer");
-}
-
-
-/*
- * ser_buffer_buffer()
- * ser_buffer_string()
- * ser_buffer_int()
- * ser_buffer_int_special()
- * ser_buffer_uint()
- * ser_buffer_boolean()
- *
- * Buffer a buffer, a string, an unsigned and signed integer, and a boolean.
- */
-static void ser_buffer_buffer(const sc_char *buffer, sc_int length) {
- sc_int index_;
-
- /* Add each character to the buffer. */
- for (index_ = 0; index_ < length; index_++)
- ser_buffer_character(buffer[index_]);
-}
-
-static void ser_buffer_string(const sc_char *string) {
- /* Buffer string, followed by DOS style end-of-line. */
- ser_buffer_buffer(string, strlen(string));
- ser_buffer_character(CARRIAGE_RETURN);
- ser_buffer_character(NEWLINE);
-}
-
-static void ser_buffer_int(sc_int value) {
- sc_char buffer[32];
-
- /* Convert to a string and buffer that. */
- sprintf(buffer, "%ld", value);
- ser_buffer_string(buffer);
-}
-
-static void ser_buffer_int_special(sc_int value) {
- sc_char buffer[32];
-
- /* Weirdo formatting for compatibility. */
- sprintf(buffer, "% ld ", value);
- ser_buffer_string(buffer);
-}
-
-static void ser_buffer_uint(sc_uint value) {
- sc_char buffer[32];
-
- /* Convert to a string and buffer that. */
- sprintf(buffer, "%lu", value);
- ser_buffer_string(buffer);
-}
-
-static void ser_buffer_boolean(sc_bool boolean) {
- /* Write a 1 for TRUE, 0 for FALSE. */
- ser_buffer_string(boolean ? "1" : "0");
-}
-
-
-/*
- * ser_save_game()
- *
- * Serialize a game and save its state using the given callback and opaque.
- */
-void ser_save_game(sc_gameref_t game, sc_write_callbackref_t callback, void *opaque) {
- const sc_var_setref_t vars = gs_get_vars(game);
- const sc_prop_setref_t bundle = gs_get_bundle(game);
- sc_vartype_t vt_key[3];
- sc_int index_, var_count;
- assert(callback);
-
- /* Store the callback and opaque references, for writer functions. */
- ser_callback = callback;
- ser_opaque = opaque;
-
- /* Write the game name. */
- vt_key[0].string = "Globals";
- vt_key[1].string = "GameName";
- ser_buffer_string(prop_get_string(bundle, "S<-ss", vt_key));
-
- /* Write the counts of rooms, objects, etc. */
- ser_buffer_int(gs_room_count(game));
- ser_buffer_int(gs_object_count(game));
- ser_buffer_int(gs_task_count(game));
- ser_buffer_int(gs_event_count(game));
- ser_buffer_int(gs_npc_count(game));
-
- /* Write the score and player information. */
- ser_buffer_int(game->score);
- ser_buffer_int(gs_playerroom(game) + 1);
- ser_buffer_int(gs_playerparent(game));
- ser_buffer_int(gs_playerposition(game));
-
- /* Write player gender. */
- vt_key[0].string = "Globals";
- vt_key[1].string = "PlayerGender";
- ser_buffer_int(prop_get_integer(bundle, "I<-ss", vt_key));
-
- /*
- * Write encumbrance details. The player limits are constant for a given
- * game, and can be extracted from properties. The current sizes and
- * weights can also be recalculated from held objects, so we don't maintain
- * them in the game. We can write constants here, then, and ignore
- * the values on restoring. Note however that if the Adrift Runner is
- * relying on these values, this may give it problems with one of our saved
- * games.
- */
- ser_buffer_int(90);
- ser_buffer_int(0);
- ser_buffer_int(90);
- ser_buffer_int(0);
-
- /* Save rooms information. */
- for (index_ = 0; index_ < gs_room_count(game); index_++)
- ser_buffer_boolean(gs_room_seen(game, index_));
-
- /* Save objects information. */
- for (index_ = 0; index_ < gs_object_count(game); index_++) {
- ser_buffer_int(gs_object_position(game, index_));
- ser_buffer_boolean(gs_object_seen(game, index_));
- ser_buffer_int(gs_object_parent(game, index_));
- if (gs_object_openness(game, index_) != 0)
- ser_buffer_int(gs_object_openness(game, index_));
-
- if (gs_object_state(game, index_) != 0)
- ser_buffer_int(gs_object_state(game, index_));
-
- ser_buffer_boolean(gs_object_unmoved(game, index_));
- }
-
- /* Save tasks information. */
- for (index_ = 0; index_ < gs_task_count(game); index_++) {
- ser_buffer_boolean(gs_task_done(game, index_));
- ser_buffer_boolean(gs_task_scored(game, index_));
- }
-
- /* Save events information. */
- for (index_ = 0; index_ < gs_event_count(game); index_++) {
- sc_int startertype, task;
-
- /* Get starter task, if any. */
- vt_key[0].string = "Events";
- vt_key[1].integer = index_;
- vt_key[2].string = "StarterType";
- startertype = prop_get_integer(bundle, "I<-sis", vt_key);
- if (startertype == 3) {
- vt_key[2].string = "TaskNum";
- task = prop_get_integer(bundle, "I<-sis", vt_key);
- } else
- task = 0;
-
- /* Save event details. */
- ser_buffer_int(gs_event_time(game, index_));
- ser_buffer_int(task);
- ser_buffer_int(gs_event_state(game, index_) - 1);
- if (task > 0)
- ser_buffer_boolean(gs_task_done(game, task - 1));
- else
- ser_buffer_boolean(FALSE);
- }
-
- /* Save NPCs information. */
- for (index_ = 0; index_ < gs_npc_count(game); index_++) {
- sc_int walk;
-
- ser_buffer_int(gs_npc_location(game, index_));
- ser_buffer_boolean(gs_npc_seen(game, index_));
- for (walk = 0; walk < gs_npc_walkstep_count(game, index_); walk++)
- ser_buffer_int_special(gs_npc_walkstep(game, index_, walk));
- }
-
- /* Save each variable. */
- vt_key[0].string = "Variables";
- var_count = prop_get_child_count(bundle, "I<-s", vt_key);
-
- for (index_ = 0; index_ < var_count; index_++) {
- const sc_char *name;
- sc_int var_type;
-
- vt_key[1].integer = index_;
-
- vt_key[2].string = "Name";
- name = prop_get_string(bundle, "S<-sis", vt_key);
- vt_key[2].string = "Type";
- var_type = prop_get_integer(bundle, "I<-sis", vt_key);
-
- switch (var_type) {
- case TAFVAR_NUMERIC:
- ser_buffer_int(var_get_integer(vars, name));
- break;
-
- case TAFVAR_STRING:
- ser_buffer_string(var_get_string(vars, name));
- break;
-
- default:
- sc_fatal("ser_save_game: unknown variable type, %ld\n", var_type);
- }
- }
-
- /* Save timing information. */
- ser_buffer_uint(var_get_elapsed_seconds(vars));
-
- /* Save turns count. */
- ser_buffer_uint((sc_uint) game->turns);
-
- /*
- * Flush the last buffer contents, and drop the callback and opaque
- * references.
- */
- ser_flush(TRUE);
- ser_callback = NULL;
- ser_opaque = NULL;
-}
-
-
-/*
- * ser_save_game_prompted()
- *
- * Serialize a game and save its state, requesting a save stream from
- * the user.
- */
-sc_bool ser_save_game_prompted(sc_gameref_t game) {
- return g_vm->saveGame().getCode() == Common::kNoError;
-}
-
-
-/* TAS input file line counter. */
-static sc_tafref_t ser_tas = NULL;
-static sc_int ser_tasline = 0;
-
-/* Restore error jump buffer. */
-static jmp_buf ser_tas_error;
-
-/*
- * ser_get_string()
- * ser_get_int()
- * ser_get_uint()
- * ser_get_boolean()
- *
- * Wrapper round obtaining the next TAS file line, with variants to convert
- * the line content into an appropriate type.
- */
-static const sc_char *ser_get_string(void) {
- const sc_char *string;
-
- /* Get the next line, and complain if absent. */
- string = taf_next_line(ser_tas);
- if (!string) {
- sc_error("ser_get_string: out of TAS data at line %ld\n", ser_tasline);
- longjmp(ser_tas_error, 1);
- }
-
- ser_tasline++;
- return string;
-}
-
-static sc_int ser_get_int(void) {
- const sc_char *string;
- sc_int value;
-
- /* Get line, and scan for a single integer; return it. */
- string = ser_get_string();
- if (sscanf(string, "%ld", &value) != 1) {
- sc_error("ser_get_int:"
- " invalid integer at line %ld\n", ser_tasline - 1);
- longjmp(ser_tas_error, 1);
- }
-
- return value;
-}
-
-static sc_uint ser_get_uint(void) {
- const sc_char *string;
- sc_uint value;
-
- /* Get line, and scan for a single integer; return it. */
- string = ser_get_string();
- if (sscanf(string, "%lu", &value) != 1) {
- sc_error("ser_get_uint:"
- " invalid integer at line %ld\n", ser_tasline - 1);
- longjmp(ser_tas_error, 1);
- }
-
- return value;
-}
-
-static sc_bool ser_get_boolean(void) {
- const sc_char *string;
- sc_uint value;
-
- /*
- * Get line, and scan for a single integer; check it's a valid-looking flag,
- * and return it.
- */
- string = ser_get_string();
- if (sscanf(string, "%lu", &value) != 1) {
- sc_error("ser_get_boolean:"
- " invalid boolean at line %ld\n", ser_tasline - 1);
- longjmp(ser_tas_error, 1);
- }
- if (value != 0 && value != 1) {
- sc_error("ser_get_boolean:"
- " warning: suspect boolean at line %ld\n", ser_tasline - 1);
- }
-
- return value != 0;
-}
-
-
-/*
- * ser_load_game()
- *
- * Load a serialized game into the given game by repeated calls to the
- * callback() function.
- */
-sc_bool ser_load_game(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
- static sc_var_setref_t new_vars; /* For setjmp safety */
- static sc_gameref_t new_game; /* For setjmp safety */
-
- const sc_filterref_t filter = gs_get_filter(game);
- const sc_prop_setref_t bundle = gs_get_bundle(game);
- sc_vartype_t vt_key[3];
- sc_int index_, var_count;
- const sc_char *gamename;
-
- /* Create a TAF (TAS) reference from callbacks, for reader functions. */
- ser_tas = taf_create_tas(callback, opaque);
- if (!ser_tas)
- return FALSE;
-
- /* Reset line counter for error messages. */
- ser_tasline = 1;
-
- new_game = NULL;
- new_vars = NULL;
-
- /* Set up error handling jump buffer, and handle errors. */
- if (setjmp(ser_tas_error) != 0) {
- /* Destroy any temporary game and variables. */
- if (new_game)
- gs_destroy(new_game);
- if (new_vars)
- var_destroy(new_vars);
-
- /* Destroy the TAF (TAS) file and return fail status. */
- taf_destroy(ser_tas);
- ser_tas = NULL;
- return FALSE;
- }
-
- /*
- * Read the game name, and compare with the one in the game. Fail if
- * they don't match exactly. A tighter check than this would perhaps be
- * preferable, say, something based on the TAF file header, but this isn't
- * in the save file format.
- */
- vt_key[0].string = "Globals";
- vt_key[1].string = "GameName";
- gamename = prop_get_string(bundle, "S<-ss", vt_key);
- if (strcmp(ser_get_string(), gamename) != 0)
- longjmp(ser_tas_error, 1);
-
- /* Read and verify the counts in the saved game. */
- if (ser_get_int() != gs_room_count(game)
- || ser_get_int() != gs_object_count(game)
- || ser_get_int() != gs_task_count(game)
- || ser_get_int() != gs_event_count(game)
- || ser_get_int() != gs_npc_count(game))
- longjmp(ser_tas_error, 1);
-
- /* Create a variables set and game to restore into. */
- new_vars = var_create(bundle);
- new_game = gs_create(new_vars, bundle, filter);
- var_register_game(new_vars, new_game);
-
- /* All set to load TAF (TAS) data into the new game. */
-
- /* Restore the score and player information. */
- new_game->score = ser_get_int();
- gs_set_playerroom(new_game, ser_get_int() - 1);
- gs_set_playerparent(new_game, ser_get_int());
- gs_set_playerposition(new_game, ser_get_int());
-
- /* Skip player gender. */
- (void) ser_get_int();
-
- /* Skip encumbrance details, not currently maintained by the game. */
- (void) ser_get_int();
- (void) ser_get_int();
- (void) ser_get_int();
- (void) ser_get_int();
-
- /* Restore rooms information. */
- for (index_ = 0; index_ < gs_room_count(new_game); index_++)
- gs_set_room_seen(new_game, index_, ser_get_boolean());
-
- /* Restore objects information. */
- for (index_ = 0; index_ < gs_object_count(new_game); index_++) {
- sc_int openable, currentstate;
-
- /* Bypass mutators for position and parent. Fix later? */
- new_game->objects[index_].position = ser_get_int();
- gs_set_object_seen(new_game, index_, ser_get_boolean());
- new_game->objects[index_].parent = ser_get_int();
-
- vt_key[0].string = "Objects";
- vt_key[1].integer = index_;
- vt_key[2].string = "Openable";
- openable = prop_get_integer(bundle, "I<-sis", vt_key);
- gs_set_object_openness(new_game, index_,
- openable != 0 ? ser_get_int() : 0);
-
- vt_key[2].string = "CurrentState";
- currentstate = prop_get_integer(bundle, "I<-sis", vt_key);
- gs_set_object_state(new_game, index_,
- currentstate != 0 ? ser_get_int() : 0);
-
- gs_set_object_unmoved(new_game, index_, ser_get_boolean());
- }
-
- /* Restore tasks information. */
- for (index_ = 0; index_ < gs_task_count(new_game); index_++) {
- gs_set_task_done(new_game, index_, ser_get_boolean());
- gs_set_task_scored(new_game, index_, ser_get_boolean());
- }
-
- /* Restore events information. */
- for (index_ = 0; index_ < gs_event_count(new_game); index_++) {
- sc_int startertype, task;
-
- /* Restore first event details. */
- gs_set_event_time(new_game, index_, ser_get_int());
- task = ser_get_int();
- gs_set_event_state(new_game, index_, ser_get_int() + 1);
-
- /* Verify and restore the starter task, if any. */
- if (task > 0) {
- vt_key[0].string = "Events";
- vt_key[1].integer = index_;
- vt_key[2].string = "StarterType";
- startertype = prop_get_integer(bundle, "I<-sis", vt_key);
- if (startertype != 3)
- longjmp(ser_tas_error, 1);
-
- /* Restore task state. */
- gs_set_task_done(new_game, task - 1, ser_get_boolean());
- } else
- (void) ser_get_boolean();
- }
-
- /* Restore NPCs information. */
- for (index_ = 0; index_ < gs_npc_count(new_game); index_++) {
- sc_int walk;
-
- gs_set_npc_location(new_game, index_, ser_get_int());
- gs_set_npc_seen(new_game, index_, ser_get_boolean());
- for (walk = 0; walk < gs_npc_walkstep_count(new_game, index_); walk++)
- gs_set_npc_walkstep(new_game, index_, walk, ser_get_int());
- }
-
- /* Restore each variable. */
- vt_key[0].string = "Variables";
- var_count = prop_get_child_count(bundle, "I<-s", vt_key);
-
- for (index_ = 0; index_ < var_count; index_++) {
- const sc_char *name;
- sc_int var_type;
-
- vt_key[1].integer = index_;
-
- vt_key[2].string = "Name";
- name = prop_get_string(bundle, "S<-sis", vt_key);
- vt_key[2].string = "Type";
- var_type = prop_get_integer(bundle, "I<-sis", vt_key);
-
- switch (var_type) {
- case TAFVAR_NUMERIC:
- var_put_integer(new_vars, name, ser_get_int());
- break;
-
- case TAFVAR_STRING:
- var_put_string(new_vars, name, ser_get_string());
- break;
-
- default:
- sc_fatal("ser_load_game: unknown variable type, %ld\n", var_type);
- }
- }
-
- /* Restore timing information. */
- var_set_elapsed_seconds(new_vars, ser_get_uint());
-
- /* Restore turns count. */
- new_game->turns = (sc_int) ser_get_uint();
-
- /*
- * Resources tweak -- set requested to match those in the current game
- * so that they remain unchanged by the gs_copy() of new_game onto
- * game. This way, both the requested and the active resources in the
- * game are unchanged by restore.
- */
- new_game->requested_sound = game->requested_sound;
- new_game->requested_graphic = game->requested_graphic;
-
- /*
- * Quitter tweak -- set the quit jump buffer in the new game to be the
- * same as the current one, so that it remains unchanged by gs_copy(). The
- * one in the new game is still the unset one from gs_create().
- */
- memcpy(&new_game->quitter, &game->quitter, sizeof(game->quitter));
-
- /*
- * If we got this far, we successfully restored the game from the file.
- * As our final act, copy the new game onto the old one.
- */
- new_game->temporary = game->temporary;
- new_game->undo = game->undo;
- gs_copy(game, new_game);
-
- /* Done with the temporary game and variables. */
- gs_destroy(new_game);
- var_destroy(new_vars);
-
- /* Done with TAF (TAS) file; destroy it and return successfully. */
- taf_destroy(ser_tas);
- ser_tas = NULL;
- return TRUE;
-}
-
-
-/*
- * ser_load_game_prompted()
- *
- * Load a serialized game into the given game, requesting a restore
- * stream from the user.
- */
-sc_bool ser_load_game_prompted(sc_gameref_t game) {
- return g_vm->loadGame().getCode() == Common::kNoError;
-}
-
-} // End of namespace Adrift
-} // End of namespace Glk
diff --git a/engines/glk/adrift/serialization.cpp b/engines/glk/adrift/serialization.cpp
new file mode 100644
index 0000000..404619a
--- /dev/null
+++ b/engines/glk/adrift/serialization.cpp
@@ -0,0 +1,517 @@
+/* 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/adrift/serialization.h"
+#include "glk/adrift/scprotos.h"
+#include "glk/adrift/scgamest.h"
+
+namespace Glk {
+namespace Adrift {
+
+/* Assorted definitions and constants. */
+static const sc_char NEWLINE = '\n';
+static const sc_char CARRIAGE_RETURN = '\r';
+static const sc_char NUL = '\0';
+
+enum { BUFFER_SIZE = 4096 };
+
+void SaveSerializer::save() {
+ const sc_var_setref_t vars = gs_get_vars(_game);
+ const sc_prop_setref_t bundle = gs_get_bundle(_game);
+ sc_vartype_t vt_key[3];
+ sc_int index_, var_count;
+
+ // Write the _game name
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "GameName";
+ writeString(prop_get_string(bundle, "S<-ss", vt_key));
+
+ /* Write the counts of rooms, objects, etc. */
+ writeInt(gs_room_count(_game));
+ writeInt(gs_object_count(_game));
+ writeInt(gs_task_count(_game));
+ writeInt(gs_event_count(_game));
+ writeInt(gs_npc_count(_game));
+
+ /* Write the score and player information. */
+ writeInt(_game->score);
+ writeInt(gs_playerroom(_game) + 1);
+ writeInt(gs_playerparent(_game));
+ writeInt(gs_playerposition(_game));
+
+ /* Write player gender. */
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "PlayerGender";
+ writeInt(prop_get_integer(bundle, "I<-ss", vt_key));
+
+ /*
+ * Write encumbrance details. The player limits are constant for a given
+ * _game, and can be extracted from properties. The current sizes and
+ * weights can also be recalculated from held objects, so we don't maintain
+ * them in the _game. We can write constants here, then, and ignore
+ * the values on restoring. Note however that if the Adrift Runner is
+ * relying on these values, this may give it problems with one of our saved
+ * games.
+ */
+ writeInt(90);
+ writeInt(0);
+ writeInt(90);
+ writeInt(0);
+
+ /* Save rooms information. */
+ for (index_ = 0; index_ < gs_room_count(_game); index_++)
+ writeBool(gs_room_seen(_game, index_));
+
+ /* Save objects information. */
+ for (index_ = 0; index_ < gs_object_count(_game); index_++) {
+ writeInt(gs_object_position(_game, index_));
+ writeBool(gs_object_seen(_game, index_));
+ writeInt(gs_object_parent(_game, index_));
+ if (gs_object_openness(_game, index_) != 0)
+ writeInt(gs_object_openness(_game, index_));
+
+ if (gs_object_state(_game, index_) != 0)
+ writeInt(gs_object_state(_game, index_));
+
+ writeBool(gs_object_unmoved(_game, index_));
+ }
+
+ /* Save tasks information. */
+ for (index_ = 0; index_ < gs_task_count(_game); index_++) {
+ writeBool(gs_task_done(_game, index_));
+ writeBool(gs_task_scored(_game, index_));
+ }
+
+ /* Save events information. */
+ for (index_ = 0; index_ < gs_event_count(_game); index_++) {
+ sc_int startertype, task;
+
+ /* Get starter task, if any. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = index_;
+ vt_key[2].string = "StarterType";
+ startertype = prop_get_integer(bundle, "I<-sis", vt_key);
+ if (startertype == 3) {
+ vt_key[2].string = "TaskNum";
+ task = prop_get_integer(bundle, "I<-sis", vt_key);
+ }
+ else
+ task = 0;
+
+ /* Save event details. */
+ writeInt(gs_event_time(_game, index_));
+ writeInt(task);
+ writeInt(gs_event_state(_game, index_) - 1);
+ if (task > 0)
+ writeBool(gs_task_done(_game, task - 1));
+ else
+ writeBool(FALSE);
+ }
+
+ /* Save NPCs information. */
+ for (index_ = 0; index_ < gs_npc_count(_game); index_++) {
+ sc_int walk;
+
+ writeInt(gs_npc_location(_game, index_));
+ writeBool(gs_npc_seen(_game, index_));
+ for (walk = 0; walk < gs_npc_walkstep_count(_game, index_); walk++)
+ writeIntSpecial(gs_npc_walkstep(_game, index_, walk));
+ }
+
+ /* Save each variable. */
+ vt_key[0].string = "Variables";
+ var_count = prop_get_child_count(bundle, "I<-s", vt_key);
+
+ for (index_ = 0; index_ < var_count; index_++) {
+ const sc_char *name;
+ sc_int var_type;
+
+ vt_key[1].integer = index_;
+
+ vt_key[2].string = "Name";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+ vt_key[2].string = "Type";
+ var_type = prop_get_integer(bundle, "I<-sis", vt_key);
+
+ switch (var_type) {
+ case TAFVAR_NUMERIC:
+ writeInt(var_get_integer(vars, name));
+ break;
+
+ case TAFVAR_STRING:
+ writeString(var_get_string(vars, name));
+ break;
+
+ default:
+ sc_fatal("ser_save_game: unknown variable type, %ld\n", var_type);
+ }
+ }
+
+ /* Save timing information. */
+ writeUint(var_get_elapsed_seconds(vars));
+
+ /* Save turns count. */
+ writeUint((sc_uint)_game->turns);
+
+ /*
+ * Flush the last buffer contents, and drop the callback and opaque
+ * references.
+ */
+ flush(TRUE);
+ _callback = NULL;
+ _opaque = NULL;
+}
+
+void SaveSerializer::flush(sc_bool is_final) {
+ if (is_final) {
+ _callback(_opaque, _buffer.getData(), _buffer.size());
+ }
+}
+
+void SaveSerializer::writeChar(sc_char character) {
+ // Validate the buffer hasn't exceeded the maximum allowable size
+ if (_buffer.size() == BUFFER_SIZE)
+ sc_error("Ran out of serialization buffer");
+
+ // Add to the buffer
+ _buffer.writeByte(character);
+}
+
+void SaveSerializer::write(const sc_char *buffer, sc_int length) {
+ // Add each character to the buffer
+ for (int idx = 0; idx < length; ++idx)
+ writeChar(buffer[idx]);
+}
+
+void SaveSerializer::writeString(const sc_char *string) {
+ // Write string, followed by DOS style end-of-line
+ write(string, strlen(string));
+ writeChar(CARRIAGE_RETURN);
+ writeChar(NEWLINE);
+}
+
+void SaveSerializer::writeInt(sc_int value) {
+ Common::String s = Common::String::format("%ld", value);
+ writeString(s.c_str());
+}
+
+void SaveSerializer::writeIntSpecial(sc_int value) {
+ Common::String s = Common::String::format("% ld ", value);
+ writeString(s.c_str());
+}
+
+void SaveSerializer::writeUint(sc_uint value) {
+ Common::String s = Common::String::format("%lu", value);
+ writeString(s.c_str());
+}
+
+void SaveSerializer::writeBool(sc_bool boolean) {
+ // Write a 1 for TRUE, 0 for FALSE
+ writeString(boolean ? "1" : "0");
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* TAS input file line counter. */
+static sc_tafref_t ser_tas = NULL;
+static sc_int ser_tasline = 0;
+
+/* Restore error jump buffer. */
+static jmp_buf ser_tas_error;
+static sc_var_setref_t new_vars; /* For setjmp safety */
+static sc_gameref_t new_game; /* For setjmp safety */
+
+bool LoadSerializer::load() {
+ const sc_filterref_t filter = gs_get_filter(_game);
+ const sc_prop_setref_t bundle = gs_get_bundle(_game);
+ sc_vartype_t vt_key[3];
+ sc_int index_, var_count;
+ const sc_char *gamename;
+
+ /* Create a TAF (TAS) reference from callbacks, for reader functions. */
+ ser_tas = taf_create_tas(_callback, _opaque);
+ if (!ser_tas)
+ return FALSE;
+
+ /* Reset line counter for error messages. */
+ ser_tasline = 1;
+
+ new_game = NULL;
+ new_vars = NULL;
+
+ /* Set up error handling jump buffer, and handle errors. */
+ if (setjmp(ser_tas_error) != 0) {
+ /* Destroy any temporary _game and variables. */
+ if (new_game)
+ gs_destroy(new_game);
+ if (new_vars)
+ var_destroy(new_vars);
+
+ /* Destroy the TAF (TAS) file and return fail status. */
+ taf_destroy(ser_tas);
+ ser_tas = NULL;
+ return FALSE;
+ }
+
+ /*
+ * Read the _game name, and compare with the one in the _game. Fail if
+ * they don't match exactly. A tighter check than this would perhaps be
+ * preferable, say, something based on the TAF file header, but this isn't
+ * in the save file format.
+ */
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "GameName";
+ gamename = prop_get_string(bundle, "S<-ss", vt_key);
+ if (strcmp(readString(), gamename) != 0)
+ longjmp(ser_tas_error, 1);
+
+ /* Read and verify the counts in the saved _game. */
+ if (readInt() != gs_room_count(_game)
+ || readInt() != gs_object_count(_game)
+ || readInt() != gs_task_count(_game)
+ || readInt() != gs_event_count(_game)
+ || readInt() != gs_npc_count(_game))
+ longjmp(ser_tas_error, 1);
+
+ /* Create a variables set and _game to restore into. */
+ new_vars = var_create(bundle);
+ new_game = gs_create(new_vars, bundle, filter);
+ var_register_game(new_vars, new_game);
+
+ /* All set to load TAF (TAS) data into the new _game. */
+
+ /* Restore the score and player information. */
+ new_game->score = readInt();
+ gs_set_playerroom(new_game, readInt() - 1);
+ gs_set_playerparent(new_game, readInt());
+ gs_set_playerposition(new_game, readInt());
+
+ /* Skip player gender. */
+ (void)readInt();
+
+ /* Skip encumbrance details, not currently maintained by the _game. */
+ (void)readInt();
+ (void)readInt();
+ (void)readInt();
+ (void)readInt();
+
+ /* Restore rooms information. */
+ for (index_ = 0; index_ < gs_room_count(new_game); index_++)
+ gs_set_room_seen(new_game, index_, readBool());
+
+ /* Restore objects information. */
+ for (index_ = 0; index_ < gs_object_count(new_game); index_++) {
+ sc_int openable, currentstate;
+
+ /* Bypass mutators for position and parent. Fix later? */
+ new_game->objects[index_].position = readInt();
+ gs_set_object_seen(new_game, index_, readBool());
+ new_game->objects[index_].parent = readInt();
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = index_;
+ vt_key[2].string = "Openable";
+ openable = prop_get_integer(bundle, "I<-sis", vt_key);
+ gs_set_object_openness(new_game, index_,
+ openable != 0 ? readInt() : 0);
+
+ vt_key[2].string = "CurrentState";
+ currentstate = prop_get_integer(bundle, "I<-sis", vt_key);
+ gs_set_object_state(new_game, index_,
+ currentstate != 0 ? readInt() : 0);
+
+ gs_set_object_unmoved(new_game, index_, readBool());
+ }
+
+ /* Restore tasks information. */
+ for (index_ = 0; index_ < gs_task_count(new_game); index_++) {
+ gs_set_task_done(new_game, index_, readBool());
+ gs_set_task_scored(new_game, index_, readBool());
+ }
+
+ /* Restore events information. */
+ for (index_ = 0; index_ < gs_event_count(new_game); index_++) {
+ sc_int startertype, task;
+
+ /* Restore first event details. */
+ gs_set_event_time(new_game, index_, readInt());
+ task = readInt();
+ gs_set_event_state(new_game, index_, readInt() + 1);
+
+ /* Verify and restore the starter task, if any. */
+ if (task > 0) {
+ vt_key[0].string = "Events";
+ vt_key[1].integer = index_;
+ vt_key[2].string = "StarterType";
+ startertype = prop_get_integer(bundle, "I<-sis", vt_key);
+ if (startertype != 3)
+ longjmp(ser_tas_error, 1);
+
+ /* Restore task state. */
+ gs_set_task_done(new_game, task - 1, readBool());
+ }
+ else
+ (void)readBool();
+ }
+
+ /* Restore NPCs information. */
+ for (index_ = 0; index_ < gs_npc_count(new_game); index_++) {
+ sc_int walk;
+
+ gs_set_npc_location(new_game, index_, readInt());
+ gs_set_npc_seen(new_game, index_, readBool());
+ for (walk = 0; walk < gs_npc_walkstep_count(new_game, index_); walk++)
+ gs_set_npc_walkstep(new_game, index_, walk, readInt());
+ }
+
+ /* Restore each variable. */
+ vt_key[0].string = "Variables";
+ var_count = prop_get_child_count(bundle, "I<-s", vt_key);
+
+ for (index_ = 0; index_ < var_count; index_++) {
+ const sc_char *name;
+ sc_int var_type;
+
+ vt_key[1].integer = index_;
+
+ vt_key[2].string = "Name";
+ name = prop_get_string(bundle, "S<-sis", vt_key);
+ vt_key[2].string = "Type";
+ var_type = prop_get_integer(bundle, "I<-sis", vt_key);
+
+ switch (var_type) {
+ case TAFVAR_NUMERIC:
+ var_put_integer(new_vars, name, readInt());
+ break;
+
+ case TAFVAR_STRING:
+ var_put_string(new_vars, name, readString());
+ break;
+
+ default:
+ sc_fatal("ser_load_game: unknown variable type, %ld\n", var_type);
+ }
+ }
+
+ /* Restore timing information. */
+ var_set_elapsed_seconds(new_vars, readUint());
+
+ /* Restore turns count. */
+ new_game->turns = (sc_int)readUint();
+
+ /*
+ * Resources tweak -- set requested to match those in the current _game
+ * so that they remain unchanged by the gs_copy() of new_game onto
+ * _game. This way, both the requested and the active resources in the
+ * _game are unchanged by restore.
+ */
+ new_game->requested_sound = _game->requested_sound;
+ new_game->requested_graphic = _game->requested_graphic;
+
+ /*
+ * Quitter tweak -- set the quit jump buffer in the new _game to be the
+ * same as the current one, so that it remains unchanged by gs_copy(). The
+ * one in the new _game is still the unset one from gs_create().
+ */
+ memcpy(&new_game->quitter, &_game->quitter, sizeof(_game->quitter));
+
+ /*
+ * If we got this far, we successfully restored the _game from the file.
+ * As our final act, copy the new _game onto the old one.
+ */
+ new_game->temporary = _game->temporary;
+ new_game->undo = _game->undo;
+ gs_copy(_game, new_game);
+
+ /* Done with the temporary _game and variables. */
+ gs_destroy(new_game);
+ var_destroy(new_vars);
+
+ /* Done with TAF (TAS) file; destroy it and return successfully. */
+ taf_destroy(ser_tas);
+ ser_tas = NULL;
+ return TRUE;
+}
+
+const sc_char *LoadSerializer::readString() {
+ const sc_char *string;
+
+ /* Get the next line, and complain if absent. */
+ string = taf_next_line(ser_tas);
+ if (!string) {
+ sc_error("readString: out of TAS data at line %ld\n", ser_tasline);
+ longjmp(ser_tas_error, 1);
+ }
+
+ ser_tasline++;
+ return string;
+}
+
+sc_int LoadSerializer::readInt() {
+ const sc_char *string;
+ sc_int value;
+
+ // Get line, and scan for a single integer; return it
+ string = readString();
+ if (sscanf(string, "%ld", &value) != 1) {
+ sc_error("readInt: invalid integer at line %ld\n", ser_tasline - 1);
+ longjmp(ser_tas_error, 1);
+ }
+
+ return value;
+}
+
+sc_uint LoadSerializer::readUint() {
+ const sc_char *string;
+ sc_uint value;
+
+ // Get line, and scan for a single integer; return it
+ string = readString();
+ if (sscanf(string, "%lu", &value) != 1) {
+ sc_error("readUint: invalid integer at line %ld\n", ser_tasline - 1);
+ longjmp(ser_tas_error, 1);
+ }
+
+ return value;
+}
+
+sc_bool LoadSerializer::readBool(void) {
+ const sc_char *string;
+ sc_uint value;
+
+ // Get line, and scan for a single integer; check it's a valid-looking flag, and return it.
+ string = readString();
+ if (sscanf(string, "%lu", &value) != 1) {
+ sc_error("readBool:"
+ " invalid boolean at line %ld\n", ser_tasline - 1);
+ longjmp(ser_tas_error, 1);
+ }
+ if (value != 0 && value != 1) {
+ sc_error("readBool:"
+ " warning: suspect boolean at line %ld\n", ser_tasline - 1);
+ }
+
+ return value != 0;
+}
+
+} // End of namespace Adrift
+} // End of namespace Glk
diff --git a/engines/glk/adrift/serialization.h b/engines/glk/adrift/serialization.h
new file mode 100644
index 0000000..47559a2
--- /dev/null
+++ b/engines/glk/adrift/serialization.h
@@ -0,0 +1,143 @@
+/* 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 ADRIFT_SERIALIZATION_H
+#define ADRIFT_SERIALIZATION_H
+
+#include "common/memstream.h"
+#include "common/str.h"
+#include "glk/adrift/scprotos.h"
+
+namespace Glk {
+namespace Adrift {
+
+/**
+ * Saving serializer class
+ */
+class SaveSerializer {
+private:
+ sc_gameref_t _game;
+ sc_write_callbackref_t _callback;
+ void *_opaque;
+ Common::MemoryWriteStreamDynamic _buffer;
+private:
+ /**
+ * Flush pending buffer contents
+ */
+ void flush(sc_bool is_final);
+
+ /**
+ * add a character to the buffer.
+ */
+ void writeChar(sc_char character);
+
+ /**
+ * Write a buffer
+ */
+ void write(const sc_char *buffer, sc_int length);
+
+ /**
+ * Write a string
+ */
+ void writeString(const sc_char *string);
+
+ /**
+ * Write an integer
+ */
+ void writeInt(sc_int value);
+
+ /**
+ * Write a special/long integer
+ */
+ void writeIntSpecial(sc_int value);
+
+ /**
+ * Write an unsigned integer
+ */
+ void writeUint(sc_uint value);
+
+ /**
+ * Write a boolean
+ */
+ void writeBool(sc_bool boolean);
+public:
+ /**
+ * Constructor
+ */
+ SaveSerializer(sc_gameref_t game, sc_write_callbackref_t callback, void *opaque) :
+ _game(game), _callback(callback), _opaque(opaque), _buffer(DisposeAfterUse::YES) {
+ assert(callback);
+ }
+
+ /**
+ * Save method
+ */
+ void save();
+};
+
+/**
+ * Loading serializer class
+ */
+class LoadSerializer {
+private:
+ sc_gameref_t _game;
+ sc_read_callbackref_t _callback;
+ void *_opaque;
+private:
+ /**
+ * Reads a string
+ */
+ const sc_char *readString();
+
+ /**
+ * Read a signed integer
+ */
+ sc_int readInt();
+
+ /**
+ * Read an unsigned integer
+ */
+ sc_uint readUint();
+
+ /**
+ * Read a boolean
+ */
+ sc_bool readBool();
+public:
+ /**
+ * Constructor
+ */
+ LoadSerializer(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) :
+ _game(game), _callback(callback), _opaque(opaque) {
+ assert(callback);
+ }
+
+ /**
+ * Does the loading
+ */
+ bool load();
+};
+
+} // End of namespace Adrift
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index bc65355..8727b93 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -46,12 +46,12 @@ MODULE_OBJS := \
adrift/scresour.o \
adrift/screstrs.o \
adrift/scrunner.o \
- adrift/scserial.o \
adrift/sctaffil.o \
adrift/sctafpar.o \
adrift/sctasks.o \
adrift/scutils.o \
adrift/scvars.o \
+ adrift/serialization.o \
adrift/sxfile.o \
adrift/sxglob.o \
adrift/sxmain.o \
Commit: 41c7d31fb6fe55c8579242fffd0bd70a4b86aa20
https://github.com/scummvm/scummvm/commit/41c7d31fb6fe55c8579242fffd0bd70a4b86aa20
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Refactoring load serializer to not use longjmp
Changed paths:
A engines/glk/jumps.h
R engines/glk/alan2/jumps.h
engines/glk/adrift/serialization.cpp
engines/glk/adrift/serialization.h
engines/glk/alan2/exe.h
engines/glk/alan2/inter.h
engines/glk/alan2/main.h
engines/glk/alan2/parse.h
diff --git a/engines/glk/adrift/serialization.cpp b/engines/glk/adrift/serialization.cpp
index 404619a..5a855e7 100644
--- a/engines/glk/adrift/serialization.cpp
+++ b/engines/glk/adrift/serialization.cpp
@@ -124,7 +124,7 @@ void SaveSerializer::save() {
if (task > 0)
writeBool(gs_task_done(_game, task - 1));
else
- writeBool(FALSE);
+ writeBool(false);
}
/* Save NPCs information. */
@@ -177,8 +177,8 @@ void SaveSerializer::save() {
* references.
*/
flush(TRUE);
- _callback = NULL;
- _opaque = NULL;
+ _callback = nullptr;
+ _opaque = nullptr;
}
void SaveSerializer::flush(sc_bool is_final) {
@@ -225,20 +225,13 @@ void SaveSerializer::writeUint(sc_uint value) {
}
void SaveSerializer::writeBool(sc_bool boolean) {
- // Write a 1 for TRUE, 0 for FALSE
+ // Write a 1 for TRUE, 0 for false
writeString(boolean ? "1" : "0");
}
/*--------------------------------------------------------------------------*/
-/* TAS input file line counter. */
-static sc_tafref_t ser_tas = NULL;
-static sc_int ser_tasline = 0;
-
-/* Restore error jump buffer. */
-static jmp_buf ser_tas_error;
-static sc_var_setref_t new_vars; /* For setjmp safety */
-static sc_gameref_t new_game; /* For setjmp safety */
+#define CHECK if (context._break) goto ser_tas_error
bool LoadSerializer::load() {
const sc_filterref_t filter = gs_get_filter(_game);
@@ -246,144 +239,128 @@ bool LoadSerializer::load() {
sc_vartype_t vt_key[3];
sc_int index_, var_count;
const sc_char *gamename;
+ sc_var_setref_t new_vars = nullptr;
+ sc_gameref_t new_game = nullptr;
+ Context context;
- /* Create a TAF (TAS) reference from callbacks, for reader functions. */
+ // Create a TAF (TAS) reference from callbacks, for reader functions
ser_tas = taf_create_tas(_callback, _opaque);
if (!ser_tas)
- return FALSE;
+ return false;
- /* Reset line counter for error messages. */
+ // Reset line counter for error messages.
ser_tasline = 1;
- new_game = NULL;
- new_vars = NULL;
-
- /* Set up error handling jump buffer, and handle errors. */
- if (setjmp(ser_tas_error) != 0) {
- /* Destroy any temporary _game and variables. */
- if (new_game)
- gs_destroy(new_game);
- if (new_vars)
- var_destroy(new_vars);
-
- /* Destroy the TAF (TAS) file and return fail status. */
- taf_destroy(ser_tas);
- ser_tas = NULL;
- return FALSE;
- }
-
- /*
- * Read the _game name, and compare with the one in the _game. Fail if
- * they don't match exactly. A tighter check than this would perhaps be
- * preferable, say, something based on the TAF file header, but this isn't
- * in the save file format.
- */
+ // Read the _game name, and compare with the one in the _game. Fail if they don't match exactly.
+ // A tighter check than this would perhaps be preferable, say, something based on the TAF file
+ // header, but this isn't in the save file format.
+
vt_key[0].string = "Globals";
vt_key[1].string = "GameName";
gamename = prop_get_string(bundle, "S<-ss", vt_key);
- if (strcmp(readString(), gamename) != 0)
- longjmp(ser_tas_error, 1);
-
- /* Read and verify the counts in the saved _game. */
- if (readInt() != gs_room_count(_game)
- || readInt() != gs_object_count(_game)
- || readInt() != gs_task_count(_game)
- || readInt() != gs_event_count(_game)
- || readInt() != gs_npc_count(_game))
- longjmp(ser_tas_error, 1);
-
- /* Create a variables set and _game to restore into. */
+ if (strcmp(readString(context), gamename) != 0 || context._break)
+ goto ser_tas_error;
+
+ // Read and verify the counts in the saved _game.
+ if ((readInt(context) != gs_room_count(_game) || context._break)
+ || (readInt(context) != gs_object_count(_game) || context._break)
+ || (readInt(context) != gs_task_count(_game) || context._break)
+ || (readInt(context) != gs_event_count(_game) || context._break)
+ || (readInt(context) != gs_npc_count(_game) || context._break))
+ goto ser_tas_error;
+
+ // Create a variables set and _game to restore into.
new_vars = var_create(bundle);
new_game = gs_create(new_vars, bundle, filter);
var_register_game(new_vars, new_game);
- /* All set to load TAF (TAS) data into the new _game. */
+ // All set to load TAF (TAS) data into the new _game.
- /* Restore the score and player information. */
- new_game->score = readInt();
- gs_set_playerroom(new_game, readInt() - 1);
- gs_set_playerparent(new_game, readInt());
- gs_set_playerposition(new_game, readInt());
+ // Restore the score and player information.
+ new_game->score = readInt(context); CHECK;
+ gs_set_playerroom(new_game, readInt(context) - 1); CHECK;
+ gs_set_playerparent(new_game, readInt(context)); CHECK;
+ gs_set_playerposition(new_game, readInt(context)); CHECK;
- /* Skip player gender. */
- (void)readInt();
+ // Skip player gender.
+ (void)readInt(context); CHECK;
- /* Skip encumbrance details, not currently maintained by the _game. */
- (void)readInt();
- (void)readInt();
- (void)readInt();
- (void)readInt();
+ // Skip encumbrance details, not currently maintained by the _game.
+ (void)readInt(context); CHECK;
+ (void)readInt(context); CHECK;
+ (void)readInt(context); CHECK;
+ (void)readInt(context); CHECK;
- /* Restore rooms information. */
- for (index_ = 0; index_ < gs_room_count(new_game); index_++)
- gs_set_room_seen(new_game, index_, readBool());
+ // Restore rooms information.
+ for (index_ = 0; index_ < gs_room_count(new_game); index_++) {
+ gs_set_room_seen(new_game, index_, readBool(context)); CHECK;
+ }
- /* Restore objects information. */
+ // Restore objects information.
for (index_ = 0; index_ < gs_object_count(new_game); index_++) {
sc_int openable, currentstate;
- /* Bypass mutators for position and parent. Fix later? */
- new_game->objects[index_].position = readInt();
- gs_set_object_seen(new_game, index_, readBool());
- new_game->objects[index_].parent = readInt();
+ // Bypass mutators for position and parent. Fix later?
+ new_game->objects[index_].position = readInt(context); CHECK;
+ gs_set_object_seen(new_game, index_, readBool(context)); CHECK;
+ new_game->objects[index_].parent = readInt(context); CHECK;
vt_key[0].string = "Objects";
vt_key[1].integer = index_;
vt_key[2].string = "Openable";
openable = prop_get_integer(bundle, "I<-sis", vt_key);
- gs_set_object_openness(new_game, index_,
- openable != 0 ? readInt() : 0);
+ gs_set_object_openness(new_game, index_, openable != 0 ? readInt(context) : 0); CHECK;
vt_key[2].string = "CurrentState";
currentstate = prop_get_integer(bundle, "I<-sis", vt_key);
gs_set_object_state(new_game, index_,
- currentstate != 0 ? readInt() : 0);
+ currentstate != 0 ? readInt(context) : 0); CHECK;
- gs_set_object_unmoved(new_game, index_, readBool());
+ gs_set_object_unmoved(new_game, index_, readBool(context)); CHECK;
}
- /* Restore tasks information. */
+ // Restore tasks information.
for (index_ = 0; index_ < gs_task_count(new_game); index_++) {
- gs_set_task_done(new_game, index_, readBool());
- gs_set_task_scored(new_game, index_, readBool());
+ gs_set_task_done(new_game, index_, readBool(context)); CHECK;
+ gs_set_task_scored(new_game, index_, readBool(context)); CHECK;
}
- /* Restore events information. */
+ // Restore events information.
for (index_ = 0; index_ < gs_event_count(new_game); index_++) {
sc_int startertype, task;
- /* Restore first event details. */
- gs_set_event_time(new_game, index_, readInt());
- task = readInt();
- gs_set_event_state(new_game, index_, readInt() + 1);
+ // Restore first event details.
+ gs_set_event_time(new_game, index_, readInt(context)); CHECK;
+ task = readInt(context); CHECK;
+ gs_set_event_state(new_game, index_, readInt(context) + 1); CHECK;
- /* Verify and restore the starter task, if any. */
+ // Verify and restore the starter task, if any.
if (task > 0) {
vt_key[0].string = "Events";
vt_key[1].integer = index_;
vt_key[2].string = "StarterType";
startertype = prop_get_integer(bundle, "I<-sis", vt_key);
if (startertype != 3)
- longjmp(ser_tas_error, 1);
+ goto ser_tas_error;
- /* Restore task state. */
- gs_set_task_done(new_game, task - 1, readBool());
+ // Restore task state.
+ gs_set_task_done(new_game, task - 1, readBool(context)); CHECK;
+ } else {
+ (void)readBool(context); CHECK;
}
- else
- (void)readBool();
}
- /* Restore NPCs information. */
+ // Restore NPCs information.
for (index_ = 0; index_ < gs_npc_count(new_game); index_++) {
sc_int walk;
- gs_set_npc_location(new_game, index_, readInt());
- gs_set_npc_seen(new_game, index_, readBool());
+ gs_set_npc_location(new_game, index_, readInt(context)); CHECK;
+ gs_set_npc_seen(new_game, index_, readBool(context)); CHECK;
for (walk = 0; walk < gs_npc_walkstep_count(new_game, index_); walk++)
- gs_set_npc_walkstep(new_game, index_, walk, readInt());
+ gs_set_npc_walkstep(new_game, index_, walk, readInt(context)); CHECK;
}
- /* Restore each variable. */
+ // Restore each variable.
vt_key[0].string = "Variables";
var_count = prop_get_child_count(bundle, "I<-s", vt_key);
@@ -400,11 +377,11 @@ bool LoadSerializer::load() {
switch (var_type) {
case TAFVAR_NUMERIC:
- var_put_integer(new_vars, name, readInt());
+ var_put_integer(new_vars, name, readInt(context)); CHECK;
break;
case TAFVAR_STRING:
- var_put_string(new_vars, name, readString());
+ var_put_string(new_vars, name, readString(context)); CHECK;
break;
default:
@@ -412,102 +389,108 @@ bool LoadSerializer::load() {
}
}
- /* Restore timing information. */
- var_set_elapsed_seconds(new_vars, readUint());
+ // Restore timing information.
+ var_set_elapsed_seconds(new_vars, readUint(context)); CHECK;
- /* Restore turns count. */
- new_game->turns = (sc_int)readUint();
+ // Restore turns count.
+ new_game->turns = (sc_int)readUint(context); CHECK;
- /*
- * Resources tweak -- set requested to match those in the current _game
- * so that they remain unchanged by the gs_copy() of new_game onto
- * _game. This way, both the requested and the active resources in the
- * _game are unchanged by restore.
+ /* Resources tweak -- set requested to match those in the current _game so that they remain
+ * unchanged by the gs_copy() of new_game onto game. This way, both the requested and the
+ * active resources in the game are unchanged by restore.
*/
new_game->requested_sound = _game->requested_sound;
new_game->requested_graphic = _game->requested_graphic;
- /*
- * Quitter tweak -- set the quit jump buffer in the new _game to be the
+ /* Quitter tweak -- set the quit jump buffer in the new _game to be the
* same as the current one, so that it remains unchanged by gs_copy(). The
* one in the new _game is still the unset one from gs_create().
*/
memcpy(&new_game->quitter, &_game->quitter, sizeof(_game->quitter));
- /*
- * If we got this far, we successfully restored the _game from the file.
+ /* If we got this far, we successfully restored the _game from the file.
* As our final act, copy the new _game onto the old one.
*/
new_game->temporary = _game->temporary;
new_game->undo = _game->undo;
gs_copy(_game, new_game);
- /* Done with the temporary _game and variables. */
+ // Done with the temporary _game and variables.
gs_destroy(new_game);
var_destroy(new_vars);
- /* Done with TAF (TAS) file; destroy it and return successfully. */
+ // Done with TAF (TAS) file; destroy it and return successfully
+ taf_destroy(ser_tas);
+ return true;
+
+ser_tas_error:
+ // Destroy any temporary _game and variables
+ if (new_game)
+ gs_destroy(new_game);
+ if (new_vars)
+ var_destroy(new_vars);
+
+ // Destroy the TAF (TAS) file and return fail status
taf_destroy(ser_tas);
- ser_tas = NULL;
- return TRUE;
+ return false;
}
-const sc_char *LoadSerializer::readString() {
+const sc_char *LoadSerializer::readString(CONTEXT) {
const sc_char *string;
/* Get the next line, and complain if absent. */
string = taf_next_line(ser_tas);
if (!string) {
sc_error("readString: out of TAS data at line %ld\n", ser_tasline);
- longjmp(ser_tas_error, 1);
+ LONG_JUMP0
}
ser_tasline++;
return string;
}
-sc_int LoadSerializer::readInt() {
+sc_int LoadSerializer::readInt(CONTEXT) {
const sc_char *string;
sc_int value;
// Get line, and scan for a single integer; return it
- string = readString();
+ R0FUNC0(readString, string)
if (sscanf(string, "%ld", &value) != 1) {
sc_error("readInt: invalid integer at line %ld\n", ser_tasline - 1);
- longjmp(ser_tas_error, 1);
+ LONG_JUMP0
}
return value;
}
-sc_uint LoadSerializer::readUint() {
+sc_uint LoadSerializer::readUint(CONTEXT) {
const sc_char *string;
sc_uint value;
// Get line, and scan for a single integer; return it
- string = readString();
+ R0FUNC0(readString, string)
if (sscanf(string, "%lu", &value) != 1) {
sc_error("readUint: invalid integer at line %ld\n", ser_tasline - 1);
- longjmp(ser_tas_error, 1);
+ LONG_JUMP0
}
return value;
}
-sc_bool LoadSerializer::readBool(void) {
+sc_bool LoadSerializer::readBool(CONTEXT) {
const sc_char *string;
sc_uint value;
// Get line, and scan for a single integer; check it's a valid-looking flag, and return it.
- string = readString();
+ R0FUNC0(readString, string)
+ string = readString(context);
if (sscanf(string, "%lu", &value) != 1) {
- sc_error("readBool:"
- " invalid boolean at line %ld\n", ser_tasline - 1);
- longjmp(ser_tas_error, 1);
+ sc_error("readBool: invalid boolean at line %ld\n", ser_tasline - 1);
+ LONG_JUMP0
}
if (value != 0 && value != 1) {
- sc_error("readBool:"
- " warning: suspect boolean at line %ld\n", ser_tasline - 1);
+ sc_error("readBool: warning: suspect boolean at line %ld\n", ser_tasline - 1);
+ LONG_JUMP0
}
return value != 0;
diff --git a/engines/glk/adrift/serialization.h b/engines/glk/adrift/serialization.h
index 47559a2..c696044 100644
--- a/engines/glk/adrift/serialization.h
+++ b/engines/glk/adrift/serialization.h
@@ -26,6 +26,7 @@
#include "common/memstream.h"
#include "common/str.h"
#include "glk/adrift/scprotos.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Adrift {
@@ -102,32 +103,34 @@ private:
sc_gameref_t _game;
sc_read_callbackref_t _callback;
void *_opaque;
+ sc_tafref_t ser_tas;
+ sc_int ser_tasline;
private:
/**
* Reads a string
*/
- const sc_char *readString();
+ const sc_char *readString(CONTEXT);
/**
* Read a signed integer
*/
- sc_int readInt();
+ sc_int readInt(CONTEXT);
/**
* Read an unsigned integer
*/
- sc_uint readUint();
+ sc_uint readUint(CONTEXT);
/**
* Read a boolean
*/
- sc_bool readBool();
+ sc_bool readBool(CONTEXT);
public:
/**
* Constructor
*/
LoadSerializer(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) :
- _game(game), _callback(callback), _opaque(opaque) {
+ _game(game), _callback(callback), _opaque(opaque), ser_tas(nullptr), ser_tasline(0) {
assert(callback);
}
diff --git a/engines/glk/alan2/exe.h b/engines/glk/alan2/exe.h
index 89a34b5..b46f5b8 100644
--- a/engines/glk/alan2/exe.h
+++ b/engines/glk/alan2/exe.h
@@ -27,7 +27,7 @@
*/
#include "glk/alan2/types.h"
-#include "glk/alan2/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan2 {
diff --git a/engines/glk/alan2/inter.h b/engines/glk/alan2/inter.h
index bb26ce1..ee2c323 100644
--- a/engines/glk/alan2/inter.h
+++ b/engines/glk/alan2/inter.h
@@ -23,7 +23,7 @@
#ifndef GLK_ALAN2_INTER
#define GLK_ALAN2_INTER
-#include "glk/alan2/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan2 {
diff --git a/engines/glk/alan2/jumps.h b/engines/glk/alan2/jumps.h
deleted file mode 100644
index 2aa4561..0000000
--- a/engines/glk/alan2/jumps.h
+++ /dev/null
@@ -1,70 +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_ALAN2_JUMPS
-#define GLK_ALAN2_JUMPS
-
-/* This provides a simplified version of the ScummVM coroutines to allow for automated
- * breakouts to the main game loop from subroutinese rather than using unportable setjmps
- */
-
-namespace Glk {
-namespace Alan2 {
-
-/**
- * Context used for flagging when a break to the outer game loop
- */
-struct Context {
- bool _break;
- Context() : _break(false) {}
-};
-
-#define CALL0(METHOD) { METHOD(context); if (context._break) return; }
-#define CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return; }
-#define CALL2(METHOD, P1, P2) { METHOD(context, P1, P2); if (context._break) return; }
-#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P1, P2, P3); if (context._break) return; }
-#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P1, P2, P3, P4); if (context._break) return; }
-#define FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return; }
-#define FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return; }
-#define FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P1, P2); if (context._break) return; }
-#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P1, P2, P3); if (context._break) return; }
-#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P1, P2, P3, P4); if (context._break) return; }
-
-#define R0CALL0(METHOD) { METHOD(context); if (context._break) return 0; }
-#define R0CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return 0; }
-#define R0CALL2(METHOD, P1, P2) { METHOD(context, P1, P2); if (context._break) return 0; }
-#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P1, P2, P3); if (context._break) return 0; }
-#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P1, P2, P3, P4); if (context._break) return 0; }
-#define R0FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return 0; }
-#define R0FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return 0; }
-#define R0FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P1, P2); if (context._break) return 0; }
-#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P1, P2, P3); if (context._break) return 0; }
-#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P1, P2, P3, P4); if (context._break) return 0; }
-
-#define CONTEXT Context &context
-#define LONG_JUMP { context._break = true; return; }
-#define LONG_JUMP0 { context._break = true; return 0; }
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan2/main.h b/engines/glk/alan2/main.h
index 3473ebf..a43d3f7 100644
--- a/engines/glk/alan2/main.h
+++ b/engines/glk/alan2/main.h
@@ -27,7 +27,7 @@
#include "common/file.h"
#include "glk/alan2/types.h"
-#include "glk/alan2/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan2 {
diff --git a/engines/glk/alan2/parse.h b/engines/glk/alan2/parse.h
index 100d739..1cfdcf1 100644
--- a/engines/glk/alan2/parse.h
+++ b/engines/glk/alan2/parse.h
@@ -25,7 +25,7 @@
/* Parse data for ALAN interpreter module. */
-#include "engines/glk/alan2/jumps.h"
+#include "engines/glk/jumps.h"
namespace Glk {
namespace Alan2 {
diff --git a/engines/glk/jumps.h b/engines/glk/jumps.h
new file mode 100644
index 0000000..f343812
--- /dev/null
+++ b/engines/glk/jumps.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_JUMPS
+#define GLK_JUMPS
+
+/* This provides a simplified version of the ScummVM coroutines to allow for automated
+ * breakouts to the main game loop from subroutinese rather than using unportable setjmps
+ */
+
+namespace Glk {
+
+/**
+ * Context used for flagging when a break to the outer game loop
+ */
+struct Context {
+ bool _break;
+ Context() : _break(false) {}
+};
+
+#define CALL0(METHOD) { METHOD(context); if (context._break) return; }
+#define CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return; }
+#define CALL2(METHOD, P1, P2) { METHOD(context, P1, P2); if (context._break) return; }
+#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P1, P2, P3); if (context._break) return; }
+#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P1, P2, P3, P4); if (context._break) return; }
+#define FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return; }
+#define FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return; }
+#define FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P1, P2); if (context._break) return; }
+#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P1, P2, P3); if (context._break) return; }
+#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P1, P2, P3, P4); if (context._break) return; }
+
+#define R0CALL0(METHOD) { METHOD(context); if (context._break) return 0; }
+#define R0CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return 0; }
+#define R0CALL2(METHOD, P1, P2) { METHOD(context, P1, P2); if (context._break) return 0; }
+#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P1, P2, P3); if (context._break) return 0; }
+#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P1, P2, P3, P4); if (context._break) return 0; }
+#define R0FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return 0; }
+#define R0FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return 0; }
+#define R0FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P1, P2); if (context._break) return 0; }
+#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P1, P2, P3); if (context._break) return 0; }
+#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P1, P2, P3, P4); if (context._break) return 0; }
+
+#define CONTEXT Context &context
+#define LONG_JUMP { context._break = true; return; }
+#define LONG_JUMP0 { context._break = true; return 0; }
+
+} // End of namespace Glk
+
+#endif
Commit: c098422a0d7d60893f4068af329e511699553e50
https://github.com/scummvm/scummvm/commit/c098422a0d7d60893f4068af329e511699553e50
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Fixes for loading savegames to work
Changed paths:
engines/glk/adrift/scprotos.h
engines/glk/adrift/sctaffil.cpp
engines/glk/adrift/serialization.cpp
diff --git a/engines/glk/adrift/scprotos.h b/engines/glk/adrift/scprotos.h
index 37d2bdc..7533597 100644
--- a/engines/glk/adrift/scprotos.h
+++ b/engines/glk/adrift/scprotos.h
@@ -96,6 +96,7 @@ extern sc_uint sc_hash(const sc_char *string);
/* TAF file reader/decompressor enumerations, opaque typedef and functions. */
enum {
TAF_VERSION_NONE = 0,
+ TAF_VERSION_500 = 500,
TAF_VERSION_400 = 400,
TAF_VERSION_390 = 390,
TAF_VERSION_380 = 380
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index 4bee769..321f08a 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -22,7 +22,7 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
-#include "common/textconsole.h"
+#include "common/algorithm.h"
#include "common/zlib.h"
#include "common/memstream.h"
@@ -441,10 +441,37 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
return true;
#else
- return true;
+ return false;
#endif
}
+/*
+ * taf_read_raw()
+ *
+ * Read an uncompressed version 4.0 TAF save chunk used by ScummVM
+ */
+static sc_bool taf_read_raw(sc_tafref_t taf, sc_read_callbackref_t callback,
+ void *opaque, sc_bool is_gamefile) {
+ byte *buffer = new byte[BUFFER_SIZE];
+ size_t bytesRead, bytesLeft = 0;
+ size_t totalBytes, bytesWritten;
+
+ for (;;) {
+ bytesRead = callback(opaque, buffer + bytesLeft, BUFFER_SIZE - bytesLeft);
+ if ((bytesLeft + bytesRead) == 0)
+ break;
+
+ totalBytes = bytesLeft + bytesRead;
+ bytesWritten = taf_append_buffer(taf, buffer, totalBytes);
+
+ bytesLeft = totalBytes - bytesWritten;
+ if (bytesLeft)
+ Common::copy(buffer + bytesWritten, buffer + totalBytes, buffer);
+ }
+
+ delete[] buffer;
+ return true;
+}
/*
* taf_create_from_callback()
@@ -506,8 +533,8 @@ static sc_tafref_t taf_create_from_callback(sc_read_callbackref_t callback,
return NULL;
}
} else {
- /* Saved games are always considered to be version 4.0. */
- taf->version = TAF_VERSION_400;
+ /* Saved games are always considered to be for ScummVM, version 5.0. */
+ taf->version = TAF_VERSION_500;
}
/*
@@ -516,6 +543,10 @@ static sc_tafref_t taf_create_from_callback(sc_read_callbackref_t callback,
* it's obfuscated with the Visual Basic PRNG.
*/
switch (taf->version) {
+ case TAF_VERSION_500:
+ status = taf_read_raw(taf, callback, opaque, is_gamefile);
+ break;
+
case TAF_VERSION_400:
status = taf_decompress(taf, callback, opaque, is_gamefile);
break;
diff --git a/engines/glk/adrift/serialization.cpp b/engines/glk/adrift/serialization.cpp
index 5a855e7..c0fa81b 100644
--- a/engines/glk/adrift/serialization.cpp
+++ b/engines/glk/adrift/serialization.cpp
@@ -242,6 +242,7 @@ bool LoadSerializer::load() {
sc_var_setref_t new_vars = nullptr;
sc_gameref_t new_game = nullptr;
Context context;
+ sc_int count = 0;
// Create a TAF (TAS) reference from callbacks, for reader functions
ser_tas = taf_create_tas(_callback, _opaque);
@@ -291,13 +292,15 @@ bool LoadSerializer::load() {
(void)readInt(context); CHECK;
(void)readInt(context); CHECK;
- // Restore rooms information.
- for (index_ = 0; index_ < gs_room_count(new_game); index_++) {
+ // Restore rooms information
+ count = gs_room_count(new_game);
+ for (index_ = 0; index_ < count; ++index_) {
gs_set_room_seen(new_game, index_, readBool(context)); CHECK;
}
- // Restore objects information.
- for (index_ = 0; index_ < gs_object_count(new_game); index_++) {
+ // Restore objects information
+ count = gs_object_count(new_game);
+ for (index_ = 0; index_ < count; ++index_) {
sc_int openable, currentstate;
// Bypass mutators for position and parent. Fix later?
@@ -325,8 +328,9 @@ bool LoadSerializer::load() {
gs_set_task_scored(new_game, index_, readBool(context)); CHECK;
}
- // Restore events information.
- for (index_ = 0; index_ < gs_event_count(new_game); index_++) {
+ // Restore events information
+ count = gs_event_count(new_game);
+ for (index_ = 0; index_ < count; index_++) {
sc_int startertype, task;
// Restore first event details.
@@ -350,8 +354,9 @@ bool LoadSerializer::load() {
}
}
- // Restore NPCs information.
- for (index_ = 0; index_ < gs_npc_count(new_game); index_++) {
+ // Restore NPCs information
+ count = gs_npc_count(new_game);
+ for (index_ = 0; index_ < count; index_++) {
sc_int walk;
gs_set_npc_location(new_game, index_, readInt(context)); CHECK;
@@ -483,7 +488,6 @@ sc_bool LoadSerializer::readBool(CONTEXT) {
// Get line, and scan for a single integer; check it's a valid-looking flag, and return it.
R0FUNC0(readString, string)
- string = readString(context);
if (sscanf(string, "%lu", &value) != 1) {
sc_error("readBool: invalid boolean at line %ld\n", ser_tasline - 1);
LONG_JUMP0
Commit: ac744241783da16ddf67b1874e93ff949a4c41b3
https://github.com/scummvm/scummvm/commit/ac744241783da16ddf67b1874e93ff949a4c41b3
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Add loading savegames from launcher
Changed paths:
engines/glk/adrift/os_glk.cpp
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index c9c9c0c..c0b35c4 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -26,6 +26,7 @@
#include "glk/glk.h"
#include "glk/streams.h"
#include "glk/windows.h"
+#include "common/config-manager.h"
#include "common/textconsole.h"
#include "common/translation.h"
@@ -2786,7 +2787,7 @@ static enum gsc_end_option gsc_get_ending_option() {
* and generally handle options. The second is called from g_vm->glk_main, and
* does the real work of running the game.
*/
-static int gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream,
+static int gsc_startup_code(Common::SeekableReadStream *game_stream, int restore_slot,
sc_uint trace_flags, sc_bool enable_debugger, sc_bool stable_random, const sc_char *locale) {
winid_t window;
assert(game_stream);
@@ -2850,16 +2851,15 @@ static int gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t res
* If the game was created successfully and there is a restore stream, try
* to immediately restore the game from that stream.
*/
- if (gsc_game && restore_stream) {
- if (!sc_load_game_from_callback(gsc_game, gsc_callback, restore_stream)) {
+ if (gsc_game && restore_slot != -1) {
+ if (g_vm->loadGameState(restore_slot).getCode() != Common::kNoError) {
sc_free_game(gsc_game);
gsc_game = nullptr;
gsc_game_message = "Unable to restore this Adrift game from the requested file.";
- } else
+ } else {
gsc_game_message = nullptr;
+ }
}
- if (restore_stream)
- g_vm->glk_stream_close(restore_stream, nullptr);
/* If successful, set game debugging and synchronize to the core's locale. */
if (gsc_game) {
@@ -3078,8 +3078,11 @@ bool adrift_startup_code(Common::SeekableReadStream *gameFile) {
stable_random = gDebugLevel > 0;
locale = nullptr;
+ // Check for savegame to load immediate
+ int saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+
// Use the generic startup code to complete startup
- return gsc_startup_code(gameFile, nullptr, trace_flags, enable_debugger, stable_random, locale);
+ return gsc_startup_code(gameFile, saveSlot, trace_flags, enable_debugger, stable_random, locale);
}
} // End of namespace Adrift
Commit: a401ccc61e5f70350152bccc05e45c68520d845d
https://github.com/scummvm/scummvm/commit/a401ccc61e5f70350152bccc05e45c68520d845d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: Remove some outstanding longjmp artifacts from sub-engines
Changed paths:
engines/glk/alan2/main.h
engines/glk/tads/tads2/error.cpp
engines/glk/tads/tads2/error_handling.cpp
engines/glk/tads/tads2/error_handling.h
diff --git a/engines/glk/alan2/main.h b/engines/glk/alan2/main.h
index a43d3f7..afab540 100644
--- a/engines/glk/alan2/main.h
+++ b/engines/glk/alan2/main.h
@@ -87,9 +87,6 @@ extern const char *advnam;
extern int col, lin;
extern int paglen, pagwidth;
-/* Long jump buffer for restart */
-//extern jmp_buf restart_label;
-
extern Boolean verbose, errflg, trcflg, dbgflg, stpflg, logflg, statusflg;
extern Boolean fail;
extern Boolean anyOutput;
diff --git a/engines/glk/tads/tads2/error.cpp b/engines/glk/tads/tads2/error.cpp
index ad83d06..5ce0e10 100644
--- a/engines/glk/tads/tads2/error.cpp
+++ b/engines/glk/tads/tads2/error.cpp
@@ -162,12 +162,7 @@ int errfmt(char *outbuf, int outbufl, const char *fmt, int argc, const erradef *
}
#ifdef DEBUG
-void errjmp(buf, e)
-jmp_buf buf;
-int e;
-{
- longjmp(buf, e);
-}
+#error lonjump isn't supported in ScummVM
#endif /* DEBUG */
diff --git a/engines/glk/tads/tads2/error_handling.cpp b/engines/glk/tads/tads2/error_handling.cpp
index ac2b01d..86b3077 100644
--- a/engines/glk/tads/tads2/error_handling.cpp
+++ b/engines/glk/tads/tads2/error_handling.cpp
@@ -137,10 +137,7 @@ int errfmt(char *outbuf, int outbufl, char *fmt, int argc, erradef *argv)
}
#if defined(DEBUG) && !defined(ERR_NO_MACRO)
-void errjmp(jmp_buf buf, int e)
-{
- longjmp(buf, e);
-}
+#error longjmp isn't supported in ScummVM
#endif /* DEBUG */
diff --git a/engines/glk/tads/tads2/error_handling.h b/engines/glk/tads/tads2/error_handling.h
index 8d37929..d127594 100644
--- a/engines/glk/tads/tads2/error_handling.h
+++ b/engines/glk/tads/tads2/error_handling.h
@@ -83,7 +83,6 @@ struct errdef {
char errfac[ERRFACMAX+1]; /* facility of current error */
erradef erraav[10]; /* parameters for error */
int erraac; /* count of parameters in argc */
- //jmp_buf errbuf; ScummVM doesn't support using jump buffers
};
#define ERRBUFSIZ 512
@@ -190,7 +189,7 @@ char *errstr(errcxdef *ctx, const char *str, int len);
void errsign(errcxdef *ctx, int e, const char *facility);
#else /* ERR_NO_MACRO */
# ifdef DEBUG
-void errjmp(jmp_buf buf, int e);
+void errjmp(jump_buf buf, int e);
# define errsign(ctx, e, fac) \
(strncpy((ctx)->errcxptr->errfac, fac, ERRFACMAX),\
(ctx)->errcxptr->errfac[ERRFACMAX]='\0',\
Commit: 1e483ec0f50a430598f5f76f59338d74f67b20f5
https://github.com/scummvm/scummvm/commit/1e483ec0f50a430598f5f76f59338d74f67b20f5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:27-07:00
Commit Message:
GLK: ADRIFT: Refactor tokenizer to not use longjmp
Changed paths:
engines/glk/adrift/scexpr.cpp
diff --git a/engines/glk/adrift/scexpr.cpp b/engines/glk/adrift/scexpr.cpp
index 2375b5e..0f4c2be 100644
--- a/engines/glk/adrift/scexpr.cpp
+++ b/engines/glk/adrift/scexpr.cpp
@@ -22,6 +22,7 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Adrift {
@@ -545,16 +546,12 @@ static sc_int expr_eval_abs(sc_int value) {
return value < 0 ? -value : value;
}
-
-/* Parse error jump buffer. */
-static jmp_buf expr_parse_error;
-
/*
- * expr_eval_action()
+ * expr_eval_action
*
* Evaluate the effect of a token into the values stack.
*/
-static void expr_eval_action(sc_int token) {
+static void expr_eval_action(CONTEXT, sc_int token) {
sc_vartype_t token_value;
switch (token) {
@@ -577,7 +574,7 @@ static void expr_eval_action(sc_int token) {
if (!var_get(expr_varset, token_value.string, &type, &vt_rvalue)) {
sc_error("expr_eval_action:"
" undefined variable, %s\n", token_value.string);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
switch (type) {
case VAR_INTEGER:
@@ -1044,23 +1041,23 @@ static void expr_eval_action(sc_int token) {
static sc_int expr_parse_lookahead = TOK_NONE;
/* Forward declaration of factor parsers and string expression parser. */
-static void expr_parse_numeric_factor(void);
-static void expr_parse_string_factor(void);
-static void expr_parse_string_expr(void);
+static void expr_parse_numeric_factor(CONTEXT);
+static void expr_parse_string_factor(CONTEXT);
+static void expr_parse_string_expr(CONTEXT);
/*
- * expr_parse_match()
+ * expr_parse_match
*
* Match a token to the lookahead, then advance lookahead.
*/
-static void expr_parse_match(sc_int token) {
+static void expr_parse_match(CONTEXT, sc_int token) {
if (expr_parse_lookahead == token)
expr_parse_lookahead = expr_next_token();
else {
/* Syntax error. */
sc_error("expr_parse_match: syntax error,"
" expected %ld, got %ld\n", expr_parse_lookahead, token);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
}
@@ -1143,14 +1140,14 @@ static int expr_parse_contains_token(const sc_precedence_entry_t *entry, sc_int
* to match tokens, then decide whether, and how, to recurse into itself, or
* whether to parse a highest-precedence factor.
*/
-static void expr_parse_numeric_element(sc_int precedence) {
+static void expr_parse_numeric_element(CONTEXT, sc_int precedence) {
const sc_precedence_entry_t *entry;
/* See if the level passed in has listed tokens. */
entry = PRECEDENCE_TABLE + precedence;
if (entry->token_count == 0) {
/* Precedence levels that hit the table end are factors. */
- expr_parse_numeric_factor();
+ CALL0(expr_parse_numeric_factor);
return;
}
@@ -1158,27 +1155,27 @@ static void expr_parse_numeric_element(sc_int precedence) {
* Parse initial higher-precedence factor, then others that associate
* with the given level.
*/
- expr_parse_numeric_element(precedence + 1);
+ CALL1(expr_parse_numeric_element, precedence + 1);
while (expr_parse_contains_token(entry, expr_parse_lookahead)) {
sc_int token;
/* Note token and match, parse next level, then action this token. */
token = expr_parse_lookahead;
- expr_parse_match(token);
- expr_parse_numeric_element(precedence + 1);
- expr_eval_action(token);
+ CALL1(expr_parse_match, token);
+ CALL1(expr_parse_numeric_element, precedence + 1);
+ CALL1(expr_eval_action, token);
}
}
/*
- * expr_parse_numeric_expr()
+ * expr_parse_numeric_expr
*
* Parse a complete numeric (sub-)expression.
*/
-static void expr_parse_numeric_expr(void) {
+static void expr_parse_numeric_expr(CONTEXT) {
/* Call the parser of the lowest precedence operators. */
- expr_parse_numeric_element(0);
+ CALL1(expr_parse_numeric_element, 0);
}
@@ -1187,30 +1184,30 @@ static void expr_parse_numeric_expr(void) {
*
* Parse a numeric expression factor.
*/
-static void expr_parse_numeric_factor(void) {
+static void expr_parse_numeric_factor(CONTEXT) {
/* Handle factors based on lookahead token. */
switch (expr_parse_lookahead) {
/* Handle straightforward factors first. */
case TOK_LPAREN:
- expr_parse_match(TOK_LPAREN);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_RPAREN);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
break;
case TOK_UMINUS:
- expr_parse_match(TOK_UMINUS);
- expr_parse_numeric_factor();
- expr_eval_action(TOK_UMINUS);
+ CALL1(expr_parse_match, TOK_UMINUS);
+ CALL0(expr_parse_numeric_factor);
+ CALL1(expr_eval_action, TOK_UMINUS);
break;
case TOK_UPLUS:
- expr_parse_match(TOK_UPLUS);
- expr_parse_numeric_factor();
+ CALL1(expr_parse_match, TOK_UPLUS);
+ CALL0(expr_parse_numeric_factor);
break;
case TOK_INTEGER:
- expr_eval_action(TOK_INTEGER);
- expr_parse_match(TOK_INTEGER);
+ CALL1(expr_eval_action, TOK_INTEGER);
+ CALL1(expr_parse_match, TOK_INTEGER);
break;
case TOK_VARIABLE: {
@@ -1221,51 +1218,51 @@ static void expr_parse_numeric_factor(void) {
if (!var_get(expr_varset, token_value.string, &type, &vt_rvalue)) {
sc_error("expr_parse_numeric_factor:"
" undefined variable, %s\n", token_value.string);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
if (type != VAR_INTEGER) {
sc_error("expr_parse_numeric_factor:"
" string variable in numeric context, %s\n",
token_value.string);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
- expr_eval_action(TOK_VARIABLE);
- expr_parse_match(TOK_VARIABLE);
+ CALL1(expr_eval_action, TOK_VARIABLE);
+ CALL1(expr_parse_match, TOK_VARIABLE);
break;
}
/* Handle functions as factors. */
case TOK_ABS:
/* Parse as "abs (val)". */
- expr_parse_match(TOK_ABS);
- expr_parse_match(TOK_LPAREN);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_ABS);
+ CALL1(expr_parse_match, TOK_ABS);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_ABS);
break;
case TOK_IF:
/* Parse as "if (boolean, val1, val2)". */
- expr_parse_match(TOK_IF);
- expr_parse_match(TOK_LPAREN);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_COMMA);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_COMMA);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_IF);
+ CALL1(expr_parse_match, TOK_IF);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_IF);
break;
case TOK_RANDOM:
/* Parse as "random (low, high)". */
- expr_parse_match(TOK_RANDOM);
- expr_parse_match(TOK_LPAREN);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_COMMA);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_RANDOM);
+ CALL1(expr_parse_match, TOK_RANDOM);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_RANDOM);
break;
case TOK_MAX:
@@ -1277,64 +1274,64 @@ static void expr_parse_numeric_factor(void) {
/* Match up the function name and opening parenthesis. */
token = expr_parse_lookahead;
- expr_parse_match(token);
- expr_parse_match(TOK_LPAREN);
+ CALL1(expr_parse_match, token);
+ CALL1(expr_parse_match, TOK_LPAREN);
/* Count variable number of arguments as they are stacked. */
- expr_parse_numeric_expr();
+ CALL0(expr_parse_numeric_expr);
argument_count = 1;
while (expr_parse_lookahead == TOK_COMMA) {
- expr_parse_match(TOK_COMMA);
- expr_parse_numeric_expr();
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_numeric_expr);
argument_count++;
}
- expr_parse_match(TOK_RPAREN);
+ CALL1(expr_parse_match, TOK_RPAREN);
/* Push additional value -- the count of arguments. */
expr_eval_push_integer(argument_count);
- expr_eval_action(token);
+ CALL1(expr_eval_action, token);
break;
}
case TOK_INSTR:
/* Parse as "instr (val1, val2)". */
- expr_parse_match(TOK_INSTR);
- expr_parse_match(TOK_LPAREN);
- expr_parse_string_expr();
- expr_parse_match(TOK_COMMA);
- expr_parse_string_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_INSTR);
+ CALL1(expr_parse_match, TOK_INSTR);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_INSTR);
break;
case TOK_LEN:
/* Parse as "len (val)". */
- expr_parse_match(TOK_LEN);
- expr_parse_match(TOK_LPAREN);
- expr_parse_string_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_LEN);
+ CALL1(expr_parse_match, TOK_LEN);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_LEN);
break;
case TOK_VAL:
/* Parse as "val (val)". */
- expr_parse_match(TOK_VAL);
- expr_parse_match(TOK_LPAREN);
- expr_parse_string_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_VAL);
+ CALL1(expr_parse_match, TOK_VAL);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_VAL);
break;
case TOK_IDENT:
/* Unrecognized function-type token. */
sc_error("expr_parse_numeric_factor: syntax error, unknown ident\n");
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
default:
/* Syntax error. */
sc_error("expr_parse_numeric_factor:"
" syntax error, unexpected token, %ld\n", expr_parse_lookahead);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
}
@@ -1344,17 +1341,17 @@ static void expr_parse_numeric_factor(void) {
*
* Parse a complete string (sub-)expression.
*/
-static void expr_parse_string_expr(void) {
+static void expr_parse_string_expr(CONTEXT) {
/*
* Parse a string factor, then all repeated concatenations. Because the '+'
* and '&' are context sensitive, we have to invent/translate them into the
* otherwise unused TOK_CONCATENATE for evaluation.
*/
- expr_parse_string_factor();
+ CALL0(expr_parse_string_factor);
while (expr_parse_lookahead == TOK_AND || expr_parse_lookahead == TOK_ADD) {
- expr_parse_match(expr_parse_lookahead);
- expr_parse_string_factor();
- expr_eval_action(TOK_CONCATENATE);
+ CALL1(expr_parse_match, expr_parse_lookahead);
+ CALL0(expr_parse_string_factor);
+ CALL1(expr_eval_action, TOK_CONCATENATE);
}
}
@@ -1364,19 +1361,19 @@ static void expr_parse_string_expr(void) {
*
* Parse a string expression factor.
*/
-static void expr_parse_string_factor(void) {
+static void expr_parse_string_factor(CONTEXT) {
/* Handle factors based on lookahead token. */
switch (expr_parse_lookahead) {
/* Handle straightforward factors first. */
case TOK_LPAREN:
- expr_parse_match(TOK_LPAREN);
- expr_parse_string_expr();
- expr_parse_match(TOK_RPAREN);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
break;
case TOK_STRING:
- expr_eval_action(TOK_STRING);
- expr_parse_match(TOK_STRING);
+ CALL1(expr_eval_action, TOK_STRING);
+ CALL1(expr_parse_match, TOK_STRING);
break;
case TOK_VARIABLE: {
@@ -1387,16 +1384,16 @@ static void expr_parse_string_factor(void) {
if (!var_get(expr_varset, token_value.string, &type, &vt_rvalue)) {
sc_error("expr_parse_string_factor:"
" undefined variable, %s\n", token_value.string);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
if (type != VAR_STRING) {
sc_error("expr_parse_string_factor:"
" numeric variable in string context, %s\n",
token_value.string);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
- expr_eval_action(TOK_VARIABLE);
- expr_parse_match(TOK_VARIABLE);
+ CALL1(expr_eval_action, TOK_VARIABLE);
+ CALL1(expr_parse_match, TOK_VARIABLE);
break;
}
@@ -1409,11 +1406,11 @@ static void expr_parse_string_factor(void) {
sc_int token;
token = expr_parse_lookahead;
- expr_parse_match(token);
- expr_parse_match(TOK_LPAREN);
- expr_parse_string_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(token);
+ CALL1(expr_parse_match, token);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, token);
break;
}
@@ -1424,48 +1421,48 @@ static void expr_parse_string_factor(void) {
sc_int token;
token = expr_parse_lookahead;
- expr_parse_match(token);
- expr_parse_match(TOK_LPAREN);
- expr_parse_string_expr();
- expr_parse_match(TOK_COMMA);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(token);
+ CALL1(expr_parse_match, token);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, token);
break;
}
case TOK_MID:
/* Parse as "mid (text,start,length)". */
- expr_parse_match(TOK_MID);
- expr_parse_match(TOK_LPAREN);
- expr_parse_string_expr();
- expr_parse_match(TOK_COMMA);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_COMMA);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_MID);
+ CALL1(expr_parse_match, TOK_MID);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_string_expr);
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_COMMA);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_MID);
break;
case TOK_STR:
/* Parse as "str (val)". */
- expr_parse_match(TOK_STR);
- expr_parse_match(TOK_LPAREN);
- expr_parse_numeric_expr();
- expr_parse_match(TOK_RPAREN);
- expr_eval_action(TOK_STR);
+ CALL1(expr_parse_match, TOK_STR);
+ CALL1(expr_parse_match, TOK_LPAREN);
+ CALL0(expr_parse_numeric_expr);
+ CALL1(expr_parse_match, TOK_RPAREN);
+ CALL1(expr_eval_action, TOK_STR);
break;
case TOK_IDENT:
/* Unrecognized function-type token. */
sc_error("expr_parse_string_factor: syntax error, unknown ident\n");
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
default:
/* Syntax error. */
sc_error("expr_parse_string_factor:"
" syntax error, unexpected token, %ld\n", expr_parse_lookahead);
- longjmp(expr_parse_error, 1);
+ LONG_JUMP;
}
}
@@ -1479,21 +1476,22 @@ static void expr_parse_string_factor(void) {
static sc_bool expr_evaluate_expression(const sc_char *expression, sc_var_setref_t vars,
sc_int assign_type, sc_vartype_t *vt_rvalue) {
assert(assign_type == VAR_INTEGER || assign_type == VAR_STRING);
+ Context context;
/* Reset values stack and start tokenizer. */
expr_eval_start(vars);
expr_tokenize_start(expression);
- /* Try parsing an expression, and catch errors. */
- if (setjmp(expr_parse_error) == 0) {
- /* Parse an expression, and ensure it ends at string end. */
- expr_parse_lookahead = expr_next_token();
- if (assign_type == VAR_STRING)
- expr_parse_string_expr();
- else
- expr_parse_numeric_expr();
- expr_parse_match(TOK_EOS);
- } else {
+ // Try parsing an expression, and ensure it ends at string end. */
+ expr_parse_lookahead = expr_next_token();
+ if (assign_type == VAR_STRING)
+ expr_parse_string_expr(context);
+ else
+ expr_parse_numeric_expr(context);
+ if (!context._break)
+ expr_parse_match(context, TOK_EOS);
+
+ if (context._break) {
/* Parse error -- clean up tokenizer, collect garbage, and fail. */
expr_tokenize_end();
expr_eval_garbage_collect();
Commit: f6f4d3ee11d81ef08d51d35cdf3055137374886e
https://github.com/scummvm/scummvm/commit/f6f4d3ee11d81ef08d51d35cdf3055137374886e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:28-07:00
Commit Message:
GLK: ADRIFT: Convert parser code to no longer use longjmp
Changed paths:
engines/glk/adrift/scparser.cpp
diff --git a/engines/glk/adrift/scparser.cpp b/engines/glk/adrift/scparser.cpp
index 7b49693..cabda66 100644
--- a/engines/glk/adrift/scparser.cpp
+++ b/engines/glk/adrift/scparser.cpp
@@ -23,6 +23,7 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Adrift {
@@ -92,6 +93,7 @@ enum { UIP_ALLOCATION_AVOIDANCE_SIZE = 128 };
static sc_char uip_static_temporary[UIP_ALLOCATION_AVOIDANCE_SIZE];
static sc_char *uip_temporary = NULL;
+
/*
* uip_tokenize_start()
* uip_tokenize_end()
@@ -246,12 +248,8 @@ typedef sc_ptnode_t *sc_ptnoderef_t;
/* Predictive parser lookahead token. */
static sc_uip_tok_t uip_parse_lookahead = TOK_NONE;
-/* Parse error jump buffer. */
-static jmp_buf uip_parse_error;
-
/* Parse tree for cleanup, and forward declaration of pattern list parser. */
static sc_ptnoderef_t uip_parse_tree = NULL;
-static void uip_parse_list(sc_ptnoderef_t list);
/*
* Pool of statically allocated nodes, for faster allocations. Nodes are
@@ -279,19 +277,23 @@ static sc_ptshortword_t uip_word_pool[UIP_WORD_POOL_SIZE];
static sc_int uip_word_pool_cursor = 0;
static sc_int uip_word_pool_available = UIP_WORD_POOL_SIZE;
+// Forward declarations
+static void uip_parse_list(CONTEXT, sc_ptnoderef_t list);
+
+
/*
- * uip_parse_match()
+ * uip_parse_matc
*
* Match a token to the lookahead, then advance lookahead.
*/
-static void uip_parse_match(sc_uip_tok_t token) {
+static void uip_parse_match(CONTEXT, sc_uip_tok_t token) {
if (uip_parse_lookahead == token)
uip_parse_lookahead = uip_next_token();
else {
/* Syntax error. */
sc_error("uip_parse_match: syntax error, expected %ld, got %ld\n",
(sc_int) uip_parse_lookahead, (sc_int) token);
- longjmp(uip_parse_error, 1);
+ LONG_JUMP;
}
}
@@ -461,24 +463,24 @@ static void uip_destroy_node(sc_ptnoderef_t node) {
* Parse a set of .../.../... alternatives for choices and optionals. The
* first function is a helper, returning a newly constructed parsed list.
*/
-static sc_ptnoderef_t uip_parse_new_list(void) {
+static sc_ptnoderef_t uip_parse_new_list(CONTEXT) {
sc_ptnoderef_t list;
/* Create a new list node, parse into it, and return it. */
list = uip_new_node(NODE_LIST);
- uip_parse_list(list);
+ R0CALL1(uip_parse_list, list);
return list;
}
-static void uip_parse_alternatives(sc_ptnoderef_t node) {
+static void uip_parse_alternatives(CONTEXT, sc_ptnoderef_t node) {
sc_ptnoderef_t child;
/* Parse initial alternative, then add other listed alternatives. */
- node->left_child = uip_parse_new_list();
+ FUNC0(uip_parse_new_list, node->left_child);
child = node->left_child;
while (uip_parse_lookahead == TOK_ALTERNATES_SEPARATOR) {
- uip_parse_match(TOK_ALTERNATES_SEPARATOR);
- child->right_sibling = uip_parse_new_list();
+ CALL1(uip_parse_match, TOK_ALTERNATES_SEPARATOR);
+ FUNC0(uip_parse_new_list, child->right_sibling);
child = child->right_sibling;
}
}
@@ -489,31 +491,31 @@ static void uip_parse_alternatives(sc_ptnoderef_t node) {
*
* Parse a single pattern element.
*/
-static sc_ptnoderef_t uip_parse_element(void) {
+static sc_ptnoderef_t uip_parse_element(CONTEXT) {
sc_ptnoderef_t node = NULL;
sc_uip_tok_t token;
/* Handle pattern element based on lookahead token. */
switch (uip_parse_lookahead) {
case TOK_WHITESPACE:
- uip_parse_match(TOK_WHITESPACE);
+ R0CALL1(uip_parse_match, TOK_WHITESPACE);
node = uip_new_node(NODE_WHITESPACE);
break;
case TOK_CHOICE:
/* Parse a [...[/.../...]] choice. */
- uip_parse_match(TOK_CHOICE);
+ R0CALL1(uip_parse_match, TOK_CHOICE);
node = uip_new_node(NODE_CHOICE);
- uip_parse_alternatives(node);
- uip_parse_match(TOK_CHOICE_END);
+ R0CALL1(uip_parse_alternatives, node);
+ R0CALL1(uip_parse_match, TOK_CHOICE_END);
break;
case TOK_OPTIONAL:
/* Parse a {...[/.../...]} optional element. */
- uip_parse_match(TOK_OPTIONAL);
+ R0CALL1(uip_parse_match, TOK_OPTIONAL);
node = uip_new_node(NODE_OPTIONAL);
- uip_parse_alternatives(node);
- uip_parse_match(TOK_OPTIONAL_END);
+ R0CALL1(uip_parse_alternatives, node);
+ R0CALL1(uip_parse_match, TOK_OPTIONAL_END);
break;
case TOK_WILDCARD:
@@ -523,7 +525,7 @@ static sc_ptnoderef_t uip_parse_element(void) {
case TOK_TEXT_REFERENCE:
/* Parse %mumble% references and * wildcards. */
token = uip_parse_lookahead;
- uip_parse_match(token);
+ R0CALL1(uip_parse_match, token);
switch (token) {
case TOK_WILDCARD:
node = uip_new_node(NODE_WILDCARD);
@@ -554,7 +556,7 @@ static sc_ptnoderef_t uip_parse_element(void) {
word = uip_new_word(token_value);
/* Store details in a word node. */
- uip_parse_match(TOK_WORD);
+ R0CALL1(uip_parse_match, TOK_WORD);
node = uip_new_node(NODE_WORD);
node->word = word;
break;
@@ -569,7 +571,7 @@ static sc_ptnoderef_t uip_parse_element(void) {
name = uip_new_word(token_value);
/* Store details in a variable node, overloading word. */
- uip_parse_match(TOK_VARIABLE);
+ R0CALL1(uip_parse_match, TOK_VARIABLE);
node = uip_new_node(NODE_VARIABLE);
node->word = name;
break;
@@ -579,7 +581,7 @@ static sc_ptnoderef_t uip_parse_element(void) {
/* Syntax error. */
sc_error("uip_parse_element: syntax error,"
" unexpected token, %ld\n", (sc_int) uip_parse_lookahead);
- longjmp(uip_parse_error, 1);
+ LONG_JUMP0;
}
/* Return the newly created node. */
@@ -593,7 +595,7 @@ static sc_ptnoderef_t uip_parse_element(void) {
*
* Parse a list of pattern elements.
*/
-static void uip_parse_list(sc_ptnoderef_t list) {
+static void uip_parse_list(CONTEXT, sc_ptnoderef_t list) {
sc_ptnoderef_t child, node;
/* Add elements until a list terminator token is encountered. */
@@ -617,7 +619,7 @@ static void uip_parse_list(sc_ptnoderef_t list) {
default:
/* Add the next node at the appropriate link. */
- node = uip_parse_element();
+ FUNC0(uip_parse_element, node);
if (child == list) {
child->left_child = node;
child = child->left_child;
@@ -1614,9 +1616,10 @@ void uip_debug_trace(sc_bool flag) {
* need to copy each of the pattern and match strings passed in.
*/
sc_bool uip_match(const sc_char *pattern, const sc_char *string, sc_gameref_t game) {
- static sc_char *cleansed; /* For setjmp safety. */
+ static sc_char *cleansed = nullptr;
sc_char buffer[UIP_ALLOCATION_AVOIDANCE_SIZE];
sc_bool match;
+ Context context;
assert(pattern && string && game);
/* Start tokenizer. */
@@ -1625,21 +1628,21 @@ sc_bool uip_match(const sc_char *pattern, const sc_char *string, sc_gameref_t ga
sc_trace("UIParser: pattern \"%s\"\n", cleansed);
uip_tokenize_start(cleansed);
- /* Try parsing the pattern, and catch errors. */
- if (setjmp(uip_parse_error) == 0) {
- /* Parse the pattern into a match tree. */
- uip_parse_lookahead = uip_next_token();
- uip_parse_tree = uip_new_node(NODE_LIST);
- uip_parse_list(uip_parse_tree);
- uip_tokenize_end();
- cleansed = uip_free_cleansed_string(cleansed, buffer);
- } else {
- /* Parse error -- clean up and fail. */
+ // Try parsing the pattern into a match tree
+ uip_parse_lookahead = uip_next_token();
+ uip_parse_tree = uip_new_node(NODE_LIST);
+ uip_parse_list(context, uip_parse_tree);
+
+ if (context._break) {
+ // Parse error -- clean up and fail
uip_tokenize_end();
uip_destroy_tree(uip_parse_tree);
uip_parse_tree = NULL;
cleansed = uip_free_cleansed_string(cleansed, buffer);
return FALSE;
+ } else {
+ uip_tokenize_end();
+ cleansed = uip_free_cleansed_string(cleansed, buffer);
}
/* Dump out the pattern tree if requested. */
Commit: 97686a7c030a685146bdb10e32f6cd8e4eb52d1e
https://github.com/scummvm/scummvm/commit/97686a7c030a685146bdb10e32f6cd8e4eb52d1e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:28-07:00
Commit Message:
GLK: ADRIFT: Refactor TAF file parser to not use longjmp
Changed paths:
engines/glk/adrift/sctafpar.cpp
diff --git a/engines/glk/adrift/sctafpar.cpp b/engines/glk/adrift/sctafpar.cpp
index 6c2dcda..7dd7edf 100644
--- a/engines/glk/adrift/sctafpar.cpp
+++ b/engines/glk/adrift/sctafpar.cpp
@@ -22,6 +22,7 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Adrift {
@@ -685,9 +686,6 @@ static const sc_char *parse_get_string_property(void) {
}
-/* Parse error jump buffer. */
-static jmp_buf parse_taf_error;
-
/* Pushback line, and pushback requested flag. */
static const sc_char *parse_pushback_line = NULL;
static sc_bool parse_use_pushback = FALSE;
@@ -702,7 +700,7 @@ static sc_bool parse_use_pushback = FALSE;
* the line content into an integer or boolean, and a function for effective
* TAF line pushback.
*/
-static const sc_char *parse_get_taf_string(void) {
+static const sc_char *parse_get_taf_string(CONTEXT) {
const sc_char *line;
/* If pushback requested, use that instead of reading. */
@@ -718,7 +716,7 @@ static const sc_char *parse_get_taf_string(void) {
sc_error("parse_get_taf_string:"
" out of TAF data at line %ld\n", parse_tafline);
parse_stack_backtrace();
- longjmp(parse_taf_error, 1);
+ LONG_JUMP0;
}
/* Note this line for possible pushback. */
@@ -733,23 +731,23 @@ static const sc_char *parse_get_taf_string(void) {
return line;
}
-static sc_int parse_get_taf_integer(void) {
+static sc_int parse_get_taf_integer(CONTEXT) {
const sc_char *line;
sc_int integer;
/* Get line, and scan for a single integer; return it. */
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
if (sscanf(line, "%ld", &integer) != 1) {
sc_error("parse_get_taf_integer:"
" invalid integer at line %ld\n", parse_tafline - 1);
parse_stack_backtrace();
- longjmp(parse_taf_error, 1);
+ LONG_JUMP0;
}
return integer;
}
-static sc_bool parse_get_taf_boolean(void) {
+static sc_bool parse_get_taf_boolean(CONTEXT) {
const sc_char *line;
sc_uint boolean;
@@ -757,12 +755,12 @@ static sc_bool parse_get_taf_boolean(void) {
* Get line, and scan for a single integer; check it's a valid-looking flag,
* and return it.
*/
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
if (sscanf(line, "%lu", &boolean) != 1) {
sc_error("parse_get_taf_boolean:"
" invalid boolean at line %ld\n", parse_tafline - 1);
parse_stack_backtrace();
- longjmp(parse_taf_error, 1);
+ LONG_JUMP0;
}
if (boolean != 0 && boolean != 1) {
sc_error("parse_get_taf_boolean:"
@@ -811,16 +809,16 @@ enum {
};
/* Forward declarations of parse functions for recursion. */
-static void parse_element(const sc_char *element);
-static void parse_class(const sc_char *class_);
-static void parse_descriptor(const sc_char *descriptor);
+static void parse_element(CONTEXT, const sc_char *element);
+static void parse_class(CONTEXT, const sc_char *class_);
+static void parse_descriptor(CONTEXT, const sc_char *descriptor);
/*
* parse_array()
*
* Parse a descriptor [] array.
*/
-static void parse_array(const sc_char *array) {
+static void parse_array(CONTEXT, const sc_char *array) {
sc_int count, index_;
sc_char element[PARSE_TEMP_LENGTH];
@@ -838,7 +836,7 @@ static void parse_array(const sc_char *array) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- parse_element(element);
+ CALL1(parse_element, element);
parse_pop_key();
}
@@ -855,7 +853,7 @@ static void parse_array(const sc_char *array) {
*
* Parse a variable-length vector of properties.
*/
-static void parse_vector_common(const sc_char *vector, sc_int count) {
+static void parse_vector_common(CONTEXT, const sc_char *vector, sc_int count) {
sc_int index_;
/* Parse the vector property count times, pushing a key on each. */
@@ -865,35 +863,35 @@ static void parse_vector_common(const sc_char *vector, sc_int count) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- parse_element(vector + 1);
+ CALL1(parse_element, vector + 1);
parse_pop_key();
}
}
-static void parse_vector(const sc_char *vector) {
+static void parse_vector(CONTEXT, const sc_char *vector) {
sc_int count;
if (parse_trace)
sc_trace("Parse: entering vector %s\n", vector);
/* Find the count of elements in the vector, and parse. */
- count = parse_get_taf_integer();
- parse_vector_common(vector, count);
+ FUNC0(parse_get_taf_integer, count);
+ CALL2(parse_vector_common, vector, count);
if (parse_trace)
sc_trace("Parse: leaving vector %s\n", vector);
}
-static void parse_vector_alternate(const sc_char *vector) {
+static void parse_vector_alternate(CONTEXT, const sc_char *vector) {
sc_int count;
if (parse_trace)
sc_trace("Parse: entering alternate vector %s\n", vector);
/* Element count, this is a vector described by size - 1. */
- count = parse_get_taf_integer() + 1;
- parse_vector_common(vector, count);
+ FUNC0(parse_get_taf_integer, count) + 1;
+ CALL2(parse_vector_common, vector, count);
if (parse_trace)
sc_trace("Parse: leaving alternate vector %s\n", vector);
@@ -965,7 +963,7 @@ static sc_bool parse_test_expression(const sc_char *test_expression) {
return retval;
}
-static void parse_expression(const sc_char *expression) {
+static void parse_expression(CONTEXT, const sc_char *expression) {
sc_char test_expression[PARSE_TEMP_LENGTH];
sc_bool is_present;
@@ -994,7 +992,7 @@ static void parse_expression(const sc_char *expression) {
sc_fatal("parse_expression: bad list, %s\n", expression + next);
/* Parse this isolated element. */
- parse_element(element);
+ CALL1(parse_element, element);
/* Advance to the start of the next element. */
next += strlen(element);
@@ -1013,7 +1011,7 @@ static void parse_expression(const sc_char *expression) {
* Helper for parse_terminal(), reads in a multiline string. The return
* string is malloc'ed, and the caller needs to handle that.
*/
-static sc_char *parse_read_multiline(void) {
+static sc_char *parse_read_multiline(CONTEXT) {
const sc_byte *separator = NULL;
const sc_char *line;
sc_char *multiline;
@@ -1035,18 +1033,18 @@ static sc_char *parse_read_multiline(void) {
}
/* Take a simple copy of the first line. */
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
multiline = (sc_char *)sc_malloc(strlen(line) + 1);
strcpy(multiline, line);
/* Now concatenate until separator found. */
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
while (memcmp(line, separator, SEPARATOR_SIZE) != 0) {
multiline = (sc_char *)sc_realloc(multiline,
strlen(multiline) + strlen(line) + 2);
strcat(multiline, "\n");
strcat(multiline, line);
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
}
return multiline;
@@ -1058,7 +1056,7 @@ static sc_char *parse_read_multiline(void) {
*
* Common handler for string, integer, boolean, and multiline parse terminals.
*/
-static void parse_terminal(const sc_char *terminal) {
+static void parse_terminal(CONTEXT, const sc_char *terminal) {
sc_vartype_t vt_key, vt_value;
if (parse_trace)
@@ -1071,7 +1069,7 @@ static void parse_terminal(const sc_char *terminal) {
/* Retrieve, or invent, then store the value. */
switch (terminal[0]) {
case PARSE_INTEGER:
- vt_value.integer = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, vt_value.integer);
parse_put_property(vt_value, PROP_INTEGER);
break;
case PARSE_DEFAULT_ZERO:
@@ -1080,7 +1078,7 @@ static void parse_terminal(const sc_char *terminal) {
break;
case PARSE_BOOLEAN:
- vt_value.boolean = parse_get_taf_boolean();
+ FUNC0(parse_get_taf_boolean, vt_value.boolean);
parse_put_property(vt_value, PROP_BOOLEAN);
break;
case PARSE_DEFAULT_FALSE:
@@ -1090,7 +1088,7 @@ static void parse_terminal(const sc_char *terminal) {
break;
case PARSE_STRING:
- vt_value.string = parse_get_taf_string();
+ FUNC0(parse_get_taf_string, vt_value.string);
parse_put_property(vt_value, PROP_STRING);
break;
case PARSE_DEFAULT_EMPTY:
@@ -1100,7 +1098,7 @@ static void parse_terminal(const sc_char *terminal) {
case PARSE_MULTILINE:
/* Assign to and adopt mutable string rather than const string. */
- vt_value.mutable_string = parse_read_multiline();
+ FUNC0(parse_read_multiline, vt_value.mutable_string);
parse_put_property(vt_value, PROP_STRING);
assert(parse_bundle);
@@ -1108,13 +1106,13 @@ static void parse_terminal(const sc_char *terminal) {
break;
case PARSE_IGNORE_INTEGER:
- (void) parse_get_taf_integer();
+ CALL0(parse_get_taf_integer);
break;
case PARSE_IGNORE_BOOLEAN:
- (void) parse_get_taf_boolean();
+ CALL0(parse_get_taf_boolean);
break;
case PARSE_IGNORE_STRING:
- (void) parse_get_taf_string();
+ CALL0(parse_get_taf_string);
break;
default:
@@ -1365,7 +1363,7 @@ static void parse_handle_v400_resources(sc_bool has_sound, sc_bool has_graphics)
* Handler for special items that can't be described accurately, and
* therefore need careful treatment.
*/
-static void parse_special(const sc_char *special) {
+static void parse_special(CONTEXT, const sc_char *special) {
if (parse_trace)
sc_trace("Parse: entering special %s\n", special);
@@ -1391,10 +1389,10 @@ static void parse_special(const sc_char *special) {
sc_int flag;
/* Get next flag, and if true, pushback and parse. */
- flag = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, flag);
if (flag != 0) {
parse_taf_pushback();
- parse_descriptor("#Dest #Var1 #Var2 #Var3");
+ CALL1(parse_descriptor, "#Dest #Var1 #Var2 #Var3");
}
}
@@ -1404,10 +1402,10 @@ static void parse_special(const sc_char *special) {
sc_int flag;
/* Get next flag, and if true, pushback and parse. */
- flag = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, flag);
if (flag != 0) {
parse_taf_pushback();
- parse_descriptor("#Dest #Var1 #Var2 ZVar3");
+ CALL1(parse_descriptor, "#Dest #Var1 #Var2 ZVar3");
}
}
@@ -1432,7 +1430,7 @@ static void parse_special(const sc_char *special) {
case ROOMLIST_ONE_ROOM:
/* Store this room as the single list entry. */
- parse_element("#Room");
+ CALL1(parse_element, "#Room");
break;
case ROOMLIST_SOME_ROOMS:
@@ -1452,7 +1450,7 @@ static void parse_special(const sc_char *special) {
sc_bool this_room;
/* Get flag for this room. */
- this_room = parse_get_taf_boolean();
+ FUNC0(parse_get_taf_boolean, this_room);
/* Store flag directly. */
vt_key.integer = index_;
@@ -1484,8 +1482,9 @@ static void parse_special(const sc_char *special) {
parse_pop_key();
/* Get Parent if the object is part of an NPC. */
- if (type == ROOMLIST_NPC_PART)
- parse_element("#Parent");
+ if (type == ROOMLIST_NPC_PART) {
+ CALL1(parse_element, "#Parent");
+ }
}
/* Parse a list of rooms and times for a walk. */
@@ -1509,7 +1508,7 @@ static void parse_special(const sc_char *special) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- room = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, room);
vt_value.integer = room;
parse_put_property(vt_value, PROP_INTEGER);
@@ -1522,7 +1521,7 @@ static void parse_special(const sc_char *special) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- time = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, time);
vt_value.integer = time;
parse_put_property(vt_value, PROP_INTEGER);
@@ -1544,7 +1543,7 @@ static void parse_special(const sc_char *special) {
/* Read a boolean for each room. */
l2index_ = 0;
for (index_ = 0; index_ < num_rooms; index_++) {
- in_group = parse_get_taf_boolean();
+ FUNC0(parse_get_taf_boolean, in_group);
/* Store raw flag as List[index_]. */
vt_key.string = "List";
@@ -1923,7 +1922,7 @@ static void parse_fixup_v390_v380_room_alts(void) {
* Handler for fixup special items to help with conversions from TAF version
* 3.9 format into version 4.0.
*/
-static void parse_fixup_v390(const sc_char *fixup) {
+static void parse_fixup_v390(CONTEXT, const sc_char *fixup) {
if (parse_trace)
sc_trace("Parse: entering version 3.9 fixup %s\n", fixup);
@@ -1956,10 +1955,11 @@ static void parse_fixup_v390(const sc_char *fixup) {
var2 = parse_get_integer_property();
parse_pop_key();
- if (var2 == 5)
- parse_descriptor("$Expr ZVar5");
- else
- parse_descriptor("EExpr #Var5");
+ if (var2 == 5) {
+ CALL1(parse_descriptor, "$Expr ZVar5");
+ } else {
+ CALL1(parse_descriptor, "EExpr #Var5");
+ }
}
/*
@@ -2964,7 +2964,7 @@ static void parse_fixup_v380(const sc_char *fixup) {
* Handler for fixup special items to help with conversions from TAF version
* 3.9 and version 3.8 formats into version 4.0.
*/
-static void parse_fixup(const sc_char *fixup) {
+static void parse_fixup(CONTEXT, const sc_char *fixup) {
/*
* Pick a fixup handler specific to the TAF version. This helps keep
* fixup code separate, rather than glommed into one large function.
@@ -2974,7 +2974,7 @@ static void parse_fixup(const sc_char *fixup) {
sc_fatal("parse_fixup: unexpected call\n");
break;
case TAF_VERSION_390:
- parse_fixup_v390(fixup);
+ CALL1(parse_fixup_v390, fixup);
break;
case TAF_VERSION_380:
parse_fixup_v380(fixup);
@@ -2991,32 +2991,32 @@ static void parse_fixup(const sc_char *fixup) {
*
* Parse a class descriptor element.
*/
-static void parse_element(const sc_char *element) {
+static void parse_element(CONTEXT, const sc_char *element) {
if (parse_trace)
sc_trace("Parse: entering element %s\n", element);
/* Determine the element type from the first character. */
switch (element[0]) {
case PARSE_ARRAY:
- parse_array(element);
+ CALL1(parse_array, element);
break;
case PARSE_VECTOR:
- parse_vector(element);
+ CALL1(parse_vector, element);
break;
case PARSE_VECTOR_ALTERNATE:
- parse_vector_alternate(element);
+ CALL1(parse_vector_alternate, element);
break;
case PARSE_CLASS:
- parse_class(element);
+ CALL1(parse_class, element);
break;
case PARSE_EXPRESSION:
- parse_expression(element);
+ CALL1(parse_expression, element);
break;
case PARSE_SPECIAL:
- parse_special(element);
+ CALL1(parse_special, element);
break;
case PARSE_FIXUP:
- parse_fixup(element);
+ CALL1(parse_fixup, element);
break;
case PARSE_INTEGER:
@@ -3030,7 +3030,7 @@ static void parse_element(const sc_char *element) {
case PARSE_IGNORE_BOOLEAN:
case PARSE_IGNORE_STRING:
case PARSE_MULTILINE:
- parse_terminal(element);
+ CALL1(parse_terminal, element);
break;
default:
sc_fatal("parse_element: bad type, %c\n", element[0]);
@@ -3046,7 +3046,7 @@ static void parse_element(const sc_char *element) {
*
* Parse a class's properties descriptor list.
*/
-static void parse_descriptor(const sc_char *descriptor) {
+static void parse_descriptor(CONTEXT, const sc_char *descriptor) {
sc_int next;
/* Find and parse each element in the descriptor. */
@@ -3058,7 +3058,7 @@ static void parse_descriptor(const sc_char *descriptor) {
sc_fatal("parse_element: no element, %s\n", descriptor + next);
/* Parse this isolated element. */
- parse_element(element);
+ CALL1(parse_element, element);
/* Advance over the element and any trailing whitespace. */
next += strlen(element);
@@ -3072,7 +3072,7 @@ static void parse_descriptor(const sc_char *descriptor) {
*
* Parse a class of properties.
*/
-static void parse_class(const sc_char *class_) {
+static void parse_class(CONTEXT, const sc_char *class_) {
sc_char class_name[PARSE_TEMP_LENGTH];
sc_int index_;
sc_vartype_t vt_key;
@@ -3102,7 +3102,7 @@ static void parse_class(const sc_char *class_) {
}
/* Parse each element in the descriptor. */
- parse_descriptor(parse_schema[index_].descriptor);
+ CALL1(parse_descriptor, parse_schema[index_].descriptor);
/* Pop a key if the class tag was pushed above. */
if (index_ > 0)
@@ -3354,6 +3354,7 @@ static void parse_add_version(sc_prop_setref_t bundle, sc_tafref_t taf) {
*/
sc_bool parse_game(sc_tafref_t taf, sc_prop_setref_t bundle) {
assert(taf && bundle);
+ Context context;
/* Store the TAF to read from, and the bundle to store into. */
parse_taf = taf;
@@ -3361,14 +3362,13 @@ sc_bool parse_game(sc_tafref_t taf, sc_prop_setref_t bundle) {
parse_schema = parse_select_schema(parse_taf);
parse_depth = 0;
- /* Try parsing, and catch errors from longjmp. */
- if (setjmp(parse_taf_error) == 0) {
- /* Parse a complete game. */
- taf_first_line(parse_taf);
- parse_tafline = 0;
- parse_class("<_GAME_>");
- } else {
- /* Error with one of the TAF file lines. */
+ // Try parsing a complete game
+ taf_first_line(parse_taf);
+ parse_tafline = 0;
+ parse_class(context, "<_GAME_>");
+
+ if (context._break) {
+ // Error with one of the TAF file lines
parse_clear_v400_resources_table();
parse_taf = NULL;
parse_bundle = NULL;
Commit: 043093209ee3ff8a00b76885f7624ff349aff839
https://github.com/scummvm/scummvm/commit/043093209ee3ff8a00b76885f7624ff349aff839
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:28-07:00
Commit Message:
GLK: ALAN3: Merge duplicate jumps.h
Changed paths:
R engines/glk/alan3/jumps.h
engines/glk/alan3/act.h
engines/glk/alan3/actor.h
engines/glk/alan3/alt_info.h
engines/glk/alan3/checkentry.h
engines/glk/alan3/container.h
engines/glk/alan3/debug.h
engines/glk/alan3/exe.h
engines/glk/alan3/glkio.h
engines/glk/alan3/instance.h
engines/glk/alan3/inter.h
engines/glk/alan3/location.h
engines/glk/alan3/main.cpp
engines/glk/alan3/msg.h
engines/glk/alan3/parse.cpp
engines/glk/alan3/parse.h
engines/glk/alan3/rules.h
engines/glk/alan3/scan.h
engines/glk/alan3/syntax.h
engines/glk/alan3/syserr.h
engines/glk/alan3/utils.h
engines/glk/jumps.h
diff --git a/engines/glk/alan3/act.h b/engines/glk/alan3/act.h
index b2daa25..b24551b 100644
--- a/engines/glk/alan3/act.h
+++ b/engines/glk/alan3/act.h
@@ -25,7 +25,7 @@
/* Header file for action unit of ARUN Alan System interpreter */
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/params.h"
namespace Glk {
diff --git a/engines/glk/alan3/actor.h b/engines/glk/alan3/actor.h
index 6ac20b2..9df5ae2 100644
--- a/engines/glk/alan3/actor.h
+++ b/engines/glk/alan3/actor.h
@@ -24,7 +24,7 @@
#define GLK_ALAN3_ACTOR
#include "glk/alan3/acode.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/alt_info.h b/engines/glk/alan3/alt_info.h
index a46d16b..75a097f 100644
--- a/engines/glk/alan3/alt_info.h
+++ b/engines/glk/alan3/alt_info.h
@@ -27,7 +27,7 @@
#include "glk/alan3/types.h"
#include "glk/alan3/acode.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/params.h"
#include "glk/alan3/parameter_position.h"
diff --git a/engines/glk/alan3/checkentry.h b/engines/glk/alan3/checkentry.h
index a0c3d25..36e4fb7 100644
--- a/engines/glk/alan3/checkentry.h
+++ b/engines/glk/alan3/checkentry.h
@@ -25,7 +25,7 @@
#include "glk/alan3/types.h"
#include "glk/alan3/acode.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/container.h b/engines/glk/alan3/container.h
index 86d84c6..3196d4e 100644
--- a/engines/glk/alan3/container.h
+++ b/engines/glk/alan3/container.h
@@ -25,7 +25,7 @@
#include "glk/alan3/types.h"
#include "glk/alan3/acode.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/debug.h b/engines/glk/alan3/debug.h
index 1f5e2c1..64d2f52 100644
--- a/engines/glk/alan3/debug.h
+++ b/engines/glk/alan3/debug.h
@@ -26,7 +26,7 @@
/* Header file for debug handler in Alan interpreter */
#include "glk/alan3/types.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/exe.h b/engines/glk/alan3/exe.h
index df5892c..333feeb 100644
--- a/engines/glk/alan3/exe.h
+++ b/engines/glk/alan3/exe.h
@@ -27,7 +27,7 @@
/* IMPORTS */
#include "glk/alan3/sysdep.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/acode.h"
#include "glk/alan3/types.h"
#include "glk/alan3/set.h"
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index 333a24b..5b54228 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -25,7 +25,7 @@
#include "glk/glk_api.h"
#include "glk/windows.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/instance.h b/engines/glk/alan3/instance.h
index 7c2b9cf..00932c5 100644
--- a/engines/glk/alan3/instance.h
+++ b/engines/glk/alan3/instance.h
@@ -25,7 +25,7 @@
#include "common/serializer.h"
#include "glk/alan3/acode.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/types.h"
#include "glk/alan3/set.h"
diff --git a/engines/glk/alan3/inter.h b/engines/glk/alan3/inter.h
index 887a06a..7efb92d 100644
--- a/engines/glk/alan3/inter.h
+++ b/engines/glk/alan3/inter.h
@@ -27,7 +27,7 @@
#include "glk/alan3/types.h"
#include "glk/alan3/stack.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/jumps.h b/engines/glk/alan3/jumps.h
deleted file mode 100644
index 10c33fa..0000000
--- a/engines/glk/alan3/jumps.h
+++ /dev/null
@@ -1,87 +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_ALAN2_JUMPS
-#define GLK_ALAN2_JUMPS
-
-/* This provides a simplified version of the ScummVM coroutines to allow for automated
- * breakouts to the main game loop from subroutinese rather than using unportable setjmps
- */
-
-#include "common/str.h"
-
-namespace Glk {
-namespace Alan3 {
-
-/**
- * Context used for flagging when a break to the outer game loop
- */
-struct Context {
- bool _break;
- Common::String _label;
-
- /**
- * Constructor
- */
- Context() : _break(false) {}
-
- /**
- * Clear
- */
- void clear() {
- _break = false;
- _label = "";
- }
-};
-
-#define CALL0(METHOD) { METHOD(context); if (context._break) return; }
-#define CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return; }
-#define CALL2(METHOD, P1, P2) { METHOD(context, P1, P2); if (context._break) return; }
-#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P1, P2, P3); if (context._break) return; }
-#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P1, P2, P3, P4); if (context._break) return; }
-#define FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return; }
-#define FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return; }
-#define FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P1, P2); if (context._break) return; }
-#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P1, P2, P3); if (context._break) return; }
-#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P1, P2, P3, P4); if (context._break) return; }
-
-#define R0CALL0(METHOD) { METHOD(context); if (context._break) return 0; }
-#define R0CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return 0; }
-#define R0CALL2(METHOD, P1, P2) { METHOD(context, P1, P2); if (context._break) return 0; }
-#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P1, P2, P3); if (context._break) return 0; }
-#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P1, P2, P3, P4); if (context._break) return 0; }
-#define R0FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return 0; }
-#define R0FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return 0; }
-#define R0FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P1, P2); if (context._break) return 0; }
-#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P1, P2, P3); if (context._break) return 0; }
-#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P1, P2, P3, P4); if (context._break) return 0; }
-
-#define CONTEXT Context &context
-#define LONG_JUMP { context._break = true; context._label = "turn"; return; }
-#define LONG_JUMP0 { context._break = true; return 0; }
-#define LONG_JUMP_LABEL(LBL) { context._break = true; context._label = LBL; return; }
-#define LONG_JUMP_LABEL0(LBL) { context._break = true; context._label = LBL; return 0; }
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan3/location.h b/engines/glk/alan3/location.h
index 005f8bc..e5dcd50 100644
--- a/engines/glk/alan3/location.h
+++ b/engines/glk/alan3/location.h
@@ -24,7 +24,7 @@
#define GLK_ALAN3_LOCATION
#include "glk/alan3/types.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index d20ec44..9939e3a 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -34,7 +34,7 @@
#include "glk/alan3/glkio.h"
#include "glk/alan3/instance.h"
#include "glk/alan3/inter.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/lists.h"
#include "glk/alan3/literal.h"
#include "glk/alan3/location.h"
diff --git a/engines/glk/alan3/msg.h b/engines/glk/alan3/msg.h
index 6275c72..667c01a 100644
--- a/engines/glk/alan3/msg.h
+++ b/engines/glk/alan3/msg.h
@@ -24,7 +24,7 @@
#define GLK_ALAN3_MSG
#include "glk/alan3/acode.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/types.h"
#include "glk/alan3/params.h"
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp
index efa5464..9ddd454 100644
--- a/engines/glk/alan3/parse.cpp
+++ b/engines/glk/alan3/parse.cpp
@@ -31,7 +31,7 @@
#include "glk/alan3/glkio.h"
#include "glk/alan3/instance.h"
#include "glk/alan3/inter.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/lists.h"
#include "glk/alan3/literal.h"
#include "glk/alan3/location.h"
diff --git a/engines/glk/alan3/parse.h b/engines/glk/alan3/parse.h
index 2737183..8ef11b1 100644
--- a/engines/glk/alan3/parse.h
+++ b/engines/glk/alan3/parse.h
@@ -27,7 +27,7 @@
#include "glk/alan3/types.h"
#include "glk/alan3/params.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/rules.h b/engines/glk/alan3/rules.h
index abb5a2b..ad8ed26 100644
--- a/engines/glk/alan3/rules.h
+++ b/engines/glk/alan3/rules.h
@@ -25,7 +25,7 @@
/* Header file for rules handler in Alan interpreter */
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/acode.h"
namespace Glk {
diff --git a/engines/glk/alan3/scan.h b/engines/glk/alan3/scan.h
index 6f565c05..06d9e97 100644
--- a/engines/glk/alan3/scan.h
+++ b/engines/glk/alan3/scan.h
@@ -26,7 +26,7 @@
/* Player input scanner for ALAN interpreter module. */
#include "glk/alan3/types.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/syntax.h b/engines/glk/alan3/syntax.h
index 8aebc23..d5b48a6 100644
--- a/engines/glk/alan3/syntax.h
+++ b/engines/glk/alan3/syntax.h
@@ -24,7 +24,7 @@
#define GLK_ALAN3_SYNTAX
#include "glk/alan3/types.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
#include "glk/alan3/memory.h"
namespace Glk {
diff --git a/engines/glk/alan3/syserr.h b/engines/glk/alan3/syserr.h
index fc80e72..1e6654c 100644
--- a/engines/glk/alan3/syserr.h
+++ b/engines/glk/alan3/syserr.h
@@ -25,7 +25,7 @@
/* Header file for syserr unit of ARUN Alan System interpreter */
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/alan3/utils.h b/engines/glk/alan3/utils.h
index 0c56e0a..37cabda 100644
--- a/engines/glk/alan3/utils.h
+++ b/engines/glk/alan3/utils.h
@@ -26,7 +26,7 @@
/* Utility functions for the Alan interpreter */
#include "glk/alan3/types.h"
-#include "glk/alan3/jumps.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Alan3 {
diff --git a/engines/glk/jumps.h b/engines/glk/jumps.h
index f343812..6da1a45 100644
--- a/engines/glk/jumps.h
+++ b/engines/glk/jumps.h
@@ -23,6 +23,8 @@
#ifndef GLK_JUMPS
#define GLK_JUMPS
+#include "common/str.h"
+
/* This provides a simplified version of the ScummVM coroutines to allow for automated
* breakouts to the main game loop from subroutinese rather than using unportable setjmps
*/
@@ -34,7 +36,17 @@ namespace Glk {
*/
struct Context {
bool _break;
+ Common::String _label;
+
Context() : _break(false) {}
+
+ /**
+ * Clear the context
+ */
+ void clear() {
+ _break = false;
+ _label = "";
+ }
};
#define CALL0(METHOD) { METHOD(context); if (context._break) return; }
@@ -62,6 +74,8 @@ struct Context {
#define CONTEXT Context &context
#define LONG_JUMP { context._break = true; return; }
#define LONG_JUMP0 { context._break = true; return 0; }
+#define LONG_JUMP_LABEL(LBL) { context._break = true; context._label = LBL; return; }
+#define LONG_JUMP_LABEL0(LBL) { context._break = true; context._label = LBL; return 0; }
} // End of namespace Glk
Commit: b44d36e97bedf8b37efc411651271a0bef585a0f
https://github.com/scummvm/scummvm/commit/b44d36e97bedf8b37efc411651271a0bef585a0f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:28-07:00
Commit Message:
GLK: ADRIFT: Convert overall game quit long jump to use contexts
Changed paths:
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/scare.h
engines/glk/adrift/scdebug.cpp
engines/glk/adrift/scgamest.cpp
engines/glk/adrift/scgamest.h
engines/glk/adrift/scinterf.cpp
engines/glk/adrift/scprops.cpp
engines/glk/adrift/scprotos.h
engines/glk/adrift/screstrs.cpp
engines/glk/adrift/scrunner.cpp
engines/glk/adrift/serialization.cpp
engines/glk/adrift/sxtester.cpp
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index c0b35c4..b08dfbb 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -2888,6 +2888,7 @@ static int gsc_startup_code(Common::SeekableReadStream *game_stream, int restore
static void gsc_main() {
sc_bool is_running;
+ Context context;
/* Ensure SCARE internal types have the right sizes. */
if (!(sizeof(sc_byte) == 1 && sizeof(sc_char) == 1
@@ -2927,7 +2928,12 @@ static void gsc_main() {
while (is_running) {
/* Run the game until it ends, or the user quits. */
gsc_status_notify();
- sc_interpret_game(gsc_game);
+
+ if (!context._break)
+ sc_interpret_game(context, gsc_game);
+
+ // End point for any context long jump
+ context.clear();
/*
* If the game did not complete, the user quit explicitly, so leave the
@@ -2956,17 +2962,17 @@ static void gsc_main() {
switch (gsc_get_ending_option()) {
case GAME_RESTART:
gsc_short_delay();
- sc_restart_game(gsc_game);
+ sc_restart_game(context, gsc_game);
break;
case GAME_UNDO:
if (sc_is_game_undo_available(gsc_game)) {
- sc_undo_game_turn(gsc_game);
+ sc_undo_game_turn(context, gsc_game);
gsc_normal_string("The previous turn has been undone.\n");
} else {
gsc_normal_string("Sorry, no undo is available.\n");
gsc_short_delay();
- sc_restart_game(gsc_game);
+ sc_restart_game(context, gsc_game);
}
break;
diff --git a/engines/glk/adrift/scare.h b/engines/glk/adrift/scare.h
index d4e0231..1dc7c6e 100644
--- a/engines/glk/adrift/scare.h
+++ b/engines/glk/adrift/scare.h
@@ -25,9 +25,7 @@
#include "common/scummsys.h"
#include "common/stream.h"
-#undef longjmp
-#undef setjmp
-#include <setjmp.h>
+#include "glk/jumps.h"
namespace Glk {
namespace Adrift {
@@ -111,11 +109,11 @@ extern sc_game sc_game_from_stream(Common::SeekableReadStream *stream);
extern sc_game sc_game_from_callback(sc_int(*callback)
(void *, sc_byte *, sc_int),
void *opaque);
-extern void sc_interpret_game(sc_game game);
-extern void sc_restart_game(sc_game game);
+extern void sc_interpret_game(CONTEXT, sc_game game);
+extern void sc_restart_game(CONTEXT, sc_game game);
extern sc_bool sc_save_game(sc_game game);
extern sc_bool sc_load_game(sc_game game);
-extern sc_bool sc_undo_game_turn(sc_game game);
+extern sc_bool sc_undo_game_turn(CONTEXT, sc_game game);
extern void sc_quit_game(sc_game game);
extern sc_bool sc_save_game_to_filename(sc_game game, const sc_char *filename);
extern void sc_save_game_to_stream(sc_game game, Common::SeekableReadStream *stream);
diff --git a/engines/glk/adrift/scdebug.cpp b/engines/glk/adrift/scdebug.cpp
index a752506..23c8ed2 100644
--- a/engines/glk/adrift/scdebug.cpp
+++ b/engines/glk/adrift/scdebug.cpp
@@ -1891,6 +1891,7 @@ static sc_bool debug_compare_variable(sc_gameref_t from, sc_gameref_t with, sc_i
const sc_char *name;
sc_int var_type, var_type2;
sc_bool equal = FALSE;
+ vt_rvalue.voidp = vt_rvalue2.voidp = nullptr;
if (from->bundle != with->bundle)
sc_fatal("debug_compare_variable: property sharing malfunction\n");
@@ -2203,7 +2204,7 @@ static void debug_dispatch(sc_gameref_t game, sc_command_t command, sc_command_t
*
* Create a small debugging dialog with the user.
*/
-static void debug_dialog(sc_gameref_t game) {
+static void debug_dialog(CONTEXT, sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_debuggerref_t debug = debug_get_debugger(game);
const sc_var_setref_t vars = gs_get_vars(game);
@@ -2264,7 +2265,7 @@ static void debug_dialog(sc_gameref_t game) {
/* Drop printfilter contents and quit the game. */
pf_empty(filter);
- run_quit(game);
+ CALL1(run_quit, game);
/* Just in case... */
if_print_debug("Unable to quit from the game. Sorry.\n");
@@ -2326,13 +2327,14 @@ sc_bool debug_run_command(sc_gameref_t game, const sc_char *debug_command) {
*/
sc_bool debug_cmd_debugger(sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
+ Context context;
/* If debugging disallowed (not initialized), ignore the call. */
- if (debug)
- debug_dialog(game);
- else
+ if (debug) {
+ debug_dialog(context, game);
+ } else {
if_print_string("SCARE's game debugger is not enabled. Sorry.\n");
-
+ }
/*
* Set as administrative command, so as not to consume a game turn, and
* return successfully.
@@ -2354,7 +2356,7 @@ sc_bool debug_cmd_debugger(sc_gameref_t game) {
* The second is called on exit from the game, and may make a final sweep for
* watchpoints and offer the debug dialog one last time.
*/
-void debug_game_started(sc_gameref_t game) {
+void debug_game_started(CONTEXT, sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/* If debugging disallowed (not initialized), ignore the call. */
@@ -2368,20 +2370,21 @@ void debug_game_started(sc_gameref_t game) {
if_print_debug("\n--- SCARE " SCARE_VERSION SCARE_PATCH_LEVEL
" Game Debugger\n"
"--- Type 'help' for a list of commands.\n");
- debug_dialog(game);
+ CALL1(debug_dialog, game);
} else {
/*
* It's a restore or undo through memos, so run the dialog only if
* single-stepping; no need to check watchpoints for this case as
* none can be set -- no undo.
*/
- if (debug->single_step)
- debug_dialog(game);
+ if (debug->single_step) {
+ CALL1(debug_dialog, game);
+ }
}
}
}
-void debug_game_ended(sc_gameref_t game) {
+void debug_game_ended(CONTEXT, sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/* If debugging disallowed (not initialized), ignore the call. */
@@ -2412,7 +2415,7 @@ void debug_game_ended(sc_gameref_t game) {
}
/* Run a final dialog. */
- debug_dialog(game);
+ CALL1(debug_dialog, game);
}
}
@@ -2423,7 +2426,7 @@ void debug_game_ended(sc_gameref_t game) {
* Called after each turn by the main game loop. Checks for any set
* watchpoints, and triggers a debug dialog when any fire.
*/
-void debug_turn_update(sc_gameref_t game) {
+void debug_turn_update(CONTEXT, sc_gameref_t game) {
const sc_debuggerref_t debug = debug_get_debugger(game);
/* If debugging disallowed (not initialized), ignore the call. */
@@ -2441,8 +2444,9 @@ void debug_turn_update(sc_gameref_t game) {
* Run debugger dialog if any watchpoints triggered, or if single
* stepping (even if none triggered).
*/
- if (debug_check_watchpoints(game) || debug->single_step)
- debug_dialog(game);
+ if (debug_check_watchpoints(game) || debug->single_step) {
+ CALL1(debug_dialog, game);
+ }
}
}
diff --git a/engines/glk/adrift/scgamest.cpp b/engines/glk/adrift/scgamest.cpp
index 84abf6b..ab92b41 100644
--- a/engines/glk/adrift/scgamest.cpp
+++ b/engines/glk/adrift/scgamest.cpp
@@ -783,10 +783,7 @@ sc_gameref_t gs_create(sc_var_setref_t vars, sc_prop_setref_t bundle, sc_filterr
game->her_npc = -1;
game->it_npc = -1;
- /* Clear the quit jump buffer for tidiness. */
- memset(&game->quitter, 0, sizeof(game->quitter));
-
- /* Return the constructed game state. */
+ // Return the constructed game state
return game;
}
@@ -959,9 +956,6 @@ void gs_copy(sc_gameref_t to, sc_gameref_t from) {
to->him_npc = from->him_npc;
to->her_npc = from->her_npc;
to->it_npc = from->it_npc;
-
- /* Copy over the quit jump buffer. */
- memcpy(&to->quitter, &from->quitter, sizeof(from->quitter));
}
diff --git a/engines/glk/adrift/scgamest.h b/engines/glk/adrift/scgamest.h
index a246d05..494f750 100644
--- a/engines/glk/adrift/scgamest.h
+++ b/engines/glk/adrift/scgamest.h
@@ -180,9 +180,6 @@ struct sc_game_s {
sc_int him_npc;
sc_int her_npc;
sc_int it_npc;
-
- /* Longjump buffer for external requests to quit. */
- jmp_buf quitter;
};
typedef sc_game_s sc_game_t;
diff --git a/engines/glk/adrift/scinterf.cpp b/engines/glk/adrift/scinterf.cpp
index ff7456b..c01d99a 100644
--- a/engines/glk/adrift/scinterf.cpp
+++ b/engines/glk/adrift/scinterf.cpp
@@ -403,22 +403,22 @@ static sc_bool if_game_error(sc_gameref_t game, const sc_char *function_name) {
* behaving like sc_restart_game()), but will return if the game could not
* be restored. sc_undo_game_turn() behaves like sc_load_game().
*/
-void sc_interpret_game(sc_game game) {
+void sc_interpret_game(CONTEXT, sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_interpret_game"))
return;
- run_interpret(game_);
+ run_interpret(context, game_);
}
-void sc_restart_game(sc_game game) {
+void sc_restart_game(CONTEXT, sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_restart_game"))
return;
- run_restart(game_);
+ CALL1(run_restart, game_);
}
sc_bool sc_save_game(sc_game game) {
@@ -430,31 +430,31 @@ sc_bool sc_save_game(sc_game game) {
return run_save_prompted(game_);
}
-sc_bool sc_load_game(sc_game game) {
+sc_bool sc_load_game(CONTEXT, sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_load_game"))
return FALSE;
- return run_restore_prompted(game_);
+ return run_restore_prompted(context, game_);
}
-sc_bool sc_undo_game_turn(sc_game game) {
+sc_bool sc_undo_game_turn(CONTEXT, sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_undo_game_turn"))
return FALSE;
- return run_undo(game_);
+ return run_undo(context, game_);
}
-void sc_quit_game(sc_game game) {
+void sc_quit_game(CONTEXT, sc_game game) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_quit_game"))
return;
- run_quit(game_);
+ run_quit(context, game_);
}
@@ -526,7 +526,7 @@ void sc_save_game_to_callback(sc_game game,
run_save(game_, callback, opaque);
}
-sc_bool sc_load_game_from_filename(sc_game game, const sc_char *filename) {
+sc_bool sc_load_game_from_filename(CONTEXT, sc_game game, const sc_char *filename) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
Common::InSaveFile *sf;
sc_bool status;
@@ -545,13 +545,13 @@ sc_bool sc_load_game_from_filename(sc_game game, const sc_char *filename) {
return FALSE;
}
- status = run_restore(game_, if_file_read_callback, sf);
+ status = run_restore(context, game_, if_file_read_callback, sf);
delete sf;
return status;
}
-sc_bool sc_load_game_from_stream(sc_game game, Common::SeekableReadStream *stream) {
+sc_bool sc_load_game_from_stream(CONTEXT, sc_game game, Common::SeekableReadStream *stream) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
if (if_game_error(game_, "sc_load_game_from_stream"))
@@ -562,10 +562,10 @@ sc_bool sc_load_game_from_stream(sc_game game, Common::SeekableReadStream *strea
return FALSE;
}
- return run_restore(game_, if_file_read_callback, stream);
+ return run_restore(context, game_, if_file_read_callback, stream);
}
-sc_bool sc_load_game_from_callback(sc_game game,
+sc_bool sc_load_game_from_callback(CONTEXT, sc_game game,
sc_int(*callback)(void *, sc_byte *, sc_int), void *opaque) {
const sc_gameref_t game_ = (const sc_gameref_t)game;
@@ -577,7 +577,7 @@ sc_bool sc_load_game_from_callback(sc_game game,
return FALSE;
}
- return run_restore(game_, callback, opaque);
+ return run_restore(context, game_, callback, opaque);
}
diff --git a/engines/glk/adrift/scprops.cpp b/engines/glk/adrift/scprops.cpp
index 0888173..166f506 100644
--- a/engines/glk/adrift/scprops.cpp
+++ b/engines/glk/adrift/scprops.cpp
@@ -256,7 +256,7 @@ static sc_prop_noderef_t prop_find_child(sc_prop_noderef_t parent, sc_int type,
/* See if this node has any children. */
if (parent->child_list) {
sc_int index_;
- sc_prop_noderef_t child;
+ sc_prop_noderef_t child = nullptr;
/* Do the lookup based on name type. */
switch (type) {
diff --git a/engines/glk/adrift/scprotos.h b/engines/glk/adrift/scprotos.h
index 7533597..39fba6b 100644
--- a/engines/glk/adrift/scprotos.h
+++ b/engines/glk/adrift/scprotos.h
@@ -21,6 +21,7 @@
*/
#include "glk/adrift/scare.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Adrift {
@@ -621,20 +622,17 @@ extern void res_sync_resources(sc_gameref_t game);
extern void res_cancel_resources(sc_gameref_t game);
/* Game runner functions. */
-extern sc_bool run_game_task_commands(sc_gameref_t game,
- const sc_char *string);
+extern sc_bool run_game_task_commands(sc_gameref_t game, const sc_char *string);
extern sc_gameref_t run_create(sc_read_callbackref_t callback, void *opaque);
-extern void run_interpret(sc_gameref_t game);
+extern void run_interpret(CONTEXT, sc_gameref_t game);
extern void run_destroy(sc_gameref_t game);
-extern void run_restart(sc_gameref_t game);
-extern void run_save(sc_gameref_t game,
- sc_write_callbackref_t callback, void *opaque);
+extern void run_restart(CONTEXT, sc_gameref_t game);
+extern void run_save(sc_gameref_t game, sc_write_callbackref_t callback, void *opaque);
extern sc_bool run_save_prompted(sc_gameref_t game);
-extern sc_bool run_restore(sc_gameref_t game,
- sc_read_callbackref_t callback, void *opaque);
-extern sc_bool run_restore_prompted(sc_gameref_t game);
-extern sc_bool run_undo(sc_gameref_t game);
-extern void run_quit(sc_gameref_t game);
+extern sc_bool run_restore(CONTEXT, sc_gameref_t game, sc_read_callbackref_t callback, void *opaque);
+extern sc_bool run_restore_prompted(CONTEXT, sc_gameref_t game);
+extern sc_bool run_undo(CONTEXT, sc_gameref_t game);
+extern void run_quit(CONTEXT, sc_gameref_t game);
extern sc_bool run_is_running(sc_gameref_t game);
extern sc_bool run_has_completed(sc_gameref_t game);
extern sc_bool run_is_undo_available(sc_gameref_t game);
@@ -757,9 +755,9 @@ extern sc_bool debug_run_command(sc_gameref_t game,
extern sc_bool debug_cmd_debugger(sc_gameref_t game);
extern void debug_set_enabled(sc_gameref_t game, sc_bool enable);
extern sc_bool debug_get_enabled(sc_gameref_t game);
-extern void debug_game_started(sc_gameref_t game);
-extern void debug_game_ended(sc_gameref_t game);
-extern void debug_turn_update(sc_gameref_t game);
+extern void debug_game_started(CONTEXT, sc_gameref_t game);
+extern void debug_game_ended(CONTEXT, sc_gameref_t game);
+extern void debug_turn_update(CONTEXT, sc_gameref_t game);
/* OS interface functions. */
extern sc_bool if_get_trace_flag(sc_uint bitmask);
diff --git a/engines/glk/adrift/screstrs.cpp b/engines/glk/adrift/screstrs.cpp
index c808129..e69ad3e 100644
--- a/engines/glk/adrift/screstrs.cpp
+++ b/engines/glk/adrift/screstrs.cpp
@@ -24,6 +24,10 @@
#include "glk/adrift/scprotos.h"
#include "glk/adrift/scgamest.h"
+#undef longjmp
+#undef setjmp
+#include <setjmp.h>
+
namespace Glk {
namespace Adrift {
diff --git a/engines/glk/adrift/scrunner.cpp b/engines/glk/adrift/scrunner.cpp
index 288ca83..dbf160f 100644
--- a/engines/glk/adrift/scrunner.cpp
+++ b/engines/glk/adrift/scrunner.cpp
@@ -1237,7 +1237,7 @@ static sc_bool run_player_input(sc_gameref_t game) {
*
* Main interpreter loop.
*/
-static void run_main_loop(sc_gameref_t game) {
+static void run_main_loop(CONTEXT, sc_gameref_t game) {
const sc_filterref_t filter = gs_get_filter(game);
const sc_var_setref_t vars = gs_get_vars(game);
const sc_prop_setref_t bundle = gs_get_bundle(game);
@@ -1304,13 +1304,13 @@ static void run_main_loop(sc_gameref_t game) {
* the initial room visited as this is how the debugger differentiates
* restarts from restore or undo back to game start.
*/
- debug_game_started(game);
+ CALL1(debug_game_started, game);
/* Note the initial room as visited. */
gs_set_room_seen(game, gs_playerroom(game), TRUE);
} else {
/* Notify the debugger that the game has restarted. */
- debug_game_started(game);
+ CALL1(debug_game_started, game);
}
/*
@@ -1381,7 +1381,7 @@ static void run_main_loop(sc_gameref_t game) {
gs_set_room_seen(game, gs_playerroom(game), TRUE);
/* Give the debugger a chance to catch watchpoints. */
- debug_turn_update(game);
+ CALL1(debug_turn_update, game);
}
}
@@ -1394,7 +1394,7 @@ static void run_main_loop(sc_gameref_t game) {
* scan and offer the dialog if appropriate.
*/
run_update_status(game);
- debug_game_ended(game);
+ CALL1(debug_game_ended, game);
/*
* Final resource sync, score change notification and printfilter flush
@@ -1575,7 +1575,7 @@ static void run_quit_handler(sc_gameref_t game) {
*
* Intepret the game in a game context.
*/
-void run_interpret(sc_gameref_t game) {
+void run_interpret(CONTEXT, sc_gameref_t game) {
assert(gs_is_game_valid(game));
/* Verify the game is not already running, and is runnable. */
@@ -1597,9 +1597,8 @@ void run_interpret(sc_gameref_t game) {
/* Run the main interpreter loop until no more restarts. */
game->is_running = TRUE;
do {
- /* Run the game until some form of halt is requested. */
- if (setjmp(game->quitter) == 0)
- run_main_loop(game);
+ // Run the game until some form of halt is requested
+ CALL1(run_main_loop, game);
/*
* If the halt was a restart or restore, cancel the request, handle
@@ -1682,19 +1681,18 @@ void run_destroy(sc_gameref_t game) {
* Quits a running game. This function calls a longjump to act as if
* run_main_loop() returned, and so never returns to its caller.
*/
-void run_quit(sc_gameref_t game) {
+void run_quit(CONTEXT, sc_gameref_t game) {
assert(gs_is_game_valid(game));
- /* Disallow quitting a non-running game. */
+ // Disallow quitting a non-running game
if (!game->is_running) {
sc_error("run_quit: game is not running\n");
return;
}
- /* Exit the main loop with a longjump. */
+ // Exit the main loop
game->is_running = FALSE;
- longjmp(game->quitter, 1);
- sc_fatal("run_quit: unable to quit cleanly\n");
+ LONG_JUMP;
}
@@ -1705,7 +1703,7 @@ void run_quit(sc_gameref_t game) {
* function calls a longjump to act as if run_main_loop() returned, and so
* never returns to its caller. For stopped games, it returns.
*/
-void run_restart(sc_gameref_t game) {
+void run_restart(CONTEXT, sc_gameref_t game) {
assert(gs_is_game_valid(game));
/*
@@ -1715,11 +1713,10 @@ void run_restart(sc_gameref_t game) {
if (game->is_running) {
game->is_running = FALSE;
game->do_restart = TRUE;
- longjmp(game->quitter, 1);
- sc_fatal("run_restart: unable to restart cleanly\n");
+ LONG_JUMP;
}
- /* Restart locally, and ensure that the game remains stopped. */
+ // Restart locally, and ensure that the game remains stopped
run_restart_handler(game);
game->is_running = FALSE;
}
@@ -1756,7 +1753,7 @@ sc_bool run_save_prompted(sc_gameref_t game) {
* restore, and for stopped games, they will return, with TRUE if successful,
* FALSE if restore failed.
*/
-static sc_bool run_restore_common(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
+static sc_bool run_restore_common(CONTEXT, sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
sc_bool is_running, status;
/*
@@ -1778,8 +1775,7 @@ static sc_bool run_restore_common(sc_gameref_t game, sc_read_callbackref_t callb
if (game->is_running) {
game->is_running = FALSE;
game->do_restore = TRUE;
- longjmp(game->quitter, 1);
- sc_fatal("run_restore_common: unable to restart cleanly\n");
+ LONG_JUMP0;
}
}
@@ -1787,17 +1783,17 @@ static sc_bool run_restore_common(sc_gameref_t game, sc_read_callbackref_t callb
return status;
}
-sc_bool run_restore(sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
+sc_bool run_restore(CONTEXT, sc_gameref_t game, sc_read_callbackref_t callback, void *opaque) {
assert(gs_is_game_valid(game));
assert(callback);
- return run_restore_common(game, callback, opaque);
+ return run_restore_common(context, game, callback, opaque);
}
-sc_bool run_restore_prompted(sc_gameref_t game) {
+sc_bool run_restore_prompted(CONTEXT, sc_gameref_t game) {
assert(gs_is_game_valid(game));
- return run_restore_common(game, NULL, NULL);
+ return run_restore_common(context, game, NULL, NULL);
}
@@ -1807,7 +1803,7 @@ sc_bool run_restore_prompted(sc_gameref_t game) {
* Undo a turn in either a running or a stopped game. Returns TRUE on
* successful undo, FALSE if no undo buffer is available.
*/
-sc_bool run_undo(sc_gameref_t game) {
+sc_bool run_undo(CONTEXT, sc_gameref_t game) {
const sc_memo_setref_t memento = gs_get_memento(game);
sc_bool is_running;
assert(gs_is_game_valid(game));
@@ -1845,8 +1841,7 @@ sc_bool run_undo(sc_gameref_t game) {
if (game->is_running) {
game->is_running = FALSE;
game->do_restore = TRUE;
- longjmp(game->quitter, 1);
- sc_fatal("run_undo: unable to restart cleanly\n");
+ LONG_JUMP0;
}
/* Game undo on non-running game accomplished with memos. */
diff --git a/engines/glk/adrift/serialization.cpp b/engines/glk/adrift/serialization.cpp
index c0fa81b..02939cc 100644
--- a/engines/glk/adrift/serialization.cpp
+++ b/engines/glk/adrift/serialization.cpp
@@ -407,12 +407,6 @@ bool LoadSerializer::load() {
new_game->requested_sound = _game->requested_sound;
new_game->requested_graphic = _game->requested_graphic;
- /* Quitter tweak -- set the quit jump buffer in the new _game to be the
- * same as the current one, so that it remains unchanged by gs_copy(). The
- * one in the new _game is still the unset one from gs_create().
- */
- memcpy(&new_game->quitter, &_game->quitter, sizeof(_game->quitter));
-
/* If we got this far, we successfully restored the _game from the file.
* As our final act, copy the new _game onto the old one.
*/
diff --git a/engines/glk/adrift/sxtester.cpp b/engines/glk/adrift/sxtester.cpp
index ae28b3b..c0ea336 100644
--- a/engines/glk/adrift/sxtester.cpp
+++ b/engines/glk/adrift/sxtester.cpp
@@ -32,7 +32,7 @@ namespace Adrift {
* Run the game using the given script. Returns the count of errors from
* the script's monitoring.
*/
-static sc_int test_run_game_script(sc_game game, sx_script script) {
+static sc_int test_run_game_script(CONTEXT, sc_game game, sx_script script) {
sc_int errors;
/* Ensure completely repeatable random number sequences. */
@@ -40,7 +40,7 @@ static sc_int test_run_game_script(sc_game game, sx_script script) {
/* Start interpreting the script stream. */
scr_start_script(game, script);
- sc_interpret_game(game);
+ R0CALL1(sc_interpret_game, game);
/* Wrap up the script interpreter and capture error count. */
errors = scr_finalize_script();
@@ -57,6 +57,7 @@ static sc_int test_run_game_script(sc_game game, sx_script script) {
sc_int test_run_game_tests(const sx_test_descriptor_t tests[], sc_int count, sc_bool is_verbose) {
const sx_test_descriptor_t *test;
sc_int errors;
+ Context context;
assert(tests);
errors = 0;
@@ -72,7 +73,7 @@ sc_int test_run_game_tests(const sx_test_descriptor_t tests[], sc_int count, sc_
sc_get_game_author(test->game));
}
- test_errors = test_run_game_script(test->game, test->script);
+ test_errors = test_run_game_script(context, test->game, test->script);
errors += test_errors;
if (is_verbose) {
Commit: 9e17ff0c75ea790b2619a920b77b580f9d8d1ce2
https://github.com/scummvm/scummvm/commit/9e17ff0c75ea790b2619a920b77b580f9d8d1ce2
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:28-07:00
Commit Message:
GLK: ADRIFT: Convert remaining long_jmp to use context
Changed paths:
engines/glk/adrift/screstrs.cpp
diff --git a/engines/glk/adrift/screstrs.cpp b/engines/glk/adrift/screstrs.cpp
index e69ad3e..77b2110 100644
--- a/engines/glk/adrift/screstrs.cpp
+++ b/engines/glk/adrift/screstrs.cpp
@@ -868,9 +868,6 @@ static sc_int restr_eval_result(sc_int *lowest_fail) {
}
-/* Parse error jump buffer. */
-static jmp_buf restr_parse_error;
-
/* Single lookahead token for parser. */
static sc_char restr_lookahead = '\0';
@@ -879,19 +876,18 @@ static sc_char restr_lookahead = '\0';
*
* Match a token with an expectation.
*/
-static void restr_match(sc_char c) {
+static void restr_match(CONTEXT, sc_char c) {
if (restr_lookahead == c)
restr_lookahead = restr_next_token();
else {
- sc_error("restr_match:"
- " syntax error, expected %d, got %d\n", c, restr_lookahead);
- longjmp(restr_parse_error, 1);
+ sc_error("restr_match: syntax error, expected %d, got %d\n", c, restr_lookahead);
+ LONG_JUMP;
}
}
/* Forward declaration for recursion. */
-static void restr_bexpr(void);
+static void restr_bexpr(CONTEXT);
/*
* restr_andexpr()
@@ -900,40 +896,40 @@ static void restr_bexpr(void);
*
* Expression parsers. Here we go again...
*/
-static void restr_andexpr(void) {
- restr_bexpr();
+static void restr_andexpr(CONTEXT) {
+ CALL0(restr_bexpr);
while (restr_lookahead == TOK_AND) {
- restr_match(TOK_AND);
- restr_bexpr();
+ CALL1(restr_match, TOK_AND);
+ CALL0(restr_bexpr);
restr_eval_action(TOK_AND);
}
}
-static void restr_orexpr(void) {
- restr_andexpr();
+static void restr_orexpr(CONTEXT) {
+ CALL0(restr_andexpr);
while (restr_lookahead == TOK_OR) {
- restr_match(TOK_OR);
- restr_andexpr();
+ CALL1(restr_match, TOK_OR);
+ CALL0(restr_andexpr);
restr_eval_action(TOK_OR);
}
}
-static void restr_bexpr(void) {
+static void restr_bexpr(CONTEXT) {
switch (restr_lookahead) {
case TOK_RESTRICTION:
- restr_match(TOK_RESTRICTION);
+ CALL1(restr_match, TOK_RESTRICTION);
restr_eval_action(TOK_RESTRICTION);
break;
case TOK_LPAREN:
- restr_match(TOK_LPAREN);
- restr_orexpr();
- restr_match(TOK_RPAREN);
+ CALL1(restr_match, TOK_LPAREN);
+ CALL0(restr_orexpr);
+ CALL1(restr_match, TOK_RPAREN);
break;
default:
sc_error("restr_bexpr: syntax error, unexpected %d\n", restr_lookahead);
- longjmp(restr_parse_error, 1);
+ LONG_JUMP;
}
}
@@ -988,6 +984,7 @@ sc_bool restr_eval_task_restrictions(sc_gameref_t game, sc_int task, sc_bool *pa
sc_int restr_count, lowest_fail;
const sc_char *pattern;
sc_bool result;
+ Context context;
assert(pass && fail_message);
/* Get the count of restrictions on the task. */
@@ -1011,22 +1008,21 @@ sc_bool restr_eval_task_restrictions(sc_gameref_t game, sc_int task, sc_bool *pa
pattern = prop_get_string(bundle, "S<-sis", vt_key);
if (restr_trace) {
- sc_trace("Restr: task %ld"
- " has %ld restrictions, %s\n", task, restr_count, pattern);
+ sc_trace("Restr: task %ld has %ld restrictions, %s\n", task, restr_count, pattern);
}
/* Set up the evaluation stack and tokenizer. */
restr_eval_start(game, task);
restr_tokenize_start(pattern);
- /* Try parsing the pattern, and catch errors. */
- if (setjmp(restr_parse_error) == 0) {
- /* Parse the pattern, and ensure it ends at string end. */
- restr_lookahead = restr_next_token();
- restr_orexpr();
- restr_match(TOK_EOS);
- } else {
- /* Parse error -- clean up tokenizer and return fail. */
+ // Parse the pattern, and ensure it ends at string end
+ restr_lookahead = restr_next_token();
+ restr_orexpr(context);
+ if (!context._break)
+ restr_match(context, TOK_EOS);
+
+ if (context._break) {
+ // Parse error -- clean up tokenizer and return fail
restr_tokenize_end();
return FALSE;
}
@@ -1036,8 +1032,7 @@ sc_bool restr_eval_task_restrictions(sc_gameref_t game, sc_int task, sc_bool *pa
result = restr_eval_result(&lowest_fail);
if (restr_trace) {
- sc_trace("Restr: task %ld"
- " restrictions %s\n", task, result ? "PASS" : "FAIL");
+ sc_trace("Restr: task %ld restrictions %s\n", task, result ? "PASS" : "FAIL");
}
/*
Commit: 239fbce8e3741a4b02339c2ecc5fce53cee6562e
https://github.com/scummvm/scummvm/commit/239fbce8e3741a4b02339c2ecc5fce53cee6562e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-25T20:13:28-07:00
Commit Message:
GLK: ADRIFT: gcc compilation fixes
Changed paths:
engines/glk/adrift/os_glk.cpp
engines/glk/adrift/scare.h
engines/glk/adrift/scexpr.cpp
engines/glk/adrift/sclibrar.cpp
engines/glk/adrift/sctaffil.cpp
engines/glk/adrift/sctafpar.cpp
engines/glk/adrift/sxmain.cpp
engines/glk/detection.cpp
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index b08dfbb..dce48f8 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -82,9 +82,9 @@ static int gsc_commands_enabled = TRUE, gsc_abbreviations_enabled = TRUE,
sc_game gsc_game = nullptr;
/* Special out-of-band os_confirm() options used locally with os_glk. */
-static const sc_int GSC_CONF_SUBTLE_HINT = INT_MAX,
- GSC_CONF_UNSUBTLE_HINT = INT_MAX - 1,
- GSC_CONF_CONTINUE_HINTS = INT_MAX - 2;
+static const sc_int GSC_CONF_SUBTLE_HINT = INTEGER_MAX,
+ GSC_CONF_UNSUBTLE_HINT = INTEGER_MAX - 1,
+ GSC_CONF_CONTINUE_HINTS = INTEGER_MAX - 2;
/* Forward declaration of event wait functions, and a short delay. */
static void gsc_event_wait_2(glui32 wait_type_1,
@@ -120,7 +120,7 @@ static void gsc_fatal(const char *string) {
g_vm->glk_set_window(gsc_main_window);
g_vm->glk_set_style(style_Normal);
g_vm->glk_put_string("\n\nINTERNAL ERROR: ");
- g_vm->glk_put_string((char *) string);
+ g_vm->glk_put_string((const char *)string);
g_vm->glk_put_string("\n\nPlease record the details of this error, try to"
" note down everything you did to cause it, and email"
@@ -549,7 +549,7 @@ static void gsc_put_char_uni(glui32 unicode, const char *ascii) {
/* Print ascii to the transcript, then reattach it. */
if (gsc_transcript_stream) {
if (ascii)
- g_vm->glk_put_string_stream(gsc_transcript_stream, (char *) ascii);
+ g_vm->glk_put_string_stream(gsc_transcript_stream, (const char *)ascii);
else
g_vm->glk_put_char_stream(gsc_transcript_stream, '?');
@@ -630,7 +630,7 @@ static void gsc_put_char_locale(sc_char ch, const gsc_locale_t *locale, sc_bool
* directly with Glk.
*/
if (ascii) {
- g_vm->glk_put_string((char *) ascii);
+ g_vm->glk_put_string((const char *)ascii);
return;
}
@@ -1484,7 +1484,7 @@ static void gsc_styled_string(glui32 style, const char *message) {
assert(message);
g_vm->glk_set_style(style);
- g_vm->glk_put_string((char *) message);
+ g_vm->glk_put_string((const char *)message);
g_vm->glk_set_style(style_Normal);
}
@@ -1585,6 +1585,7 @@ void os_display_hints(sc_game game) {
* Stub functions. The unused variables defeat gcc warnings.
*/
void os_play_sound(const sc_char *filepath, sc_int offset, sc_int length, sc_bool is_looping) {
+/*
const sc_char *unused1;
sc_int unused2, unused3;
sc_bool unused4;
@@ -1592,6 +1593,7 @@ void os_play_sound(const sc_char *filepath, sc_int offset, sc_int length, sc_boo
unused2 = offset;
unused3 = length;
unused4 = is_looping;
+*/
}
void os_stop_sound() {
@@ -1640,11 +1642,13 @@ void os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
}
#else
void os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
+/*
const sc_char *unused1;
sc_int unused2, unused3;
unused1 = filepath;
unused2 = offset;
unused3 = length;
+*/
}
#endif
@@ -2527,7 +2531,7 @@ sc_bool os_confirm(sc_int type) {
do {
g_vm->glk_request_char_event(gsc_main_window);
gsc_event_wait(evtype_CharInput, &event);
- } while (event.val1 > UCHAR_MAX);
+ } while (event.val1 > BYTE_MAX);
response = g_vm->glk_char_to_upper(event.val1);
} while (response != 'Y' && response != 'N');
@@ -2601,6 +2605,9 @@ static void gsc_event_wait_2(glui32 wait_type_1, glui32 wait_type_2, event_t *ev
/* Refresh any sensitive windows on size events. */
gsc_status_redraw();
break;
+
+ default:
+ break;
}
} while (!(event->type == (EvType)wait_type_1 || event->type == (EvType)wait_type_2));
}
@@ -2656,14 +2663,14 @@ void os_write_file(void *opaque, const sc_byte *buffer, sc_int length) {
strid_t stream = (strid_t) opaque;
assert(opaque && buffer);
- g_vm->glk_put_buffer_stream(stream, (char *) buffer, length);
+ g_vm->glk_put_buffer_stream(stream, (const char *)buffer, length);
}
sc_int os_read_file(void *opaque, sc_byte *buffer, sc_int length) {
strid_t stream = (strid_t) opaque;
assert(opaque && buffer);
- return g_vm->glk_get_buffer_stream(stream, (char *) buffer, length);
+ return g_vm->glk_get_buffer_stream(stream, (char *)buffer, length);
}
@@ -2694,7 +2701,7 @@ enum gsc_end_option { GAME_RESTART, GAME_UNDO, GAME_QUIT };
* The following value needs to be passed between the startup_code and main
* functions.
*/
-static char *gsc_game_message = nullptr;
+static const char *gsc_game_message;
/*
@@ -2737,7 +2744,7 @@ static enum gsc_end_option gsc_get_ending_option() {
{
g_vm->glk_request_char_event(gsc_main_window);
gsc_event_wait(evtype_CharInput, &event);
- } while (event.val1 > UCHAR_MAX);
+ } while (event.val1 > BYTE_MAX);
response = g_vm->glk_char_to_upper(event.val1);
} while (response != 'R' && response != 'U' && response != 'Q');
@@ -2844,8 +2851,9 @@ static int gsc_startup_code(Common::SeekableReadStream *game_stream, int restore
if (!gsc_game) {
gsc_game = nullptr;
gsc_game_message = "Unable to load an Adrift game from the requested file.";
- } else
+ } else {
gsc_game_message = nullptr;
+ }
/*
* If the game was created successfully and there is a restore stream, try
@@ -3037,30 +3045,30 @@ void adrift_main() {
*/
glkunix_argumentlist_t glkunix_arguments[] = {
{
- (char *) "-nc", glkunix_arg_NoValue,
- (char *) "-nc No local handling for Glk special commands"
+ (const char *)"-nc", glkunix_arg_NoValue,
+ (const char *)"-nc No local handling for Glk special commands"
},
{
- (char *) "-na", glkunix_arg_NoValue,
- (char *) "-na Turn off abbreviation expansions"
+ (const char *)"-na", glkunix_arg_NoValue,
+ (const char *)"-na Turn off abbreviation expansions"
},
{
- (char *) "-nu", glkunix_arg_NoValue,
- (char *) "-nu Turn off any use of Unicode output"
+ (const char *)"-nu", glkunix_arg_NoValue,
+ (const char *)"-nu Turn off any use of Unicode output"
},
#ifdef LINUX_GRAPHICS
{
- (char *) "-ng", glkunix_arg_NoValue,
- (char *) "-ng Turn off attempts at game graphics"
+ (const char *)"-ng", glkunix_arg_NoValue,
+ (const char *)"-ng Turn off attempts at game graphics"
},
#endif
{
- (char *) "-r", glkunix_arg_ValueFollows,
- (char *) "-r FILE Restore from FILE on starting the game"
+ (const char *)"-r", glkunix_arg_ValueFollows,
+ (const char *)"-r FILE Restore from FILE on starting the game"
},
{
- (char *) "", glkunix_arg_ValueCanFollow,
- (char *) "filename game to run"
+ (const char *)"", glkunix_arg_ValueCanFollow,
+ (const char *)"filename game to run"
},
{nullptr, glkunix_arg_End, nullptr}
};
diff --git a/engines/glk/adrift/scare.h b/engines/glk/adrift/scare.h
index 1dc7c6e..04a2872 100644
--- a/engines/glk/adrift/scare.h
+++ b/engines/glk/adrift/scare.h
@@ -47,6 +47,9 @@ typedef long sc_int;
typedef unsigned long sc_uint;
typedef int sc_bool;
+#define BYTE_MAX 0xff
+#define INTEGER_MAX 0x7fff
+
/* Enumerated confirmation types, passed to os_confirm(). */
enum {
SC_CONF_QUIT = 0,
diff --git a/engines/glk/adrift/scexpr.cpp b/engines/glk/adrift/scexpr.cpp
index 0f4c2be..0078f2c 100644
--- a/engines/glk/adrift/scexpr.cpp
+++ b/engines/glk/adrift/scexpr.cpp
@@ -114,7 +114,7 @@ static sc_int expr_multichar_search(const sc_char *name, const sc_expr_multichar
}
/* Return the token matched, or TOK_NONE. */
- return entry->name ? entry->token : TOK_NONE;
+ return entry->name ? entry->token : (sc_int)TOK_NONE;
}
diff --git a/engines/glk/adrift/sclibrar.cpp b/engines/glk/adrift/sclibrar.cpp
index c17a3a7..89f2dee 100644
--- a/engines/glk/adrift/sclibrar.cpp
+++ b/engines/glk/adrift/sclibrar.cpp
@@ -1363,7 +1363,7 @@ sc_bool lib_cmd_redo_number(sc_gameref_t game) {
* for the ugliness.
*/
game->do_again = FALSE;
- game->redo_sequence = INT_MAX;
+ game->redo_sequence = INTEGER_MAX;
}
game->is_admin = TRUE;
@@ -1393,7 +1393,7 @@ static sc_bool lib_cmd_redo_text_last_common(sc_gameref_t game, const sc_char *t
/* As with failed numeric redo above, special-case this return. */
game->do_again = FALSE;
- game->redo_sequence = INT_MAX;
+ game->redo_sequence = INTEGER_MAX;
game->is_admin = TRUE;
return TRUE;
@@ -1450,7 +1450,7 @@ static sc_bool lib_cmd_redo_text_last_common(sc_gameref_t game, const sc_char *t
/* As with failed numeric redo above, special-case this return. */
game->do_again = FALSE;
- game->redo_sequence = INT_MAX;
+ game->redo_sequence = INTEGER_MAX;
}
game->is_admin = TRUE;
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index 321f08a..0cda5ec 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -26,18 +26,6 @@
#include "common/zlib.h"
#include "common/memstream.h"
-#if defined(USE_ZLIB)
-#ifdef __SYMBIAN32__
-#include <zlib\zlib.h>
-#else
-#include <zlib.h>
-#endif
-
-#if ZLIB_VERNUM < 0x1204
-#error Version 1.2.0.4 or newer of zlib is required for this code
-#endif
-#endif
-
namespace Glk {
namespace Adrift {
@@ -129,7 +117,7 @@ static sc_int taf_random_state = 0x00a09e86;
static sc_byte taf_random(void) {
/* Generate and return the next pseudo-random number. */
taf_random_state = (taf_random_state * PRNG_CST1 + PRNG_CST2) & PRNG_CST3;
- return (UCHAR_MAX * (sc_uint) taf_random_state) / (sc_uint)(PRNG_CST3 + 1);
+ return (BYTE_MAX * (sc_uint) taf_random_state) / (sc_uint)(PRNG_CST3 + 1);
}
static void taf_random_reset(void) {
@@ -419,7 +407,7 @@ static sc_bool taf_unobfuscate(sc_tafref_t taf, sc_read_callbackref_t callback,
*/
static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
void *opaque, sc_bool is_gamefile) {
-#if USE_ZLIB
+#if defined(USE_ZLIB)
Common::SeekableReadStream *src = (Common::SeekableReadStream *)opaque;
assert(src);
Common::MemoryWriteStreamDynamic dest(DisposeAfterUse::YES);
diff --git a/engines/glk/adrift/sctafpar.cpp b/engines/glk/adrift/sctafpar.cpp
index 7dd7edf..046cb24 100644
--- a/engines/glk/adrift/sctafpar.cpp
+++ b/engines/glk/adrift/sctafpar.cpp
@@ -884,14 +884,14 @@ static void parse_vector(CONTEXT, const sc_char *vector) {
}
static void parse_vector_alternate(CONTEXT, const sc_char *vector) {
- sc_int count;
+ sc_int count1;
if (parse_trace)
sc_trace("Parse: entering alternate vector %s\n", vector);
/* Element count, this is a vector described by size - 1. */
- FUNC0(parse_get_taf_integer, count) + 1;
- CALL2(parse_vector_common, vector, count);
+ FUNC0(parse_get_taf_integer, count1);
+ CALL2(parse_vector_common, vector, count1 + 1);
if (parse_trace)
sc_trace("Parse: leaving alternate vector %s\n", vector);
@@ -3240,7 +3240,7 @@ static void parse_add_alrs_index(sc_prop_setref_t bundle) {
* get the shortest and longest defined.
*/
alr_lengths = (sc_int *)sc_malloc(alr_count * sizeof(*alr_lengths));
- shortest = INT_MAX;
+ shortest = INTEGER_MAX;
longest = 0;
for (index_ = 0; index_ < alr_count; index_++) {
const sc_char *original;
diff --git a/engines/glk/adrift/sxmain.cpp b/engines/glk/adrift/sxmain.cpp
index d01e226..63ff12e 100644
--- a/engines/glk/adrift/sxmain.cpp
+++ b/engines/glk/adrift/sxmain.cpp
@@ -113,13 +113,13 @@ int glk_main(int argc, const char *argv[]) {
script = sx_fopen(name, "scr", "r");
if (!script) {
- error("%s: %s.scr: %s\n", program, name, strerror(errno));
+ error("%s: %s.scr: %s\n", program, name, "open");
continue;
}
stream = sx_fopen(name, "taf", "rb");
if (!stream) {
- error("%s: %s.taf: %s\n", program, name, strerror(errno));
+ error("%s: %s.taf: %s\n", program, name, "open");
delete script;
continue;
}
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index cce1ec1..4be0c38 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -70,9 +70,9 @@ GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const Common:
addExtraEntry("filename", filename);
}
-GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const char *extra,
+GlkDetectedGame::GlkDetectedGame(const char *id, const char *desc, const char *xtra,
const Common::String &filename, Common::Language lang) :
- DetectedGame(id, desc, lang, Common::kPlatformUnknown, extra) {
+ DetectedGame(id, desc, lang, Common::kPlatformUnknown, xtra) {
setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
addExtraEntry("filename", filename);
}
More information about the Scummvm-git-logs
mailing list