[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