[Scummvm-git-logs] scummvm master -> 1c412d3da705dabd709614c409927ce8f6fbfe05

dreammaster paulfgilbert at gmail.com
Sun Jul 7 00:33:33 CEST 2019


This automated email contains information about 43 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
cd7cf41414 GLK: ALAN3: Initial files commit
822cd6f165 GLK: ALAN3: Further warning fixes
305330bda7 GLK: ALAN3: Change EOF to a uint32 EOD to fix compiler warnings
2de068a98a GLK: ALAN3: Further warning fixes
aebf256610 GLK: ALAN3: Removal of #ifdef blocks
dc40211ec5 GLK: ALAN3: Proper indentation & formatting
86f9985951 GLK: ALAN3: Re-enable main game loop
9c197d71ab GLK: ALAN3: Add support for loading a3r Blorb files
3527f9c48d GLK: ALAN3: Add detection logic
f2f46395ba GLK: ALAN3: Further gcc warning fixes
4d7cfeb2c7 GLK: ALAN3: Context clearing in main loop, add packing to code structures
f5ad5b00d0 GLK: ALAN3: Fix endianness of loading temporary header
5c8c4b3b6e GLK: ALAN3: Standardize on using syserr for errors
395174301b GLK: ALAN3: Change header version field from char[4] to byte[4]
b8a737a8a4 GLK: ALAN3: Further loading fixes
ae6ae33bed GLK: ALAN3: Fix setup and outputing of text data
f0d5304a4c GLK: ALAN3: Fix jumps.h macros
c833d39ccf GLK: ALAN3: Outer game loop to handle forfeit setjmp replacement
55b93f5a20 GLK: ALAN3: Hook up empty lines to forfeit longjmp replacement
ec979b8555 GLK: ALAN3: Fix quitting game from input line when window closed
18566feefc GLK: ALAN3: Implement savegame code
5dea662313 GLK: ALAN3: Wrapping method calls in longjmp replacement macros
6a4931106d GLK: ALAN3: Wrap playererr and terminate methods in context
1183dc65bb GLK: ALAN3: Remove deprecated glkstart.cpp
3e9d215dd8 GLK: ALAN3: Minor errors cleanup
d185cc5894 GLK: ALAN3: Remove adventureName variable
0f0c2c97e1 GLK: ALAN3: Move some Glk interface methods to glkio.cpp
efdf25b3d2 GLK: ALAN3: Move term.cpp code into glkio.cpp
b634a97f41 GLK: ALAN3: Move readline.cpp into glkio.cpp
c5214f6d34 GLK: ALAN3: Making GlkIO base class
87a86c0fb6 GLK: ALAN3: Merge saving & loading code, loading fixes
4de30c9e2f GLK: ALAN3: Fix Valgrind identified memory issues
3165fa628a GLK: ALAN3: Add loading savegame from launcher
f28d3b7496 GLK: ALAN3: Further refactoring of setjmp calls
17d0459566 GLK: ALAN3: Fix gcc warning
69f87bebf1 GLK: ALAN3: Fix double-free of memory array
4c014a105c GLK: Properly free pair window children on exit
2fbb8af0bc GLK: ALAN3: Move soundChannel static to GlkIO field
1d2dee43d2 GLK: Fix playback of Blorb AIFF chunks
0502ac4bb1 GLK: ALAN3: Create GlkDetectedGame base class for simplifying detections
5dda48c1c7 GLK: Change other sub-engines to use GlkDetectedGame
2c39c903fc GLK: GLULXE: Fix MSVC field alignment warnings
1c412d3da7 GLK: Properly handle sound setup


Commit: cd7cf4141425e3e77b164d2dbcbae8de1eacb035
    https://github.com/scummvm/scummvm/commit/cd7cf4141425e3e77b164d2dbcbae8de1eacb035
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:07-07:00

Commit Message:
GLK: ALAN3: Initial files commit

Changed paths:
  A engines/glk/alan3/acode.h
  A engines/glk/alan3/act.cpp
  A engines/glk/alan3/act.h
  A engines/glk/alan3/actor.cpp
  A engines/glk/alan3/actor.h
  A engines/glk/alan3/alan3.cpp
  A engines/glk/alan3/alan3.h
  A engines/glk/alan3/alan_version.cpp
  A engines/glk/alan3/alan_version.h
  A engines/glk/alan3/alt_info.cpp
  A engines/glk/alan3/alt_info.h
  A engines/glk/alan3/args.cpp
  A engines/glk/alan3/args.h
  A engines/glk/alan3/attribute.cpp
  A engines/glk/alan3/attribute.h
  A engines/glk/alan3/checkentry.cpp
  A engines/glk/alan3/checkentry.h
  A engines/glk/alan3/class.cpp
  A engines/glk/alan3/class.h
  A engines/glk/alan3/compatibility.cpp
  A engines/glk/alan3/compatibility.h
  A engines/glk/alan3/container.cpp
  A engines/glk/alan3/container.h
  A engines/glk/alan3/current.cpp
  A engines/glk/alan3/current.h
  A engines/glk/alan3/debug.cpp
  A engines/glk/alan3/debug.h
  A engines/glk/alan3/decode.cpp
  A engines/glk/alan3/decode.h
  A engines/glk/alan3/dictionary.cpp
  A engines/glk/alan3/dictionary.h
  A engines/glk/alan3/event.cpp
  A engines/glk/alan3/event.h
  A engines/glk/alan3/exe.cpp
  A engines/glk/alan3/exe.h
  A engines/glk/alan3/fnmatch.cpp
  A engines/glk/alan3/fnmatch.h
  A engines/glk/alan3/glkio.cpp
  A engines/glk/alan3/glkio.h
  A engines/glk/alan3/glkstart.cpp
  A engines/glk/alan3/glkstart.h
  A engines/glk/alan3/instance.cpp
  A engines/glk/alan3/instance.h
  A engines/glk/alan3/inter.cpp
  A engines/glk/alan3/inter.h
  A engines/glk/alan3/lists.cpp
  A engines/glk/alan3/lists.h
  A engines/glk/alan3/literal.cpp
  A engines/glk/alan3/literal.h
  A engines/glk/alan3/location.cpp
  A engines/glk/alan3/location.h
  A engines/glk/alan3/main.cpp
  A engines/glk/alan3/main.h
  A engines/glk/alan3/memory.cpp
  A engines/glk/alan3/memory.h
  A engines/glk/alan3/msg.cpp
  A engines/glk/alan3/msg.h
  A engines/glk/alan3/options.cpp
  A engines/glk/alan3/options.h
  A engines/glk/alan3/output.cpp
  A engines/glk/alan3/output.h
  A engines/glk/alan3/parameter_position.cpp
  A engines/glk/alan3/parameter_position.h
  A engines/glk/alan3/params.cpp
  A engines/glk/alan3/params.h
  A engines/glk/alan3/parse.cpp
  A engines/glk/alan3/parse.h
  A engines/glk/alan3/readline.cpp
  A engines/glk/alan3/readline.h
  A engines/glk/alan3/resources.h
  A engines/glk/alan3/reverse.cpp
  A engines/glk/alan3/reverse.h
  A engines/glk/alan3/rules.cpp
  A engines/glk/alan3/rules.h
  A engines/glk/alan3/save.cpp
  A engines/glk/alan3/save.h
  A engines/glk/alan3/scan.cpp
  A engines/glk/alan3/scan.h
  A engines/glk/alan3/score.cpp
  A engines/glk/alan3/score.h
  A engines/glk/alan3/set.cpp
  A engines/glk/alan3/set.h
  A engines/glk/alan3/stack.cpp
  A engines/glk/alan3/stack.h
  A engines/glk/alan3/state.cpp
  A engines/glk/alan3/state.h
  A engines/glk/alan3/state_stack.cpp
  A engines/glk/alan3/state_stack.h
  A engines/glk/alan3/syntax.cpp
  A engines/glk/alan3/syntax.h
  A engines/glk/alan3/sysdep.cpp
  A engines/glk/alan3/sysdep.h
  A engines/glk/alan3/syserr.cpp
  A engines/glk/alan3/syserr.h
  A engines/glk/alan3/term.cpp
  A engines/glk/alan3/term.h
  A engines/glk/alan3/types.cpp
  A engines/glk/alan3/types.h
  A engines/glk/alan3/utils.cpp
  A engines/glk/alan3/utils.h
  A engines/glk/alan3/version.h
  A engines/glk/alan3/word.cpp
  A engines/glk/alan3/word.h
    engines/glk/module.mk


diff --git a/engines/glk/alan3/acode.h b/engines/glk/alan3/acode.h
new file mode 100644
index 0000000..a399d3c
--- /dev/null
+++ b/engines/glk/alan3/acode.h
@@ -0,0 +1,724 @@
+/* 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_ACODE
+#define GLK_ACODE
+
+#include "common/scummsys.h"
+
+namespace Glk {
+namespace Alan3 {
+
+#define ACODEEXTENSION ".a3c"
+
+typedef uint32 Aptr;		 /* Type for an ACODE memory address used in the structures */
+/* TODO: Here's the major 32->64bit problem: Aptrs are 32 bit to fit
+   into the 32-bit structure of the Amachine, but sometimes this is
+   used to store a *real* pointer value, which on 64-bit machines are
+   64bits. */
+
+typedef uint32 Aword;		/* Type for an ACODE word */
+typedef uint32 Aaddr;		/* Type for an ACODE address */
+typedef uint32 Aid;			/* Type for an ACODE Instance Id value */
+typedef int32 Abool;		/* Type for an ACODE Boolean value */
+typedef int32 Aint;			/* Type for an ACODE Integer value */
+typedef int32 Aset;			/* Type for an ACODE Set value */
+typedef int CodeValue;		/* Definition for the packing process */
+
+#ifndef TRUE
+#define TRUE (0==0)
+#endif
+#ifndef FALSE
+#define FALSE (!TRUE)
+#endif
+
+/* Constants for the Acode file, words/block & bytes/block */
+#define BLOCKLEN 256L
+#define BLOCKSIZE (BLOCKLEN*sizeof(Aword))
+
+
+/* Definitions for the packing process */
+#define VALUEBITS 16
+
+#define EOFChar 256
+#define TOPVALUE (((CodeValue)1<<VALUEBITS) - 1) /* Highest value possible */
+
+/* Half and quarter points in the code value range */
+#define ONEQUARTER (TOPVALUE/4+1)	/* Point after first quarter */
+#define HALF (2*ONEQUARTER)		/* Point after first half */
+#define THREEQUARTER (3*ONEQUARTER)	/* Point after third quarter */
+
+
+/* AMACHINE Word Classes, bit positions */
+typedef int WordKind;
+#define  SYNONYM_WORD 0
+#define  SYNONYM_BIT (((Aword)1)<<SYNONYM_WORD)
+
+#define  ADJECTIVE_WORD (SYNONYM_WORD+1)
+#define  ADJECTIVE_BIT (((Aword)1)<<ADJECTIVE_WORD)
+
+#define  ALL_WORD (ADJECTIVE_WORD+1)
+#define  ALL_BIT (((Aword)1)<<ALL_WORD)
+
+#define  EXCEPT_WORD (ALL_WORD+1)
+#define  EXCEPT_BIT (((Aword)1)<<EXCEPT_WORD)
+
+#define  CONJUNCTION_WORD (EXCEPT_WORD+1)
+#define  CONJUNCTION_BIT (((Aword)1)<<CONJUNCTION_WORD)
+
+#define  PREPOSITION_WORD (CONJUNCTION_WORD+1)
+#define  PREPOSITION_BIT (((Aword)1)<<PREPOSITION_WORD)
+
+#define  DIRECTION_WORD (PREPOSITION_WORD+1)
+#define  DIRECTION_BIT (((Aword)1)<<DIRECTION_WORD)
+
+#define  IT_WORD (DIRECTION_WORD+1)
+#define  IT_BIT (((Aword)1)<<IT_WORD)
+
+#define  NOISE_WORD (IT_WORD+1)
+#define  NOISE_BIT (((Aword)1)<<NOISE_WORD)
+
+#define  NOUN_WORD (NOISE_WORD+1)
+#define  NOUN_BIT (((Aword)1)<<NOUN_WORD)
+
+#define  THEM_WORD (NOUN_WORD+1)
+#define  THEM_BIT (((Aword)1)<<THEM_WORD)
+
+#define  VERB_WORD (THEM_WORD+1)
+#define  VERB_BIT (((Aword)1)<<VERB_WORD)
+
+#define  PRONOUN_WORD (VERB_WORD+1)
+#define  PRONOUN_BIT (((Aword)1)<<PRONOUN_WORD)
+
+#define  WRD_CLASSES (PRONOUN_WORD+1)
+
+
+/* The #nowhere and NO_LOCATION constants */
+#define NO_LOCATION 0
+#define NOWHERE 1
+
+
+/* Syntax element classifications */
+#define EOS (-2)		/* End Of Syntax */
+
+/* Syntax element flag bits */
+#define MULTIPLEBIT 0x1
+#define OMNIBIT 0x2
+
+
+/* Parameter Classes */
+enum ClaKind {		/* NOTE! These must have the same order as */
+    CLA_OBJ = 1,			/* the name classes in NAM.H */
+    CLA_CNT = (int)CLA_OBJ<<1,
+    CLA_ACT = (int)CLA_CNT<<1,
+    CLA_NUM = (int)CLA_ACT<<1,
+    CLA_STR = (int)CLA_NUM<<1,
+    CLA_COBJ = (int)CLA_STR<<1,
+    CLA_CACT = (int)CLA_COBJ<<1
+};
+
+
+/* Verb Qualifiers */
+enum QualClass {
+    Q_DEFAULT,
+    Q_AFTER,
+    Q_BEFORE,
+    Q_ONLY
+};
+
+
+/* The AMACHINE Operations */
+enum OpClass {
+    C_CONST,
+    C_STMOP,
+    C_CURVAR
+};
+
+/* AMACHINE Text Styles */
+enum TextStyle {
+    NORMAL_STYLE,
+    EMPHASIZED_STYLE,
+    PREFORMATTED_STYLE,
+    ALERT_STYLE,
+    QUOTE_STYLE
+};
+
+
+#define CONSTANT(op) ((Aword)op)
+#define INSTRUCTION(op) ((((Aword)C_STMOP)<<28)|((Aword)op))
+#define CURVAR(op) ((((Aword)C_CURVAR)<<28)|((Aword)op))
+
+enum InstClass {
+    I_LINE,                    /* Source line debug info */
+    I_PRINT,                   /* Print a string from the text file */
+    I_STYLE,                   /* Set output text style */
+    I_QUIT,
+    I_LOOK,
+    I_SAVE,
+    I_RESTORE,
+    I_LIST,                     /* List contents of a container */
+    I_EMPTY,
+    I_SCORE,
+    I_VISITS,
+    I_SCHEDULE,
+    I_CANCEL,
+    I_LOCATE,
+    I_MAKE,                     /* Set a boolean attribute to the */
+                                /* value on top of stack */
+    I_SET,                      /* Set a numeric attribute to the */
+                                /* value on top of stack */
+    I_SETSTR,                   /* Set a string valued attribute to */
+                                /* the string on top of stack, */
+                                /* deallocate current contents first */
+    I_SETSET,                   /* Set a Set valued attribute to */
+                                /* the Set on top of stack, */
+                                /* deallocate current contents first */
+    I_NEWSET,                   /* Push a new, empty set at the top of stack */
+    I_ATTRIBUTE,                /* Push the value of an attribute */
+    I_ATTRSTR,                  /* Push a copy of a string attribute */
+    I_ATTRSET,                  /* Push a copy of a set attribute */
+    I_UNION,                    /* Add a set from the top of stack to a */
+                                /* set valued attribute */
+    I_GETSTR,                   /* Get a string contents from text
+                                   file, create a copy and push it
+                                   on top of stack */
+    I_INCR,                     /* Increase an attribute */
+    I_DECR,                     /* Decrease a numeric attribute */
+    I_INCLUDE,			        /* Include a value in the set on stack top */
+    I_EXCLUDE,			        /* Remove a value from the set on stack top */
+    I_SETSIZE,                  /* Push number of members in a set */
+    I_SETMEMB,                  /* Push the member with index <top>-1
+                                   from set <top> */
+    I_CONTSIZE,                 /* Push number of members in a container */
+    I_CONTMEMB,                 /* Push the member with index <top>-1
+                                   from container <top> */
+    I_USE,
+    I_STOP,
+    I_AT,
+    I_IN,
+    I_INSET,
+    I_HERE,
+    I_NEARBY,
+    I_NEAR,
+    I_WHERE,                    /* Current position of an instance */
+    I_LOCATION,                 /* The *location* an instance is at */
+    I_DESCRIBE,
+    I_SAY,
+    I_SAYINT,
+    I_SAYSTR,
+    I_IF,
+    I_ELSE,
+    I_ENDIF,
+    I_AND,
+    I_OR,
+    I_NE,
+    I_EQ,
+    I_STREQ,			/* String compare */
+    I_STREXACT,			/* Exact match */
+    I_LE,
+    I_GE,
+    I_LT,
+    I_GT,
+    I_PLUS,
+    I_MINUS,
+    I_MULT,
+    I_DIV,
+    I_NOT,
+    I_UMINUS,
+    I_RND,
+    I_RETURN,
+    I_SYSTEM,
+    I_RESTART,
+    I_BTW,
+    I_CONTAINS,
+    I_DUP,
+    I_DEPEND,
+    I_DEPCASE,
+    I_DEPEXEC,
+    I_DEPELSE,
+    I_ENDDEP,
+    I_ISA,
+    I_FRAME,
+    I_SETLOCAL,
+    I_GETLOCAL,
+    I_ENDFRAME,
+    I_LOOP,
+    I_LOOPNEXT,
+    I_LOOPEND,
+    I_SUM,                /* Aggregates: */
+    I_MAX,
+    I_MIN,
+    I_COUNT,              /* COUNT aggregate & limit meta-attribute */
+    I_SHOW,
+    I_PLAY,
+    I_CONCAT,
+    I_STRIP,
+    I_POP,
+	I_TRANSCRIPT,
+    I_DUPSTR              /* Duplicate the string on the top of the stack */
+};
+
+enum SayForm {
+    SAY_SIMPLE,
+    SAY_DEFINITE,
+    SAY_INDEFINITE,
+    SAY_NEGATIVE,
+    SAY_PRONOUN
+};
+
+enum VarClass {
+    V_PARAM,
+    V_CURLOC,
+    V_CURACT,
+    V_CURVRB,
+    V_SCORE,
+    V_CURRENT_INSTANCE,
+    V_MAX_INSTANCE
+};
+
+/* For transitivity in HERE, IN etc. */
+enum ATrans {
+    TRANSITIVE = 0,
+    DIRECT = 1,
+    INDIRECT = 2
+};
+
+/* Predefined attributes, one is for containers and the other for locations
+   and since instances cannot be both, the attributes can have the same number */
+#define OPAQUEATTRIBUTE 1
+#define VISITSATTRIBUTE 1
+#define PREDEFINEDATTRIBUTES OPAQUEATTRIBUTE
+
+#define I_CLASS(x) ((x)>>28)
+#define I_OP(x)    ((x&0x08000000)?(x)|0xf0000000:(x)&0x0fffffff)
+
+
+/* AMACHINE Table entry types */
+
+#define AwordSizeOf(x) (sizeof(x)/sizeof(Aword))
+
+struct ArticleEntry {
+    Aaddr address;		/* Address of article code */
+    Abool isForm;		/* Is the article a complete form? */
+};
+
+struct ClassEntry {	/* CLASS TABLE */
+    Aword code;             /* Own code */
+    Aaddr id;               /* Address to identifier string */
+    Aint parent;            /* Code for the parent class, 0 if none */
+    Aaddr name;             /* Address to name printing code */
+    Aint pronoun;           /* Code for the pronoun word */
+    Aaddr initialize;		/* Address to initialization statements */
+    Aaddr descriptionChecks;     /* Address of description checks */
+    Aaddr description;           /* Address of description code */
+    ArticleEntry definite;       /* Definite article entry */
+    ArticleEntry indefinite;     /* Indefinite article entry */
+    ArticleEntry negative;       /* Negative article entry */
+    Aaddr mentioned;		/* Address of code for Mentioned clause */
+    Aaddr verbs;            /* Address of verb table */
+    Aaddr entered;          /* Address of code for Entered clause */
+};
+
+struct InstanceEntry {	/* INSTANCE TABLE */
+    Aint code;                  /* Own code */
+    Aaddr id;                   /* Address to identifier string */
+    Aint parent;                /* Code for the parent class, 0 if none */
+    Aaddr name;                 /* Address to name printing code */
+    Aint pronoun;               /* Word code for the pronoun */
+    Aint initialLocation;       /* Code for current location */
+    Aaddr initialize;           /* Address to initialization statements */
+    Aint container;             /* Code for a possible container property */
+    Aaddr initialAttributes;	/* Address of attribute list */
+    Aaddr checks;		        /* Address of description checks */
+    Aaddr description;          /* Address of description code */
+    ArticleEntry definite;	    /* Definite article entry */
+    ArticleEntry indefinite;    /* Indefinite article entry */
+    ArticleEntry negative;	    /* Negative article entry */
+    Aaddr mentioned;		    /* Address to short description code */
+    Aaddr verbs;                /* Address of local verb list */
+    Aaddr entered;              /* Address of entered code (location only) */
+    Aaddr exits;		        /* Address of exit list */
+};
+
+struct AttributeEntry {			/* ATTRIBUTE LIST */
+    Aint code;                  /* Its code */
+    Aptr value;                 /* Its value, a string has a dynamic
+                                   string pointer, a set has a pointer
+                                   to a dynamically allocated set */
+    Aaddr id;                   /* Address to the name */
+};
+
+struct AttributeHeaderEntry {	/* ATTRIBUTE LIST in header */
+    Aint code;                          /* Its code */
+    Aword value;                /* Its value, a string has a dynamic
+                                   string pointer, a set has a pointer
+                                   to a dynamically allocated set */
+    Aaddr id;                   /* Address to the name */
+};
+
+struct ExitEntry {	/* EXIT TABLE structure */
+    Aword code;             /* Direction code */
+    Aaddr checks;           /* Address of check table */
+    Aaddr action;           /* Address of action code */
+    Aword target;           /* Id for the target location */
+};
+
+
+struct RuleEntry {      /* RULE TABLE */
+  Abool alreadyRun;
+  Aaddr exp;                    /* Address to expression code */
+  Aaddr stms;                   /* Address to run */
+};
+
+
+#define RESTRICTIONCLASS_CONTAINER (-2)
+#define RESTRICTIONCLASS_INTEGER (-3)
+#define RESTRICTIONCLASS_STRING (-4)
+
+struct RestrictionEntry {         /* PARAMETER RESTRICTION TABLE */
+    Aint parameterNumber;         /* Parameter number */
+    Aint _class;                  /* Parameter class code */
+    Aaddr stms;                   /* Exception statements */
+};
+
+struct ContainerEntry {	/* CONTAINER TABLE */
+    Aword owner;                /* Owner instance index */
+    Aint _class;                /* Class to allow in container */
+    Aaddr limits;               /* Address to limit check code */
+    Aaddr header;               /* Address to header code */
+    Aaddr empty;                /* Address to code for header when empty */
+    Aaddr extractChecks;        /* Address to check before extracting */
+    Aaddr extractStatements;    /* Address to execute when extracting */
+};
+
+
+struct ElementEntry {	/* SYNTAX ELEMENT TABLES */
+    Aint code;                  /* Code for this element, 0 -> parameter */
+    Aword flags;                /* Flags for multiple/omni (if parameter), syntax number/verb of EOS */
+    Aaddr next;                 /* Address to next element table ... */
+                                /* ... or restrictions if code == EOS */
+};
+
+struct SyntaxEntryPreBeta2 {	/* SYNTAX TABLE */
+    Aint code;                          /* Code for verb word */
+    Aaddr elms;                         /* Address to element tables */
+};
+
+struct SyntaxEntry {     /* SYNTAX TABLE */
+    Aint code;                   /* Code for verb word, or 0 if starting with parameter */
+    Aaddr elms;                  /* Address to element tables */
+    Aaddr parameterNameTable;    /* Address to a table of id-addresses giving the names of the parameters */
+};
+
+struct ParameterMapEntry {	/* PARAMETER MAPPING TABLE */
+    Aint syntaxNumber;
+    Aaddr parameterMapping;
+    Aint verbCode;
+};
+
+struct EventEntry {	/* EVENT TABLE */
+    Aaddr id;                   /* Address to name string */
+    Aaddr code;
+};
+
+struct ScriptEntry {	/* SCRIPT TABLE */
+    Aaddr id;                   /* Address to name string */
+    Aint code;			/* Script number */
+    Aaddr description;		/* Optional description statements */
+    Aaddr steps;		/* Address to steps */
+};
+
+struct StepEntry {	/* STEP TABLE */
+    Aaddr after;		/* Expression to say after how many ticks? */
+    Aaddr exp;			/* Expression to condition saying when */
+    Aaddr stms;			/* Address to the actual code */
+};
+
+struct AltEntry {	/* VERB ALTERNATIVE TABLE */
+    Aword qual;			/* Verb execution qualifier */
+    Aint param;			/* Parameter number */
+    Aaddr checks;		/* Address of the check table */
+    Aaddr action;		/* Address of the action code */
+};
+
+struct SourceFileEntry { /* SOURCE FILE NAME TABLE */
+    Aint fpos;
+    Aint len;
+};
+
+struct SourceLineEntry { /* SOURCE LINE TABLE */
+    Aint file;
+    Aint line;
+};
+
+struct StringInitEntry { /* STRING INITIALISATION TABLE */
+    Aword fpos;                  /* File position */
+    Aword len;                   /* Length */
+    Aint instanceCode;           /* Where to store it */
+    Aint attributeCode;
+};
+
+struct SetInitEntry {	/* SET INITIALISATION TABLE */
+    Aint size;                  /* Size of the initial set */
+    Aword setAddress;           /* Address to the initial set */
+    Aint instanceCode;          /* Where to store it */
+    Aint attributeCode;
+};
+
+struct DictionaryEntry { /* Dictionary */
+    Aaddr string;                /* ACODE address to string */
+    Aword classBits;             /* Word class */
+    Aword code;
+    Aaddr adjectiveRefs;        /* Address to reference list */
+    Aaddr nounRefs;             /* Address to reference list */
+    Aaddr pronounRefs;          /* Address to reference list */
+};
+
+
+
+/* AMACHINE Header */
+
+struct ACodeHeader {
+    /* Important info */
+    char tag[4];              /* "ALAN" */
+    char version[4];          /* Version of compiler */
+    Aword uid;                /* Unique id of the compiled game */
+    Aword size;               /* Size of ACD-file in Awords */
+    /* Options */
+    Abool pack;               /* Is the text packed and encoded ? */
+    Aword stringOffset;       /* Offset to string data in game file */
+    Aword pageLength;         /* Length of a displayed page */
+    Aword pageWidth;          /* and width */
+    Aword debug;              /* Option: debug */
+    /* Data structures */
+    Aaddr classTableAddress;
+    Aword classMax;
+    Aword entityClassId;
+    Aword thingClassId;
+    Aword objectClassId;
+    Aword locationClassId;
+    Aword actorClassId;
+    Aword literalClassId;
+    Aword integerClassId;
+    Aword stringClassId;
+    Aaddr instanceTableAddress;	/* Instance table */
+    Aword instanceMax;          /* Highest number of an instance */
+    Aword theHero;              /* The hero instance code (id) */
+    Aaddr containerTableAddress;
+    Aword containerMax;
+    Aaddr scriptTableAddress;
+    Aword scriptMax;
+    Aaddr eventTableAddress;
+    Aword eventMax;
+    Aaddr syntaxTableAddress;
+    Aaddr parameterMapAddress;
+    Aword syntaxMax;
+    Aaddr dictionary;
+    Aaddr verbTableAddress;
+    Aaddr ruleTableAddress;
+    Aaddr messageTableAddress;
+    /* Miscellaneous */
+    Aint attributesAreaSize;	/* Size of attribute data area in Awords */
+    Aint maxParameters;		/* Maximum number of parameters in any syntax */
+    Aaddr stringInitTable;	/* String init table address */
+    Aaddr setInitTable;		/* Set init table address */
+    Aaddr start;		/* Address to Start code */
+    Aword maximumScore;		/* Maximum score */
+    Aaddr scores;		/* Score table */
+    Aint scoreCount;		/* Max index into scores table */
+    Aaddr sourceFileTable;	/* Table of fpos/len for source filenames */
+    Aaddr sourceLineTable;	/* Table of available source lines to break on */
+    Aaddr freq;			/* Address to Char freq's for coding */
+    Aword acdcrc;		/* Checksum for acd code (excl. hdr) */
+    Aword txtcrc;		/* Checksum for text data file */
+    Aaddr ifids;		/* Address to IFIDS */
+    Aaddr prompt;
+};
+
+struct Pre3_0beta2Header {
+    /* Important info */
+    char tag[4];		/* "ALAN" */
+    char version[4];		/* Version of compiler */
+    Aword uid;			/* Unique id of the compiled game */
+    Aword size;			/* Size of ACD-file in Awords */
+    /* Options */
+    Abool pack;			/* Is the text packed ? */
+    Aword stringOffset;		/* Offset to string data in game file */
+    Aword pageLength;		/* Length of a page */
+    Aword pageWidth;		/* and width */
+    Aword debug;		/* Option: debug */
+    /* Data structures */
+    Aaddr classTableAddress;	/* Class table */
+    Aword classMax;		/* Number of classes */
+    Aword entityClassId;
+    Aword thingClassId;
+    Aword objectClassId;
+    Aword locationClassId;
+    Aword actorClassId;
+    Aword literalClassId;
+    Aword integerClassId;
+    Aword stringClassId;
+    Aaddr instanceTableAddress;	/* Instance table */
+    Aword instanceMax;		/* Highest number of an instance */
+    Aword theHero;		/* The hero instance code (id) */
+    Aaddr containerTableAddress;
+    Aword containerMax;
+    Aaddr scriptTableAddress;
+    Aword scriptMax;
+    Aaddr eventTableAddress;
+    Aword eventMax;
+    Aaddr syntaxTableAddress;
+    Aaddr parameterMapAddress;
+    Aword syntaxMax;
+    Aaddr dictionary;
+    Aaddr verbTableAddress;
+    Aaddr ruleTableAddress;
+    Aaddr messageTableAddress;
+    /* Miscellaneous */
+    Aint attributesAreaSize;	/* Size of attribute data area in Awords */
+    Aint maxParameters;		/* Maximum number of parameters in any syntax */
+    Aaddr stringInitTable;	/* String init table address */
+    Aaddr setInitTable;		/* Set init table address */
+    Aaddr start;		/* Address to Start code */
+    Aword maximumScore;		/* Maximum score */
+    Aaddr scores;		/* Score table */
+    Aint scoreCount;		/* Max index into scores table */
+    Aaddr sourceFileTable;	/* Table of fpos/len for source filenames */
+    Aaddr sourceLineTable;	/* Table of available source lines to break on */
+    Aaddr freq;			/* Address to Char freq's for coding */
+    Aword acdcrc;		/* Checksum for acd code (excl. hdr) */
+    Aword txtcrc;		/* Checksum for text data file */
+    Aaddr ifids;		/* Address to IFIDS */
+};
+
+struct Pre3_0alpha5Header {
+    /* Important info */
+    char tag[4];		/* "ALAN" */
+    char version[4];		/* Version of compiler */
+    Aword uid;			/* Unique id of the compiled game */
+    Aword size;			/* Size of ACD-file in Awords */
+    /* Options */
+    Abool pack;			/* Is the text packed ? */
+    Aword stringOffset;		/* Offset to string data in game file */
+    Aword pageLength;		/* Length of a page */
+    Aword pageWidth;		/* and width */
+    Aword debug;		/* Option: debug */
+    /* Data structures */
+    Aaddr classTableAddress;	/* Class table */
+    Aword classMax;		/* Number of classes */
+    Aword entityClassId;
+    Aword thingClassId;
+    Aword objectClassId;
+    Aword locationClassId;
+    Aword actorClassId;
+    Aword literalClassId;
+    Aword integerClassId;
+    Aword stringClassId;
+    Aaddr instanceTableAddress;	/* Instance table */
+    Aword instanceMax;		/* Highest number of an instance */
+    Aword theHero;		/* The hero instance code (id) */
+    Aaddr containerTableAddress;
+    Aword containerMax;
+    Aaddr scriptTableAddress;
+    Aword scriptMax;
+    Aaddr eventTableAddress;
+    Aword eventMax;
+    Aaddr syntaxTableAddress;
+    Aaddr parameterMapAddress;
+    Aword syntaxMax;
+    Aaddr dictionary;
+    Aaddr verbTableAddress;
+    Aaddr ruleTableAddress;
+    Aaddr messageTableAddress;
+    /* Miscellaneous */
+    Aint attributesAreaSize;	/* Size of attribute data area in Awords */
+    Aint maxParameters;		/* Maximum number of parameters in any syntax */
+    Aaddr stringInitTable;	/* String init table address */
+    Aaddr setInitTable;		/* Set init table address */
+    Aaddr start;		/* Address to Start code */
+    Aword maximumScore;		/* Maximum score */
+    Aaddr scores;		/* Score table */
+    Aint scoreCount;		/* Max index into scores table */
+    Aaddr sourceFileTable;	/* Table of fpos/len for source filenames */
+    Aaddr sourceLineTable;	/* Table of available source lines to break on */
+    Aaddr freq;			/* Address to Char freq's for coding */
+    Aword acdcrc;		/* Checksum for acd code (excl. hdr) */
+    Aword txtcrc;		/* Checksum for text data file */
+};
+
+/* Error message numbers */
+enum MsgKind {
+    M_UNKNOWN_WORD,
+    M_WHAT,
+    M_WHAT_WORD,
+    M_MULTIPLE,
+    M_NOUN,
+    M_AFTER_BUT,
+    M_BUT_ALL,
+    M_NOT_MUCH,
+    M_WHICH_ONE_START,
+    M_WHICH_ONE_COMMA,
+    M_WHICH_ONE_OR,
+    M_NO_SUCH,
+    M_NO_WAY,
+    M_CANT0,
+    M_SEE_START,
+    M_SEE_COMMA,
+    M_SEE_AND,
+    M_SEE_END,
+    M_CONTAINS,
+    M_CARRIES,
+    M_CONTAINS_COMMA,
+    M_CONTAINS_AND,
+    M_CONTAINS_END,
+    M_EMPTY,
+    M_EMPTYHANDED,
+    M_CANNOTCONTAIN,
+    M_SCORE,
+    M_MORE,
+    M_AGAIN,
+    M_SAVEWHERE,
+    M_SAVEOVERWRITE,
+    M_SAVEFAILED,
+    M_RESTOREFROM,
+    M_SAVEMISSING,
+    M_NOTASAVEFILE,
+    M_SAVEVERS,
+    M_SAVENAME,
+    M_REALLY,
+    M_QUITACTION,
+    M_UNDONE,
+    M_NO_UNDO,
+    M_WHICH_PRONOUN_START,
+    M_WHICH_PRONOUN_FIRST,
+	M_IMPOSSIBLE_WITH,
+    M_CONTAINMENT_LOOP,
+    M_CONTAINMENT_LOOP2,
+    MSGMAX
+};
+
+#define NO_MSG MSGMAX
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
new file mode 100644
index 0000000..87366cd
--- /dev/null
+++ b/engines/glk/alan3/act.cpp
@@ -0,0 +1,124 @@
+/* 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/alan3/act.h"
+#include "glk/alan3/alt_info.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/exe.h"
+#include "glk/alan3/lists.h"
+#include "common/textconsole.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/*----------------------------------------------------------------------*/
+static void executeCommand(int verb, Parameter parameters[])
+{
+    static AltInfo *altInfos = NULL; /* Need to survive lots of different exits...*/
+    int altIndex;
+
+    /* Did we leave anything behind last time... */
+    if (altInfos != NULL)
+        free(altInfos);
+
+    altInfos = findAllAlternatives(verb, parameters);
+
+    if (anyCheckFailed(altInfos, EXECUTE_CHECK_BODY_ON_FAIL))
+        return;
+
+    /* Check for anything to execute... */
+    if (!anythingToExecute(altInfos))
+        error(M_CANT0);
+
+    /* Now perform actions! First try any BEFORE or ONLY from inside out */
+    for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
+        if (altInfos[altIndex].alt != 0) // TODO Can this ever be NULL? Why?
+            if (altInfos[altIndex].alt->qual == (Aword)Q_BEFORE
+                || altInfos[altIndex].alt->qual == (Aword)Q_ONLY) {
+                if (!executedOk(&altInfos[altIndex]))
+                    abortPlayerCommand();
+                if (altInfos[altIndex].alt->qual == (Aword)Q_ONLY)
+                    return;
+            }
+    }
+        
+    /* Then execute any not declared as AFTER, i.e. the default */
+    for (altIndex = 0; !altInfos[altIndex].end; altIndex++) {
+        if (altInfos[altIndex].alt != 0)
+            if (altInfos[altIndex].alt->qual != (Aword)Q_AFTER)
+                if (!executedOk(&altInfos[altIndex]))
+                    abortPlayerCommand();
+    }
+        
+    /* Finally, the ones declared as AFTER */
+    for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
+        if (altInfos[altIndex].alt != 0)
+            if (!executedOk(&altInfos[altIndex]))
+                abortPlayerCommand();
+    }
+}
+
+
+/*======================================================================
+ 
+  action()
+ 
+  Execute the command. Handles acting on multiple items
+  such as ALL, THEM or lists of objects.
+ 
+*/
+void action(int verb, Parameter parameters[], Parameter multipleMatches[])
+{
+    int i, multiplePosition;
+    char marker[10];
+        
+    multiplePosition = findMultiplePosition(parameters);
+    if (multiplePosition != -1) {
+#ifdef TODO        
+		jmp_buf savedReturnLabel;
+        memcpy(savedReturnLabel, returnLabel, sizeof(returnLabel));
+        sprintf(marker, "($%d)", multiplePosition+1); /* Prepare a printout with $1/2/3 */
+        for (i = 0; !isEndOfArray(&multipleMatches[i]); i++) {
+            copyParameter(&parameters[multiplePosition], &multipleMatches[i]);
+            setGlobalParameters(parameters); /* Need to do this here since the marker use them */
+            output(marker);
+            // TODO: if execution for one parameter aborts we should return here, not to top level
+            if (setjmp(returnLabel) == NO_JUMP_RETURN)
+                executeCommand(verb, parameters);
+            if (multipleMatches[i+1].instance != EOF)
+                para();
+        }
+        memcpy(returnLabel, savedReturnLabel, sizeof(returnLabel));
+        parameters[multiplePosition].instance = 0;
+#else
+		::error("TODO: action");
+#endif
+    } else {
+        setGlobalParameters(parameters);
+        executeCommand(verb, parameters);
+    }
+
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/act.h b/engines/glk/alan3/act.h
new file mode 100644
index 0000000..09f8676
--- /dev/null
+++ b/engines/glk/alan3/act.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_ACT
+#define GLK_ALAN3_ACT
+
+/* Header file for action unit of ARUN Alan System interpreter */
+
+#include "glk/alan3/params.h"
+
+namespace Glk {
+namespace Alan3 {
+
+extern void action(int verb, Parameter *parameters, Parameter *multipleMatches);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/actor.cpp b/engines/glk/alan3/actor.cpp
new file mode 100644
index 0000000..5152305
--- /dev/null
+++ b/engines/glk/alan3/actor.cpp
@@ -0,0 +1,82 @@
+/* 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/alan3/actor.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/container.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/*======================================================================*/
+ScriptEntry *scriptOf(int actor) {
+    ScriptEntry *scr;
+
+    if (admin[actor].script != 0) {
+        for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++)
+            if (scr->code == admin[actor].script)
+                break;
+        if (!isEndOfArray(scr))
+            return scr;
+    }
+    return NULL;
+}
+
+
+/*======================================================================*/
+StepEntry *stepOf(int actor) {
+    StepEntry *step;
+    ScriptEntry *scr = scriptOf(actor);
+
+    if (scr == NULL) return NULL;
+
+    step = (StepEntry*)pointerTo(scr->steps);
+    step = &step[admin[actor].step];
+
+    return step;
+}
+
+
+/*======================================================================*/
+void describeActor(int actor)
+{
+    ScriptEntry *script = scriptOf(actor);
+
+    if (script != NULL && script->description != 0)
+        interpret(script->description);
+    else if (hasDescription(actor))
+        describeAnything(actor);
+    else {
+        printMessageWithInstanceParameter(M_SEE_START, actor);
+        printMessage(M_SEE_END);
+        if (instances[actor].container != 0)
+            describeContainer(actor);
+    }
+    admin[actor].alreadyDescribed = TRUE;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/actor.h b/engines/glk/alan3/actor.h
new file mode 100644
index 0000000..8b2c1ad
--- /dev/null
+++ b/engines/glk/alan3/actor.h
@@ -0,0 +1,39 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_ACTOR
+#define GLK_ALAN3_ACTOR
+
+#include "glk/alan3/acode.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* FUNCTIONS */
+extern ScriptEntry *scriptOf(int actor);
+extern StepEntry *stepOf(int actor);
+extern void describeActor(int actor);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
new file mode 100644
index 0000000..d5a062b
--- /dev/null
+++ b/engines/glk/alan3/alan3.cpp
@@ -0,0 +1,149 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/alan3/alan3.h"
+#include "glk/alan3/exe.h"
+#include "glk/alan3/main.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/options.h"
+#include "common/system.h"
+#include "common/config-manager.h"
+#include "common/translation.h"
+#include "common/error.h"
+#include "common/scummsys.h"
+#include "common/serializer.h"
+#include "glk/glk.h"
+#include "glk/streams.h"
+
+namespace Glk {
+namespace Alan3 {
+
+Alan3 *g_vm = nullptr;
+
+Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
+		vm_exited_cleanly(false), _restartFlag(false), _saveSlot(-1), _pendingLook(false) {
+	g_vm = this;
+//	txtfil = nullptr;
+//	logfil = nullptr;
+	memory = nullptr;
+
+	verboseOption = false;
+	ignoreErrorOption = false;
+	debugOption = false;
+	traceSectionOption = false;
+	tracePushOption = false;
+	traceStackOption = false;
+	traceSourceOption = false;
+	traceInstructionOption = false;
+	transcriptOption = false;
+	logOption = false;
+	statusLineOption = true;
+	regressionTestOption = false;
+}
+
+void Alan3::runGame() {
+	if (initialize())
+		Glk::Alan3::run();
+
+	deinitialize();
+}
+
+bool Alan3::initialize() {
+	// Set up adventure name
+	_advName = getFilename();
+	if (_advName.size() > 4 && _advName[_advName.size() - 4] == '.')
+		_advName = Common::String(_advName.c_str(), _advName.size() - 4);
+
+	// first, open a window for error output
+	glkMainWin = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
+	if (glkMainWin == nullptr)
+		::error("FATAL ERROR: Cannot open initial window");
+
+	g_vm->glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
+	glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
+	                                     winmethod_Fixed, 1, wintype_TextGrid, 0);
+	g_vm->glk_set_window(glkMainWin);
+/*
+	// Set up the code file to point to the already opened game file
+	codfil = &_gameFile;
+	strncpy(codfnm, getFilename().c_str(), 255);
+	codfnm[255] = '\0';
+
+	if (_gameFile.size() < 8) {
+		GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
+		return false;
+	}
+
+	if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
+		GUIErrorMessage(_("This is not a valid Alan3 file."));
+		return false;
+	}
+
+	// Open up the text file
+	txtfil = new Common::File();
+	if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
+		GUIErrorMessage("Could not open adventure text data file");
+		delete txtfil;
+		return false;
+	}
+
+	// Check for a save being loaded directly from the launcher
+	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+*/
+	return true;
+}
+
+void Alan3::deinitialize() {
+	free(memory);
+/*
+	delete txtfil;
+	delete logfil;
+*/
+}
+
+Common::Error Alan3::readSaveData(Common::SeekableReadStream *rs) {
+	Common::Serializer s(rs, nullptr);
+	synchronizeSave(s);
+
+	return Common::kNoError;
+}
+
+Common::Error Alan3::writeGameData(Common::WriteStream *ws) {
+	Common::Serializer s(nullptr, ws);
+	synchronizeSave(s);
+
+	ws->flush();
+	return Common::kNoError;
+}
+
+// This works around gcc errors for passing packed structure fields
+void syncVal(Common::Serializer &s, uint32 *fld) {
+	uint32 &v = *fld;
+	s.syncAsUint32LE(v);
+}
+
+void Alan3::synchronizeSave(Common::Serializer &s) {
+	// TODO
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
new file mode 100644
index 0000000..ea8548a
--- /dev/null
+++ b/engines/glk/alan3/alan3.h
@@ -0,0 +1,102 @@
+/* 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_ALAN3
+#define GLK_ALAN3
+
+#include "glk/glk_api.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/**
+ * Alan3 game interpreter
+ */
+class Alan3 : public GlkAPI {
+private:
+	bool _restartFlag;
+public:
+	bool vm_exited_cleanly;
+	Common::String _advName;
+	int _saveSlot;
+	bool _pendingLook;
+private:
+	/**
+	 * Initialization
+	 */
+	bool initialize();
+
+	/**
+	 * Deinitialization
+	 */
+	void deinitialize();
+
+	/**
+	 * Synchronize data to or from a save file
+	 */
+	void synchronizeSave(Common::Serializer &s);
+public:
+	/**
+	 * Constructor
+	 */
+	Alan3(OSystem *syst, const GlkGameDescription &gameDesc);
+
+	/**
+	 * Run the game
+	 */
+	void runGame();
+
+	/**
+	 * Flag for the game to restart
+	 */
+	void setRestart(bool flag) { _restartFlag = flag; }
+
+	/**
+	 * Returns whether the game should restart
+	 */
+	bool shouldRestart() const { return _restartFlag; }
+
+	/**
+	 * Returns the running interpreter type
+	 */
+	virtual InterpreterType getInterpreterType() const override {
+		return INTERPRETER_ALAN3;
+	}
+
+	/**
+	 * 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 Alan3 *g_vm;
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/alan_version.cpp b/engines/glk/alan3/alan_version.cpp
new file mode 100644
index 0000000..bb244ec
--- /dev/null
+++ b/engines/glk/alan3/alan_version.cpp
@@ -0,0 +1,42 @@
+/* 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/alan3/alan_version.h"
+
+namespace Glk {
+namespace Alan3 {
+
+const Product alan = {
+  "Alan",
+  "Adventure Language System",
+  "Alan 3.0beta6",
+  "Alan 3.0beta6 -- Adventure Language System (2017-09-08 10:18)",
+  "2017-09-08",
+  "10:18:25",
+  "Thomas",
+  "thoni64",
+  "cygwin32",
+  {"3.0beta6", 3, 0, 6, 1504858705, "beta"}
+};
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/alan_version.h b/engines/glk/alan3/alan_version.h
new file mode 100644
index 0000000..efc26d2
--- /dev/null
+++ b/engines/glk/alan3/alan_version.h
@@ -0,0 +1,36 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_ALAN_VERSION
+#define GLK_ALAN3_ALAN_VERSION
+
+#include "glk/alan3/version.h"
+
+namespace Glk {
+namespace Alan3 {
+
+extern const Product alan;
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/alt_info.cpp b/engines/glk/alan3/alt_info.cpp
new file mode 100644
index 0000000..b9e2dc0
--- /dev/null
+++ b/engines/glk/alan3/alt_info.cpp
@@ -0,0 +1,381 @@
+/* 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/alan3/alt_info.h"
+#include "glk/alan3/types.h"
+#include "glk/alan3/checkentry.h"
+#include "glk/alan3/debug.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/class.h"
+#include "glk/alan3/params.h"
+#include "glk/alan3/literal.h"
+#include "glk/alan3/syntax.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* Types */
+typedef AltInfo *AltInfoFinder(int verb, Parameter parameters[]);
+
+
+/*======================================================================*/
+void primeAltInfo(AltInfo *altInfo, int level, int parameter, int instance, int cls)
+{
+    altInfo->level = level;
+    altInfo->parameter = parameter;
+    altInfo->instance = instance;
+    altInfo->_class = cls;
+    altInfo->done = FALSE;
+    altInfo->end = FALSE;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceInstanceAndItsClass(Aid instance, Aid cls)
+{
+    traceSay(instance);
+    printf("[%d]", instance);
+    if (cls != NO_CLASS)
+        printf(", inherited from %s[%d]", idOfClass(cls), cls);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceAltInfo(AltInfo *alt) {
+    switch (alt->level) {
+    case GLOBAL_LEVEL:
+        printf("GLOBAL");
+        break;
+    case LOCATION_LEVEL:
+        printf("in (location) ");
+        traceInstanceAndItsClass(current.location, alt->_class);
+        break;
+    case PARAMETER_LEVEL: {
+		char *parameterName = parameterNameInSyntax(current.verb, alt->parameter);
+		if (parameterName != NULL)
+			printf("in parameter %s(#%d)=", parameterName, alt->parameter);
+		else
+			printf("in parameter #%d=", alt->parameter);
+        traceInstanceAndItsClass(globalParameters[alt->parameter-1].instance, alt->_class);
+        break;
+	}
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceVerbCheck(AltInfo *alt, bool execute)
+{
+    if (traceSectionOption && execute) {
+        printf("\n<VERB %d, ", current.verb);
+        traceAltInfo(alt);
+        printf(", CHECK:>\n");
+    }
+}
+
+
+/*======================================================================*/
+bool checkFailed(AltInfo *altInfo, bool execute)
+{
+    if (altInfo->alt != NULL && altInfo->alt->checks != 0) {
+        traceVerbCheck(altInfo, execute);
+        // TODO Why does this not generate a regression error with !
+        // Need a new regression case?
+        fail = FALSE;
+        if (checksFailed(altInfo->alt->checks, execute)) return TRUE;
+        if (fail) return TRUE;
+    }
+    return FALSE;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceVerbExecution(AltInfo *alt)
+{
+    if (traceSectionOption) {
+        printf("\n<VERB %d, ", current.verb);
+        traceAltInfo(alt);
+        printf(", DOES");
+        switch (alt->alt->qual) {
+        case Q_BEFORE: printf(" (BEFORE)");
+            break;
+        case Q_ONLY: printf(" (ONLY)");
+            break;
+        case Q_AFTER: printf(" (AFTER)");
+            break;
+        case Q_DEFAULT:
+            break;
+        }
+        printf(":>\n");
+    }
+}
+
+
+/*======================================================================*/
+bool executedOk(AltInfo *altInfo)
+{
+    fail = FALSE;
+    if (!altInfo->done && altInfo->alt->action != 0) {
+        traceVerbExecution(altInfo);
+        current.instance = altInfo->instance;
+        interpret(altInfo->alt->action);
+    }
+    altInfo->done = TRUE;
+    return !fail;
+}
+
+
+/*======================================================================*/
+bool canBeExecuted(AltInfo *altInfo) {
+    return altInfo->alt != NULL && altInfo->alt->action != 0;
+}
+
+
+/*======================================================================*/
+AltInfo *duplicateAltInfoArray(AltInfo original[]) {
+    int size;
+    AltInfo *duplicate;
+	
+    for (size = 0; original[size].end != TRUE; size++)
+        ;
+    size++;
+    duplicate = (AltInfo *)allocate(size*sizeof(AltInfo));
+    memcpy(duplicate, original, size*sizeof(AltInfo));
+    return duplicate;
+}
+
+
+/*======================================================================*/
+int lastAltInfoIndex(AltInfo altInfo[])
+{
+    int altIndex;
+	
+    /* Loop to last alternative */
+    for (altIndex = -1; !altInfo[altIndex+1].end; altIndex++)
+        ;
+    return altIndex;
+}
+
+
+/*----------------------------------------------------------------------*/
+static AltInfo *nextFreeAltInfo(AltInfoArray altInfos) {
+    return &altInfos[lastAltInfoIndex(altInfos)+1];
+}
+
+
+/*----------------------------------------------------------------------*/
+static void addAlternative(AltInfoArray altInfos, int verb, int level, Aint parameterNumber, Aint theClass, Aid theInstance, AltEntryFinder finder) {
+    AltInfo *altInfoP = nextFreeAltInfo(altInfos);
+	
+    altInfoP->alt = (*finder)(verb, parameterNumber, theInstance, theClass);
+    if (altInfoP->alt != NULL) {
+        primeAltInfo(altInfoP, level, parameterNumber, theInstance, theClass);
+        altInfoP[1].end = TRUE;
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void addGlobalAlternatives(AltInfoArray altInfos, int verb, AltEntryFinder finder ) {
+    addAlternative(altInfos, verb, GLOBAL_LEVEL, NO_PARAMETER, NO_CLASS, NO_INSTANCE, finder);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void addAlternativesFromParents(AltInfoArray altInfos, int verb, int level, Aint parameterNumber, Aint theClass, Aid theInstance, AltEntryFinder finder){
+    if (classes[theClass].parent != 0)
+        addAlternativesFromParents(altInfos, verb, level,
+                                   parameterNumber,
+                                   classes[theClass].parent,
+                                   theInstance,
+                                   finder);
+	
+    addAlternative(altInfos, verb, level, parameterNumber, theClass, theInstance, finder);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void addAlternativesFromLocation(AltInfoArray altInfos, int verb, Aid location, AltEntryFinder finder) {
+    if (admin[location].location != 0)
+        addAlternativesFromLocation(altInfos, verb, admin[location].location, finder);
+	
+    addAlternativesFromParents(altInfos, verb,
+                               LOCATION_LEVEL,
+                               NO_PARAMETER,
+                               instances[location].parent,
+                               location,
+                               finder);
+	
+    addAlternative(altInfos, verb, LOCATION_LEVEL, NO_PARAMETER, NO_CLASS, location, finder);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void addAlternativesFromParameter(AltInfoArray altInfos, int verb, Parameter parameters[], int parameterNumber, AltEntryFinder finder) {
+    Aid parent;
+    Aid theInstance = parameters[parameterNumber-1].instance;
+	
+    if (isLiteral(theInstance))
+        parent = literals[literalFromInstance(theInstance)]._class;
+    else
+        parent = instances[theInstance].parent;
+    addAlternativesFromParents(altInfos, verb, PARAMETER_LEVEL, parameterNumber, parent, theInstance, finder);
+	
+    if (!isLiteral(theInstance))
+        addAlternative(altInfos, verb, PARAMETER_LEVEL, parameterNumber, NO_CLASS, theInstance, finder);
+}
+
+
+/*======================================================================*/
+bool anyCheckFailed(AltInfoArray altInfo, bool execute)
+{
+    int altIndex;
+    
+    if (altInfo != NULL)
+	for (altIndex = 0; !altInfo[altIndex].end; altIndex++) {
+	    current.instance = altInfo[altIndex].instance;
+	    if (checkFailed(&altInfo[altIndex], execute))
+		return TRUE;
+	}
+    return FALSE;
+}
+
+
+/*======================================================================*/
+bool anythingToExecute(AltInfo altInfo[])
+{
+    int altIndex;
+	
+    /* Check for anything to execute... */
+    if (altInfo != NULL)
+	for (altIndex = 0; !altInfo[altIndex].end; altIndex++)
+	    if (canBeExecuted(&altInfo[altIndex]))
+		return TRUE;
+    return FALSE;
+}
+
+
+/*----------------------------------------------------------------------*/
+static VerbEntry *findVerbEntry(int verbCode, VerbEntry *entries) {
+    VerbEntry *verbEntry;
+    for (verbEntry = entries; !isEndOfArray(verbEntry); verbEntry++) {
+        if (verbEntry->code < 0) {
+            /* Verb codes are negative for Meta verbs, if so they are also 1 off to avoid EOF */
+            if (abs(verbEntry->code)-1 == verbCode)
+                return verbEntry;
+        } else {
+            if (verbEntry->code == verbCode)
+                return verbEntry;
+        }
+    }
+    return NULL;
+}
+
+
+/*----------------------------------------------------------------------*/
+static AltEntry *findAlternative(Aaddr verbTableAddress, int verbCode, int parameterNumber)
+{
+    AltEntry *alt;
+    VerbEntry *verbEntry;
+	
+    if (verbTableAddress == 0) return NULL;
+
+    verbEntry = findVerbEntry(verbCode, (VerbEntry *) pointerTo(verbTableAddress));
+    if (verbEntry != NULL)
+        for (alt = (AltEntry *) pointerTo(verbEntry->alts); !isEndOfArray(alt); alt++) {
+            if (alt->param == parameterNumber || alt->param == 0) {
+                if (verbEntry->code < 0) current.meta = TRUE;
+                return alt;
+            }
+        }
+    return NULL;
+}
+
+
+/*----------------------------------------------------------------------*/
+static AltEntry *alternativeFinder(int verb, int parameterNumber, int theInstance, int theClass)
+{
+    if (theClass != NO_CLASS)
+        return findAlternative(classes[theClass].verbs, verb, parameterNumber);
+    else if (theInstance != NO_INSTANCE)
+        return findAlternative(instances[theInstance].verbs, verb, parameterNumber);
+    else
+        return findAlternative(header->verbTableAddress, verb, parameterNumber);
+}
+
+
+/*======================================================================*/
+AltInfo *findAllAlternatives(int verb, Parameter parameters[]) {
+    int parameterNumber;
+    AltInfo altInfos[1000];
+    altInfos[0].end = TRUE;
+    
+    addGlobalAlternatives(altInfos, verb, &alternativeFinder);
+	
+    addAlternativesFromLocation(altInfos, verb, current.location, &alternativeFinder);
+
+    for (parameterNumber = 1; !isEndOfArray(&parameters[parameterNumber-1]); parameterNumber++) {
+        addAlternativesFromParameter(altInfos, verb, parameters, parameterNumber, &alternativeFinder);
+    }
+    return duplicateAltInfoArray(altInfos);
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool possibleWithFinder(int verb, Parameter parameters[], AltInfoFinder *finder) {
+    bool anything;
+    AltInfo *allAlternatives;
+
+    allAlternatives = finder(verb, parameters);
+
+    // TODO Need to do this since anyCheckFailed() call execute() which assumes the global parameters
+    setGlobalParameters(parameters);
+    if (anyCheckFailed(allAlternatives, DONT_EXECUTE_CHECK_BODY_ON_FAIL))
+        anything = FALSE;
+    else
+	anything = anythingToExecute(allAlternatives);
+
+    if (allAlternatives != NULL)
+      deallocate(allAlternatives);
+
+    return(anything);
+}
+
+
+
+/*======================================================================*/
+bool possible(int verb, Parameter inParameters[], ParameterPosition parameterPositions[])
+{
+    // This is a wrapper for possibleWithFinder() which is used in unit tests
+    // possible() should be used "for real".
+
+    return possibleWithFinder(verb, inParameters, findAllAlternatives);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/alt_info.h b/engines/glk/alan3/alt_info.h
new file mode 100644
index 0000000..de99585
--- /dev/null
+++ b/engines/glk/alan3/alt_info.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_ALT_INFO
+#define GLK_ALAN3_ALT_INFO
+
+/* An info node about the Verb Alternatives found and possibly executed */
+
+#include "glk/alan3/types.h"
+#include "glk/alan3/acode.h"
+#include "glk/alan3/params.h"
+#include "glk/alan3/parameter_position.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* Constants */
+
+#define GLOBAL_LEVEL (0)
+#define LOCATION_LEVEL (1)
+#define PARAMETER_LEVEL (2)
+
+#define NO_PARAMETER ((Aword)-1)
+#define NO_INSTANCE ((Aword)-1)
+#define NO_CLASS ((Aword)-1)
+
+/* tryCheck() flags */
+#define EXECUTE_CHECK_BODY_ON_FAIL TRUE
+#define DONT_EXECUTE_CHECK_BODY_ON_FAIL FALSE
+
+
+/* Types */
+
+struct AltInfo {
+	bool end;		/* Indicator of end in AltInfoArray, first empty has TRUE here */
+	AltEntry *alt;
+	bool done;
+	Aint level;		/* 0 - Global, 1 - location, 2 - parameter */
+	Aid _class;		/* In which class, only used for tracing */
+	Aid instance;	/* In which instance the Alternative was found,
+					   used to set current.instance and tracing */
+	Aid parameter;	   /* In which parameter, only used for tracing */
+};
+
+typedef AltEntry *(*AltEntryFinder)(int verb, int parameterNumber, int theInstance, int theClass);
+
+typedef AltInfo AltInfoArray[];
+
+
+
+/* Data */
+
+
+/* Functions */
+extern void primeAltInfo(AltInfo *altInfo, int level, int parameter, int instance, int cls);
+extern bool executedOk(AltInfo *altInfo);
+extern bool checkFailed(AltInfo *altInfo, bool execute);
+extern bool canBeExecuted(AltInfo *altInfo);
+extern AltInfo *duplicateAltInfoArray(AltInfoArray altInfos);
+extern int lastAltInfoIndex(AltInfoArray altInfos);
+extern bool anyCheckFailed(AltInfoArray altInfos, bool execute);
+extern bool anythingToExecute(AltInfoArray altInfos);
+extern bool possible(int verb, Parameter parameters[], ParameterPosition parameterPositions[]);
+extern AltInfo *findAllAlternatives(int verb, Parameter parameters[]);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/args.cpp b/engines/glk/alan3/args.cpp
new file mode 100644
index 0000000..7a020cd
--- /dev/null
+++ b/engines/glk/alan3/args.cpp
@@ -0,0 +1,159 @@
+/* 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/alan3/args.h"
+#include "glk/alan3/alan3.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/sysdep.h"
+#include "glk/alan3/utils.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+/* The files and filenames */
+char *adventureName;        /* The name of the game */
+char *adventureFileName;
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+/*======================================================================*/
+char *gameName(char *fullPathName) {
+    char *foundGameName = "";
+
+    if (fullPathName != NULL) {
+        foundGameName = strdup(baseNameStart(fullPathName));
+        foundGameName[strlen(foundGameName)-4] = '\0'; /* Strip off .A3C */
+    }
+
+    if (foundGameName[0] == '.' && foundGameName[1] == '/')
+        strcpy(foundGameName, &foundGameName[2]);
+
+    return foundGameName;
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *removeQuotes(char *argument) {
+    char *str = strdup(&argument[1]);
+    str[strlen(str)-1] = '\0';
+    return str;
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool isQuoted(char *argument) {
+    return argument[0] == '"' && strlen(argument) > 2;
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *addAcodeExtension(char *advFilename) {
+    if (strlen(advFilename) < strlen(ACODEEXTENSION)
+        || compareStrings(&advFilename[strlen(advFilename)-4], ACODEEXTENSION) != 0) {
+        advFilename = (char *)realloc(advFilename, strlen(advFilename)+strlen(ACODEEXTENSION)+1);
+        strcat(advFilename, ACODEEXTENSION);
+    }
+    return advFilename;
+}
+
+
+
+/*----------------------------------------------------------------------*/
+static void switches(int argc, char *argv[])
+{
+    int i;
+
+    for (i = 1; i < argc; i++) {
+        char *argument = argv[i];
+
+        if (argument[0] == '-') {
+            switch (toLower(argument[1]))
+                {
+                case 'i':
+                    ignoreErrorOption = TRUE;
+                    break;
+                case 't':
+                    traceSectionOption = TRUE;
+                    switch (argument[2]) {
+                    case '9':
+                    case '8':
+                    case '7':
+                    case '6':
+                    case '5' : traceStackOption = TRUE;
+                    case '4' : tracePushOption = TRUE;
+                    case '3' : traceInstructionOption = TRUE;
+                    case '2' : traceSourceOption = TRUE;
+                    case '\0':
+                    case '1': traceSectionOption = TRUE;
+                    }
+                    break;
+                case 'd':
+                    debugOption = TRUE;
+                    break;
+                case 'l':
+                    transcriptOption = TRUE;
+                    logOption = FALSE;
+                    break;
+                case 'v':
+                    verboseOption = TRUE;
+                    break;
+                case 'n':
+                    statusLineOption = FALSE;
+                    break;
+                case 'c':
+                    logOption = TRUE;
+                    transcriptOption = FALSE;
+                    break;
+                case 'r':
+                    regressionTestOption = TRUE;
+                    break;
+                default:
+                    printf("Unrecognized switch, -%c\n", argument[1]);
+                    usage(argv[0]);
+                    terminate(0);
+                }
+        } else {
+
+            if (isQuoted(argument))
+                adventureFileName = removeQuotes(argument);
+            else
+                adventureFileName = strdup(argument);
+
+            adventureFileName = addAcodeExtension(adventureFileName);
+
+            adventureName = gameName(adventureFileName);
+
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+bool differentInterpreterName(char *string) {
+    return strcasecmp(string, PROGNAME) != 0;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/args.h b/engines/glk/alan3/args.h
new file mode 100644
index 0000000..f70cf3a
--- /dev/null
+++ b/engines/glk/alan3/args.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_
+#define GLK_ALAN3_
+
+/* Argument handling */
+
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+#ifndef PROGNAME
+#ifdef HAVE_GARGLK
+#define PROGNAME "alan3"
+#else
+#define PROGNAME "arun"
+#endif
+#endif
+
+/* DATA */
+extern char *adventureName; /* The name of the game */
+extern char *adventureFileName;
+
+/* FUNCTIONS */
+extern char *gameName(char fullPathName[]);
+extern void args(int argc, char *argv[]);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/attribute.cpp b/engines/glk/alan3/attribute.cpp
new file mode 100644
index 0000000..1e5a6dd
--- /dev/null
+++ b/engines/glk/alan3/attribute.cpp
@@ -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.
+ *
+ */
+
+#include "glk/alan3/attribute.h"
+#include "glk/alan3/syserr.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/lists.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/*----------------------------------------------------------------------*/
+static AttributeEntry *findAttribute(AttributeEntry *attributeTable, int attributeCode)
+{
+  AttributeEntry *attribute = attributeTable;
+  while (attribute->code != attributeCode) {
+    attribute++;
+    if (isEndOfArray(attribute))
+      syserr("Attribute not found.");
+  }
+  return attribute;
+}
+
+
+/*======================================================================*/
+Aptr getAttribute(AttributeEntry *attributeTable, int attributeCode)
+{
+  AttributeEntry *attribute = findAttribute(attributeTable, attributeCode);
+
+  return attribute->value;
+}
+
+
+/*======================================================================*/
+void setAttribute(AttributeEntry *attributeTable, int attributeCode, Aptr newValue)
+{
+  AttributeEntry *attribute = findAttribute(attributeTable, attributeCode);
+
+  attribute->value = newValue;
+  gameStateChanged = TRUE;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/attribute.h b/engines/glk/alan3/attribute.h
new file mode 100644
index 0000000..02aac0d
--- /dev/null
+++ b/engines/glk/alan3/attribute.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_ATTRIBUTE
+#define GLK_ALAN3_ATTRIBUTE
+
+#include "glk/alan3/acode.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* FUNCTIONS */
+extern Aptr getAttribute(AttributeEntry *attributeTable, int attributeCode);
+extern void setAttribute(AttributeEntry *attributeTable, int attributeCode, Aptr newValue);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
\ No newline at end of file
diff --git a/engines/glk/alan3/checkentry.cpp b/engines/glk/alan3/checkentry.cpp
new file mode 100644
index 0000000..51a839c
--- /dev/null
+++ b/engines/glk/alan3/checkentry.cpp
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/alan3/checkentry.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/memory.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/*======================================================================*/
+bool checksFailed(Aaddr adr, bool execute)
+{
+    CheckEntry *chk = (CheckEntry *) pointerTo(adr);
+    if (chk->exp == 0) {
+        if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
+            interpret(chk->stms);
+        return TRUE;
+    } else {
+        while (!isEndOfArray(chk)) {
+            if (!evaluate(chk->exp)) {
+                if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
+                    interpret(chk->stms);
+                return TRUE;
+            }
+            chk++;
+        }
+        return FALSE;
+    }
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/checkentry.h b/engines/glk/alan3/checkentry.h
new file mode 100644
index 0000000..a39558f
--- /dev/null
+++ b/engines/glk/alan3/checkentry.h
@@ -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.
+ *
+ */
+
+#ifndef GLK_ALAN3_CHECKENTRY
+#define GLK_ALAN3_CHECKENTRY
+
+#include "glk/alan3/types.h"
+#include "glk/alan3/acode.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* CONSTANTS */
+#ifndef EXECUTE_CHECK_BODY_ON_FAIL
+#define EXECUTE_CHECK_BODY_ON_FAIL TRUE
+#define DONT_EXECUTE_CHECK_BODY_ON_FAIL FALSE
+#endif
+
+
+/* TYPES */
+struct CheckEntry { /* CHECK TABLE */
+  Aaddr exp;            /* ACODE address to expression code */
+  Aaddr stms;           /* ACODE address to statement code */
+};
+
+
+/* DATA */
+typedef CheckEntry CheckEntryArray[];
+
+
+/* FUNCTIONS */
+extern bool checksFailed(Aaddr adr, bool execute);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/class.cpp b/engines/glk/alan3/class.cpp
new file mode 100644
index 0000000..b23d8ac
--- /dev/null
+++ b/engines/glk/alan3/class.cpp
@@ -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.
+ *
+ */
+
+#include "glk/alan3/class.h"
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+ClassEntry *classes; /* Class table pointer */
+
+/*======================================================================*/
+char *idOfClass(int theClass) {
+    return (char *)pointerTo(classes[theClass].id);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/class.h b/engines/glk/alan3/class.h
new file mode 100644
index 0000000..a6ff071
--- /dev/null
+++ b/engines/glk/alan3/class.h
@@ -0,0 +1,40 @@
+/* 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_ALAN3_CLASS
+#define GLK_ALAN3_CLASS
+
+#include "glk/alan3/acode.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* DATA */
+extern ClassEntry *classes;		/* Class table pointer */
+
+/* FUNCTIONS */
+extern char *idOfClass(int theClass);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/compatibility.cpp b/engines/glk/alan3/compatibility.cpp
new file mode 100644
index 0000000..a8efb47
--- /dev/null
+++ b/engines/glk/alan3/compatibility.cpp
@@ -0,0 +1,69 @@
+/* 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/alan3/compatibility.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/*----------------------------------------------------------------------*/
+static bool is3_0Alpha(char version[]) {
+    return version[3] == 3 && version[2] == 0 && version[0] == 'a';
+}
+
+/*----------------------------------------------------------------------*/
+static bool is3_0Beta(char version[]) {
+    return version[3] == 3 && version[2] == 0 && version[0] == 'b';
+}
+
+/*----------------------------------------------------------------------*/
+static int correction(char version[]) {
+    return version[1];
+}
+
+/*======================================================================*/
+bool isPreAlpha5(char version[4]) {
+    return is3_0Alpha(version) && correction(version) <5;
+}
+
+/*======================================================================*/
+bool isPreBeta2(char version[4]) {
+    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) == 1);
+}
+
+/*======================================================================*/
+bool isPreBeta3(char version[4]) {
+    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 2);
+}
+
+/*======================================================================*/
+bool isPreBeta4(char version[4]) {
+    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 3);
+}
+
+/*======================================================================*/
+bool isPreBeta5(char version[4]) {
+    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 4);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/compatibility.h b/engines/glk/alan3/compatibility.h
new file mode 100644
index 0000000..0187c72
--- /dev/null
+++ b/engines/glk/alan3/compatibility.h
@@ -0,0 +1,42 @@
+/* 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_ALAN3_COMPATIBILITY
+#define GLK_ALAN3_COMPATIBILITY
+
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* FUNCTIONS: */
+extern bool isPreAlpha5(char version[4]);
+extern bool isPreBeta2(char version[4]);
+extern bool isPreBeta3(char version[4]);
+extern bool isPreBeta4(char version[4]);
+extern bool isPreBeta5(char version[4]);
+extern char *decodedGameVersion(char version[]);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/container.cpp b/engines/glk/alan3/container.cpp
new file mode 100644
index 0000000..4b812c9
--- /dev/null
+++ b/engines/glk/alan3/container.cpp
@@ -0,0 +1,190 @@
+/* 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/alan3/container.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/syserr.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/output.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+ContainerEntry *containers;  /* Container table pointer */
+
+
+/*----------------------------------------------------------------------*/
+static int countInContainer(int containerIndex)	/* IN - the container to count in */
+{
+    int j = 0;
+
+    for (uint instanceIndex = 1; instanceIndex <= header->instanceMax; instanceIndex++)
+        if (isIn(instanceIndex, containerIndex, DIRECT))
+            /* Then it's in this container also */
+            j++;
+    return(j);
+}
+
+
+/*----------------------------------------------------------------------*/
+static int sumAttributeInContainer(
+                                   Aint containerIndex,			/* IN - the container to sum */
+                                   Aint attributeIndex			/* IN - the attribute to sum over */
+                                   ) {
+    uint instanceIndex;
+    int sum = 0;
+
+    for (instanceIndex = 1; instanceIndex <= header->instanceMax; instanceIndex++)
+        if (isIn(instanceIndex, containerIndex, DIRECT)) {	/* Then it's directly in this cont */
+            if (instances[instanceIndex].container != 0)	/* This is also a container! */
+                sum = sum + sumAttributeInContainer(instanceIndex, attributeIndex);
+            sum = sum + getInstanceAttribute(instanceIndex, attributeIndex);
+        }
+    return(sum);
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool containerIsEmpty(int container)
+{
+    int i;
+
+    for (i = 1; i <= header->instanceMax; i++)
+        if (isDescribable(i) && isIn(i, container, TRANSITIVE))
+            return FALSE;
+    return TRUE;
+}
+
+
+/*======================================================================*/
+void describeContainer(int container)
+{
+    if (!containerIsEmpty(container) && !isOpaque(container))
+        list(container);
+}
+
+
+/*======================================================================*/
+bool passesContainerLimits(Aint theContainer, Aint theAddedInstance) {
+    LimitEntry *limit;
+    Aword props;
+
+    if (!isAContainer(theContainer))
+        syserr("Checking limits for a non-container.");
+
+    /* Find the container properties */
+    props = instances[theContainer].container;
+
+    if (containers[props].limits != 0) { /* Any limits at all? */
+        for (limit = (LimitEntry *) pointerTo(containers[props].limits); !isEndOfArray(limit); limit++)
+            if (limit->atr == 1-I_COUNT) { /* TODO This is actually some encoding of the attribute number, right? */
+                if (countInContainer(theContainer) >= limit->val) {
+                    interpret(limit->stms);
+                    return(FALSE);
+                }
+            } else {
+                if (sumAttributeInContainer(theContainer, limit->atr) + getInstanceAttribute(theAddedInstance, limit->atr) > limit->val) {
+                    interpret(limit->stms);
+                    return(FALSE);
+                }
+            }
+    }
+    return(TRUE);
+}
+
+
+/*======================================================================*/
+int containerSize(int container, ATrans trans) {
+    Aint i;
+    Aint count = 0;
+
+    for (i = 1; i <= header->instanceMax; i++) {
+        if (isIn(i, container, trans))
+            count++;
+    }
+    return(count);
+}
+
+/*======================================================================*/
+void list(int container)
+{
+    int i;
+    Aword props;
+    Aword foundInstance[2] = {0,0};
+    int found = 0;
+    Aint previousThis = current.instance;
+
+    current.instance = container;
+
+    /* Find container table entry */
+    props = instances[container].container;
+    if (props == 0) syserr("Trying to list something not a container.");
+
+    for (i = 1; i <= header->instanceMax; i++) {
+        if (isDescribable(i)) {
+            /* We can only see objects and actors directly in this container... */
+            if (admin[i].location == container) { /* Yes, it's in this container */
+                if (found == 0) {
+                    if (containers[props].header != 0)
+                        interpret(containers[props].header);
+                    else {
+                        if (isAActor(containers[props].owner))
+                            printMessageWithInstanceParameter(M_CARRIES, containers[props].owner);
+                        else
+                            printMessageWithInstanceParameter(M_CONTAINS, containers[props].owner);
+                    }
+                    foundInstance[0] = i;
+                } else if (found == 1)
+                    foundInstance[1] = i;
+                else {
+                    printMessageWithInstanceParameter(M_CONTAINS_COMMA, i);
+                }
+                found++;
+            }
+        }
+    }
+
+    if (found > 0) {
+        if (found > 1)
+            printMessageWithInstanceParameter(M_CONTAINS_AND, foundInstance[1]);
+        printMessageWithInstanceParameter(M_CONTAINS_END, foundInstance[0]);
+    } else {
+        if (containers[props].empty != 0)
+            interpret(containers[props].empty);
+        else {
+            if (isAActor(containers[props].owner))
+                printMessageWithInstanceParameter(M_EMPTYHANDED, containers[props].owner);
+            else
+                printMessageWithInstanceParameter(M_EMPTY, containers[props].owner);
+        }
+    }
+    needSpace = TRUE;
+    current.instance = previousThis;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/container.h b/engines/glk/alan3/container.h
new file mode 100644
index 0000000..88aac47
--- /dev/null
+++ b/engines/glk/alan3/container.h
@@ -0,0 +1,45 @@
+/* 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_ALAN3_CONTAINER
+#define GLK_ALAN3_CONTAINER
+
+#include "glk/alan3/types.h"
+#include "glk/alan3/acode.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* DATA */
+extern ContainerEntry *containers; /* Container table pointer */
+
+
+/* FUNCTIONS */
+extern int containerSize(int container, ATrans trans);
+extern bool passesContainerLimits(Aint container, Aint addedInstance);
+extern void describeContainer(int container);
+extern void list(int cnt);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/current.cpp b/engines/glk/alan3/current.cpp
new file mode 100644
index 0000000..7c2dfe2
--- /dev/null
+++ b/engines/glk/alan3/current.cpp
@@ -0,0 +1,33 @@
+/* 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/alan3/current.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+CurVars current;
+bool gameStateChanged = FALSE;
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/current.h b/engines/glk/alan3/current.h
new file mode 100644
index 0000000..3939816
--- /dev/null
+++ b/engines/glk/alan3/current.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_CURRENT
+#define GLK_ALAN3_CURRENT
+
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* TYPES */
+struct CurVars {
+    int syntax,
+        verb,
+        location,
+        actor,
+        instance,
+        tick,
+        score,
+        visits,
+        sourceLine,
+        sourceFile;
+    bool meta;
+};
+
+/* DATA */
+extern CurVars current;
+extern bool gameStateChanged;
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
new file mode 100644
index 0000000..f368617
--- /dev/null
+++ b/engines/glk/alan3/debug.cpp
@@ -0,0 +1,1129 @@
+/* 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/alan3/debug.h"
+#include "glk/alan3/alan3.h"
+#include "glk/alan3/class.h"
+#include "glk/alan3/sysdep.h"
+#include "glk/alan3/alan_version.h"
+#include "glk/alan3/compatibility.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/event.h"
+#include "glk/alan3/exe.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/readline.h"
+#include "glk/alan3/sysdep.h"
+#include "glk/alan3/utils.h"
+#include "glk/streams.h"
+
+namespace Glk {
+namespace Alan3 {
+
+#define BREAKPOINTMAX 50
+
+
+/* PUBLIC: */
+int breakpointCount = 0;
+Breakpoint breakpoint[BREAKPOINTMAX];
+
+#define debugPrefix "adbg: "
+
+/*----------------------------------------------------------------------*/
+static void showAttributes(AttributeEntry *attributes)
+{
+    AttributeEntry *at;
+    int i;
+    char str[80];
+
+    if (attributes == 0)
+        return;
+
+    i = 1;
+    for (at = attributes; !isEndOfArray(at); at++) {
+        sprintf(str, "$i$t%s[%d] = %d", (char *) pointerTo(at->id), at->code, (int)at->value);
+#if ISO == 0
+        fromIso(str, str);
+#endif
+        output(str);
+        i++;
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showContents(int cnt)
+{
+    int i;
+    char str[80];
+    Abool found = FALSE;
+
+    output("$iContains:");
+    for (i = 1; i <= header->instanceMax; i++) {
+        if (isIn(i, cnt, DIRECT)) { /* Yes, it's directly in this container */
+            if (!found)
+                found = TRUE;
+            output("$i$t");
+            say(i);
+            sprintf(str, "[%d] ", i);
+            output(str);
+        }
+    }
+    if (!found)
+        output("nothing");
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *idOfInstance(int instance) {
+    int base = header->instanceTableAddress+
+        header->instanceMax*sizeof(InstanceEntry)/sizeof(Aword)+1;
+    return (char *)&memory[memory[base+instance-1]];
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayInstanceNumberAndName(int ins) {
+    char buf[1000];
+
+    sprintf(buf, "[%d] %s (\"$$", ins, idOfInstance(ins));
+    output(buf);
+    say(ins);
+    output("$$\")");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayLocationOfInstance(int ins, char *prefix) {
+    if (admin[ins].location == 0)
+        return;
+    else {
+        output(prefix);
+        if (isALocation(admin[ins].location)) {
+            output("at");
+            sayInstanceNumberAndName(admin[ins].location);
+            sayLocationOfInstance(admin[ins].location, prefix);
+        } else if (isAContainer(admin[ins].location)) {
+            if (isAObject(admin[ins].location))
+                output("in");
+            else if (isAActor(admin[ins].location))
+                output("carried by");
+            sayInstanceNumberAndName(admin[ins].location);
+            sayLocationOfInstance(admin[ins].location, prefix);
+        } else
+            output("Illegal location!");
+    }
+}
+
+/*----------------------------------------------------------------------*/
+static void listInstance(int ins) {
+    output("$i");
+    sayInstanceNumberAndName(ins);
+    if (instances[ins].container)
+        output("(container)");
+    sayLocationOfInstance(ins, ", ");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listInstances(char *pattern)
+{
+    int ins;
+    bool found = FALSE;
+
+    for (ins = 1; ins <= header->instanceMax; ins++) {
+        if (pattern == NULL || (pattern != NULL && match(pattern, idOfInstance(ins)))) {
+            if (!found) {
+                output("Instances:");
+                found = TRUE;
+            }
+            listInstance(ins);
+        }
+    }
+    if (pattern != NULL && !found)
+        output("No instances matched the pattern.");
+}
+
+/*----------------------------------------------------------------------*/
+static void showInstance(int ins)
+{
+    char str[80];
+
+    if (ins > header->instanceMax || ins < 1) {
+        sprintf(str, "Instance index %d is out of range.", ins);
+        output(str);
+        return;
+    }
+
+    output("The");
+    sayInstanceNumberAndName(ins);
+    if (instances[ins].parent) {
+        sprintf(str, "Isa %s[%d]", idOfClass(instances[ins].parent), instances[ins].parent);
+        output(str);
+    }
+
+    if (!isA(ins, header->locationClassId) || (isA(ins, header->locationClassId) && admin[ins].location != 0)) {
+        sprintf(str, "$iLocation:");
+        output(str);
+        needSpace = TRUE;
+        sayLocationOfInstance(ins, "");
+    }
+
+    output("$iAttributes:");
+    showAttributes(admin[ins].attributes);
+
+    if (instances[ins].container)
+        showContents(ins);
+
+    if (isA(ins, header->actorClassId)) {
+        if (admin[ins].script == 0)
+            output("$iIs idle");
+        else {
+            sprintf(str, "$iExecuting script: %d, Step: %d", admin[ins].script, admin[ins].step);
+            output(str);
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listObjects(void)
+{
+    int obj;
+
+    output("Objects:");
+    for (obj = 1; obj <= header->instanceMax; obj++)
+        if (isAObject(obj))
+            listInstance(obj);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showObject(int obj)
+{
+    char str[80];
+
+
+    if (!isAObject(obj)) {
+        sprintf(str, "Instance %d is not an object", obj);
+        output(str);
+        return;
+    }
+
+    showInstance(obj);
+
+}
+
+#ifdef UNDEF_WHEN_NEEDED
+/*----------------------------------------------------------------------*/
+static void showcnts(void)
+{
+    char str[80];
+    int cnt;
+
+    output("Containers:");
+    for (cnt = 1; cnt <= header->containerMax; cnt++) {
+        sprintf(str, "$i%3d: ", cnt);
+        output(str);
+        if (containers[cnt].owner != 0)
+            say(containers[cnt].owner);
+    }
+
+}
+
+/*----------------------------------------------------------------------*/
+static void showContainer(int cnt)
+{
+    char str[80];
+
+    if (cnt < 1 || cnt > header->containerMax) {
+        sprintf(str, "Container number out of range. Between 1 and %d, please.", header->containerMax);
+        output(str);
+        return;
+    }
+
+    sprintf(str, "Container %d :", cnt);
+    output(str);
+    if (containers[cnt].owner != 0) {
+        cnt = containers[cnt].owner;
+        say(cnt);
+        sprintf(str, "$iLocation: %d", where(cnt, TRUE));
+        output(str);
+    }
+    showContents(cnt);
+}
+#endif
+
+
+/*----------------------------------------------------------------------*/
+static int sourceFileNumber(char *fileName) {
+    SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
+    int n;
+
+    for (n = 0; *(Aword*)&entries[n] != EOF; n++) {
+        char *entryName;
+        entryName = getStringFromFile(entries[n].fpos, entries[n].len);
+        if (strcmp(entryName, fileName) == 0) return n;
+        entryName = baseNameStart(entryName);
+        if (strcmp(entryName, fileName) == 0) return n;
+    }
+    return -1;
+}
+
+
+
+/*----------------------------------------------------------------------*/
+static void printClassName(int c) {
+    output(idOfClass(c));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showClassInheritance(int c) {
+    char str[80];
+
+    if (classes[c].parent != 0) {
+        output(", Isa");
+        printClassName(classes[c].parent);
+        sprintf(str, "[%d]", classes[c].parent);
+        output(str);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showClass(int cla)
+{
+    char str[80];
+
+    if (cla < 1) {
+        sprintf(str, "Class index %d is out of range.", cla);
+        output(str);
+        return;
+    }
+
+    output("$t");
+    printClassName(cla);
+    sprintf(str, "[%d]", cla);
+    output(str);
+    showClassInheritance(cla);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listClass(int c)
+{
+    char str[80];
+
+    sprintf(str, "%3d: ", c);
+    output(str);
+    printClassName(c);
+    showClassInheritance(c);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showClassHierarchy(int thisItem, int depth)
+{
+    int i;
+    int child;
+
+    output("$i");
+    for (i=0; i < depth; i++)
+        output("$t");
+
+    listClass(thisItem);
+    for (child = 1; child <= header->classMax; child++) {
+        if (classes[child].parent == thisItem) {
+            showClassHierarchy(child, depth+1);
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listLocations(void)
+{
+    int loc;
+
+    output("Locations:");
+    for (loc = 1; loc <= header->instanceMax; loc++)
+        if (isALocation(loc))
+            listInstance(loc);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showLocation(int loc)
+{
+    char str[80];
+
+
+    if (!isALocation(loc)) {
+        sprintf(str, "Instance %d is not a location.", loc);
+        output(str);
+        return;
+    }
+
+    output("The ");
+    say(loc);
+    sprintf(str, "(%d) Isa location :", loc);
+    output(str);
+
+    output("$iAttributes =");
+    showAttributes(admin[loc].attributes);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listActors(void)
+{
+    int act;
+
+    output("Actors:");
+    for (act = 1; act <= header->instanceMax; act++)
+        if (isAActor(act))
+            listInstance(act);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showActor(int act)
+{
+    char str[80];
+
+    if (!isAActor(act)) {
+        sprintf(str, "Instance %d is not an actor.", act);
+        output(str);
+        return;
+    }
+
+    showInstance(act);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void showEvents(void)
+{
+    int event, i;
+    char str[80];
+    bool scheduled;
+
+    output("Events:");
+    for (event = 1; event <= header->eventMax; event++) {
+        sprintf(str, "$i%d [%s]:", event, (char *)pointerTo(events[event].id));
+#if ISO == 0
+        fromIso(str, str);
+#endif
+        output(str);
+        scheduled = FALSE;
+        for (i = 0; i < eventQueueTop; i++)
+            if ((scheduled = (eventQueue[i].event == event)))
+                break;
+        if (scheduled) {
+            sprintf(str, "Scheduled for +%d, at ", eventQueue[i].after);
+            output(str);
+            say(eventQueue[i].where);
+        } else
+            output("Not scheduled.");
+    }
+}
+
+
+/*======================================================================*/
+char *sourceFileName(int fileNumber) {
+    SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
+
+    return getStringFromFile(entries[fileNumber].fpos, entries[fileNumber].len);
+}
+
+
+/*======================================================================*/
+bool readLine(Common::SeekableReadStream *rs, char *line, int maxLen) {
+	if (rs->pos() < rs->size()) {
+		line[maxLen - 1] = '\0';
+
+		char c;
+		do {
+			c = rs->readByte();
+			*line++ = c;
+		} while (--maxLen > 1);
+	}
+
+	return rs->pos() < rs->size();
+}
+
+
+/*======================================================================*/
+char *readSourceLine(int file, int line) {
+    int count;
+#define SOURCELINELENGTH 1000
+    static char buffer[SOURCELINELENGTH];
+
+	frefid_t sourceFileRef = g_vm->glk_fileref_create_by_name(fileusage_TextMode, sourceFileName(file), 0);
+	strid_t sourceFile = g_vm->glk_stream_open_file(sourceFileRef, filemode_Read, 0);
+
+    if (sourceFile != NULL) {
+		for (count = 0; count < line; count++) {
+			if (!readLine(*sourceFile, buffer, SOURCELINELENGTH))
+				return NULL;
+
+			// If not read the whole line, or no newline, try to read again
+			while (strchr(buffer, '\n') == NULL) {
+				if (!readLine(*sourceFile, buffer, SOURCELINELENGTH))
+					break;
+			}
+		}
+
+		delete sourceFile;
+        return buffer;
+    }
+
+	return NULL;
+}
+
+/*======================================================================*/
+void showSourceLine(int fileNumber, int line) {
+    char *buffer = readSourceLine(fileNumber, line);
+    if (buffer != NULL) {
+        if (buffer[strlen(buffer)-1] == '\n')
+            buffer[strlen(buffer)-1] = '\0';
+        printf("<%05d>: %s", line, buffer);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listFiles() {
+    SourceFileEntry *entry;
+    int i = 0;
+    for (entry = (SourceFileEntry *)pointerTo(header->sourceFileTable); *((Aword*)entry) != EOF; entry++) {
+        printf("  %2d : %s\n", i, sourceFileName(i));
+        i++;
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listLines() {
+    SourceLineEntry *entry;
+    for (entry = (SourceLineEntry *)pointerTo(header->sourceLineTable); *((Aword*)entry) != EOF; entry++)
+        printf("  %s:%d\n", sourceFileName(entry->file), entry->line);
+}
+
+
+/*----------------------------------------------------------------------*/
+static int findSourceLineIndex(SourceLineEntry *entry, int file, int line) {
+    /* Will return index to the closest line available */
+    int i = 0;
+
+    while (!isEndOfArray(&entry[i]) && entry[i].file != file)
+        i++;
+    while (!isEndOfArray(&entry[i]) && entry[i].file == file  && entry[i].line < line)
+        i++;
+    if (isEndOfArray(entry) || entry[i].file != file)
+        return i-1;
+    else
+        return i;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void listBreakpoints() {
+    int i;
+    bool found = FALSE;
+
+    for (i = 0; i < BREAKPOINTMAX; i++)
+        if (breakpoint[i].line != 0) {
+            if (!found)
+                printf("Breakpoints set:\n");
+            found = TRUE;
+            printf("    %s:%d\n", sourceFileName(breakpoint[i].file), breakpoint[i].line);
+        }
+    if (!found)
+        printf("No breakpoints set\n");
+}
+
+
+/*======================================================================*/
+int breakpointIndex(int file, int line) {
+    int i;
+
+    for (i = 0; i < BREAKPOINTMAX; i++)
+        if (breakpoint[i].line == line && breakpoint[i].file == file)
+            return i;
+    return -1;
+}
+
+
+/*----------------------------------------------------------------------*/
+static int availableBreakpointSlot() {
+    int i;
+
+    for (i = 0; i < BREAKPOINTMAX; i++)
+        if (breakpoint[i].line == 0)
+            return i;
+    return -1;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void setBreakpoint(int file, int line) {
+    int i = breakpointIndex(file, line);
+
+    if (i != -1)
+        printf("Breakpoint already set at %s:%d\n", sourceFileName(file), line);
+    else {
+        i = availableBreakpointSlot();
+        if (i == -1)
+            printf("No room for more breakpoints. Delete one first.\n");
+        else {
+            int lineIndex = findSourceLineIndex((SourceLineEntry *)pointerTo(header->sourceLineTable), file, line);
+            SourceLineEntry *entry = (SourceLineEntry *)pointerTo(header->sourceLineTable);
+            char leadingText[100] = "Breakpoint";
+            if (entry[lineIndex].file == EOF) {
+                printf("Line %d not available\n", line);
+            } else {
+                if (entry[lineIndex].line != line)
+                    sprintf(leadingText, "Line %d not available, breakpoint instead", line);
+                breakpoint[i].file = entry[lineIndex].file;
+                breakpoint[i].line = entry[lineIndex].line;
+                printf("%s set at %s:%d\n", leadingText, sourceFileName(entry[lineIndex].file), entry[lineIndex].line);
+                showSourceLine(entry[lineIndex].file, entry[lineIndex].line);
+                printf("\n");
+            }
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void deleteBreakpoint(int line, int file) {
+    int i = breakpointIndex(file, line);
+
+    if (i == -1)
+        printf("No breakpoint set at %s:%d\n", sourceFileName(file), line);
+    else {
+        breakpoint[i].line = 0;
+        printf("Breakpoint at %s:%d deleted\n", sourceFileName(file), line);
+    }
+}
+
+
+
+static bool saved_traceSection, saved_traceInstruction, saved_capitilize, saved_tracePush, saved_traceStack, saved_traceSource;
+static int loc;
+
+/*======================================================================*/
+void saveInfo(void)
+{
+    /* Save some important things */
+    saved_capitilize = capitalize; capitalize = FALSE;
+    saved_traceSection = traceSectionOption; traceSectionOption = FALSE;
+    saved_traceSource = traceSourceOption; traceSourceOption = FALSE;
+    saved_traceInstruction = traceInstructionOption; traceInstructionOption = FALSE;
+    saved_tracePush = tracePushOption; tracePushOption = FALSE;
+    saved_traceStack = traceStackOption; traceStackOption = FALSE;
+    loc = current.location; current.location = where(HERO, DIRECT);
+}
+
+
+/*======================================================================*/
+void restoreInfo(void)
+{
+    /* Restore! */
+    capitalize = saved_capitilize;
+    traceSectionOption = saved_traceSection;
+    traceInstructionOption = saved_traceInstruction;
+    traceSourceOption = saved_traceSource;
+    tracePushOption = saved_tracePush;
+    traceStackOption = saved_traceStack;
+    current.location = loc;
+}
+
+#define HELP_COMMAND 'H'
+#define QUIT_COMMAND 'Q'
+#define EXIT_COMMAND 'X'
+#define GO_COMMAND 'G'
+#define FILES_COMMAND 'F'
+#define INSTANCES_COMMAND 'I'
+#define CLASSES_COMMAND 'C'
+#define OBJECTS_COMMAND 'O'
+#define ACTORS_COMMAND 'A'
+#define LOCATIONS_COMMAND 'L'
+#define EVENTS_COMMAND 'E'
+#define BREAK_COMMAND 'B'
+#define DELETE_COMMAND 'D'
+#define TRACE_COMMAND 'R'
+#define SECTION_TRACE_COMMAND 'T'
+#define INSTRUCTION_TRACE_COMMAND 'S'
+#define NEXT_COMMAND 'N'
+#define UNKNOWN_COMMAND '?'
+#define AMBIGUOUS_COMMAND '-'
+#define TRACE_SOURCE_COMMAND 's'
+#define TRACE_SECTION_COMMAND 'e'
+#define TRACE_INSTRUCTION_COMMAND 'i'
+#define TRACE_PUSH_COMMAND 'p'
+#define TRACE_STACK_COMMAND 't'
+
+typedef struct DebugParseEntry {
+    char *command;
+    char *parameter;
+    char code;
+    char *helpText;
+} DebugParseEntry;
+
+static DebugParseEntry commandEntries[] = {
+    {"help", "", HELP_COMMAND, "this help"},
+    {"?", "", HELP_COMMAND, "d:o"},
+    {"break", "[[file:]n]", BREAK_COMMAND, "set breakpoint at source line [n] (optionally in [file])"},
+    {"delete", "[[file:]n]", DELETE_COMMAND, "delete breakpoint at source line [n] (optionally in [file])"},
+    {"files", "", FILES_COMMAND, "list source files"},
+    {"events", "", EVENTS_COMMAND, "list events"},
+    {"classes", "", CLASSES_COMMAND, "list class hierarchy"},
+    {"instances", "[n]", INSTANCES_COMMAND, "list instance(s), all, wildcard, number or name"},
+    {"objects", "[n]", OBJECTS_COMMAND, "list instance(s) that are objects"},
+    {"actors", "[n]", ACTORS_COMMAND, "list instance(s) that are actors"},
+    {"locations", "[n]", LOCATIONS_COMMAND, "list instances that are locations"},
+    {"trace", "('source'|'section'|'instruction'|'push'|'stack')", TRACE_COMMAND, "toggle various traces"},
+    {"next", "", NEXT_COMMAND, "run game and stop at next source line"},
+    {"go", "", GO_COMMAND, "go another player turn"},
+    {"exit", "", EXIT_COMMAND, "exit to game, enter 'debug' to get back"},
+    {"x", "", EXIT_COMMAND, "d:o"},
+    {"quit", "", QUIT_COMMAND, "quit game"},
+    {NULL, NULL}
+};
+
+static DebugParseEntry traceSubcommand[] = {
+    {"source", "", TRACE_SOURCE_COMMAND, ""},
+    {"section", "", TRACE_SECTION_COMMAND, ""},
+    {"instructions", "", TRACE_INSTRUCTION_COMMAND, ""},
+    {"pushs", "", TRACE_PUSH_COMMAND, ""},
+    {"stacks", "", TRACE_STACK_COMMAND, ""},
+    {NULL, NULL}
+};
+
+
+static char *spaces(int length) {
+    static char buf[200];
+    int i;
+
+    for (i = 0; i<length; i++)
+        buf[i] = ' ';
+    buf[i] = '\0';
+    return buf;
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *padding(DebugParseEntry *entry, int maxLength) {
+    return spaces(maxLength-strlen(entry->command)-strlen(entry->parameter));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleHelpCommand() {
+    if (!regressionTestOption)
+        output(alan.longHeader);
+
+    DebugParseEntry *entry = commandEntries;
+
+    int maxLength = 0;
+    for (entry = commandEntries; entry->command != NULL; entry++) {
+        if (strlen(entry->command)+strlen(entry->parameter) > maxLength)
+            maxLength = strlen(entry->command)+strlen(entry->parameter);
+    }
+
+    output("$nADBG Commands (can be abbreviated):");
+    for (entry = commandEntries; entry->command != NULL; entry++) {
+        char buf[200];
+        sprintf(buf, "$i%s %s %s$n$t$t-- %s", entry->command, entry->parameter, padding(entry, maxLength), entry->helpText);
+        output(buf);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static DebugParseEntry *findEntry(char *command, DebugParseEntry *entry) {
+    while (entry->command != NULL) {
+        if (strncasecmp(command, entry->command, strlen(command)) == 0)
+            return entry;
+        entry++;
+    }
+    return NULL;
+}
+
+
+/*----------------------------------------------------------------------*/
+static char parseDebugCommand(char *command) {
+    DebugParseEntry *entry = findEntry(command, commandEntries);
+    if (entry != NULL) {
+        if (strlen(command) < strlen(entry->command)) {
+            /* See if there are any more partial matches */
+            if (findEntry(command, entry+1) != NULL)
+                /* TODO: we should list the possible matches somehow */
+                return AMBIGUOUS_COMMAND;
+        }
+        return entry->code;
+    } else
+        return UNKNOWN_COMMAND;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void readCommand(char buf[]) {
+    char c;
+
+    capitalize = FALSE;
+    if (anyOutput) newline();
+    do {
+        output("adbg> ");
+
+#ifdef USE_READLINE
+        if (!readline(buf)) {
+#else
+        if (fgets(buf, 255, stdin) == NULL) {
+#endif
+            newline();
+            quitGame();
+        }
+        lin = 1;
+        c = buf[0];
+    } while (c == '\0');
+}
+
+
+/*----------------------------------------------------------------------*/
+static void displaySourceLocation(int line, int fileNumber) {
+    char *cause;
+    if (anyOutput) newline();
+    if (breakpointIndex(fileNumber, line) != -1)
+        cause = "Breakpoint hit at";
+    else
+        cause = "Stepping to";
+    printf("%s %s %s:%d\n", debugPrefix, cause, sourceFileName(fileNumber), line);
+    showSourceLine(fileNumber, line);
+    printf("\n");
+    anyOutput = FALSE;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void toggleSectionTrace() {
+    if ((saved_traceSection = !saved_traceSection))
+        printf("Section trace on.");
+    else
+        printf("Section trace off.");
+}
+
+/*----------------------------------------------------------------------*/
+static void toggleInstructionTrace() {
+    if ((saved_traceInstruction = !saved_traceInstruction))
+        printf("Single instruction trace on.");
+    else
+        printf("Single instruction trace off.");
+}
+
+/*----------------------------------------------------------------------*/
+static void toggleSourceTrace() {
+    if ((saved_traceSource = !saved_traceSource))
+        printf("Source code trace on.");
+    else
+        printf("Source code trace off.");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void togglePushTrace() {
+    if ((saved_tracePush = !saved_tracePush))
+        printf("Stack Push trace on.");
+    else
+        printf("Stack Push trace off.");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void toggleStackTrace() {
+    if ((saved_traceStack = !saved_traceStack))
+        printf("Full stack trace on.");
+    else
+        printf("Full stack trace off.");
+}
+
+
+/*----------------------------------------------------------------------*/
+static int parseTraceCommand() {
+    char *subcommand = strtok(NULL, "");
+    DebugParseEntry *entry;
+    if (subcommand == 0)
+        return UNKNOWN_COMMAND;
+    else {
+        entry = findEntry(subcommand, traceSubcommand);
+        if (entry != NULL) {
+            if (strlen(subcommand) < strlen(entry->command)) {
+                if (findEntry(subcommand, entry+1) != NULL)
+                    return AMBIGUOUS_COMMAND;
+            }
+            return entry->code;
+        } else
+            return UNKNOWN_COMMAND;
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *printTraceState(bool state) {
+    if (state)
+        return "on  - Traces";
+    else
+        return "off - Doesn't trace";
+}
+
+/*----------------------------------------------------------------------*/
+static void printTrace(void) {
+    printf("Trace section     : %s entry to every section (check, description, event, actor, ...)\n", printTraceState(saved_traceSection));
+    printf("Trace source      : %s every source line executed\n", printTraceState(saved_traceSource));
+    printf("Trace instruction : %s every Amachine instruction executed\n", printTraceState(saved_traceInstruction));
+    printf("Trace push        : %s every push onto the Amachine stack\n", printTraceState(saved_tracePush));
+    printf("Trace stack       : %s the complete stack every time\n", printTraceState(saved_traceStack));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleTraceCommand() {
+    char subcommand = parseTraceCommand();
+
+    switch (subcommand) {
+    case TRACE_SECTION_COMMAND: toggleSectionTrace(); break;
+    case TRACE_SOURCE_COMMAND: toggleSourceTrace(); break;
+    case TRACE_INSTRUCTION_COMMAND: toggleInstructionTrace(); break;
+    case TRACE_PUSH_COMMAND: togglePushTrace(); break;
+    case TRACE_STACK_COMMAND: toggleStackTrace(); break;
+    case AMBIGUOUS_COMMAND: output("Ambiguous Trace subcommand abbreviation. ? for help."); break;
+    default: printTrace();
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleBreakCommand(int fileNumber) {
+    char *parameter = strtok(NULL, ":");
+    if (parameter != NULL && isalpha((int)parameter[0])) {
+        fileNumber = sourceFileNumber(parameter);
+        if (fileNumber == -1) {
+            printf("No such file: '%s'\n", parameter);
+            return;
+        }
+        parameter = strtok(NULL, "");
+    }
+    if (parameter == NULL)
+        listBreakpoints();
+    else
+        setBreakpoint(fileNumber, atoi(parameter));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleDeleteCommand(bool calledFromBreakpoint, int line, int fileNumber) {
+    char *parameter = strtok(NULL, "");
+    if (parameter == NULL) {
+        if (calledFromBreakpoint)
+            deleteBreakpoint(line, fileNumber);
+        else
+            printf("No current breakpoint to delete\n");
+    } else
+        deleteBreakpoint(atoi(parameter), fileNumber);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleNextCommand(bool calledFromBreakpoint) {
+    stopAtNextLine = TRUE;
+    debugOption = FALSE;
+    if (!calledFromBreakpoint)
+        current.sourceLine = 0;
+    restoreInfo();
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleLocationsCommand() {
+    char *parameter = strtok(NULL, "");
+    if (parameter == 0)
+        listLocations();
+    else
+        showLocation(atoi(parameter));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleActorsCommand() {
+    char *parameter = strtok(NULL, "");
+    if (parameter == NULL)
+        listActors();
+    else
+        showActor(atoi(parameter));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleClassesCommand() {
+    char *parameter = strtok(NULL, "");
+    if (parameter == NULL || strchr(parameter, '*') != 0) {
+        output("Classes:");
+        showClassHierarchy(1, 0);
+        listInstances(parameter);
+    } else if (isdigit((int)parameter[0]))
+        showClass(atoi(parameter));
+    else {
+        printf("You have to give a class index to display. You can't use names (yet).");
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleObjectsCommand() {
+    char *parameter = strtok(NULL, "");
+    if (parameter == NULL)
+        listObjects();
+    else
+        showObject(atoi(parameter));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void handleInstancesCommand() {
+    char *parameter = strtok(NULL, "");
+    int i;
+
+    if (parameter == NULL || strchr(parameter, '*') != 0)
+        listInstances(parameter);
+    else if (isdigit((int)parameter[0]))
+        showInstance(atoi(parameter));
+    else {
+        for (i = 1; i<header->instanceMax; i++)
+            if (strcmp(parameter, idOfInstance(i)) == 0) {
+                showInstance(i);
+                return;
+            }
+        printf("No instance named '%s'.", parameter);
+    }
+}
+
+/*----------------------------------------------------------------------*/
+static bool exactSameVersion() {
+    return header->version[3] == alan.version.version
+        && header->version[2] == alan.version.revision
+        && header->version[1] == alan.version.correction
+        && header->version[0] == alan.version.state[0];
+}
+
+
+/*======================================================================*/
+void debug(bool calledFromBreakpoint, int line, int fileNumber)
+{
+    static bool warned = FALSE;
+
+    saveInfo();
+
+#ifdef HAVE_GLK
+    g_vm->glk_set_style(style_Preformatted);
+#endif
+
+    if (calledFromBreakpoint)
+        displaySourceLocation(line, fileNumber);
+    else {
+        if (!exactSameVersion() && !warned && !regressionTestOption) {
+            printf("<WARNING: You are debugging a game which has version %s.>\n",
+                   decodedGameVersion(header->version));
+            printf("<That is not exactly the same as this interpreter (%s).>\n", alan.version.string);
+            printf("<This might cause a lot of trouble. Cross your fingers...>\n");
+            warned = TRUE;
+        }
+    }
+
+    while (TRUE) {
+
+        char commandLine[200];
+        readCommand(commandLine);
+        char *command = strtok(commandLine, " ");
+        char commandCode = parseDebugCommand(command);
+
+        switch (commandCode) {
+        case AMBIGUOUS_COMMAND: output("Ambiguous ADBG command abbreviation. ? for help."); break;
+        case ACTORS_COMMAND: handleActorsCommand(); break;
+        case BREAK_COMMAND: handleBreakCommand(fileNumber); break;
+        case CLASSES_COMMAND: handleClassesCommand(); break;
+        case DELETE_COMMAND: handleDeleteCommand(calledFromBreakpoint, line, fileNumber); break;
+        case EVENTS_COMMAND: showEvents(); break;
+        case EXIT_COMMAND: debugOption = FALSE; restoreInfo(); goto exit_debug;
+        case FILES_COMMAND: listFiles(); break;
+        case GO_COMMAND: restoreInfo(); goto exit_debug;
+        case HELP_COMMAND: handleHelpCommand(); break;
+        case INSTANCES_COMMAND: handleInstancesCommand(); break;
+        case TRACE_COMMAND: handleTraceCommand(); break;
+        case INSTRUCTION_TRACE_COMMAND: toggleInstructionTrace(); break;
+        case LOCATIONS_COMMAND: handleLocationsCommand(); break;
+        case NEXT_COMMAND: handleNextCommand(calledFromBreakpoint); goto exit_debug;
+        case OBJECTS_COMMAND: handleObjectsCommand(); break;
+        case QUIT_COMMAND: terminate(0); break;
+        case SECTION_TRACE_COMMAND: toggleSectionTrace(); break;
+        default: output("Unknown ADBG command. ? for help."); break;
+        }
+    }
+
+ exit_debug:
+#ifdef HAVE_GLK
+	g_vm->glk_set_style(style_Normal);
+#endif
+    ;
+}
+
+
+/*======================================================================*/
+void traceSay(int item)
+{
+    /*
+      Say something, but make sure we don't disturb anything and that it is
+      shown to the player. Needed for tracing. During debugging things are
+      set up to avoid this problem.
+    */
+
+    saveInfo();
+    needSpace = FALSE;
+    col = 1;
+    if (item == 0)
+        printf("$null$");
+    else
+        say(item);
+    needSpace = FALSE;
+    col = 1;
+    restoreInfo();
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/debug.h b/engines/glk/alan3/debug.h
new file mode 100644
index 0000000..3bebe27
--- /dev/null
+++ b/engines/glk/alan3/debug.h
@@ -0,0 +1,58 @@
+/* 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_ALAN3_DEBUG
+#define GLK_ALAN3_DEBUG
+
+/* Header file for debug handler in Alan interpreter */
+
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* Types: */
+
+struct Breakpoint {
+  int line;
+  int file;
+};
+
+
+/* Data: */
+extern int breakpointCount;
+extern Breakpoint breakpoint[];
+
+/* Functions: */
+extern void saveInfo(void);
+extern void restoreInfo(void);
+extern int breakpointIndex(int file, int line);
+extern char *sourceFileName(int file);
+extern char *readSourceLine(int file, int line);
+extern void showSourceLine(int fileNumber, int line);
+extern void debug(bool calledFromBreakpoint, int line, int fileNumber);
+extern void traceSay(int item);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/decode.cpp b/engines/glk/alan3/decode.cpp
new file mode 100644
index 0000000..c06d19a
--- /dev/null
+++ b/engines/glk/alan3/decode.cpp
@@ -0,0 +1,182 @@
+/* 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/alan3/decode.h"
+#include "glk/alan3/acode.h"
+#include "glk/alan3/syserr.h"
+#include "glk/alan3/exe.h"
+#include "glk/alan3/memory.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+Aword *freq;            /* Cumulative character frequencies */
+
+
+/* PRIVATE DATA */
+/* Bit output */
+static int decodeBuffer;	/* Bits to be input */
+static int bitsToGo;		/* Bits still in buffer */
+static int garbageBits;		/* Bits past EOF */
+
+
+static int inputBit(void)
+{
+  int bit;
+
+  /* More bits available ? */
+  if (!bitsToGo) {
+	/* No, so get more */
+	 decodeBuffer = (textFile->pos() >= textFile->size()) ? EOF : textFile->readByte();
+    if (decodeBuffer == EOF) {
+      garbageBits++;
+      if (garbageBits > VALUEBITS-2)
+	syserr("Error in encoded data file.");
+    } else
+      bitsToGo = 8;		/* Another Char, 8 new bits */
+  }
+  bit = decodeBuffer&1;		/* Get next bit */
+  decodeBuffer = decodeBuffer>>1; /* and remove it */
+  bitsToGo--;
+  return bit;
+}
+
+
+/* Current state of decoding */
+
+static CodeValue value;			/* Currently seen code value */
+static CodeValue low, high;		/* Current code region */
+
+
+void startDecoding(void)
+{
+  int i;
+
+  bitsToGo = 0;
+  garbageBits = 0;
+
+  value = 0;
+  for (i = 0; i < VALUEBITS; i++)
+    value = 2*value + inputBit();
+  low = 0;
+  high = TOPVALUE;
+}
+
+
+int decodeChar(void)
+{
+  long range;
+  int f;
+  int symbol;
+
+  range = (long)(high-low) + 1;
+  f = (((long)(value-low)+1)*freq[0]-1)/range;
+
+  /* Find the symbol */
+  for (symbol = 1; freq[symbol] > f; symbol++);
+
+  high = low + range*freq[symbol-1]/freq[0]-1;
+  low = low + range*freq[symbol]/freq[0];
+
+  for (;;) {
+    if (high < HALF)
+      ;
+    else if (low >= HALF) {
+      value = value - HALF;
+      low = low - HALF;
+      high = high - HALF;
+    } else if (low >= ONEQUARTER && high < THREEQUARTER) {
+      value = value - ONEQUARTER;
+      low = low - ONEQUARTER;
+      high = high - ONEQUARTER;
+    } else
+      break;
+
+    /* Scale up the range */
+    low = 2*low;
+    high = 2*high+1;
+    value = 2*value + inputBit();
+  }
+  return symbol-1;
+}
+
+
+
+/* Structure for saved decode info */
+struct DecodeInfo {
+  long fpos;
+  int buffer;
+  int bits;
+  CodeValue value;
+  CodeValue high;
+  CodeValue low;
+};
+
+
+/*======================================================================
+
+  pushDecode()
+
+  Save so much info about the decoding process so it is possible to
+  restore and continue later.
+
+ */
+void *pushDecode(void)
+{
+  DecodeInfo *info;
+
+  info = (DecodeInfo *)allocate(sizeof(DecodeInfo));
+  info->fpos = textFile->pos();
+  info->buffer = decodeBuffer;
+  info->bits = bitsToGo;
+  info->value = value;
+  info->high = high;
+  info->low = low;
+  return(info);
+}
+
+
+/*======================================================================
+
+  popDecode()
+
+  Restore enough info about the decoding process so it is possible to
+  continue after having decoded something else.
+
+ */
+void popDecode(void *i)
+{
+  DecodeInfo *info = (DecodeInfo *) i;
+
+  textFile->seek(info->fpos);
+  decodeBuffer = info->buffer;
+  bitsToGo = info->bits;
+  value = info->value;
+  high = info->high;
+  low = info->low;
+
+  free(info);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/decode.h b/engines/glk/alan3/decode.h
new file mode 100644
index 0000000..c239d85
--- /dev/null
+++ b/engines/glk/alan3/decode.h
@@ -0,0 +1,46 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_DECODE
+#define GLK_ALAN3_DECODE
+
+/* Arithmetic decoding module in Arun */
+
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* DATA */
+extern Aword *freq;     /* Cumulated character frequencies for text decoding */
+
+/* FUNCTIONS */
+
+extern void startDecoding(void);
+extern int decodeChar(void);
+extern void *pushDecode(void);
+extern void popDecode(void *info);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/dictionary.cpp b/engines/glk/alan3/dictionary.cpp
new file mode 100644
index 0000000..375b7f7
--- /dev/null
+++ b/engines/glk/alan3/dictionary.cpp
@@ -0,0 +1,135 @@
+/* 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/alan3/dictionary.h"
+#include "glk/alan3/word.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+DictionaryEntry *dictionary;    /* Dictionary pointer */
+int dictionarySize;
+int conjWord;           /* First conjunction in dictionary, for ',' */
+
+
+
+/* Word class query methods, move to Word.c */
+/* Word classes are numbers but in the dictionary they are generated as bits */
+static bool isVerb(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&VERB_BIT)!=0;
+}
+
+bool isVerbWord(int wordIndex) {
+    return isVerb(playerWords[wordIndex].code);
+}
+
+bool isConjunction(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&CONJUNCTION_BIT)!=0;
+}
+
+bool isConjunctionWord(int wordIndex) {
+    return isConjunction(playerWords[wordIndex].code);
+}
+
+static bool isExcept(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&EXCEPT_BIT)!=0;
+}
+
+bool isExceptWord(int wordIndex) {
+    return isExcept(playerWords[wordIndex].code);
+}
+
+static bool isThem(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&THEM_BIT)!=0;
+}
+
+bool isThemWord(int wordIndex) {
+    return isThem(playerWords[wordIndex].code);
+}
+
+static bool isIt(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&IT_BIT)!=0;
+}
+
+bool isItWord(int wordIndex) {
+    return isIt(playerWords[wordIndex].code);
+}
+
+static bool isNoun(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&NOUN_BIT)!=0;
+}
+
+bool isNounWord(int wordIndex) {
+    return isNoun(playerWords[wordIndex].code);
+}
+
+static bool isAdjective(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&ADJECTIVE_BIT)!=0;
+}
+
+bool isAdjectiveWord(int wordIndex) {
+    return isAdjective(playerWords[wordIndex].code);
+}
+
+static bool isPreposition(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&PREPOSITION_BIT)!=0;
+}
+
+bool isPrepositionWord(int wordIndex) {
+    return isPreposition(playerWords[wordIndex].code);
+}
+
+bool isAll(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&ALL_BIT)!=0;
+}
+
+bool isAllWord(int wordIndex) {
+    return isAll(playerWords[wordIndex].code);
+}
+
+static bool isDir(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&DIRECTION_BIT)!=0;
+}
+
+bool isDirectionWord(int wordIndex) {
+    return isDir(playerWords[wordIndex].code);
+}
+
+bool isNoise(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&NOISE_BIT)!=0;
+}
+
+bool isPronoun(int wordCode) {
+  return wordCode < dictionarySize && (dictionary[wordCode].classBits&PRONOUN_BIT)!=0;
+}
+
+bool isPronounWord(int wordIndex) {
+    return isPronoun(playerWords[wordIndex].code);
+}
+
+bool isLiteralWord(int wordIndex) {
+  return playerWords[wordIndex].code >= dictionarySize;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/dictionary.h b/engines/glk/alan3/dictionary.h
new file mode 100644
index 0000000..1f5f5f9
--- /dev/null
+++ b/engines/glk/alan3/dictionary.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_DICTIONARY
+#define GLK_ALAN3_DICTIONARY
+
+#include "glk/alan3/acode.h"
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* DATA */
+extern DictionaryEntry *dictionary;
+extern int dictionarySize;
+extern int conjWord;        /* First conjunction in dictionary */
+
+
+/* FUNCTIONS */
+extern bool isVerbWord(int wordIndex);
+extern bool isConjunctionWord(int wordIndex);
+extern bool isExceptWord(int wordIndex);
+extern bool isThemWord(int wordIndex);
+extern bool isItWord(int wordIndex);
+extern bool isNounWord(int wordIndex);
+extern bool isAdjectiveWord(int wordIndex);
+extern bool isPrepositionWord(int wordIndex);
+extern bool isAllWord(int wordIndex);
+extern bool isDirectionWord(int wordIndex);
+extern bool isPronounWord(int wordIndex);
+extern bool isLiteralWord(int wordIndex);
+
+extern bool isConjunction(int wordCode);
+extern bool isAll(int wordCode);
+extern bool isNoise(int wordCode);
+extern bool isPronoun(int wordCode);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/event.cpp b/engines/glk/alan3/event.cpp
new file mode 100644
index 0000000..ce866be
--- /dev/null
+++ b/engines/glk/alan3/event.cpp
@@ -0,0 +1,35 @@
+/* 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/alan3/event.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+int eventQueueSize = 0;
+EventQueueEntry *eventQueue = NULL;
+int eventQueueTop = 0;
+EventEntry *events;
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/event.h b/engines/glk/alan3/event.h
new file mode 100644
index 0000000..4855548
--- /dev/null
+++ b/engines/glk/alan3/event.h
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_EVENT
+#define GLK_ALAN3_EVENT
+
+#include "glk/alan3/acode.h"
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* TYPES */
+typedef struct EventQueueEntry { /* EVENT QUEUE ENTRIES */
+  int after;
+  int event;
+  int where;
+} EventQueueEntry;
+
+
+/* DATA */
+/* Event queue */
+extern int eventQueueSize;
+extern EventQueueEntry *eventQueue;
+extern int eventQueueTop;       /* Event queue top pointer */
+extern EventEntry *events;  /* Event table pointer */
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
new file mode 100644
index 0000000..eb01870
--- /dev/null
+++ b/engines/glk/alan3/exe.cpp
@@ -0,0 +1,753 @@
+/* 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/alan3/exe.h"
+#include "glk/alan3/actor.h"
+#include "glk/alan3/alan3.h"
+#include "glk/alan3/args.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/decode.h"
+#include "glk/alan3/event.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/readline.h"
+#include "glk/alan3/save.h"
+#include "glk/alan3/score.h"
+#include "glk/alan3/state.h"
+#include "glk/alan3/syserr.h"
+#include "glk/alan3/sysdep.h"
+#include "glk/alan3/term.h"
+#include "glk/alan3/types.h"
+#include "glk/alan3/utils.h"
+#include "glk/alan3/word.h"
+#include "common/stream.h"
+#include "common/textconsole.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+
+Common::SeekableReadStream *textFile;
+
+/* Long jump buffers */
+// TODO move to longjump.c? or error.c, and abstract them into functions?
+//jmp_buf restartLabel;       /* Restart long jump return point */
+//jmp_buf returnLabel;        /* Error (or undo) long jump return point */
+//jmp_buf forfeitLabel;       /* Player forfeit by an empty command */
+
+
+/* PRIVATE CONSTANTS */
+
+#define WIDTH 80
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static char logFileName[256] = "";
+
+/*======================================================================*/
+void setStyle(int style)
+{
+#ifdef HAVE_GLK
+    switch (style) {
+    case NORMAL_STYLE: g_vm->glk_set_style(style_Normal); break;
+    case EMPHASIZED_STYLE: g_vm->glk_set_style(style_Emphasized); break;
+    case PREFORMATTED_STYLE: g_vm->glk_set_style(style_Preformatted); break;
+    case ALERT_STYLE: g_vm->glk_set_style(style_Alert); break;
+    case QUOTE_STYLE: g_vm->glk_set_style(style_BlockQuote); break;
+    }
+#endif
+}
+
+/*======================================================================*/
+void print(Aword fpos, Aword len)
+{
+    char str[2*WIDTH];            /* String buffer */
+    int outlen = 0;               /* Current output length */
+    int ch = 0;
+    int i;
+    long savfp = 0;     /* Temporary saved text file position */
+    static bool printFlag = FALSE; /* Printing already? */
+    bool savedPrintFlag = printFlag;
+    void *info = NULL;      /* Saved decoding info */
+
+
+    if (len == 0) return;
+
+    if (isHere(HERO, /*TRUE*/ DIRECT)) {   /* Check if the player will see it */
+        if (printFlag) {            /* Already printing? */
+            /* Save current text file position and/or decoding info */
+            if (header->pack)
+                info = pushDecode();
+            else
+                savfp = textFile->pos();
+        }
+        printFlag = TRUE;           /* We're printing now! */
+
+        /* Position to start of text */
+		textFile->seek(fpos+header->stringOffset);
+
+        if (header->pack)
+            startDecoding();
+        for (outlen = 0; outlen != len; outlen = outlen + strlen(str)) {
+            /* Fill the buffer from the beginning */
+            for (i = 0; i <= WIDTH || (i > WIDTH && ch != ' '); i++) {
+                if (outlen + i == len)  /* No more characters? */
+                    break;
+				if (header->pack)
+					ch = decodeChar();
+				else
+					ch = textFile->readByte();
+
+				str[i] = ch;
+				if (textFile->pos() >= textFile->size())      /* Or end of text? */
+                    break;
+            }
+            str[i] = '\0';
+#if ISO == 0
+            fromIso(str, str);
+#endif
+            output(str);
+        }
+
+        /* And restore */
+        printFlag = savedPrintFlag;
+        if (printFlag) {
+            if (header->pack)
+                popDecode(info);
+            else
+                textFile->seek(savfp);
+        }
+    }
+}
+
+
+/*======================================================================*/
+void sys(Aword fpos, Aword len)
+{
+	::error("sys calls are unsupported");
+}
+
+
+/*======================================================================*/
+char *getStringFromFile(Aword fpos, Aword len)
+{
+    char *buf = (char *)allocate(len+1);
+    char *bufp = buf;
+
+    /* Position to start of text */
+    textFile->seek(fpos+header->stringOffset);
+
+    if (header->pack)
+        startDecoding();
+    while (len--)
+        if (header->pack)
+            *(bufp++) = decodeChar();
+        else
+            *(bufp++) = textFile->readByte();
+
+    /* Terminate string with zero */
+    *bufp = '\0';
+
+    return buf;
+}
+
+
+
+/*======================================================================*/
+void score(Aword sc)
+{
+    if (sc == 0) {
+        ParameterArray messageParameters = newParameterArray();
+        addParameterForInteger(messageParameters, current.score);
+        addParameterForInteger(messageParameters, header->maximumScore);
+        addParameterForInteger(messageParameters, current.tick);
+        printMessageWithParameters(M_SCORE, messageParameters);
+        freeParameterArray(messageParameters);
+    } else {
+        current.score += scores[sc-1];
+        scores[sc-1] = 0;
+        gameStateChanged = TRUE;
+    }
+}
+
+
+/*======================================================================*/
+void visits(Aword v)
+{
+    current.visits = v;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayUndoneCommand(char *words) {
+    static Parameter *messageParameters = NULL;
+    messageParameters = (Parameter *)ensureParameterArrayAllocated(messageParameters);
+
+    current.location = where(HERO, DIRECT);
+    clearParameterArray(messageParameters);
+    addParameterForString(&messageParameters[0], words);
+    setEndOfArray(&messageParameters[1]);
+    printMessageWithParameters(M_UNDONE, messageParameters);
+}
+
+
+/*======================================================================*/
+void undo(void) {
+    forgetGameState();
+    if (anySavedState()) {
+        recallGameState();
+        sayUndoneCommand(recreatePlayerCommand());
+    } else {
+        printMessage(M_NO_UNDO);
+    }
+#ifdef TODO
+	longjmp(returnLabel, UNDO_RETURN);
+#else
+	::error("TODO: undo longjmp");
+#endif
+}
+
+
+/*======================================================================*/
+void quitGame(void)
+{
+#ifdef TODO
+	char buf[80];
+
+    current.location = where(HERO, DIRECT);
+    para();
+    while (TRUE) {
+        col = 1;
+        statusline();
+        printMessage(M_QUITACTION);
+#ifdef USE_READLINE
+        if (!readline(buf)) terminate(0);
+#else
+        if (gets(buf) == NULL) terminate(0);
+#endif
+        if (strcasecmp(buf, "restart") == 0)
+            longjmp(restartLabel, TRUE);
+        else if (strcasecmp(buf, "restore") == 0) {
+            restore();
+            return;
+        } else if (strcasecmp(buf, "quit") == 0) {
+            terminate(0);
+        } else if (strcasecmp(buf, "undo") == 0) {
+            if (gameStateChanged) {
+                rememberCommands();
+                rememberGameState();
+                undo();
+            } else {
+                if (anySavedState()) {
+                    recallGameState();
+                    sayUndoneCommand(playerWordsAsCommandString());
+                } else
+                    printMessage(M_NO_UNDO);
+                longjmp(returnLabel, UNDO_RETURN);
+            }
+        }
+    }
+#endif
+	syserr("Fallthrough in QUIT");
+}
+
+
+
+/*======================================================================*/
+void restartGame(void)
+{
+    Aint previousLocation = current.location;
+#ifdef TODO
+    current.location = where(HERO, DIRECT);
+    para();
+    if (confirm(M_REALLY)) {
+        longjmp(restartLabel, TRUE);
+    }
+    current.location = previousLocation;
+#lse
+	::error("TODO: restartGame");
+#endif
+}
+
+
+
+/*======================================================================*/
+void cancelEvent(Aword theEvent)
+{
+    int i;
+
+    for (i = eventQueueTop-1; i>=0; i--)
+        if (eventQueue[i].event == theEvent) {
+            while (i < eventQueueTop-1) {
+                eventQueue[i].event = eventQueue[i+1].event;
+                eventQueue[i].after = eventQueue[i+1].after;
+                eventQueue[i].where = eventQueue[i+1].where;
+                i++;
+            }
+            eventQueueTop--;
+            return;
+        }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void increaseEventQueue(void)
+{
+    eventQueue = (EventQueueEntry *)realloc(eventQueue, (eventQueueTop+2)*sizeof(EventQueueEntry));
+    if (eventQueue == NULL) syserr("Out of memory in increaseEventQueue()");
+
+    eventQueueSize = eventQueueTop + 2;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void moveEvent(int to, int from) {
+    eventQueue[to].event = eventQueue[from].event;
+    eventQueue[to].after = eventQueue[from].after;
+    eventQueue[to].where = eventQueue[from].where;
+}
+
+
+/*======================================================================*/
+void schedule(Aword event, Aword where, Aword after)
+{
+    int i;
+
+    if (event == 0) syserr("NULL event");
+
+    cancelEvent(event);
+    /* Check for overflow */
+    if (eventQueue == NULL || eventQueueTop == eventQueueSize)
+        increaseEventQueue();
+
+    /* Bubble this event down */
+    for (i = eventQueueTop; i >= 1 && eventQueue[i-1].after <= after; i--) {
+        moveEvent(i, i-1);
+    }
+
+    eventQueue[i].after = after;
+    eventQueue[i].where = where;
+    eventQueue[i].event = event;
+    eventQueueTop++;
+}
+
+
+// TODO Move to string.c?
+/*======================================================================*/
+Aptr concat(Aptr as1, Aptr as2)
+{
+    char *s1 = (char *)fromAptr(as1);
+    char *s2 = (char *)fromAptr(as2);
+    char *result = (char *)allocate(strlen((char*)s1)+strlen((char*)s2)+1);
+    strcpy(result, s1);
+    strcat(result, s2);
+    return toAptr(result);
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *stripCharsFromStringForwards(int count, char *initialString, char **theRest)
+{
+    int stripPosition;
+    char *strippedString;
+    char *rest;
+
+    if (count > strlen(initialString))
+        stripPosition = strlen(initialString);
+    else
+        stripPosition = count;
+    rest = strdup(&initialString[stripPosition]);
+    strippedString = strdup(initialString);
+    strippedString[stripPosition] = '\0';
+    *theRest = rest;
+    return strippedString;
+}
+
+/*----------------------------------------------------------------------*/
+static char *stripCharsFromStringBackwards(Aint count, char *initialString, char **theRest) {
+    int stripPosition;
+    char *strippedString;
+    char *rest;
+
+    if (count > strlen(initialString))
+        stripPosition = 0;
+    else
+        stripPosition = strlen(initialString)-count;
+    strippedString = strdup(&initialString[stripPosition]);
+    rest = strdup(initialString);
+    rest[stripPosition] = '\0';
+    *theRest = rest;
+    return strippedString;
+}
+
+
+/*----------------------------------------------------------------------*/
+static int countLeadingBlanks(char *string, int position) {
+    static char blanks[] = " ";
+    return strspn(&string[position], blanks);
+}
+
+
+/*----------------------------------------------------------------------*/
+static int skipWordForwards(char *string, int position)
+{
+    char separators[] = " .,?";
+
+    int i;
+
+    for (i = position; i<=strlen(string) && strchr(separators, string[i]) == NULL; i++)
+        ;
+    return i;
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *stripWordsFromStringForwards(Aint count, char *initialString, char **theRest) {
+    int skippedChars;
+    int position = 0;
+    char *stripped;
+    int i;
+
+    for (i = count; i>0; i--) {
+        /* Ignore any initial blanks */
+        skippedChars = countLeadingBlanks(initialString, position);
+        position += skippedChars;
+        position = skipWordForwards(initialString, position);
+    }
+
+    stripped = (char *)allocate(position+1);
+    strncpy(stripped, initialString, position);
+    stripped[position] = '\0';
+
+    skippedChars = countLeadingBlanks(initialString, position);
+    *theRest = strdup(&initialString[position+skippedChars]);
+
+    return(stripped);
+}
+
+
+/*----------------------------------------------------------------------*/
+static int skipWordBackwards(char *string, int position)
+{
+    char separators[] = " .,?";
+    int i;
+
+    for (i = position; i>0 && strchr(separators, string[i-1]) == NULL; i--)
+        ;
+    return i;
+}
+
+
+/*----------------------------------------------------------------------*/
+static int countTrailingBlanks(char *string, int position) {
+    int skippedChars, i;
+    skippedChars = 0;
+
+    if (position > strlen(string)-1)
+        syserr("position > length in countTrailingBlanks");
+    for (i = position; i >= 0 && string[i] == ' '; i--)
+        skippedChars++;
+    return(skippedChars);
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *stripWordsFromStringBackwards(Aint count, char *initialString, char **theRest) {
+    int skippedChars;
+    char *stripped;
+    int strippedLength;
+    int position = strlen(initialString);
+    int i;
+
+    for (i = count; i>0 && position>0; i--) {
+        position -= 1;
+        /* Ignore trailing blanks */
+        skippedChars = countTrailingBlanks(initialString, position);
+        if (position - skippedChars < 0) break; /* No more words to strip */
+        position -= skippedChars;
+        position = skipWordBackwards(initialString, position);
+    }
+
+    skippedChars = countLeadingBlanks(initialString, 0);
+    strippedLength = strlen(initialString)-position-skippedChars;
+    stripped = (char *)allocate(strippedLength+1);
+    strncpy(stripped, &initialString[position+skippedChars], strippedLength);
+    stripped[strippedLength] = '\0';
+
+    if (position > 0) {
+        skippedChars = countTrailingBlanks(initialString, position-1);
+        position -= skippedChars;
+    }
+    *theRest = strdup(initialString);
+    (*theRest)[position] = '\0';
+    return(stripped);
+}
+
+
+
+/*======================================================================*/
+Aptr strip(bool stripFromBeginningNotEnd, int count, bool stripWordsNotChars, int id, int atr)
+{
+    char *initialString = (char *)fromAptr(getInstanceAttribute(id, atr));
+    char *theStripped;
+    char *theRest;
+
+    if (stripFromBeginningNotEnd) {
+        if (stripWordsNotChars)
+            theStripped = stripWordsFromStringForwards(count, initialString, &theRest);
+        else
+            theStripped = stripCharsFromStringForwards(count, initialString, &theRest);
+    } else {
+        if (stripWordsNotChars)
+            theStripped = stripWordsFromStringBackwards(count, initialString, &theRest);
+        else
+            theStripped = stripCharsFromStringBackwards(count, initialString, &theRest);
+    }
+    setInstanceStringAttribute(id, atr, theRest);
+    return toAptr(theStripped);
+}
+
+
+/*======================================================================*/
+int getContainerMember(int container, int index, bool directly) {
+    Aint i;
+    Aint count = 0;
+
+    for (i = 1; i <= header->instanceMax; i++) {
+        if (isIn(i, container, DIRECT)) {
+            count++;
+            if (count == index)
+                return i;
+        }
+    }
+    apperr("Index not in container in 'containerMember()'");
+    return 0;
+}
+
+
+/***********************************************************************\
+
+  Description Handling
+
+\***********************************************************************/
+
+
+/*======================================================================*/
+void showImage(int image, int align)
+{
+#ifdef HAVE_GLK
+    uint ecode;
+
+    if ((g_vm->glk_gestalt(gestalt_Graphics, 0) == 1) &&
+        (g_vm->glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
+		g_vm->glk_window_flow_break(glkMainWin);
+        printf("\n");
+        ecode = g_vm->glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
+        (void)ecode;
+    }
+#endif
+}
+
+
+/*======================================================================*/
+void playSound(int sound)
+{
+#ifdef HAVE_GLK
+#ifdef GLK_MODULE_SOUND
+    static schanid_t soundChannel = NULL;
+
+    if (g_vm->glk_gestalt(gestalt_Sound, 0) == 1) {
+        if (soundChannel == NULL)
+            soundChannel = g_vm->glk_schannel_create(0);
+        if (soundChannel != NULL) {
+			g_vm->glk_schannel_stop(soundChannel);
+            (void)g_vm->glk_schannel_play(soundChannel, sound);
+        }
+    }
+#endif
+#endif
+}
+
+
+
+/*======================================================================*/
+void empty(int cnt, int whr)
+{
+    int i;
+
+    for (i = 1; i <= header->instanceMax; i++)
+        if (isIn(i, cnt, DIRECT))
+            locate(i, whr);
+}
+
+
+
+/*======================================================================*/
+void use(int actor, int script)
+{
+    char str[80];
+    StepEntry *step;
+
+    if (!isAActor(actor)) {
+        sprintf(str, "Instance is not an Actor (%d).", actor);
+        syserr(str);
+    }
+
+    admin[actor].script = script;
+    admin[actor].step = 0;
+    step = stepOf(actor);
+    if (step != NULL && step->after != 0) {
+        admin[actor].waitCount = evaluate(step->after);
+    }
+
+    gameStateChanged = TRUE;
+}
+
+/*======================================================================*/
+void stop(int act)
+{
+    char str[80];
+
+    if (!isAActor(act)) {
+        sprintf(str, "Instance is not an Actor (%d).", act);
+        syserr(str);
+    }
+
+    admin[act].script = 0;
+    admin[act].step = 0;
+
+    gameStateChanged = TRUE;
+}
+
+
+
+static int randomValue = 0;
+/*----------------------------------------------------------------------*/
+int randomInteger(int from, int to)
+{
+    if (regressionTestOption) {
+        int ret = from + randomValue;
+        /* Generate them in sequence */
+        if (ret > to) {
+            ret = from;
+            randomValue = 1;
+        } else if (ret == to)
+            randomValue = 0;
+        else
+            randomValue++;
+        return ret;
+    } else {
+        if (to == from)
+            return to;
+        else if (to > from)
+            return (rand()/10)%(to-from+1)+from;
+        else
+            return (rand()/10)%(from-to+1)+to;
+    }
+}
+
+
+
+/*----------------------------------------------------------------------*/
+bool between(int val, int low, int high)
+{
+    if (high > low)
+        return low <= val && val <= high;
+    else
+        return high <= val && val <= low;
+}
+
+
+
+/*======================================================================*/
+bool contains(Aptr string, Aptr substring)
+{
+    bool found;
+
+    strlow((char *)fromAptr(string));
+    strlow((char *)fromAptr(substring));
+
+    found = (strstr((char *)fromAptr(string), (char *)fromAptr(substring)) != 0);
+
+    return found;
+}
+
+
+/*======================================================================*/
+bool streq(char a[], char b[])
+{
+    bool eq;
+
+    strlow(a);
+    strlow(b);
+
+    eq = (strcmp(a, b) == 0);
+
+    return eq;
+}
+
+
+
+/*======================================================================*/
+void startTranscript(void) {
+    time_t tick;
+
+    if (logFile != NULL)
+        return;
+
+	Common::String target = g_vm->getTargetName() + ".log";
+
+	uint fileUsage = transcriptOption ? fileusage_Transcript : fileusage_InputRecord;
+	frefid_t logFileRef = g_vm->glk_fileref_create_by_name(fileUsage, logFileName, 0);
+	logFile = g_vm->glk_stream_open_file(logFileRef, filemode_Write, 0);
+
+	if (logFile == NULL) {
+        transcriptOption = FALSE;
+        logOption = FALSE;
+	} else {
+		transcriptOption = TRUE;
+	}
+}
+
+
+/*======================================================================*/
+void stopTranscript(void) {
+    if (logFile == NULL)
+        return;
+
+	if (transcriptOption|| logOption)
+		delete logFile;
+
+    logFile = NULL;
+    transcriptOption = FALSE;
+    logOption = FALSE;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/exe.h b/engines/glk/alan3/exe.h
new file mode 100644
index 0000000..77fb70a
--- /dev/null
+++ b/engines/glk/alan3/exe.h
@@ -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.
+ *
+ */
+
+#ifndef GLK_ALAN3_EXE
+#define GLK_ALAN3_EXE
+
+/* Header file for instruction execution unit in Alan interpreter */
+
+/* IMPORTS */
+#include "glk/alan3/sysdep.h"
+#include "glk/alan3/acode.h"
+#include "glk/alan3/types.h"
+#include "glk/alan3/set.h"
+#include "common/stream.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* CONSTANTS */
+#define NO_JUMP_RETURN 0
+#define ERROR_RETURN 1
+#define UNDO_RETURN 2
+
+
+/* DATA */
+
+/* The text and message file */
+extern Common::SeekableReadStream *textFile;
+
+/* Long jump buffer for restart, errors and undo */
+//extern jmp_buf restartLabel;
+//extern jmp_buf returnLabel;
+//extern jmp_buf forfeitLabel;
+
+
+/* FUNCTIONS */
+extern void sys(Aword fpos, Aword len);
+extern void sayInteger(int val);
+extern void sayString(char *str);
+extern Aptr strip(bool stripFromBeginningNotEnd, int count, bool stripWordsNotChars, int id, int atr);
+extern Aptr concat(Aptr s1, Aptr s2);
+extern char *getStringFromFile(Aword fpos, Aword len);
+extern void print(Aword fpos, Aword len);
+extern void setStyle(int style);
+extern void showImage(int image, int align);
+extern void playSound(int sound);
+extern void score(Aword sc);
+extern void visits(Aword v);
+extern void undo(void);
+extern void quitGame(void);
+extern void restartGame(void);
+
+extern void use(int act, int scr);
+extern void stop(int act);
+
+extern void empty(int cnt, int whr);
+extern int getContainerMember(int container, int index, bool directly);
+extern int randomInContainer(int cont);
+
+extern void schedule(Aword evt, Aword whr, Aword aft);
+extern void cancelEvent(Aword evt);
+
+extern int randomInteger(int from, int to);
+extern bool between(int val, int from, int to);
+extern bool contains(Aptr string, Aptr substring);
+extern bool streq(char a[], char b[]);
+
+extern void include(int instance, int atr, Aword member);
+extern void exclude(int instance, int atr, Aword member);
+extern void increase(int instance, int atr, Aword step);
+extern void decrease(int instance, int atr, Aword step);
+
+extern void startTranscript(void);
+extern void stopTranscript(void);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/fnmatch.cpp b/engines/glk/alan3/fnmatch.cpp
new file mode 100644
index 0000000..203a7bf
--- /dev/null
+++ b/engines/glk/alan3/fnmatch.cpp
@@ -0,0 +1,234 @@
+/* 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.
+ *
+ */
+
+/*-
+ * Copyright (c) 1989, 1993, 1994
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+#include "glk/alan3/fnmatch.h"
+#include "common/scummsys.h"
+
+namespace Glk {
+namespace Alan3 {
+
+#define EOS     '\0'
+
+#define RANGE_MATCH     1
+#define RANGE_NOMATCH   0
+#define RANGE_ERROR     (-1)
+
+static int rangematch(const char *, char, int, char **);
+
+int fnmatch(const char *pattern, const char *string, int flags) {
+        const char *stringstart;
+        char *newp;
+        char c, test;
+
+        for (stringstart = string;;)
+                switch (c = *pattern++) {
+                case EOS:
+                        if ((flags & FNM_LEADING_DIR) && *string == '/')
+                                return (0);
+                        return (*string == EOS ? 0 : FNM_NOMATCH);
+                case '?':
+                        if (*string == EOS)
+                                return (FNM_NOMATCH);
+                        if (*string == '/' && (flags & FNM_PATHNAME))
+                                return (FNM_NOMATCH);
+                        if (*string == '.' && (flags & FNM_PERIOD) &&
+                            (string == stringstart ||
+                            ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                                return (FNM_NOMATCH);
+                        ++string;
+                        break;
+                case '*':
+                        c = *pattern;
+                        /* Collapse multiple stars. */
+                        while (c == '*')
+                                c = *++pattern;
+
+                        if (*string == '.' && (flags & FNM_PERIOD) &&
+                            (string == stringstart ||
+                            ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                                return (FNM_NOMATCH);
+
+                        /* Optimize for pattern with * at end or before /. */
+                        if (c == EOS)
+                                if (flags & FNM_PATHNAME)
+                                        return ((flags & FNM_LEADING_DIR) ||
+                                            strchr(string, '/') == NULL ?
+                                            0 : FNM_NOMATCH);
+                                else
+                                        return (0);
+                        else if (c == '/' && flags & FNM_PATHNAME) {
+                                if ((string = strchr(string, '/')) == NULL)
+                                        return (FNM_NOMATCH);
+                                break;
+                        }
+
+                        /* General case, use recursion. */
+                        while ((test = *string) != EOS) {
+                                if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
+                                        return (0);
+                                if (test == '/' && flags & FNM_PATHNAME)
+                                        break;
+                                ++string;
+                        }
+                        return (FNM_NOMATCH);
+                case '[':
+                        if (*string == EOS)
+                                return (FNM_NOMATCH);
+                        if (*string == '/' && (flags & FNM_PATHNAME))
+                                return (FNM_NOMATCH);
+                        if (*string == '.' && (flags & FNM_PERIOD) &&
+                            (string == stringstart ||
+                            ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                                return (FNM_NOMATCH);
+
+                        switch (rangematch(pattern, *string, flags, &newp)) {
+                        case RANGE_ERROR:
+                                goto norm;
+                        case RANGE_MATCH:
+                                pattern = newp;
+                                break;
+                        case RANGE_NOMATCH:
+                                return (FNM_NOMATCH);
+                        }
+                        ++string;
+                        break;
+                case '\\':
+                        if (!(flags & FNM_NOESCAPE)) {
+                                if ((c = *pattern++) == EOS) {
+                                        c = '\\';
+                                        --pattern;
+                                }
+                        }
+                        /* FALLTHROUGH */
+                default:
+                norm:
+                        if (c == *string)
+                                ;
+                        else if ((flags & FNM_CASEFOLD) &&
+                                 (tolower((unsigned char)c) ==
+                                  tolower((unsigned char)*string)))
+                                ;
+                        else
+                                return (FNM_NOMATCH);
+                        string++;
+                        break;
+                }
+        /* NOTREACHED */
+}
+
+static int
+rangematch(const char *pattern, char test, int flags, char **newp)
+{
+        int negate, ok;
+        char c, c2;
+
+        /*
+         * A bracket expression starting with an unquoted circumflex
+         * character produces unspecified results (IEEE 1003.2-1992,
+         * 3.13.2).  This implementation treats it like '!', for
+         * consistency with the regular expression syntax.
+         * J.T. Conklin (conklin at ngai.kaleida.com)
+         */
+        if ( (negate = (*pattern == '!' || *pattern == '^')) )
+                ++pattern;
+
+        if (flags & FNM_CASEFOLD)
+                test = tolower((unsigned char)test);
+
+        /*
+         * A right bracket shall lose its special meaning and represent
+         * itself in a bracket expression if it occurs first in the list.
+         * -- POSIX.2 2.8.3.2
+         */
+        ok = 0;
+        c = *pattern++;
+        do {
+                if (c == '\\' && !(flags & FNM_NOESCAPE))
+                        c = *pattern++;
+                if (c == EOS)
+                        return (RANGE_ERROR);
+
+                if (c == '/' && (flags & FNM_PATHNAME))
+                        return (RANGE_NOMATCH);
+
+                if (flags & FNM_CASEFOLD)
+                        c = tolower((unsigned char)c);
+
+                if (*pattern == '-'
+                    && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+                        pattern += 2;
+                        if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+                                c2 = *pattern++;
+                        if (c2 == EOS)
+                                return (RANGE_ERROR);
+
+                        if (flags & FNM_CASEFOLD)
+                                c2 = tolower((unsigned char)c2);
+
+                        if (c <= test && test <= c2)
+                                ok = 1;
+                } else if (c == test)
+                        ok = 1;
+        } while ((c = *pattern++) != ']');
+
+        *newp = const_cast<char *>(pattern);
+        return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/fnmatch.h b/engines/glk/alan3/fnmatch.h
new file mode 100644
index 0000000..d98ffa5
--- /dev/null
+++ b/engines/glk/alan3/fnmatch.h
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_FNMATCH
+#define GLK_ALAN3_FNMATCH
+
+/*-
+ * Copyright (c) 1992, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      @(#)fnmatch.h        8.1 (Berkeley) 6/2/93
+ */
+
+namespace Glk {
+namespace Alan3 {
+
+#define FNM_NOMATCH        1        /* Match failed. */
+#define FNM_NOSYS        2        /* Function not supported (unused). */
+
+#define FNM_NOESCAPE        0x01        /* Disable backslash escaping. */
+#define FNM_PATHNAME        0x02        /* Slash must be matched by slash. */
+#define FNM_PERIOD        0x04        /* Period must be matched by period. */
+#ifndef _POSIX_SOURCE
+#define FNM_LEADING_DIR        0x08        /* Ignore /<tail> after Imatch. */
+#define FNM_CASEFOLD        0x10        /* Case insensitive search. */
+#define FNM_IGNORECASE        FNM_CASEFOLD
+#define FNM_FILE_NAME        FNM_PATHNAME
+#endif
+
+extern int fnmatch(const char *pattern, const char *string, int flags);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
+
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
new file mode 100644
index 0000000..b067156
--- /dev/null
+++ b/engines/glk/alan3/glkio.cpp
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/alan3/alan3.h"
+#include "glk/alan3/glkio.h"
+
+namespace Glk {
+namespace Alan3 {
+
+void glkio_printf(const char *fmt, ...) {
+	// If there's a savegame being loaded from the launcher, ignore any text out
+	if (g_vm->_saveSlot != -1)
+		return;
+
+	va_list argp;
+	va_start(argp, fmt);
+	if (glkMainWin) {
+		char buf[1024]; /* FIXME: buf size should be foolproof */
+		vsprintf(buf, fmt, argp);
+		g_vm->glk_put_string(buf);
+	} else {
+		// assume stdio is available in this case only
+		Common::String str = Common::String::vformat(fmt, argp);
+		warning(fmt, argp);
+	}
+
+	va_end(argp);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
new file mode 100644
index 0000000..5bcd6e6
--- /dev/null
+++ b/engines/glk/alan3/glkio.h
@@ -0,0 +1,55 @@
+/* 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_ALAN3_GLKIO
+#define GLK_ALAN3_GLKIO
+
+/* Header file for Glk output for Alan interpreter */
+
+#include "glk/alan3/alan3.h"
+#include "glk/windows.h"
+
+namespace Glk {
+namespace Alan3 {
+
+extern winid_t glkMainWin;
+extern winid_t glkStatusWin;
+
+/* NB: this header must be included in any file which calls printf() */
+
+#undef printf
+#define printf glkio_printf
+extern void glkio_printf(const char *, ...);
+
+#ifdef MAP_STDIO_TO_GLK
+#define fgetc(stream) glk_get_char_stream(stream)
+#define rewind(stream) glk_stream_set_position(stream, 0, seekmode_Start);
+#define fwrite(buf, elementSize, count, stream) glk_put_buffer_stream(stream, buf, elementSize*count);
+#define fread(buf, elementSize, count, stream) glk_get_buffer_stream(stream, buf, elementSize*count);
+#define fclose(stream) glk_stream_close(stream, NULL)
+#define fgets(buff, len, stream) glk_get_line_stream(stream, buff, len)
+#endif
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/glkstart.cpp b/engines/glk/alan3/glkstart.cpp
new file mode 100644
index 0000000..0c54cfd
--- /dev/null
+++ b/engines/glk/alan3/glkstart.cpp
@@ -0,0 +1,209 @@
+/* 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/alan3/glkstart.h"
+#include "glk/alan3/alan3.h"
+#include "glk/alan3/args.h"
+#include "glk/alan3/main.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/resources.h"
+#include "glk/alan3/utils.h"
+ //#include "glk/alan3/gi_blorb.h"
+#include "glk/streams.h"
+
+#ifdef HAVE_WINGLK
+#include "glk/alan3/WinGlk.h"
+#endif
+
+
+#ifdef HAVE_GARGLK
+#include "glk/alan3/alan_version.h"
+#endif
+
+namespace Glk {
+namespace Alan3 {
+
+glkunix_argumentlist_t glkunix_arguments[] = {
+    { "-l", glkunix_arg_NoValue, "-l: log player command and game output" },
+    { "-c", glkunix_arg_NoValue, "-c: log player commands to a file" },
+    { "-n", glkunix_arg_NoValue, "-n: no status line" },
+    { "-i", glkunix_arg_NoValue, "-i: ignore version and checksum errors" },
+    { "-d", glkunix_arg_NoValue, "-d: enter debug mode" },
+    { "-t", glkunix_arg_NoValue, "-t [<n>]: trace game execution, higher <n> gives more trace" },
+    { "-r", glkunix_arg_NoValue, "-r: refrain from printing timestamps and paging (making regression testing easier)" },
+    { "", glkunix_arg_ValueFollows, "filename: The game file to load." },
+    { NULL, glkunix_arg_End, NULL }
+};
+
+/* Resources */
+static strid_t resourceFile;
+
+/*----------------------------------------------------------------------*/
+static void openGlkWindows() {
+    glkMainWin = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
+    if (glkMainWin == NULL) {
+            printf("FATAL ERROR: Cannot open initial window");
+			g_vm->glk_exit();
+    }
+#ifdef HAVE_GARGLK
+   glk_stylehint_set (wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
+#endif
+    glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
+                                   winmethod_Fixed, 1, wintype_TextGrid, 0);
+	g_vm->glk_set_window(glkStatusWin);
+	g_vm->glk_set_style(style_Preformatted);
+	g_vm->glk_set_window(glkMainWin);
+}
+
+/*----------------------------------------------------------------------*/
+static void openResourceFile() {
+#ifdef TODO
+    char *originalFileName = strdup(adventureFileName);
+	char *resourceFileName = originalFileName;
+    char *extension = strrchr(resourceFileName, '.');
+    frefid_t resourceFileRef;
+//    giblorb_err_t ecode;
+
+    strcpy(extension, ".a3r");
+
+    resourceFileRef = winglk_fileref_create_by_name(fileusage_BinaryMode,
+                                                    resourceFileName, 0, FALSE);
+
+	if (glk_fileref_does_file_exist(resourceFileRef)) {
+        resourceFile = glk_stream_open_file(resourceFileRef, filemode_Read, 0);
+        ecode = giblorb_set_resource_map(resourceFile);
+        (void)ecode;
+    }
+    free(originalFileName);
+#endif
+}
+
+
+/*======================================================================*/
+int glkunix_startup_code(glkunix_startup_t *data) {
+    g_vm->glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Weight, 0);
+	g_vm->glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Oblique, 1);
+	g_vm->glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Indentation, 10);
+
+    /* first, open a window for error output */
+    openGlkWindows();
+
+#ifdef HAVE_GARGLK
+#if (BUILD+0) != 0
+    {
+        char name[100];
+        sprintf(name, "%s-%d", alan.shortHeader, BUILD);
+        garglk_set_program_name(name);
+    }
+#else
+	garglk_set_program_name(alan.shortHeader);
+#endif
+	char info[80];
+	sprintf(info, "%s Interpreter by Thomas Nilefalk\n", alan.shortHeader);
+	garglk_set_program_info(info);
+#endif
+
+    /* now process the command line arguments */
+    args(data->argc, data->argv);
+
+    if (adventureFileName == NULL || strcmp(adventureFileName, "") == 0) {
+        printf("You should supply a game file to play.\n");
+        usage("arun"); // TODO Find real programname from arguments
+        terminate(1);
+    }
+
+    /* Open any possible blorb resource file */
+    openResourceFile();
+
+    return TRUE;
+}
+
+
+
+#ifdef HAVE_WINGLK
+static int argCount;
+static char *argumentVector[10];
+
+/*----------------------------------------------------------------------*/
+static void splitArgs(char *commandLine) {
+    unsigned char *cp = (unsigned char *)commandLine;
+
+    while (*cp) {
+        while (*cp && isspace(*cp)) cp++;
+        if (*cp) {
+            argumentVector[argCount++] = (char *)cp;
+            if (*cp == '"') {
+                do {
+                    cp++;
+                } while (*cp != '"');
+                cp++;
+            } else
+                while (*cp && !isspace(*cp))
+                    cp++;
+            if (*cp) {
+                *cp = '\0';
+                cp++;
+            }
+        }
+    }
+}
+
+
+/*======================================================================*/
+int winglk_startup_code(const char* cmdline)
+{
+    char windowTitle[200];
+
+    /* Process the command line arguments */
+    argumentVector[0] = "";
+    argCount = 1;
+
+    splitArgs(strdup(cmdline));
+
+    args(argCount, argumentVector);
+
+
+    if (adventureFileName == NULL || strcmp(adventureFileName, "") == 0) {
+        adventureFileName = (char*)winglk_get_initial_filename(NULL, "Arun : Select an Alan game file",
+                                                               "Alan Game Files (*.a3c)|*.a3c||");
+        if (adventureFileName == NULL) {
+            terminate(0);
+        }
+        adventureName = gameName(adventureFileName);
+    }
+
+    winglk_app_set_name("WinArun");
+    winglk_set_gui(IDR_ARUN);
+
+    sprintf(windowTitle, "WinArun : %s", adventureName);
+    winglk_window_set_title(windowTitle);
+    openGlkWindows();
+
+    /* Open any possible blorb resource file */
+    openResourceFile();
+
+    return TRUE;
+}
+#endif
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/glkstart.h b/engines/glk/alan3/glkstart.h
new file mode 100644
index 0000000..4420bea
--- /dev/null
+++ b/engines/glk/alan3/glkstart.h
@@ -0,0 +1,82 @@
+/* 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_ALAN3_GLKSTART
+#define GLK_ALAN3_GLKSTART
+
+/* glkstart.h: Unix-specific header file for GlkTerm, CheapGlk, and XGlk
+        (Unix implementations of the Glk API).
+    Designed by Andrew Plotkin <erkyrath at netcom.com>
+    http://www.eblong.com/zarf/glk/index.html
+*/
+
+/* This header defines an interface that must be used by program linked
+    with the various Unix Glk libraries -- at least, the three I wrote.
+    (I encourage anyone writing a Unix Glk library to use this interface,
+    but it's not part of the Glk spec.)
+    
+    Because Glk is *almost* perfectly portable, this interface *almost*
+    doesn't have to exist. In practice, it's small.
+*/
+
+namespace Glk {
+namespace Alan3 {
+
+/* We define our own TRUE and FALSE and NULL, because ANSI
+    is a strange world. */
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define glkunix_arg_End (0)
+#define glkunix_arg_ValueFollows (1)
+#define glkunix_arg_NoValue (2)
+#define glkunix_arg_ValueCanFollow (3)
+#define glkunix_arg_NumberValue (4)
+
+struct glkunix_argumentlist_t {
+    char *name;
+    int argtype;
+    char *desc;
+};
+
+struct glkunix_startup_t {
+    int argc;
+    char **argv;
+};
+
+/* The list of command-line arguments; this should be defined in your code. */
+extern glkunix_argumentlist_t glkunix_arguments[];
+
+/* The external function; this should be defined in your code. */
+extern int glkunix_startup_code(glkunix_startup_t *data);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
new file mode 100644
index 0000000..49bc72d
--- /dev/null
+++ b/engines/glk/alan3/instance.cpp
@@ -0,0 +1,1152 @@
+/* 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/alan3/instance.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/syserr.h"
+#include "glk/alan3/attribute.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/container.h"
+#include "glk/alan3/debug.h"
+#include "glk/alan3/checkentry.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/class.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/actor.h"
+#include "glk/alan3/literal.h"
+#include "glk/alan3/dictionary.h"
+#include "glk/alan3/location.h"
+#include "glk/alan3/compatibility.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+
+InstanceEntry *instances;   /* Instance table pointer */
+
+AdminEntry *admin;      /* Administrative data about instances */
+AttributeEntry *attributes; /* Dynamic attribute values */
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+/* Instance query methods */
+
+/*======================================================================*/
+bool isA(int instance, int ancestor)
+{
+    int parent;
+
+    if (isLiteral(instance))
+        parent = literals[instance-header->instanceMax]._class;
+    else
+        parent = instances[instance].parent;
+    while (parent != 0 && parent != ancestor)
+        parent = classes[parent].parent;
+
+    return (parent != 0);
+}
+
+
+bool isAObject(int instance)
+{
+  return isA(instance, OBJECT);
+}
+
+bool isAContainer(int instance)
+{
+    return instance != 0 && !isLiteral(instance) && instances[instance].container != 0;
+}
+
+bool isAActor(int instance)
+{
+  return isA(instance, ACTOR);
+}
+
+bool isALocation(int instance)
+{
+  return isA(instance, LOCATION);
+}
+
+
+bool isLiteral(int instance)
+{
+  return instance > header->instanceMax;
+}
+
+bool isANumeric(int instance)
+{
+  return isLiteral(instance) && literals[literalFromInstance(instance)].type == NUMERIC_LITERAL;
+}
+
+bool isAString(int instance)
+{
+  return isLiteral(instance) && literals[literalFromInstance(instance)].type == STRING_LITERAL;
+}
+
+
+/*======================================================================*/
+bool isOpaque(int container) {
+    return getInstanceAttribute(container, OPAQUEATTRIBUTE);
+}
+
+
+/*======================================================================*/
+void setInstanceAttribute(int instance, int attribute, Aptr value)
+{
+    char str[80];
+
+    if (instance > 0 && instance <= header->instanceMax) {
+        setAttribute(admin[instance].attributes, attribute, value);
+        if (isALocation(instance) && attribute != VISITSATTRIBUTE)
+            /* If it wasn't the VISITSATTRIBUTE the location may have
+               changed so describe next time */
+            admin[instance].visitsCount = 0;
+    } else {
+        sprintf(str, "Can't SET/MAKE instance (%d).", instance);
+        syserr(str);
+    }
+}
+
+
+/*======================================================================*/
+void setInstanceStringAttribute(int instance, int attribute, char *string)
+{
+    deallocate(fromAptr(getInstanceAttribute(instance, attribute)));
+    setInstanceAttribute(instance, attribute, toAptr(string));
+}
+
+
+/*======================================================================*/
+void setInstanceSetAttribute(int instance, int attribute, Aptr set)
+{
+    freeSet((Set *)fromAptr(getInstanceAttribute(instance, attribute)));
+    setInstanceAttribute(instance, attribute, set);
+}
+
+
+/*----------------------------------------------------------------------*/
+static Aptr literalAttribute(int literal, int attribute)
+{
+    if (isPreBeta3(header->version)) {
+        if (attribute == 1)
+            return literals[literalFromInstance(literal)].value;
+        else
+            return 0;
+    } else {
+        if (attribute == 0)
+            return literals[literalFromInstance(literal)].value;
+        else
+            return getAttribute(admin[header->instanceMax].attributes, attribute);
+    }
+    return(EOF);
+}
+
+
+/*======================================================================*/
+Aptr getInstanceAttribute(int instance, int attribute)
+{
+    char str[80];
+
+    if (isLiteral(instance))
+        return literalAttribute(instance, attribute);
+    else {
+        if (instance > 0 && instance <= header->instanceMax) {
+            if (attribute == -1)
+                return locationOf(instance);
+            else
+                return getAttribute(admin[instance].attributes, attribute);
+        } else {
+            sprintf(str, "Can't ATTRIBUTE item (%d).", instance);
+            syserr(str);
+        }
+    }
+    return(EOF);
+}
+
+
+/*======================================================================*/
+char *getInstanceStringAttribute(int instance, int attribute)
+{
+    return strdup((char *)fromAptr(getInstanceAttribute(instance, attribute)));
+}
+
+
+/*======================================================================*/
+Set *getInstanceSetAttribute(int instance, int attribute)
+{
+    return copySet((Set *)fromAptr(getInstanceAttribute(instance, attribute)));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void verifyInstance(int instance, char *action) {
+    char message[200];
+
+    if (instance == 0) {
+        sprintf(message, "Can't %s instance (%d).", action, instance);
+        syserr(message);
+    } else if (instance > header->instanceMax) {
+        sprintf(message, "Can't %s instance (%d > instanceMax).", action, instance);
+        syserr(message);
+    }
+}
+
+
+/*======================================================================*/
+bool isHere(int id, ATrans transitivity)
+{
+    verifyInstance(id, "HERE");
+
+    return isAt(id, current.location, transitivity);
+}
+
+
+/*======================================================================*/
+bool isNearby(int instance, ATrans transitivity)
+{
+    verifyInstance(instance, "NEARBY");
+
+    if (isALocation(instance))
+        return exitto(current.location, instance);
+    else
+        return exitto(current.location, where(instance, transitivity));
+}
+
+
+/*======================================================================*/
+bool isNear(int instance, int other, ATrans trans)
+{
+    Aint l1, l2;
+
+    verifyInstance(instance, "NEAR");
+
+    if (isALocation(instance))
+        l1 = instance;
+    else
+        l1 = where(instance, trans);
+    if (isALocation(other))
+        l2 = other;
+    else
+        l2 = where(other, trans);
+    return exitto(l2, l1);
+}
+
+
+/*======================================================================*/
+/* Look in a container to see if the instance is in it. */
+bool isIn(int instance, int container, ATrans trans)
+{
+    int loc;
+
+    if (!isAContainer(container))
+        syserr("IN in a non-container.");
+
+    if (trans == DIRECT)
+        return admin[instance].location == container;
+    else {
+        loc = admin[instance].location;
+        if (trans == INDIRECT && loc != 0 && !isA(loc, LOCATION))
+            loc = admin[loc].location;
+        while (loc != 0 && !isA(loc, LOCATION))
+            if (loc == container)
+                return TRUE;
+            else
+                loc = admin[loc].location;
+        return FALSE;
+    }
+}
+
+
+
+/*======================================================================*/
+/* Look see if an instance is AT another. */
+bool isAt(int instance, int other, ATrans trans)
+{
+    if (instance == 0 || other == 0) return FALSE;
+
+    if (isALocation(instance)) {
+        /* Nested locations */
+        /* TODO - What if the other is not a location? */
+        int current = admin[instance].location;
+        switch (trans) {
+        case DIRECT:
+            return admin[instance].location == other;
+        case INDIRECT:
+            if (current == other)
+                return FALSE;
+            current = admin[current].location;
+        case TRANSITIVE:
+            while (current != 0) {
+                if (current == other)
+                    return TRUE;
+                else
+                    current = admin[current].location;
+            }
+            return FALSE;
+        }
+        syserr("Unexpected value in switch in isAt() for location");
+        return FALSE;
+    } else if (isALocation(other)) {
+        /* Instance is not a location but other is */
+        switch (trans) {
+        case DIRECT:
+            return admin[instance].location == other;
+        case INDIRECT: {
+            if (admin[instance].location == other)
+                return FALSE;   /* Directly, so not Indirectly */
+            /* Fall through to transitive handling of the location */
+        }
+        case TRANSITIVE: {
+            int location = locationOf(instance);
+            int current = other;
+            while (current != 0) {
+                if (current == location)
+                    return TRUE;
+                else
+                    current = admin[current].location;
+            }
+            return FALSE;
+        }
+        }
+        syserr("Unexpected value in switch in isAt() for non-location");
+        return FALSE;
+    } else {
+        /* Other is also not a location */
+        switch (trans) {
+        case DIRECT:
+            return positionOf(instance) == admin[other].location;
+        case INDIRECT: {
+            int location = locationOf(instance);
+            int current = other;
+            if (location == current)
+                return FALSE;
+            else
+                current = admin[current].location;
+            while (current != 0) {
+                if (current == location)
+                    return TRUE;
+                else
+                    current = admin[current].location;
+            }
+            return FALSE;
+        }
+        case TRANSITIVE: {
+            int location = locationOf(other);
+            int current = locationOf(instance);
+            bool ok = FALSE;
+            while (current != 0 && !ok) {
+                if (current == location)
+                    ok = TRUE;
+                else
+                    current = admin[current].location;
+            }
+            return ok;
+        }
+        }
+        syserr("Unexpected value in switch in isAt() for non-location");
+        return FALSE;
+    }
+}
+
+
+/*======================================================================*/
+/* Return the *location* of an instance, transitively, i.e. the first
+   location instance found when traversing the containment/position
+   links. If that didn't turn up a location see if it was in a
+   container that is somewhere, or a THING that is nowhere. It might
+   also be an ENTITY which is always everywhere so take that to mean
+   where the hero is. */
+int locationOf(int instance)
+{
+    int position;
+    int container = 0;
+
+    verifyInstance(instance, "get LOCATION of");
+
+    position = admin[instance].location;
+    while (position != 0 && !isALocation(position)) {
+        container = position;   /* Remember innermost container */
+        position = admin[position].location;
+    }
+    if (position > NOWHERE) /* It was a location so return that */
+        return position;
+    else {
+        /* If we did not find a location then it might be in a container */
+        if (container != 0)
+            instance = container;
+        /* If the instance or the container it was in is a THING then its nowhere. */
+        if (isA(instance, THING))
+            return NOWHERE;     /* #nowhere */
+        else if (isALocation(instance))
+            return NO_LOCATION; /* No location */
+        else
+            return locationOf(HERO);
+    }
+}
+
+
+/*======================================================================*/
+/* Return the current position of an instance, directly or not */
+/* TODO: this will be a possible duplicate of where() */
+int positionOf(int instance)
+{
+    return admin[instance].location;
+}
+
+
+/*======================================================================*/
+/* Return the current position of an instance, directly or not */
+int where(int instance, ATrans trans)
+{
+    verifyInstance(instance, "WHERE");
+
+    if (isALocation(instance))
+        return 0;
+    else if (trans == DIRECT)
+        return admin[instance].location;
+    else
+        return locationOf(instance);
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool executeInheritedMentioned(int cls) {
+    if (cls == 0) return FALSE;
+
+    if (classes[cls].mentioned) {
+        interpret(classes[cls].mentioned);
+        return TRUE;
+    } else
+        return executeInheritedMentioned(classes[cls].parent);
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool mention(int instance) {
+    if (instances[instance].mentioned) {
+        interpret(instances[instance].mentioned);
+        return TRUE;
+    } else
+        return executeInheritedMentioned(instances[instance].parent);
+}
+
+
+/*======================================================================*/
+void sayInstance(int instance)
+{
+#ifdef SAY_INSTANCE_WITH_PLAYER_WORDS_IF_PARAMETER
+    int p, i;
+
+    /* Find the id in the parameters... */
+    if (params != NULL)
+        for (p = 0; params[p].code != EOF; p++)
+            if (params[p].code == instance) {
+                /* Found it so.. */
+                if (params[p].firstWord == EOF) /* Any words he used? */
+                    break;      /* No... */
+                else {              /* Yes, so use them... */
+                    char *capitalized;
+                    /* Assuming the noun is the last word we can simply output the adjectives... */
+                    for (i = params[p].firstWord; i <= params[p].lastWord-1; i++)
+                        output((char *)pointerTo(dict[wrds[i]].wrd));
+                    /* ... and then the noun, capitalized if necessary */
+                    if (header->capitalizeNouns) {
+                        capitalized = strdup((char *)pointerTo(dict[wrds[params[p].lastWord]].wrd));
+                        capitalized[0] = IsoToUpperCase(capitalized[0]);
+                        output(capitalized);
+                        deallocate(capitalized);
+                    } else
+                        output((char *)pointerTo(dict[wrds[params[p].lastWord]].wrd));
+                }
+                return;
+            }
+#endif
+    if (!mention(instance))
+        interpret(instances[instance].name);
+}
+
+
+/*======================================================================*/
+void sayInteger(int value)
+{
+    char buf[25];
+
+    if (isHere(HERO, /*FALSE*/ TRANSITIVE)) {
+        sprintf(buf, "%d", value);
+        output(buf);
+    }
+}
+
+
+/*======================================================================*/
+void sayString(char *string)
+{
+    if (isHere(HERO, /*FALSE*/ TRANSITIVE))
+        output(string);
+    deallocate(string);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayLiteral(int literal)
+{
+    char *str;
+
+    if (isANumeric(literal))
+        sayInteger(literals[literal-header->instanceMax].value);
+    else {
+        str = (char *)strdup((char *)fromAptr(literals[literal-header->instanceMax].value));
+        sayString(str);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *wordWithCode(int classBit, int code) {
+    int w;
+    char str[50];
+
+    for (w = 0; w < dictionarySize; w++)
+        if (dictionary[w].code == code && ((classBit&dictionary[w].classBits) != 0))
+            return (char *)pointerTo(dictionary[w].string);
+    sprintf(str, "Could not find word of class %d with code %d.", classBit, code);
+    syserr(str);
+    return NULL;
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool sayInheritedDefiniteForm(int cls) {
+    if (cls == 0) {
+        syserr("No default definite article");
+        return FALSE;
+    } else {
+        if (classes[cls].definite.address) {
+            interpret(classes[cls].definite.address);
+            return classes[cls].definite.isForm;
+        } else
+            return sayInheritedDefiniteForm(classes[cls].parent);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayDefinite(int instance) {
+    if (instances[instance].definite.address) {
+        interpret(instances[instance].definite.address);
+        if (!instances[instance].definite.isForm)
+            sayInstance(instance);
+    } else
+        if (!sayInheritedDefiniteForm(instances[instance].parent))
+            sayInstance(instance);
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool sayInheritedIndefiniteForm(int cls) {
+    if (cls == 0) {
+        syserr("No default indefinite article");
+        return FALSE;
+    } else {
+        if (classes[cls].indefinite.address) {
+            interpret(classes[cls].indefinite.address);
+            return classes[cls].indefinite.isForm;
+        } else
+            return sayInheritedIndefiniteForm(classes[cls].parent);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayIndefinite(int instance) {
+    if (instances[instance].indefinite.address) {
+        interpret(instances[instance].indefinite.address);
+        if (!instances[instance].indefinite.isForm)
+            sayInstance(instance);
+    } else
+        if (!sayInheritedIndefiniteForm(instances[instance].parent))
+            sayInstance(instance);
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool sayInheritedNegativeForm(int cls) {
+    if (cls == 0) {
+        syserr("No default negative form");
+        return FALSE;
+    } else {
+        if (classes[cls].negative.address) {
+            interpret(classes[cls].negative.address);
+            return classes[cls].negative.isForm;
+        } else
+            return sayInheritedNegativeForm(classes[cls].parent);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayNegative(int instance) {
+    if (instances[instance].negative.address) {
+        interpret(instances[instance].negative.address);
+        if (!instances[instance].negative.isForm)
+            sayInstance(instance);
+    } else
+        if (!sayInheritedNegativeForm(instances[instance].parent))
+            sayInstance(instance);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayInheritedPronoun(int instance) {
+    if (instance == 0)
+        syserr("No default pronoun");
+    else {
+        if (classes[instance].pronoun != 0)
+            output(wordWithCode(PRONOUN_BIT, classes[instance].pronoun));
+        else
+            sayInheritedPronoun(classes[instance].parent);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayPronoun(int instance) {
+    if (instances[instance].pronoun != 0)
+        output(wordWithCode(PRONOUN_BIT, instances[instance].pronoun));
+    else
+        sayInheritedPronoun(instances[instance].parent);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void sayArticleOrForm(int id, SayForm form)
+{
+    if (!isLiteral(id))
+        switch (form) {
+        case SAY_DEFINITE:
+            sayDefinite(id);
+            break;
+        case SAY_INDEFINITE:
+            sayIndefinite(id);
+            break;
+        case SAY_NEGATIVE:
+            sayNegative(id);
+            break;
+        case SAY_PRONOUN:
+            sayPronoun(id);
+            break;
+        case SAY_SIMPLE:
+            say(id);
+            break;
+        default:
+            syserr("Unexpected form in 'sayArticleOrForm()'");
+        }
+    else
+        say(id);
+}
+
+
+/*======================================================================*/
+void say(int instance)
+{
+    Aword previousInstance = current.instance;
+    current.instance = instance;
+
+    if (isHere(HERO, /*FALSE*/ TRANSITIVE)) {
+        if (isLiteral(instance))
+            sayLiteral(instance);
+        else {
+            verifyInstance(instance, "SAY");
+            sayInstance(instance);
+        }
+    }
+    current.instance = previousInstance;
+}
+
+
+/*======================================================================*/
+void sayForm(int instance, SayForm form)
+{
+    Aword previousInstance = current.instance;
+    current.instance = instance;
+
+    sayArticleOrForm(instance, form);
+
+    current.instance = previousInstance;
+}
+
+
+/*======================================================================*/
+bool isDescribable(int instance) {
+    return isAObject(instance) || isAActor(instance);
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool inheritsDescriptionFrom(int cls)
+{
+    if (classes[cls].description != 0)
+        return TRUE;
+    else if (classes[cls].parent != 0)
+        return inheritsDescriptionFrom(classes[cls].parent);
+    else
+        return FALSE;
+}
+
+
+/*======================================================================*/
+bool hasDescription(int instance)
+{
+    if (instances[instance].description != 0)
+        return TRUE;
+    else if (instances[instance].parent != 0)
+        return inheritsDescriptionFrom(instances[instance].parent);
+    else
+        return FALSE;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void describeClass(int instance)
+{
+    if (classes[instance].description != 0) {
+        /* This class has a description, run it */
+        interpret(classes[instance].description);
+    } else {
+        /* Search up the inheritance tree, if any, to find a description */
+        if (classes[instance].parent != 0)
+            describeClass(classes[instance].parent);
+    }
+}
+
+
+/*======================================================================*/
+void describeAnything(int instance)
+{
+    if (instances[instance].description != 0) {
+        /* This instance has its own description, run it */
+        interpret(instances[instance].description);
+    } else {
+        /* Search up the inheritance tree to find a description */
+        if (instances[instance].parent != 0)
+            describeClass(instances[instance].parent);
+    }
+    admin[instance].alreadyDescribed = TRUE;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void describeObject(int object)
+{
+    if (hasDescription(object))
+        describeAnything(object);
+    else {
+        printMessageWithInstanceParameter(M_SEE_START, object);
+        printMessage(M_SEE_END);
+        if (instances[object].container != 0)
+            describeContainer(object);
+    }
+    admin[object].alreadyDescribed = TRUE;
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool inheritedDescriptionCheck(int cls)
+{
+    if (cls == 0) return TRUE;
+    if (!inheritedDescriptionCheck(classes[cls].parent)) return FALSE;
+    if (classes[cls].descriptionChecks == 0) return TRUE;
+    return !checksFailed(classes[cls].descriptionChecks, TRUE);
+}
+
+/*----------------------------------------------------------------------*/
+static bool descriptionCheck(int instance)
+{
+    int previousInstance = current.instance;
+    bool r;
+
+    current.instance = instance;
+    if (inheritedDescriptionCheck(instances[instance].parent)) {
+        if (instances[instance].checks == 0)
+            r = TRUE;
+        else
+            r = !checksFailed(instances[instance].checks, TRUE);
+    } else
+        r = FALSE;
+    current.instance = previousInstance;
+    return r;
+}
+
+
+/*======================================================================*/
+void describeInstances(void)
+{
+    int i;
+    int lastInstanceFound = 0;
+    int found = 0;
+
+    /* First describe every object here with its own description */
+    for (i = 1; i <= header->instanceMax; i++)
+        if (admin[i].location == current.location && isAObject(i) &&
+                !admin[i].alreadyDescribed && hasDescription(i))
+            describe(i);
+
+    /* Then list all things without a description */
+    for (i = 1; i <= header->instanceMax; i++)
+        if (admin[i].location == current.location
+                && !admin[i].alreadyDescribed
+                && isAObject(i)
+                && descriptionCheck(i)) {
+            if (found == 0)
+                printMessageWithInstanceParameter(M_SEE_START, i);
+            else if (found > 1)
+                printMessageWithInstanceParameter(M_SEE_COMMA, lastInstanceFound);
+            admin[i].alreadyDescribed = TRUE;
+
+            // TODO : isOpaque()
+            if (instances[i].container && containerSize(i, DIRECT) > 0 && !getInstanceAttribute(i, OPAQUEATTRIBUTE)) {
+                if (found > 0)
+                    printMessageWithInstanceParameter(M_SEE_AND, i);
+                printMessage(M_SEE_END);
+                describeContainer(i);
+                found = 0;
+                continue;       /* Actually start another list. */
+            }
+            found++;
+            lastInstanceFound = i;
+        }
+
+    if (found > 0) {
+        if (found > 1) {
+            printMessageWithInstanceParameter(M_SEE_AND, lastInstanceFound);
+        }
+        printMessage(M_SEE_END);
+    }
+
+    /* Finally all actors with a separate description */
+    for (i = 1; i <= header->instanceMax; i++)
+        if (admin[i].location == current.location && i != HERO && isAActor(i)
+        && !admin[i].alreadyDescribed)
+            describe(i);
+
+    /* Clear the describe flag for all instances */
+    for (i = 1; i <= header->instanceMax; i++)
+        admin[i].alreadyDescribed = FALSE;
+}
+
+
+/*======================================================================*/
+bool describe(int instance)
+{
+    bool descriptionOk;
+    int previousInstance = current.instance;
+
+    current.instance = instance;
+    verifyInstance(instance, "DESCRIBE");
+    if (descriptionCheck(instance)) {
+        descriptionOk = TRUE;
+        if (isAObject(instance)) {
+            describeObject(instance);
+        } else if (isAActor(instance)) {
+            describeActor(instance);
+        } else
+            describeAnything(instance);
+    } else
+        descriptionOk = FALSE;
+    current.instance = previousInstance;
+    return descriptionOk;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void locateIntoContainer(Aword theInstance, Aword theContainer) {
+    if (!isA(theInstance, containers[instances[theContainer].container]._class))
+        printMessageUsing2InstanceParameters(M_CANNOTCONTAIN, theContainer, theInstance);
+    else if (passesContainerLimits(theContainer, theInstance))
+        admin[theInstance].location = theContainer;
+    else
+        abortPlayerCommand();
+}
+
+
+/*----------------------------------------------------------------------*/
+static void locateLocation(Aword loc, Aword whr)
+{
+    Aint l = whr;
+
+    /* Ensure this does not create a recursive location chain */
+    while (l != 0) {
+        if (admin[l].location == loc)
+            apperr("Locating a location that would create a recursive loop of locations containing each other.");
+        else
+            l = admin[l].location;
+    }
+    admin[loc].location = whr;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void locateObject(Aword obj, Aword whr)
+{
+    if (isAContainer(whr)) { /* Into a container */
+        locateIntoContainer(obj, whr);
+    } else {
+        admin[obj].location = whr;
+        /* Make sure the location is described since it's changed */
+        admin[whr].visitsCount = 0;
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceEnteredClass(Aint theClass, bool empty) {
+    printf("\n<ENTERED in class ");
+    printf("%s", idOfClass(theClass));
+    printf("[%d]%s>\n", theClass, empty?" is empty":":");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceEnteredInstance(Aint instance, bool empty) {
+    printf("\n<ENTERED in instance ");
+    traceSay(instance);
+    printf("[%d]%s>\n", instance, empty?" is empty":"");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void executeInheritedEntered(Aint theClass) {
+    if (theClass == 0) return;
+    executeInheritedEntered(classes[theClass].parent);
+    if (traceSectionOption)
+        traceEnteredClass(theClass, classes[theClass].entered == 0);
+    if (classes[theClass].entered) {
+        interpret(classes[theClass].entered);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void executeEntered(Aint instance) {
+    int currentInstance = current.instance;
+    current.instance = instance;
+    if (admin[instance].location != 0)
+        executeEntered(admin[instance].location);
+    executeInheritedEntered(instances[instance].parent);
+    if (traceSectionOption)
+        traceEnteredInstance(instance, instances[instance].entered == 0);
+    if (instances[instance].entered != 0) {
+        interpret(instances[instance].entered);
+    }
+    current.instance = currentInstance;
+}
+
+
+/*----------------------------------------------------------------------*/
+static int getVisits(int location) {
+    return getInstanceAttribute(location, VISITSATTRIBUTE);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void incrementVisits(int location) {
+    setInstanceAttribute(location, VISITSATTRIBUTE, getVisits(location)+1);
+    if (admin[location].location != 0)
+        /* Nested location, so increment that too */
+        incrementVisits(admin[location].location);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void revisited(void) {
+    if (anyOutput)
+        para();
+    say(where(HERO, DIRECT));
+    printMessage(M_AGAIN);
+    newline();
+    describeInstances();
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool shouldBeDescribed(void) {
+    if (!isPreBeta5(header->version))
+        return getVisits(admin[HERO].location) % (current.visits+1) == 0
+            || admin[admin[HERO].location].visitsCount == 0;
+    else
+        return admin[admin[HERO].location].visitsCount % (current.visits+1) == 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void locateActor(Aint movingActor, Aint whr)
+{
+    Aint previousCurrentLocation = current.location;
+    Aint previousActorLocation = admin[movingActor].location;
+    Aint previousActor = current.actor;
+    Aint previousInstance = current.instance;
+
+    /* Before leaving, remember that we visited the location */
+    if (!isPreBeta5(header->version))
+        if (movingActor == HERO)
+            incrementVisits(where(HERO, DIRECT));
+
+    /* TODO Actors locating into containers is dubious, anyway as it
+       is now it allows the hero to be located into a container. And what
+       happens with current location if so... */
+    if (isAContainer(whr))
+        locateIntoContainer(movingActor, whr);
+    else {
+        current.location = whr;
+        admin[movingActor].location = whr;
+    }
+
+    /* Now we have moved, so show what is needed... */
+    current.instance = current.location;
+
+    /* Execute possible entered */
+    current.actor = movingActor;
+    if (previousActorLocation != current.location) {
+        executeEntered(current.location);
+    }
+    current.instance = previousInstance;
+    current.actor = previousActor;
+
+    if (movingActor == HERO) {
+        if (shouldBeDescribed())
+            look();
+        else
+            revisited();
+        admin[where(HERO, DIRECT)].visitsCount++;
+    } else
+        /* Ensure that the location will be described to the hero next time */
+        admin[whr].visitsCount = 0;
+
+    if (current.actor != movingActor)
+        current.location = previousCurrentLocation;
+
+    current.instance = previousInstance;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceExtract(int instance, int containerId, char *what) {
+    if (traceSectionOption) {
+        printf("\n<EXTRACT from ");
+        traceSay(instance);
+        printf("[%d, container %d], %s:>\n", instance, containerId, what);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void containmentLoopError(int instance, int whr) {
+    ParameterArray parameters = newParameterArray();
+    if (isPreBeta4(header->version))
+        output("That would be to put something inside itself.");
+    else if (whr == instance) {
+        addParameterForInstance(parameters, instance);
+        printMessageWithParameters(M_CONTAINMENT_LOOP, parameters);
+    } else {
+        addParameterForInstance(parameters, instance);
+        addParameterForInstance(parameters, whr);
+        printMessageWithParameters(M_CONTAINMENT_LOOP2, parameters);
+    }
+    free(parameters);
+    error(NO_MSG);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void runExtractStatements(int instance, int containerId) {
+    ContainerEntry *theContainer = &containers[containerId];
+
+    if (theContainer->extractStatements != 0) {
+        traceExtract(instance, containerId, "Executing");
+        interpret(theContainer->extractStatements);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static bool runExtractChecks(int instance, int containerId) {
+    ContainerEntry *theContainer = &containers[containerId];
+
+    if (theContainer->extractChecks != 0) {
+        traceExtract(instance, containerId, "Checking");
+        if (checksFailed(theContainer->extractChecks, EXECUTE_CHECK_BODY_ON_FAIL)) {
+            fail = TRUE;
+            return FALSE;       /* Failed! */
+        }
+    }
+    return TRUE;                /* Passed! */
+}
+
+
+/*======================================================================*/
+void locate(int instance, int whr)
+{
+    int containerId;
+    int previousInstance = current.instance;
+
+    verifyInstance(instance, "LOCATE");
+    verifyInstance(whr, "LOCATE AT");
+
+    /* Will this create a containment loop? */
+    if (whr == instance || (isAContainer(instance) && isIn(whr, instance, TRANSITIVE)))
+        containmentLoopError(instance, whr);
+
+    /* First check if the instance is in a container, if so run extract checks */
+    if (isAContainer(admin[instance].location)) {    /* In something? */
+        int loc = admin[instance].location;
+
+        /* Run all nested extraction checks */
+        while (isAContainer(loc)) {
+            current.instance = loc;
+            containerId = instances[loc].container;
+
+            if (!runExtractChecks(instance, containerId)) {
+                current.instance = previousInstance;
+                return;
+            }
+            runExtractStatements(instance, containerId);
+            loc = admin[loc].location;
+        }
+        current.instance = previousInstance;
+    }
+
+    if (isAActor(instance))
+        locateActor(instance, whr);
+    else if (isALocation(instance))
+        locateLocation(instance, whr);
+    else
+        locateObject(instance, whr);
+
+    gameStateChanged = TRUE;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/instance.h b/engines/glk/alan3/instance.h
new file mode 100644
index 0000000..2b5adb3
--- /dev/null
+++ b/engines/glk/alan3/instance.h
@@ -0,0 +1,97 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_INSTANCE
+#define GLK_ALAN3_INSTANCE
+
+#include "glk/alan3/acode.h"
+#include "glk/alan3/types.h"
+#include "glk/alan3/set.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* Types: */
+struct AdminEntry { /* Administrative data about instances */
+  Aint location;
+  AttributeEntry *attributes;
+  Abool alreadyDescribed;
+  Aint visitsCount;
+  Aint script;
+  Aint step;
+  Aint waitCount;
+};
+
+
+/* Data: */
+extern InstanceEntry *instances; /* Instance table pointer */
+
+extern AdminEntry *admin;   /* Administrative data about instances */
+extern AttributeEntry *attributes; /* Dynamic attribute values */
+
+
+/* Functions: */
+extern bool isA(int instance, int ancestor);
+extern bool isAObject(int instance);
+extern bool isAContainer(int instance);
+extern bool isAActor(int instance);
+extern bool isALocation(int instance);
+extern bool isLiteral(int instance);
+extern bool isANumeric(int instance);
+extern bool isAString(int instance);
+
+extern Aptr getInstanceAttribute(int instance, int attribute);
+extern char *getInstanceStringAttribute(int instane, int attribute);
+extern Set *getInstanceSetAttribute(int instance, int attribute);
+
+extern void setInstanceAttribute(int instance, int atr, Aptr value);
+extern void setInstanceStringAttribute(int instance, int attribute, char *string);
+extern void setInstanceSetAttribute(int instance, int atr, Aptr set);
+
+extern void say(int instance);
+extern void sayForm(int instance, SayForm form);
+extern void sayInstance(int instance);
+
+extern bool hasDescription(int instance);
+extern bool isDescribable(int instance);
+extern void describeAnything(int instance);
+extern void describeInstances(void);
+extern bool describe(int instance);
+
+extern int where(int instance, ATrans trans);
+extern int positionOf(int instance);
+extern int locationOf(int instance);
+
+extern bool isAt(int instance, int other, ATrans trans);
+extern bool isIn(int instance, int theContainer, ATrans trans);
+extern bool isHere(int instance, ATrans trans);
+extern bool isNearby(int instance, ATrans trans);
+extern bool isNear(int instance, int other, ATrans trans);
+
+extern bool isOpaque(int container);
+
+extern void locate(int instance, int whr);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
new file mode 100644
index 0000000..56f6966
--- /dev/null
+++ b/engines/glk/alan3/inter.cpp
@@ -0,0 +1,1412 @@
+/* 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/alan3/inter.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/exe.h"
+#include "glk/alan3/syserr.h"
+#include "glk/alan3/debug.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/save.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/score.h"
+#include "glk/alan3/params.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/container.h"
+#include "glk/alan3/location.h"
+#include "glk/alan3/compatibility.h"
+
+#ifdef HAVE_GLK
+#define MAP_STDIO_TO_GLK
+#include "glk/alan3/glkio.h"
+#endif
+
+namespace Glk {
+namespace Alan3 {
+
+bool stopAtNextLine = FALSE;
+bool fail = FALSE;
+
+
+/* PRIVATE DATA */
+
+static int pc;
+static Stack stack = NULL;
+
+static void (*interpreterMock)(Aaddr adr) = NULL;
+
+
+/*======================================================================*/
+void setInterpreterMock(void (*mock)(Aaddr adr)) {
+    interpreterMock = mock;
+}
+
+
+/*======================================================================*/
+void setInterpreterStack(Stack theStack)
+{
+    stack = theStack;
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceInstruction(char *str, ...) {
+    va_list args;
+
+    if (traceInstructionOption) {
+        va_start(args, str);
+		Common::String msg = Common::String::format(str, args);
+		va_end(args);
+
+		printf("%s", msg.c_str());
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void traceSkip() {
+    printf("\n    : \t\t\t\t\t\t\t");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void interpretIf(Aword v)
+{
+    int lev = 1;
+    Aword i;
+
+    if (!v) {
+        /* Skip to next ELSE or ENDIF on same level */
+        if (traceInstructionOption) traceSkip();
+        while (TRUE) {
+            i = memory[pc++];
+            if (I_CLASS(i) == (Aword)C_STMOP)
+                switch (I_OP(i)) {
+                case I_ELSE:
+                    if (lev == 1) {
+                        if (traceInstructionOption)
+                            printf("\n%4x: ELSE\t\t\t\t\t\t", pc);
+                        return;
+                    }
+                    break;
+                case I_IF:
+                    lev++;
+                    break;
+                case I_ENDIF:
+                    lev--;
+                    if (lev == 0) {
+                        if (traceInstructionOption)
+                            printf("\n%4x: ENDIF\t\t\t\t\t\t", pc);
+                        return;
+                    }
+                    break;
+                }
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void interpretElse(void)
+{
+    int lev = 1;
+    Aword i;
+
+    if (traceInstructionOption) traceSkip();
+    while (TRUE) {
+        /* Skip to ENDIF on the same level */
+        i = memory[pc++];
+        if (I_CLASS(i) == (Aword)C_STMOP)
+            switch (I_OP(i)) {
+            case I_ENDIF:
+                lev--;
+                if (lev == 0) return;
+                break;
+            case I_IF:
+                lev++;
+                break;
+            }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void goToLOOPEND(void) {
+    int level = 1;
+    int i;
+
+    if (traceInstructionOption) traceSkip();
+    while (TRUE) {
+        /* Skip past LOOPEND on the same level */
+        i = memory[pc];
+        if (I_CLASS(i) == (Aword)C_STMOP)
+            switch (I_OP(i)) {
+            case I_LOOPEND:
+                level--;
+                if (level == 0)
+                    return;
+                break;
+            case I_LOOP:
+                level++;
+                break;
+            }
+        pc++;
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void jumpBackToStartOfMatchingLOOP(void) {
+    int level = 1;
+    int i;
+
+    if (traceInstructionOption) traceSkip();
+    pc--;				/* Ignore the instruction we're on */
+    while (TRUE) {
+        /* Skip back past LOOP on the same level */
+        i = memory[--pc];
+        if (I_CLASS(i) == (Aword)C_STMOP)
+            switch (I_OP(i)) {
+            case I_LOOPEND:
+                level++;
+                break;
+            case I_LOOP:
+                level--;
+                if (level == 0) {
+                    return;
+                }
+                break;
+            }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void nextLoop(void)
+{
+    goToLOOPEND();
+}
+
+
+/*----------------------------------------------------------------------*/
+static void endLoop(Aint index, Aint limit)
+{
+    if (index < limit) {
+        index++;
+        push(stack, limit);
+        push(stack, index);
+        jumpBackToStartOfMatchingLOOP();
+        if (traceInstructionOption)
+            printf("\n%4x: LOOP\t\t\t\t\t\t", pc);
+        pc++;
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void stackDup(void)
+{
+    push(stack, top(stack));
+}
+
+
+/*----------------------------------------------------------------------*/
+static void depexec(Aword v)
+{
+    int lev = 1;
+    Aword i;
+    char *instructionString = "DEPELSE";
+
+    if (!v) {
+        /* The expression was not true, skip to next CASE on the same
+           level which could be a DEPCASE or DEPELSE */
+        if (traceInstructionOption) printf("\n    : ");
+        while (TRUE) {
+            i = memory[pc++];
+            if (I_CLASS(i) == (Aword)C_STMOP)
+                switch (I_OP(i)) {
+                case I_DEPEND:
+                    lev++;
+                    break;
+                case I_ENDDEP:
+                    if (lev == 1) {
+                        pc--;
+                        if (traceInstructionOption)
+                            printf("\n%4x: ENDDEP", pc);
+                        return;
+                    } else
+                        lev--;
+                    break;
+                case I_DEPCASE:
+                    instructionString = "DEPCASE";
+                case I_DEPELSE:
+                    if (lev == 1) {
+                        if (traceInstructionOption)
+                            printf("\n%4x: %s", pc, instructionString);
+                        return;
+                    }
+                    break;
+                }
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void depcase(void)
+{
+    int lev = 1;
+    Aword i;
+
+    /*
+      We have just executed a DEPCASE/DEPELSE clause as a result of a
+      DEPCASE catching so skip to end of DEPENDING block (next DEPEND
+      on same level) then return.
+    */
+
+    if (traceInstructionOption) printf("\n    : ");
+    while (TRUE) {
+        i = memory[pc++];
+        if (I_CLASS(i) == (Aword)C_STMOP)
+            switch (I_OP(i)) {
+            case I_DEPEND:
+                lev++;
+                break;
+            case I_ENDDEP:
+                lev--;
+                if (lev == 0) {
+                    pc--;
+                    return;
+                }
+                break;
+            }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *booleanValue(Abool value) {
+    if (value) return "   TRUE";
+    else return "  FALSE";
+}
+
+/*----------------------------------------------------------------------*/
+static char *stringValue(Aptr address) {
+    static char string[1000];
+
+    sprintf(string, "0x%lx (\"%s\")\t\t", (unsigned long) address, (char *)fromAptr(address));
+    return string;
+}
+
+/*----------------------------------------------------------------------*/
+static char *pointerValue(Aptr address) {
+    static char string[100];
+
+    sprintf(string, "@%6lx",(unsigned long) address);
+    return string;
+}
+
+/*----------------------------------------------------------------------*/
+static void traceStringTopValue() {
+    if (traceInstructionOption)
+        printf("\t=%s", stringValue(top(stack)));
+}
+
+/*----------------------------------------------------------------------*/
+static void tracebooleanTopValue() {
+    if (traceInstructionOption) {
+        if (top(stack)) printf("\t=TRUE\t");
+        else printf("\t=FALSE\t");
+    }
+}
+
+/*----------------------------------------------------------------------*/
+static void traceIntegerTopValue() {
+    if (traceInstructionOption)
+        printf("\t=%ld\t", (long)top(stack));
+}
+
+/*----------------------------------------------------------------------*/
+static void tracePointerTopValue() {
+    if (traceInstructionOption)
+        printf("\t=%s\t", pointerValue(top(stack)));
+}
+
+/*----------------------------------------------------------------------*/
+static void traceInstanceTopValue() {
+    if (traceInstructionOption) {
+        printf("\t=%ld ('", (long)top(stack));
+        traceSay(top(stack));
+        printf("')");
+        if (traceStackOption)
+            printf("\n\t\t\t\t\t\t\t");
+    }
+}
+
+/*----------------------------------------------------------------------*/
+static char *transitivityFlag(ATrans value) {
+    switch (value) {
+    case TRANSITIVE:
+        return "Transitive";
+    case DIRECT:
+        return "Direct";
+    case INDIRECT:
+        return "Indirect";
+    }
+    syserr("Unexpected transitivity");
+    return "ERROR";
+}
+
+/*----------------------------------------------------------------------*/
+static char *printForm(SayForm form) {
+    switch (form) {
+    case SAY_SIMPLE: return "-";
+    case SAY_INDEFINITE: return "An";
+    case SAY_DEFINITE: return "The";
+    case SAY_NEGATIVE: return "No";
+    case SAY_PRONOUN: return "It";
+    }
+    return "**Unknown!!***";
+}
+
+
+static Aaddr invocation[1000];
+int recursionDepth = 0;
+
+/*----------------------------------------------------------------------*/
+static void checkForRecursion(Aaddr adr) {
+    int i;
+
+    for (i = 0; i < recursionDepth; i++)
+        if (invocation[i] == adr)
+            apperr("Interpreter recursion.");
+    invocation[recursionDepth++] = adr;
+    if (recursionDepth > 1000)
+        syserr("Interpreter call stack too deep.");
+}
+
+
+static bool skipStackDump = FALSE; /* Need to be able to skip it for LINE */
+
+
+/*----------------------------------------------------------------------*/
+static bool stillOnSameLine(Aint line, Aint file) {
+	return line != current.sourceLine || file != current.sourceFile;
+}
+
+
+/*======================================================================*/
+void interpret(Aaddr adr)
+{
+    Aaddr oldpc;
+    Aword i;
+
+    /* Check for mock implementation */
+    if (interpreterMock != NULL) {
+        interpreterMock(adr);
+        return;
+    }
+
+    /* Sanity checks: */
+    if (adr == 0) syserr("Interpreting at address 0.");
+    checkForRecursion(adr);
+
+    if (traceInstructionOption)
+        printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++");
+
+    oldpc = pc;
+    pc = adr;
+    while(TRUE) {
+        if (pc > memTop)
+            syserr("Interpreting outside program.");
+
+        i = memory[pc++];
+
+        switch (I_CLASS(i)) {
+        case C_CONST:
+            if (tracePushOption) printf("\n%4x: PUSH  \t%7ld\t\t\t\t\t", pc-1, (long)I_OP(i));
+            push(stack, I_OP(i));
+            if (tracePushOption && traceStackOption)
+                dumpStack(stack);
+            break;
+        case C_CURVAR:
+            if (traceInstructionOption) printf("\n%4x: ", pc-1);
+            switch (I_OP(i)) {
+            case V_PARAM:
+                if (traceInstructionOption) printf("PARAM \t%7ld\t\t\t\t=%ld\t", (long)top(stack),
+                                             (long)globalParameters[top(stack)-1].instance);
+                push(stack, globalParameters[pop(stack)-1].instance);
+                break;
+            case V_CURLOC:
+                if (traceInstructionOption) printf("CURLOC \t\t\t\t\t=%d\t", current.location);
+                push(stack, current.location);
+                break;
+            case V_CURACT:
+                if (traceInstructionOption) printf("CURACT \t\t\t\t\t=%d\t", current.actor);
+                push(stack, current.actor);
+                break;
+            case V_CURVRB:
+                if (traceInstructionOption) printf("CURVRB \t\t\t\t\t=%d\t", current.verb);
+                push(stack, current.verb);
+                break;
+            case V_CURRENT_INSTANCE:
+                if (traceInstructionOption) printf("CURINS \t\t\t\t\t=%d\t", current.instance);
+                push(stack, current.instance);
+                break;
+            case V_SCORE:
+                if (traceInstructionOption) printf("CURSCORE \t\t\t\t\t=%d\t", current.score);
+                push(stack, current.score);
+                break;
+            case V_MAX_INSTANCE: {
+                int instanceMax = isPreBeta3(header->version)?header->instanceMax:header->instanceMax-1;
+                if (traceInstructionOption) printf("MAXINSTANCE \t\t\t\t=%d\t", instanceMax);
+                push(stack, instanceMax);
+                break;
+            }
+            default:
+                syserr("Unknown CURVAR instruction.");
+                break;
+            }
+            if (traceStackOption)
+                dumpStack(stack);
+            break;
+
+        case C_STMOP:
+            if (traceInstructionOption) printf("\n%4x: ", pc-1);
+            switch (I_OP(i)) {
+
+            case I_DUP:
+                if (traceInstructionOption)
+                    printf("DUP\t\t\t\t\t\t");
+                stackDup();
+                break;
+
+            case I_DUPSTR:
+                if (traceInstructionOption)
+                    printf("DUPSTR\t\t\t\t\t\t");
+                push(stack, toAptr(strdup((char*)fromAptr(top(stack)))));
+                break;
+
+            case I_POP: {
+                Aptr top = pop(stack);
+                if (traceInstructionOption)
+                    printf("POP\t%7ld", (long)top);
+                break;
+            }
+
+            case I_LINE: {
+                Aint line = pop(stack);
+                Aint file = pop(stack);
+                traceInstruction("LINE\t%7ld, %7ld\t\t\t", (long)file, (long)line);
+                if (traceStackOption)
+                    dumpStack(stack);
+                skipStackDump = TRUE;
+                if (line != 0) {
+                    bool atNext = stopAtNextLine && line != current.sourceLine;
+                    bool atBreakpoint =  breakpointIndex(file, line) != -1;
+                    if (traceSourceOption && stillOnSameLine(line, file)) {
+                        if (col != 1 || traceInstructionOption)
+                            printf("\n");
+                        showSourceLine(file, line);
+                        if (!traceInstructionOption)
+                            printf("\n");
+                    }
+                    current.sourceLine = line;
+                    current.sourceFile = file;
+                    if (atNext || atBreakpoint) {
+                        stopAtNextLine = FALSE;
+                        debug(TRUE, line, file);
+                    }
+                }
+                break;
+            }
+
+            case I_PRINT: {
+                Aint fpos = pop(stack);
+                Aint len = pop(stack);
+                if (traceInstructionOption) {
+	                printf("PRINT \t%7ld, %7ld\t\"", (long)fpos, (long)len);
+                    col = 41;		/* To break lines better! */
+                }
+                print(fpos, len);
+                if (traceInstructionOption) {
+                    printf("\"");
+                    if (traceStackOption)
+                        printf("\n\t\t\t\t\t\t\t");
+                }
+                break;
+            }
+
+            case I_STYLE: {
+                Aint style = pop(stack);
+                if (traceInstructionOption) {
+                    printf("STYLE \t%7ld\t\t\"", (long)style);
+                }
+                setStyle(style);
+                break;
+            }
+
+            case I_SYSTEM: {
+                Aint fpos = pop(stack);
+                Aint len = pop(stack);
+                if (traceInstructionOption) {
+                    printf("SYSTEM \t%7ld, %7ld\t\"", (long)fpos, (long)len);
+                    col = 34;		/* To format it better! */
+                }
+                sys(fpos, len);
+                if (traceInstructionOption)
+                    printf("\"\t\t\t\t\t\t");
+                break;
+            }
+
+            case I_GETSTR: {
+                Aint fpos = pop(stack);
+                Aint len = pop(stack);
+                if (traceInstructionOption)
+                    printf("GETSTR\t%7ld, %7ld", (long)fpos, (long)len);
+                push(stack, toAptr(getStringFromFile(fpos, len)));
+                traceStringTopValue();
+                break;
+            }
+
+            case I_QUIT: {
+                if (traceInstructionOption)
+                    printf("QUIT\t\t\t\t\t\t");
+                quitGame();
+                break;
+            }
+            case I_LOOK: {
+                if (traceInstructionOption)
+                    printf("LOOK\t\t\t\t\t\t");
+                look();
+                break;
+            }
+            case I_SAVE: {
+                if (traceInstructionOption)
+                    printf("SAVE\t\t\t\t\t\t");
+                save();
+                break;
+            }
+            case I_RESTORE: {
+                if (traceInstructionOption)
+                    printf("RESTORE\t\t\t\t\t\t");
+                restore();
+                break;
+            }
+            case I_RESTART: {
+                if (traceInstructionOption)
+                    printf("RESTART\t\t\t\t\t\t");
+                restartGame();
+                break;
+            }
+
+            case I_SCORE: {
+                Aint sc = pop(stack);
+                if (traceInstructionOption)
+                    printf("SCORE \t%7ld\t\t=%ld\t\t\t", (long)sc, (long)scores[sc-1]);
+                score(sc);
+                break;
+            }
+            case I_VISITS: {
+                Aint v = pop(stack);
+                if (traceInstructionOption)
+                    printf("VISITS \t%7ld\t\t\t\t\t", (long)v);
+                visits(v);
+                break;
+            }
+
+            case I_LIST: {
+                Aint cnt = pop(stack);
+                if (traceInstructionOption)
+                    printf("LIST \t%7ld\t\t\t\t\t", (long)cnt);
+                list(cnt);
+                break;
+            }
+            case I_EMPTY: {
+                Aint cnt = pop(stack);
+                Aint whr = pop(stack);
+                if (traceInstructionOption)
+                    printf("EMPTY \t%7ld, %7ld\t\t\t\t", (long)cnt, (long)whr);
+                empty(cnt, whr);
+                break;
+            }
+            case I_SCHEDULE: {
+                Aint event = pop(stack);
+                Aint where = pop(stack);
+                Aint after = pop(stack);
+                if (traceInstructionOption)
+                    printf("SCHEDULE \t%7ld, %7ld, %7ld\t\t\t\t", (long)event, (long)where, (long)after);
+                schedule(event, where, after);
+                break;
+            }
+            case I_CANCEL: {
+                Aint event = pop(stack);
+                if (traceInstructionOption)
+                    printf("CANCEL \t%7ld\t\t\t\t", (long)event);
+                cancelEvent(event);
+                break;
+            }
+            case I_MAKE: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                Abool val = pop(stack);
+                if (traceInstructionOption)
+                    printf("MAKE \t%7ld, %7ld, %s\t\t\t", (long)id, (long)atr, booleanValue(val));
+                setInstanceAttribute(id, atr, val);
+                break;
+            }
+            case I_SET: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                Aptr val = pop(stack);
+                if (traceInstructionOption) {
+                    printf("SET \t%7ld, %7ld, %7ld\t\t\t\t", (long)id, (long)atr, (long)val);
+                }
+                setInstanceAttribute(id, atr, val);
+                break;
+            }
+            case I_SETSTR: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                Aptr str = pop(stack);
+                if (traceInstructionOption) {
+                    printf("SETSTR\t%7ld, %7ld, %s\t\t\t\t", (long)id, (long)atr, stringValue(str));
+                }
+                setInstanceStringAttribute(id, atr, (char *)fromAptr(str));
+                break;
+            }
+            case I_SETSET: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                Aptr set = pop(stack);
+                if (traceInstructionOption) {
+                    printf("SETSET\t%7ld, %7ld, %7s\t\t", (long)id, (long)atr, pointerValue(set));
+                }
+                setInstanceSetAttribute(id, atr, set);
+                break;
+            }
+            case I_NEWSET: {
+                Set *set = newSet(0);
+                if (traceInstructionOption) {
+                    printf("NEWSET\t\t\t");
+                }
+                push(stack, toAptr(set));
+                tracePointerTopValue();
+                break;
+            }
+            case I_UNION: {
+                Aptr set2 = pop(stack);
+                Aptr set1 = pop(stack);
+                if (traceInstructionOption) {
+                    printf("UNION\t%7ld, %7ld\t\t\t\t", (long)set1, (long)set2);
+                }
+                push(stack, toAptr(setUnion((Set *)fromAptr(set1), (Set *)fromAptr(set2))));
+                tracePointerTopValue();
+                freeSet((Set *)fromAptr(set1));
+                freeSet((Set *)fromAptr(set2));
+                break;
+            }
+            case I_INCR: {
+                Aint step = pop(stack);
+                if (traceInstructionOption) {
+                    printf("INCR\t%7ld", (long)step);
+                }
+                push(stack, pop(stack) + step);
+                traceIntegerTopValue();
+                break;
+            }
+            case I_DECR: {
+                Aint step = pop(stack);
+                if (traceInstructionOption) {
+                    printf("DECR\t%7ld\t\t\t\t\t", (long)step);
+                }
+                push(stack, pop(stack) - step);
+                traceIntegerTopValue();
+                break;
+            }
+            case I_INCLUDE: {
+                Aint member = pop(stack);
+                if (traceInstructionOption) {
+                    printf("INCLUDE\t%7ld\t\t\t\t\t", (long)member);
+                }
+                addToSet((Set *)fromAptr(top(stack)), member);
+                break;
+            }
+            case I_EXCLUDE: {
+                Aint member = pop(stack);
+                if (traceInstructionOption) {
+                    printf("EXCLUDE\t%7ld", (long)member);
+                }
+                removeFromSet((Set *)fromAptr(top(stack)), member);
+                break;
+            }
+            case I_SETSIZE: {
+                Set *set = (Set *)fromAptr(pop(stack));
+                if (traceInstructionOption)
+                    printf("SETSIZE\t%7ld\t\t", (long)set);
+                push(stack, setSize(set));
+                if (traceInstructionOption)
+                    traceIntegerTopValue();
+                break;
+            }
+            case I_SETMEMB: {
+                Set *set = (Set *)fromAptr(pop(stack));
+                Aint index = pop(stack);
+                if (traceInstructionOption)
+                    printf("SETMEMB\t%7ld, %7ld", (long)set, (long)index);
+                push(stack, getSetMember(set, index));
+                if (traceInstructionOption)
+                    traceIntegerTopValue();
+                break;
+            }
+            case I_CONTSIZE: {
+                Abool transitivity = pop(stack);
+                Aint container = pop(stack);
+                if (traceInstructionOption)
+                    printf("CONTSIZE\t%7ld, %7s\t", (long)container, transitivityFlag((ATrans)transitivity));
+                push(stack, containerSize(container, (ATrans)transitivity));
+                if (traceInstructionOption)
+                    traceIntegerTopValue();
+                break;
+            }
+            case I_CONTMEMB: {
+                Abool transitivity = pop(stack);
+                Aint container = pop(stack);
+                Aint index = pop(stack);
+                if (traceInstructionOption)
+                    printf("CONTMEMB\t%7ld, %7ld, %7s", (long)container, (long)index, transitivityFlag((ATrans)transitivity));
+                push(stack, getContainerMember(container, index, transitivity));
+                if (traceInstructionOption)
+                    traceIntegerTopValue();
+                break;
+            }
+            case I_ATTRIBUTE: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("ATTRIBUTE %7ld, %7ld\t", (long)id, (long)atr);
+                push(stack, getInstanceAttribute(id, atr));
+                traceIntegerTopValue();
+                break;
+            }
+            case I_ATTRSTR: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("ATTRSTR \t%7ld, %7ld", (long)id, (long)atr);
+                push(stack, toAptr(getInstanceStringAttribute(id, atr)));
+                traceStringTopValue();
+                break;
+            }
+            case I_ATTRSET: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("ATTRSET \t%7ld, %7ld", (long)id, (long)atr);
+                push(stack, toAptr(getInstanceSetAttribute(id, atr)));
+                tracePointerTopValue();
+                break;
+            }
+            case I_SHOW: {
+                Aint image = pop(stack);
+                Aint align = pop(stack);
+                if (traceInstructionOption)
+                    printf("SHOW \t%7ld, %7ld\t\t\t\t", (long)image, (long)align);
+                showImage(image, align);
+                break;
+            }
+            case I_PLAY: {
+                Aint sound = pop(stack);
+                if (traceInstructionOption)
+                    printf("PLAY \t%7ld\t\t\t\t", (long)sound);
+                playSound(sound);
+                break;
+            }
+            case I_LOCATE: {
+                Aid id = pop(stack);
+                Aint whr = pop(stack);
+                if (traceInstructionOption)
+                    printf("LOCATE \t%7ld, %7ld\t\t\t", (long)id, (long)whr);
+                locate(id, whr);
+                break;
+            }
+            case I_WHERE: {
+                Abool transitivity = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("WHERE \t%7ld, %7s", (long)id, transitivityFlag((ATrans)transitivity));
+                push(stack, where(id, (ATrans)transitivity));
+                traceInstanceTopValue();
+                break;
+            }
+            case I_LOCATION: {
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("LOCATION \t%7ld\t\t", (long)id);
+                push(stack, locationOf(id));
+                traceInstanceTopValue();
+                break;
+            }
+            case I_HERE: {
+                Abool transitivity = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("HERE \t%7ld, %s\t\t\t", (long)id, transitivityFlag((ATrans)transitivity));
+                push(stack, isHere(id, (ATrans)transitivity));
+                tracebooleanTopValue();
+                break;
+            }
+            case I_NEARBY: {
+                Abool transitivity = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("NEARBY \t%7ld, %s\t\t\t", (long)id, transitivityFlag((ATrans)transitivity));
+                push(stack, isNearby(id, (ATrans)transitivity));
+                tracebooleanTopValue();
+                break;
+            }
+            case I_NEAR: {
+                Abool transitivity = pop(stack);
+                Aint other = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("NEAR \t%7ld, %7ld, %s\t\t\t", (long)id, (long)other, transitivityFlag((ATrans)transitivity));
+                push(stack, isNear(id, other, (ATrans)transitivity));
+                tracebooleanTopValue();
+                break;
+            }
+            case I_AT: {
+                Abool transitivity = pop(stack);
+                Aint other = pop(stack);
+                Aint instance = pop(stack);
+                if (traceInstructionOption)
+                    printf("AT \t%7ld, %7ld, %s", (long)instance, (long)other, transitivityFlag((ATrans)transitivity));
+                push(stack, isAt(instance, other, (ATrans)transitivity));
+                tracebooleanTopValue();
+                break;
+            }
+            case I_IN: {
+                Abool transitivity = pop(stack);
+                Aint cnt = pop(stack);
+                Aint obj = pop(stack);
+                if (traceInstructionOption)
+                    printf("IN \t%7ld, %7ld, %s", (long)obj, (long)cnt, transitivityFlag((ATrans)transitivity));
+                push(stack, isIn(obj, cnt, (ATrans)transitivity));
+                tracebooleanTopValue();
+                break;
+            }
+            case I_INSET: {
+                Aptr set = pop(stack);
+                Aword element = pop(stack);
+                if (traceInstructionOption)
+                    printf("INSET \t%7ld, %7ld", (long)element, (long)set);
+                push(stack, inSet((Set*)fromAptr(set), element));
+                freeSet((Set *)fromAptr(set));
+                tracebooleanTopValue();
+                break;
+            }
+            case I_USE: {
+                Aid act = pop(stack);
+                Aint scr = pop(stack);
+                if (traceInstructionOption)
+                    printf("USE \t%7ld, %7ld\t\t\t\t", (long)act, (long)scr);
+                use(act, scr);
+                break;
+            }
+            case I_STOP: {
+                Aid actor = pop(stack);
+                if (traceInstructionOption)
+                    printf("STOP \t%7ld\t\t\t\t\t", (long)actor);
+                stop(actor);
+                break;
+            }
+            case I_DESCRIBE: {
+                Aid id = pop(stack);
+                if (traceInstructionOption) {
+                    printf("DESCRIBE \t%7ld\t\t\t", (long)id);
+                    col = 41;		/* To format it better! */
+                }
+                describe(id);
+                if (traceInstructionOption)
+                    printf("\n\t\t\t\t\t\t");
+                break;
+            }
+            case I_SAY: {
+                Aint form = pop(stack);
+                Aid id = pop(stack);
+                if (traceInstructionOption)
+                    printf("SAY\t%7s, %7ld\t\t\t", printForm((SayForm)form), (long)id);
+                if (form == SAY_SIMPLE)
+                    say(id);
+                else
+                    sayForm(id, (SayForm)form);
+                if (traceInstructionOption)
+                    printf("\t\t\t\t\t\t\t");
+                break;
+            }
+            case I_SAYINT: {
+                Aword val = pop(stack);
+                if (traceInstructionOption)
+                    printf("SAYINT\t%7ld\t\t\t\"", (long)val);
+                sayInteger(val);
+                if (traceInstructionOption)
+                    printf("\"\n\t\t\t\t\t\t\t");
+                break;
+            }
+            case I_SAYSTR: {
+                Aptr adr = pop(stack);
+                if (traceInstructionOption)
+                    printf("SAYSTR\t%7ld\t\ty\t", (long)adr);
+                sayString((char *)fromAptr(adr));
+                if (traceInstructionOption)
+                    printf("\n\t\t\t\t\t\t");
+                break;
+            }
+            case I_IF: {
+                Aword v = pop(stack);
+                if (traceInstructionOption)
+                    printf("IF \t%s\t\t\t\t\t", booleanValue(v));
+                interpretIf(v);
+                break;
+            }
+            case I_ELSE: {
+                if (traceInstructionOption)
+                    printf("ELSE\t\t\t\t\t\t");
+                interpretElse();
+                break;
+            }
+            case I_ENDIF: {
+                if (traceInstructionOption)
+                    printf("ENDIF\t\t\t\t\t\t");
+                break;
+            }
+            case I_AND: {
+                Aword rh = pop(stack);
+                Aword lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("AND \t%s, %s", booleanValue(lh), booleanValue(rh));
+                push(stack, lh && rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_OR: {
+                Aword rh = pop(stack);
+                Aword lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("OR \t%s, %s", booleanValue(lh), booleanValue(rh));
+                push(stack, lh || rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_NE: {
+                Aword rh = pop(stack);
+                Aword lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("NE \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh != rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_EQ: {
+                Aword rh = pop(stack);
+                Aword lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("EQ \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh == rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_STREQ: {
+                Aptr rh = pop(stack);
+                Aptr lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("STREQ \t0x%lx, 0x%lx", (long)lh, (long)rh);
+                push(stack, streq((char *)fromAptr(lh), (char *)fromAptr(rh)));
+                tracebooleanTopValue();
+                if (traceInstructionOption)
+	                printf("\t");
+                deallocate(fromAptr(lh));
+                deallocate(fromAptr(rh));
+                break;
+            }
+            case I_STREXACT: {
+                Aptr rh = pop(stack);
+                Aptr lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("STREXACT \t0x%lx, 0x%lx", (long)lh, (long)rh);
+                push(stack, strcmp((char *)fromAptr(lh), (char *)fromAptr(rh)) == 0);
+                tracebooleanTopValue();
+                deallocate(fromAptr(lh));
+                deallocate(fromAptr(rh));
+                break;
+            }
+            case I_LE: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("LE \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh <= rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_GE: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("GE \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh >= rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_LT: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("LT \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh < rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_GT: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("GT \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh > rh);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_PLUS: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("PLUS \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh + rh);
+                traceIntegerTopValue();
+                break;
+            }
+            case I_MINUS: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("MINUS \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh - rh);
+                traceIntegerTopValue();
+                break;
+            }
+            case I_MULT: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("MULT \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh * rh);
+                traceIntegerTopValue();
+                break;
+            }
+            case I_DIV: {
+                Aint rh = pop(stack);
+                Aint lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("DIV \t%7ld, %7ld", (long)lh, (long)rh);
+                push(stack, lh / rh);
+                traceIntegerTopValue();
+                break;
+            }
+            case I_NOT: {
+                Aword val = pop(stack);
+                if (traceInstructionOption)
+                    printf("NOT \t%s\t\t\t", booleanValue(val));
+                push(stack, !val);
+                tracebooleanTopValue();
+                break;
+            }
+            case I_RND: {
+                Aint from = pop(stack);
+                Aint to = pop(stack);
+                if (traceInstructionOption)
+                    printf("RANDOM \t%7ld, %7ld", (long)from, (long)to);
+                push(stack, randomInteger(from, to));
+                traceIntegerTopValue();
+                break;
+            }
+            case I_BTW: {
+                Aint high = pop(stack);
+                Aint low = pop(stack);
+                Aint val = pop(stack);
+                if (traceInstructionOption)
+                    printf("BETWEEN \t%7ld, %7ld, %7ld", (long)val, (long)low, (long)high);
+                push(stack, between(val, low, high));
+                traceIntegerTopValue();
+                break;
+            }
+
+                /*------------------------------------------------------------* \
+                  String functions
+                \*------------------------------------------------------------*/
+            case I_CONCAT: {
+                Aptr s2 = pop(stack);
+                Aptr s1 = pop(stack);
+                if (traceInstructionOption)
+                    printf("CONCAT \t%s, %s", pointerValue(s1), pointerValue(s2));
+                push(stack, concat(s1, s2));
+                traceStringTopValue();
+                deallocate(fromAptr(s1));
+                deallocate(fromAptr(s2));
+                break;
+            }
+
+            case I_CONTAINS: {
+                Aptr substring = pop(stack);
+                Aptr string = pop(stack);
+                if (traceInstructionOption)
+                    printf("CONTAINS \t%s, %s", pointerValue(string), pointerValue(substring));
+                push(stack, contains(string, substring));
+                traceIntegerTopValue();
+                deallocate(fromAptr(string));
+                deallocate(fromAptr(substring));
+                break;
+            }
+
+            case I_STRIP: {
+                Aint atr = pop(stack);
+                Aid id = pop(stack);
+                Aint words = pop(stack);
+                Aint count = pop(stack);
+                Aint first = pop(stack);
+                if (traceInstructionOption)
+                    printf("STRIP \t%7ld, %7ld, %7ld, %7ld, %7ld", (long)first, (long)count, (long)words, (long)id, (long)atr);
+                push(stack, strip(first, count, words, id, atr));
+                traceStringTopValue();
+                break;
+            }
+
+                /*------------------------------------------------------------
+                  Aggregation
+                  ------------------------------------------------------------*/
+            case I_MIN:
+            case I_SUM:
+            case I_MAX: {
+                Aint attribute = pop(stack);
+                Aint loopIndex = pop(stack);
+                Aint limit = pop(stack);
+                Aint aggregate = pop(stack);
+                switch (I_OP(i)) {
+                case I_MAX:
+                    if (traceInstructionOption)
+                        printf("MAX \t%7ld\t\t\t", (long)attribute);
+                    if (aggregate < attribute)
+                        push(stack, attribute);
+                    else
+                        push(stack, aggregate);
+                    break;
+                case I_MIN:
+                    if (traceInstructionOption)
+                        printf("MIN \t%7ld\t\t\t", (long)attribute);
+                    if (aggregate > attribute)
+                        push(stack, attribute);
+                    else
+                        push(stack, aggregate);
+                    break;
+                case I_SUM:
+                    if (traceInstructionOption)
+                        printf("SUM \t%7ld\t\t\t", (long)attribute);
+                    push(stack, aggregate + attribute);
+                    break;
+                }
+                traceIntegerTopValue();
+                push(stack, limit);
+                push(stack, loopIndex);
+                break;
+            }
+            case I_COUNT: {
+                Aint loopIndex = pop(stack);
+                Aint limit = pop(stack);
+                if (traceInstructionOption)
+                    printf("COUNT\t\t\t");
+                push(stack, pop(stack) + 1);
+                traceIntegerTopValue();
+                push(stack, limit);
+                push(stack, loopIndex);
+                break;
+            }
+            case I_TRANSCRIPT: {
+                Aint on_or_off = pop(stack);
+                if (traceInstructionOption)
+                    printf("TRANSCRIPT\t\t\t");
+                if (on_or_off)
+                    startTranscript();
+                else
+                    stopTranscript();
+                break;
+            }
+
+                /*------------------------------------------------------------
+                  Depending On
+                  ------------------------------------------------------------*/
+            case I_DEPEND:
+                if (traceInstructionOption)
+                    printf("DEPEND\t\t\t\t\t\t");
+                break;
+
+            case I_DEPCASE:
+                if (traceInstructionOption)
+                    printf("DEPCASE\t\t\t\t\t\t");
+                depcase();
+                break;
+
+            case I_DEPEXEC: {
+                Aword v = pop(stack);
+                if (traceInstructionOption) {
+                    printf("DEPEXEC \t\t\t");
+                    if (v) printf(" TRUE"); else printf("FALSE");
+                    printf("\t\t\t\t\t");
+                }
+                depexec(v);
+                break;
+            }
+
+            case I_DEPELSE:
+                if (traceInstructionOption)
+                    printf("DEPELSE\t\t\t\t\t\t");
+                depcase();
+                break;
+
+            case I_ENDDEP:
+                if (traceInstructionOption)
+                    printf("ENDDEP\t\t\t\t\t\t");
+                pop(stack);
+                break;
+
+            case I_ISA: {
+                Aid rh = pop(stack);
+                Aid lh = pop(stack);
+                if (traceInstructionOption)
+                    printf("ISA \t%7ld, %7ld\t", (long)lh, (long)rh);
+                push(stack, isA(lh, rh));
+                tracebooleanTopValue();
+                break;
+            }
+
+            case I_FRAME: {
+                Aint size = pop(stack);
+                if (traceInstructionOption)
+                    printf("FRAME \t%7ld\t\t\t\t\t", (long)size);
+                newFrame(stack, size);
+                break;
+            }
+
+            case I_GETLOCAL: {
+                Aint framesBelow = pop(stack);
+                Aint variableNumber = pop(stack);
+                if (traceInstructionOption)
+                    printf("GETLOCAL \t%7ld, %7ld\t", (long)framesBelow, (long)variableNumber);
+                push(stack, getLocal(stack, framesBelow, variableNumber));
+                traceIntegerTopValue();
+                break;
+            }
+
+            case I_SETLOCAL: {
+                Aint framesBelow = pop(stack);
+                Aint variableNumber = pop(stack);
+                Aint value = pop(stack);
+                if (traceInstructionOption)
+                    printf("SETLOCAL \t%7ld, %7ld, %7ld\t\t", (long)framesBelow, (long)variableNumber, (long)value);
+                setLocal(stack, framesBelow, variableNumber, value);
+                break;
+            }
+
+            case I_ENDFRAME: {
+                if (traceInstructionOption)
+                    printf("ENDFRAME\t\t\t\t\t\t");
+                endFrame(stack);
+                break;
+            }
+
+            case I_LOOP: {
+                Aint index = pop(stack);
+                Aint limit = pop(stack);
+                if (traceInstructionOption)
+                    printf("LOOP \t\t\t\t\t\t");
+                push(stack, limit);
+                push(stack, index);
+                if (index > limit)
+                    goToLOOPEND();
+                break;
+            }
+
+            case I_LOOPNEXT: {
+                if (traceInstructionOption)
+                    printf("LOOPNEXT\t\t\t\t\t\t");
+                nextLoop();
+                break;
+            }
+
+            case I_LOOPEND: {
+                Aint index = pop(stack);
+                Aint limit = pop(stack);
+                if (traceInstructionOption)
+                    printf("LOOPEND\t\t\t\t\t\t");
+                endLoop(index, limit);
+                break;
+            }
+
+            case I_RETURN:
+                if (traceInstructionOption)
+                    printf("RETURN\n--------------------------------------------------\n");
+                pc = oldpc;
+                goto exitInterpreter;
+
+            default:
+                syserr("Unknown STMOP instruction.");
+                break;
+            }
+            if (fail) {
+                pc = oldpc;
+                goto exitInterpreter;
+            }
+            if (traceStackOption) {
+                if (!skipStackDump)
+                    dumpStack(stack);
+                skipStackDump = FALSE;
+            }
+            break;
+
+        default:
+            syserr("Unknown instruction class.");
+            break;
+        }
+    }
+ exitInterpreter:
+    recursionDepth--;
+
+}
+
+/*======================================================================*/
+Aword evaluate(Aaddr adr) {
+    interpret(adr);
+    return pop(stack);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/inter.h b/engines/glk/alan3/inter.h
new file mode 100644
index 0000000..f451a06
--- /dev/null
+++ b/engines/glk/alan3/inter.h
@@ -0,0 +1,54 @@
+/* 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_ALAN3_INTER
+#define GLK_ALAN3_INTER
+
+/* The interpreter of Acode */
+
+#include "glk/alan3/types.h"
+#include "glk/alan3/stack.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* DATA: */
+
+extern bool stopAtNextLine;
+extern int currentLine;
+extern int recursionDepth;
+
+/* Global failure flag */
+extern bool fail;
+
+
+/* FUNCTIONS: */
+
+extern void setInterpreterMock(void (*mock)(Aaddr adr));
+extern void setInterpreterStack(Stack stack);
+extern void interpret(Aaddr adr);
+extern Aword evaluate(Aaddr adr);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/lists.cpp b/engines/glk/alan3/lists.cpp
new file mode 100644
index 0000000..bb330c3
--- /dev/null
+++ b/engines/glk/alan3/lists.cpp
@@ -0,0 +1,65 @@
+/* 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/alan3/lists.h"
+#include "glk/alan3/syserr.h"
+
+namespace Glk {
+namespace Alan3 {
+
+void initArray(void *array) {
+	implementationOfSetEndOfArray((Aword *)array);
+}
+
+/* How to know we are at end of a table or array, first Aword == EOF */
+void implementationOfSetEndOfArray(Aword *adr)
+{
+	*adr = EOF;
+}
+
+
+bool implementationOfIsEndOfList(Aword *adr)
+{
+	return *adr == EOF;
+}
+
+int lengthOfArrayImplementation(void *array_of_any_type, int element_size_in_bytes) {
+    int length;
+    int element_size = element_size_in_bytes/sizeof(Aword);
+    Aword *array = (Aword *)array_of_any_type;
+    if (array == NULL)
+      syserr("Taking length of NULL array");
+    for (length = 0; !isEndOfArray(&array[length*element_size]); length++)
+        ;
+    return length;
+}
+
+void addElementImplementation(void *array_of_any_type, void *element, int element_size_in_bytes) {
+	Aword *array = (Aword *)array_of_any_type;
+	int length = lengthOfArray(array);
+	int element_size_in_words = element_size_in_bytes/sizeof(Aword);
+	memcpy(&array[length*element_size_in_words], element, element_size_in_bytes);
+	setEndOfArray(&array[(length+1)*element_size_in_words]);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/lists.h b/engines/glk/alan3/lists.h
new file mode 100644
index 0000000..d5b8791
--- /dev/null
+++ b/engines/glk/alan3/lists.h
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_LISTS
+#define GLK_ALAN3_LISTS
+
+/* Various utility functions for handling lists and arrays */
+
+#include "glk/alan3/acode.h"
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+extern void initArray(void *array);
+
+#define isEndOfArray(x) implementationOfIsEndOfList((Aword *) (x))
+extern bool implementationOfIsEndOfList(Aword *adr);
+
+#define setEndOfArray(x) implementationOfSetEndOfArray((Aword *) (x))
+extern void implementationOfSetEndOfArray(Aword *adr);
+
+#define lengthOfArray(array) lengthOfArrayImplementation((array), sizeof(*(array)))
+extern int lengthOfArrayImplementation(void *array, int element_size_in_bytes);
+
+#define addElement(array, element) addElementImplementation((array), (&element), sizeof(element))
+extern void addElementImplementation(void *array_of_any_type, void *element_of_any_size, int element_size_in_bytes);
+#endif
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/literal.cpp b/engines/glk/alan3/literal.cpp
new file mode 100644
index 0000000..ad49aa8
--- /dev/null
+++ b/engines/glk/alan3/literal.cpp
@@ -0,0 +1,80 @@
+/* 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/alan3/literal.h"
+#include "glk/alan3/types.h"
+#include "glk/alan3/memory.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+int litCount = 0;
+static LiteralEntry literalTable[100];
+LiteralEntry *literals = literalTable;
+
+
+/* PRIVATE TYPES & DATA */
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+/*======================================================================*/
+int instanceFromLiteral(int literalIndex) {
+    return literalIndex + header->instanceMax;
+}
+
+/*----------------------------------------------------------------------*/
+void createIntegerLiteral(int integerValue) {
+    litCount++;
+    literals[litCount]._class = header->integerClassId;
+    literals[litCount].type = NUMERIC_LITERAL;
+    literals[litCount].value = integerValue;
+}
+
+/*----------------------------------------------------------------------*/
+void createStringLiteral(char *unquotedString) {
+    litCount++;
+    literals[litCount]._class = header->stringClassId;
+    literals[litCount].type = STRING_LITERAL;
+    literals[litCount].value = toAptr(strdup(unquotedString));
+}
+
+/*----------------------------------------------------------------------*/
+void freeLiterals() {
+    int i;
+
+    for (i = 0; i <= litCount; i++)
+        if (literals[i].type == STRING_LITERAL && literals[i].value != 0) {
+            deallocate((void *)fromAptr(literals[i].value));
+        }
+    litCount = 0;}
+
+
+
+/*======================================================================*/
+int literalFromInstance(int instance) {
+    return instance - header->instanceMax;
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/literal.h b/engines/glk/alan3/literal.h
new file mode 100644
index 0000000..5afcd37
--- /dev/null
+++ b/engines/glk/alan3/literal.h
@@ -0,0 +1,58 @@
+/* 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_ALAN3_LITERAL
+#define GLK_ALAN3_LITERAL
+
+#include "glk/alan3/acode.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* TYPES */
+enum LiteralType {
+  NO_LITERAL, NUMERIC_LITERAL, STRING_LITERAL
+};
+
+struct LiteralEntry {   /* LITERAL */
+  Aint _class;          /* Class id of the literal type */
+  LiteralType type;
+  Aptr value;
+};
+
+
+/* DATA */
+extern int litCount;
+extern LiteralEntry *literals;
+
+
+/* FUNCTIONS */
+extern void createIntegerLiteral(int integerValue);
+extern void createStringLiteral(char *unquotedString);
+extern void freeLiterals(void);
+extern int literalFromInstance(int instance);
+extern int instanceFromLiteral(int literal);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/location.cpp b/engines/glk/alan3/location.cpp
new file mode 100644
index 0000000..59dccd9
--- /dev/null
+++ b/engines/glk/alan3/location.cpp
@@ -0,0 +1,130 @@
+/* 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/alan3/location.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/word.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/checkentry.h"
+#include "glk/alan3/debug.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/dictionary.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/current.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/*----------------------------------------------------------------------*/
+static void traceExit(int location, int dir, char *what) {
+    printf("\n<EXIT %s[%d] from ",
+           (char *)pointerTo(dictionary[playerWords[currentWordIndex-1].code].string), dir);
+    traceSay(location);
+    printf("[%d], %s:>\n", location, what);
+}
+
+
+
+/*======================================================================*/
+void go(int location, int dir)
+{
+    ExitEntry *theExit;
+    bool ok;
+    Aword oldloc;
+
+    theExit = (ExitEntry *) pointerTo(instances[location].exits);
+    if (instances[location].exits != 0)
+        while (!isEndOfArray(theExit)) {
+            if (theExit->code == dir) {
+                ok = TRUE;
+                if (theExit->checks != 0) {
+                    if (traceSectionOption)
+                        traceExit(location, dir, "Checking");
+                    ok = !checksFailed(theExit->checks, EXECUTE_CHECK_BODY_ON_FAIL);
+                }
+                if (ok) {
+                    oldloc = location;
+                    if (theExit->action != 0) {
+                        if (traceSectionOption)
+                            traceExit(location, dir, "Executing");
+                        interpret(theExit->action);
+                    }
+                    /* Still at the same place? */
+                    if (where(HERO, TRANSITIVE) == oldloc) {
+                        if (traceSectionOption)
+                            traceExit(location, dir, "Moving");
+                        locate(HERO, theExit->target);
+                    }
+                    return;
+                } else
+                    error(NO_MSG);
+            }
+            theExit++;
+        }
+    error(M_NO_WAY);
+}
+
+
+/*======================================================================*/
+bool exitto(int to, int from)
+{
+    ExitEntry *theExit;
+
+    if (instances[from].exits == 0)
+        return FALSE; /* No exits */
+    
+    for (theExit = (ExitEntry *) pointerTo(instances[from].exits); !isEndOfArray(theExit); theExit++)
+        if (theExit->target == to)
+            return TRUE;
+    
+    return FALSE;
+}
+
+
+/*======================================================================*/
+void look(void)
+{
+    int i;
+
+    /* Set describe flag for all objects and actors */
+    for (i = 1; i <= header->instanceMax; i++)
+        admin[i].alreadyDescribed = FALSE;
+
+    if (anyOutput)
+        para();
+
+    setSubHeaderStyle();
+    sayInstance(current.location);
+    setNormalStyle();
+
+    newline();
+    capitalize = TRUE;
+    if (describe(current.location))
+        describeInstances();
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/location.h b/engines/glk/alan3/location.h
new file mode 100644
index 0000000..14cada9
--- /dev/null
+++ b/engines/glk/alan3/location.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN3_LOCATION
+#define GLK_ALAN3_LOCATION
+
+#include "glk/alan3/types.h"
+
+namespace Glk {
+namespace Alan3 {
+
+extern bool exitto(int to, int from);
+extern void go(int location, int dir);
+extern void look(void);
+
+} // End of namespace Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
new file mode 100644
index 0000000..a81082e
--- /dev/null
+++ b/engines/glk/alan3/main.cpp
@@ -0,0 +1,893 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/textconsole.h"
+#include "glk/alan3/main.h"
+#include "glk/alan3/alan_version.h"
+#include "glk/alan3/args.h"
+#include "glk/alan3/class.h"
+#include "glk/alan3/compatibility.h"
+#include "glk/alan3/container.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/debug.h"
+#include "glk/alan3/decode.h"
+#include "glk/alan3/dictionary.h"
+#include "glk/alan3/event.h"
+#include "glk/alan3/exe.h"
+#include "glk/alan3/glkio.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/inter.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/literal.h"
+#include "glk/alan3/location.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/parse.h"
+#include "glk/alan3/reverse.h"
+#include "glk/alan3/rules.h"
+#include "glk/alan3/scan.h"
+#include "glk/alan3/score.h"
+#include "glk/alan3/state.h"
+#include "glk/alan3/syserr.h"
+#include "glk/alan3/syntax.h"
+#include "glk/alan3/term.h"
+#include "glk/alan3/utils.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/* PUBLIC DATA */
+
+/* Amachine structures - Static */
+VerbEntry *vrbs;		/* Verb table pointer */
+
+
+/* PRIVATE DATA */
+#define STACKSIZE 100
+
+
+
+#ifdef CHECKOBJ
+/*======================================================================
+
+  checkobj()
+
+  Check that the object given is valid, else print an error message
+  or find out what he wanted.
+
+  This routine is not used any longer, kept for sentimental reasons ;-)
+
+*/
+void checkobj(Aword *obj) {
+    Aword oldobj;
+
+    if (*obj != EOF)
+        return;
+
+    oldobj = EOF;
+    for (cur.obj = OBJMIN; cur.obj <= OBJMAX; cur.obj++) {
+        /* If an object is present and it is possible to perform his action */
+        if (isHere(cur.obj) && possible())
+            if (oldobj == EOF)
+                oldobj = cur.obj;
+            else
+                error(WANT);          /* And we didn't find multiple objects */
+    }
+
+    if (oldobj == EOF)
+        error(WANT);              /* But we found ONE */
+
+    *obj = cur.obj = oldobj;
+    output("($o)");             /* Then he surely meant this object */
+}
+#endif
+
+
+
+
+/*----------------------------------------------------------------------*
+ *
+ * Event Handling
+ *
+ *----------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------*/
+static char *eventName(int event) {
+    return stringAt(events[event].id);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void runPendingEvents(void)
+{
+    int i;
+
+    resetRules();
+    while (eventQueueTop != 0 && eventQueue[eventQueueTop-1].after == 0) {
+        eventQueueTop--;
+        if (isALocation(eventQueue[eventQueueTop].where))
+            current.location = eventQueue[eventQueueTop].where;
+        else
+            current.location = where(eventQueue[eventQueueTop].where, TRANSITIVE);
+        if (traceSectionOption) {
+            printf("\n<EVENT %s[%d] (at ", eventName(eventQueue[eventQueueTop].event),
+                   eventQueue[eventQueueTop].event);
+            traceSay(current.location);
+            printf(" [%d]):>\n", current.location);
+        }
+        interpret(events[eventQueue[eventQueueTop].event].code);
+        evaluateRules(rules);
+    }
+
+    for (i = 0; i<eventQueueTop; i++)
+        eventQueue[i].after--;
+}
+
+
+
+
+/*----------------------------------------------------------------------*\
+
+  Main program and initialisation
+
+\*----------------------------------------------------------------------*/
+
+
+Common::SeekableReadStream *codfil;
+static char codfnm[256] = "";
+static char txtfnm[256] = "";
+
+
+/*----------------------------------------------------------------------
+  Calculate where to start calculating the CRC. Is different for
+  different versions. CRC is calculated from pre-beta2 memory start to
+  be compatible.  If header size changes this should return beta2
+  header size for later versions.
+*/
+static int crcStart(char version[4]) {
+    /* Some earlier versions had a shorter header */
+    if (isPreAlpha5(version))
+        return sizeof(Pre3_0alpha5Header)/sizeof(Aword);
+    else if (isPreBeta2(version))
+        return sizeof(Pre3_0beta2Header)/sizeof(Aword);
+    else
+        return sizeof(ACodeHeader)/sizeof(Aword);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void readTemporaryHeader(ACodeHeader *tmphdr) {
+	codfil->seek(0);
+	codfil->read(tmphdr, sizeof(*tmphdr));
+	codfil->seek(0);
+	
+	if (strncmp((char *)tmphdr, "ALAN", 4) != 0)
+        playererr("Not an Alan game file, does not start with \"ALAN\"");
+}
+
+
+/*----------------------------------------------------------------------*/
+static void reverseMemory() {
+    if (littleEndian()) {
+        if (debugOption||traceSectionOption||traceInstructionOption)
+            output("<Hmm, this is a little-endian machine, fixing byte ordering....");
+        reverseACD();			/* Reverse content of the ACD file */
+        if (debugOption||traceSectionOption||traceInstructionOption)
+            output("OK.>$n");
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void setupHeader(ACodeHeader tmphdr) {
+    if (isPreBeta2(tmphdr.version)) {
+        header = (ACodeHeader *)duplicate(&memory[0], sizeof(ACodeHeader));
+        if (isPreAlpha5(tmphdr.version)) {
+            header->ifids = 0;
+        }
+        header->prompt = 0;
+    } else if (isPreBeta3(tmphdr.version)) {
+        header = (ACodeHeader *)pointerTo(0);
+    } else {
+        header = (ACodeHeader *)pointerTo(0);
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
+    int i;
+    /* No memory allocated yet? */
+    if (memory == NULL) {
+        memory = (Aword *)allocate(tmphdr.size * sizeof(Aword));
+    }
+
+	memTop = tmphdr.size;
+	if (sizeof(Aword) * tmphdr.size > codfil->size())
+		syserr("Could not read all ACD code.");
+
+	for (Aword i = 0; i < tmphdr.size; ++i)
+		memory[i] = codfil->readUint32LE();
+
+    /* Calculate checksum */
+    for (i = crcStart(tmphdr.version); i < memTop; i++) {
+        crc += memory[i]&0xff;
+        crc += (memory[i]>>8)&0xff;
+        crc += (memory[i]>>16)&0xff;
+        crc += (memory[i]>>24)&0xff;
+#ifdef CRCLOG
+        printf("%6x\t%6lx\t%6lx\n", i, crc, memory[i]);
+#endif
+    }
+    if (crc != tmphdr.acdcrc) {
+        sprintf(err, "Checksum error in Acode (.a3c) file (0x%lx instead of 0x%lx).",
+                (unsigned long) crc, (unsigned long) tmphdr.acdcrc);
+        if (!ignoreErrorOption)
+            syserr(err);
+        else {
+            output("<WARNING! $$");
+            output(err);
+            output("$$ Ignored, proceed at your own risk.>$n");
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------*/
+static char *decodeState(int c) {
+    static char state[3] = "\0\0";
+    switch (c) {
+    case 0: return ".";
+    case 'd': return "dev";
+    case 'a': return "alpha";
+    case 'b': return "beta";
+    default:
+        state[0] = header->version[3];
+        return state;
+    }
+}
+
+/*======================================================================*/
+char *decodedGameVersion(char version[]) {
+    static char str[100];
+    sprintf(str, "%d.%d%s%d",
+            (int)version[3],
+            (int)version[2],
+            decodeState(version[0]),
+            (int)version[1]);
+    return str;
+}
+
+/*----------------------------------------------------------------------*/
+static void incompatibleDevelopmentVersion(ACodeHeader *header) {
+    char str[80];
+    sprintf(str, "Incompatible version of ACODE program. Development versions always require exact match. Game is %ld.%ld%s%ld, interpreter %ld.%ld%s%ld!",
+            (long)(header->version[0]),
+            (long)(header->version[1]),
+            decodeState(header->version[3]),
+            (long)(header->version[2]),
+            (long)alan.version.version,
+            (long)alan.version.revision,
+            alan.version.state,
+            (long)alan.version.correction);
+    apperr(str);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void incompatibleVersion(ACodeHeader *header) {
+    char str[80];
+    sprintf(str, "Incompatible version of ACODE program. Game is %ld.%ld, interpreter %ld.%ld.",
+            (long)(header->version[0]),
+            (long)(header->version[1]),
+            (long)alan.version.version,
+            (long)alan.version.revision);
+    apperr(str);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void alphaRunningLaterGame(char gameState) {
+    output("<WARNING! You are running an alpha interpreter, but the game is generated by a");
+    if (gameState == 'b')
+        output("beta");
+    else
+        output("release");
+    output("state compiler which was released later. This might cause the game to not work fully as intended. Look for an upgraded game file.>\n");
+}
+
+/*----------------------------------------------------------------------*/
+static void nonDevelopmentRunningDevelopmentStateGame(char version[]) {
+    char errorMessage[200];
+    char versionString[100];
+
+    strcpy(errorMessage, "Games generated by a development state compiler");
+    sprintf(versionString, "(this game is v%d.%d.%d%s)", version[0], version[1],
+            version[2], decodeState(version[3]));
+    strcat(errorMessage, versionString);
+    strcat(errorMessage, "can only be run with a matching interpreter. Look for a game file generated with an alpha, beta or release state compiler.>\n");
+    apperr(errorMessage);
+}
+
+
+/*======================================================================*/
+void checkVersion(ACodeHeader *header)
+{
+    /* Strategy for version matching is:
+       1) Development interpreters/games require exact match
+       2) Alpha, Beta and Release interpreters will not run development games
+       3) Alpha interpreters must warn if they run beta or release games
+       4) Beta interpreters may introduce changes which are not alpha compatible,
+       if the change is a strict addition (i.e. if not used will not affect
+       alpha interpreters, example is introduction of a new opcode if it is
+       done at the end of the list)
+       5) Release interpreters should run alpha and beta games without problems
+
+       NOTE that we are working with a non-reversed version string/word here.
+    */
+
+    char interpreterVersion[4];
+    bool developmentVersion;
+    bool alphaVersion;
+    int compareLength;
+    char gameState = header->version[3];
+
+    /* Construct our own version */
+    interpreterVersion[0] = alan.version.version;
+    interpreterVersion[1] = alan.version.revision;
+    interpreterVersion[2] = alan.version.correction;
+    interpreterVersion[3] = alan.version.state[0];
+
+    /* Check version of .ACD file */
+    if (debugOption && !regressionTestOption) {
+        printf("<Version of '%s' is %d.%d%s%d!>\n",
+               adventureFileName,
+               (int)header->version[0],
+               (int)header->version[1],
+               decodeState(header->version[3]),
+               (int)header->version[2]);
+        newline();
+    }
+
+    /* Development version require exact match, else only 2 digit match */
+    developmentVersion = (strcmp(alan.version.state, "dev") == 0);
+    alphaVersion = (strcmp(alan.version.state, "alpha") == 0);
+    compareLength = (developmentVersion? 3 : 2);
+
+    if (gameState == 'd' && !developmentVersion)
+        /* Development state game requires development state interpreter... */
+        nonDevelopmentRunningDevelopmentStateGame(header->version);
+    else {
+        /* Compatible if version, revision (and correction if dev state) match... */
+        if (memcmp(header->version, interpreterVersion, compareLength) != 0) {
+            /* Mismatch! */
+            if (!ignoreErrorOption) {
+                if (developmentVersion)
+                    incompatibleDevelopmentVersion(header);
+                else
+                    incompatibleVersion(header);
+            } else
+                output("<WARNING! Incompatible version of ACODE program.>\n");
+        } else if (developmentVersion && gameState != 'd')
+            /* ... unless interpreter is development and game not */
+            incompatibleDevelopmentVersion(header);
+        else if (alphaVersion && gameState != 'a') {
+            /* If interpreter is alpha version and the game is later, warn! */
+            alphaRunningLaterGame(gameState);
+        }
+    }
+}
+
+/*----------------------------------------------------------------------*/
+static void load(void)
+{
+    ACodeHeader tmphdr;
+    Aword crc = 0;
+    char err[100];
+
+    readTemporaryHeader(&tmphdr);
+    checkVersion(&tmphdr);
+
+    /* Allocate and load memory */
+
+    if (littleEndian())
+        reverseHdr(&tmphdr);
+
+    if (tmphdr.size <= sizeof(ACodeHeader)/sizeof(Aword))
+        syserr("Malformed game file. Too small.");
+
+    loadAndCheckMemory(tmphdr, crc, err);
+
+    reverseMemory();
+    setupHeader(tmphdr);
+
+}
+
+
+/*----------------------------------------------------------------------*/
+static void checkDebug(void)
+{
+    /* Make sure he can't debug if not allowed! */
+    if (!header->debug) {
+        if (debugOption|traceSectionOption|traceInstructionOption) {
+            printf("<Sorry, '%s' is not compiled for debug! Exiting.>\n", adventureFileName);
+            terminate(0);
+        }
+        para();
+        debugOption = FALSE;
+        traceSectionOption = FALSE;
+        traceInstructionOption = FALSE;
+        tracePushOption = FALSE;
+    }
+#ifdef TODO
+    if (debugOption || regressionTestOption) /* If debugging... */
+        srand(1);			/* ... use no randomization */
+    else
+        srand(time(0));		/* Else seed random generator */
+#endif
+}
+
+
+/*----------------------------------------------------------------------*/
+static void initStaticData(void)
+{
+    /* Dictionary */
+    dictionary = (DictionaryEntry *) pointerTo(header->dictionary);
+    /* Find out number of entries in dictionary */
+    for (dictionarySize = 0; !isEndOfArray(&dictionary[dictionarySize]); dictionarySize++);
+
+    /* Scores */
+
+
+    /* All addresses to tables indexed by ids are converted to pointers,
+       then adjusted to point to the (imaginary) element before the
+       actual table so that [0] does not exist. Instead indices goes
+       from 1 and we can use [1]. */
+
+    if (header->instanceTableAddress == 0)
+        syserr("Instance table pointer == 0");
+    instances = (InstanceEntry *) pointerTo(header->instanceTableAddress);
+    instances--;			/* Back up one so that first is no. 1 */
+
+
+    if (header->classTableAddress == 0)
+        syserr("Class table pointer == 0");
+    classes = (ClassEntry *) pointerTo(header->classTableAddress);
+    classes--;			/* Back up one so that first is no. 1 */
+
+    if (header->containerTableAddress != 0) {
+        containers = (ContainerEntry *) pointerTo(header->containerTableAddress);
+        containers--;
+    }
+
+    if (header->eventTableAddress != 0) {
+        events = (EventEntry *) pointerTo(header->eventTableAddress);
+        events--;
+    }
+
+    /* Scores, if already allocated, copy initial data */
+    if (scores == NULL)
+        scores = (Aword *)duplicate((Aword *) pointerTo(header->scores), header->scoreCount*sizeof(Aword));
+    else
+        memcpy(scores, pointerTo(header->scores), header->scoreCount*sizeof(Aword));
+
+    if (literals == NULL)
+        literals = (LiteralEntry *)allocate(sizeof(Aword)*(MAXPARAMS+1));
+
+    stxs = (SyntaxEntry *) pointerTo(header->syntaxTableAddress);
+    vrbs = (VerbEntry *) pointerTo(header->verbTableAddress);
+    msgs = (MessageEntry *) pointerTo(header->messageTableAddress);
+    initRules(header->ruleTableAddress);
+
+    if (header->pack)
+        freq = (Aword *) pointerTo(header->freq);
+}
+
+
+/*----------------------------------------------------------------------*/
+static void initStrings(void)
+{
+    StringInitEntry *init;
+
+    for (init = (StringInitEntry *) pointerTo(header->stringInitTable); !isEndOfArray(init); init++)
+        setInstanceAttribute(init->instanceCode, init->attributeCode, toAptr(getStringFromFile(init->fpos, init->len)));
+}
+
+/*----------------------------------------------------------------------*/
+static Aint sizeOfAttributeData(void)
+{
+    int i;
+    int size = 0;
+
+    for (i=1; i<=header->instanceMax; i++) {
+        AttributeEntry *attribute = (AttributeEntry *)pointerTo(instances[i].initialAttributes);
+        while (!isEndOfArray(attribute)) {
+            size += AwordSizeOf(AttributeEntry);
+            attribute++;
+        }
+        size += 1;			/* For EOF */
+    }
+
+    if (size != header->attributesAreaSize
+        && (sizeof(AttributeHeaderEntry) == sizeof(AttributeEntry)))
+        syserr("Attribute area size calculated wrong.");
+    return size;
+}
+
+
+/*----------------------------------------------------------------------*/
+static AttributeEntry *initializeAttributes(int awordSize)
+{
+    Aword *attributeArea = (Aword *)allocate(awordSize*sizeof(Aword));
+    Aword *currentAttributeArea = attributeArea;
+    int i;
+
+    for (i=1; i<=header->instanceMax; i++) {
+        AttributeHeaderEntry *originalAttribute = (AttributeHeaderEntry *)pointerTo(instances[i].initialAttributes);
+        admin[i].attributes = (AttributeEntry *)currentAttributeArea;
+        while (!isEndOfArray(originalAttribute)) {
+            ((AttributeEntry *)currentAttributeArea)->code = originalAttribute->code;
+            ((AttributeEntry *)currentAttributeArea)->value = originalAttribute->value;
+            ((AttributeEntry *)currentAttributeArea)->id = originalAttribute->id;
+            currentAttributeArea += AwordSizeOf(AttributeEntry);
+            originalAttribute++;
+        }
+        *((Aword*)currentAttributeArea) = EOF;


Commit: 822cd6f16564a4fbb3436600894c144bf9e160d6
    https://github.com/scummvm/scummvm/commit/822cd6f16564a4fbb3436600894c144bf9e160d6
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:07-07:00

Commit Message:
GLK: ALAN3: Further warning fixes

Changed paths:
    engines/glk/alan3/act.cpp
    engines/glk/alan3/container.cpp
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/decode.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/location.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/output.cpp
    engines/glk/alan3/params.cpp
    engines/glk/alan3/reverse.cpp
    engines/glk/alan3/rules.cpp
    engines/glk/alan3/state.cpp
    engines/glk/alan3/sysdep.cpp
    engines/glk/glulxe/serial.cpp


diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
index 87366cd..1c89e35 100644
--- a/engines/glk/alan3/act.cpp
+++ b/engines/glk/alan3/act.cpp
@@ -89,16 +89,18 @@ static void executeCommand(int verb, Parameter parameters[])
 */
 void action(int verb, Parameter parameters[], Parameter multipleMatches[])
 {
-    int i, multiplePosition;
-    char marker[10];
-        
+    int multiplePosition;
+#ifdef TODO
+	char marker[10];
+#endif
+
     multiplePosition = findMultiplePosition(parameters);
     if (multiplePosition != -1) {
-#ifdef TODO        
+#ifdef TODO
 		jmp_buf savedReturnLabel;
         memcpy(savedReturnLabel, returnLabel, sizeof(returnLabel));
         sprintf(marker, "($%d)", multiplePosition+1); /* Prepare a printout with $1/2/3 */
-        for (i = 0; !isEndOfArray(&multipleMatches[i]); i++) {
+        for (int i = 0; !isEndOfArray(&multipleMatches[i]); i++) {
             copyParameter(&parameters[multiplePosition], &multipleMatches[i]);
             setGlobalParameters(parameters); /* Need to do this here since the marker use them */
             output(marker);
diff --git a/engines/glk/alan3/container.cpp b/engines/glk/alan3/container.cpp
index 4b812c9..b9508f5 100644
--- a/engines/glk/alan3/container.cpp
+++ b/engines/glk/alan3/container.cpp
@@ -71,7 +71,7 @@ static int sumAttributeInContainer(
 /*----------------------------------------------------------------------*/
 static bool containerIsEmpty(int container)
 {
-    int i;
+    uint i;
 
     for (i = 1; i <= header->instanceMax; i++)
         if (isDescribable(i) && isIn(i, container, TRANSITIVE))
@@ -102,7 +102,7 @@ bool passesContainerLimits(Aint theContainer, Aint theAddedInstance) {
     if (containers[props].limits != 0) { /* Any limits at all? */
         for (limit = (LimitEntry *) pointerTo(containers[props].limits); !isEndOfArray(limit); limit++)
             if (limit->atr == 1-I_COUNT) { /* TODO This is actually some encoding of the attribute number, right? */
-                if (countInContainer(theContainer) >= limit->val) {
+                if (countInContainer(theContainer) >= (int)limit->val) {
                     interpret(limit->stms);
                     return(FALSE);
                 }
@@ -119,7 +119,7 @@ bool passesContainerLimits(Aint theContainer, Aint theAddedInstance) {
 
 /*======================================================================*/
 int containerSize(int container, ATrans trans) {
-    Aint i;
+    Aword i;
     Aint count = 0;
 
     for (i = 1; i <= header->instanceMax; i++) {
@@ -132,7 +132,7 @@ int containerSize(int container, ATrans trans) {
 /*======================================================================*/
 void list(int container)
 {
-    int i;
+    uint i;
     Aword props;
     Aword foundInstance[2] = {0,0};
     int found = 0;
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index f368617..7e017ab 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -54,17 +54,17 @@ Breakpoint breakpoint[BREAKPOINTMAX];
 #define debugPrefix "adbg: "
 
 /*----------------------------------------------------------------------*/
-static void showAttributes(AttributeEntry *attributes)
+static void showAttributes(AttributeEntry *attrib)
 {
     AttributeEntry *at;
     int i;
     char str[80];
 
-    if (attributes == 0)
+    if (attrib == 0)
         return;
 
     i = 1;
-    for (at = attributes; !isEndOfArray(at); at++) {
+    for (at = attrib; !isEndOfArray(at); at++) {
         sprintf(str, "$i$t%s[%d] = %d", (char *) pointerTo(at->id), at->code, (int)at->value);
 #if ISO == 0
         fromIso(str, str);
@@ -78,7 +78,7 @@ static void showAttributes(AttributeEntry *attributes)
 /*----------------------------------------------------------------------*/
 static void showContents(int cnt)
 {
-    int i;
+    uint i;
     char str[80];
     Abool found = FALSE;
 
@@ -152,7 +152,7 @@ static void listInstance(int ins) {
 /*----------------------------------------------------------------------*/
 static void listInstances(char *pattern)
 {
-    int ins;
+    uint ins;
     bool found = FALSE;
 
     for (ins = 1; ins <= header->instanceMax; ins++) {
@@ -173,7 +173,7 @@ static void showInstance(int ins)
 {
     char str[80];
 
-    if (ins > header->instanceMax || ins < 1) {
+    if (ins > (int)header->instanceMax || ins < 1) {
         sprintf(str, "Instance index %d is out of range.", ins);
         output(str);
         return;
@@ -213,7 +213,7 @@ static void showInstance(int ins)
 /*----------------------------------------------------------------------*/
 static void listObjects(void)
 {
-    int obj;
+    uint obj;
 
     output("Objects:");
     for (obj = 1; obj <= header->instanceMax; obj++)
@@ -350,7 +350,7 @@ static void listClass(int c)
 static void showClassHierarchy(int thisItem, int depth)
 {
     int i;
-    int child;
+    uint child;
 
     output("$i");
     for (i=0; i < depth; i++)
@@ -368,7 +368,7 @@ static void showClassHierarchy(int thisItem, int depth)
 /*----------------------------------------------------------------------*/
 static void listLocations(void)
 {
-    int loc;
+    uint loc;
 
     output("Locations:");
     for (loc = 1; loc <= header->instanceMax; loc++)
@@ -402,7 +402,7 @@ static void showLocation(int loc)
 /*----------------------------------------------------------------------*/
 static void listActors(void)
 {
-    int act;
+    uint act;
 
     output("Actors:");
     for (act = 1; act <= header->instanceMax; act++)
@@ -429,7 +429,8 @@ static void showActor(int act)
 /*----------------------------------------------------------------------*/
 static void showEvents(void)
 {
-    int event, i;
+	uint event;
+	int i;
     char str[80];
     bool scheduled;
 
@@ -442,7 +443,7 @@ static void showEvents(void)
         output(str);
         scheduled = FALSE;
         for (i = 0; i < eventQueueTop; i++)
-            if ((scheduled = (eventQueue[i].event == event)))
+            if ((scheduled = (eventQueue[i].event == (int)event)))
                 break;
         if (scheduled) {
             sprintf(str, "Scheduled for +%d, at ", eventQueue[i].after);
@@ -529,14 +530,6 @@ static void listFiles() {
 
 
 /*----------------------------------------------------------------------*/
-static void listLines() {
-    SourceLineEntry *entry;
-    for (entry = (SourceLineEntry *)pointerTo(header->sourceLineTable); *((Aword*)entry) != EOF; entry++)
-        printf("  %s:%d\n", sourceFileName(entry->file), entry->line);
-}
-
-
-/*----------------------------------------------------------------------*/
 static int findSourceLineIndex(SourceLineEntry *entry, int file, int line) {
     /* Will return index to the closest line available */
     int i = 0;
@@ -754,7 +747,7 @@ static void handleHelpCommand() {
 
     int maxLength = 0;
     for (entry = commandEntries; entry->command != NULL; entry++) {
-        if (strlen(entry->command)+strlen(entry->parameter) > maxLength)
+        if (strlen(entry->command)+strlen(entry->parameter) > (uint)maxLength)
             maxLength = strlen(entry->command)+strlen(entry->parameter);
     }
 
@@ -1018,7 +1011,7 @@ static void handleObjectsCommand() {
 /*----------------------------------------------------------------------*/
 static void handleInstancesCommand() {
     char *parameter = strtok(NULL, "");
-    int i;
+    uint i;
 
     if (parameter == NULL || strchr(parameter, '*') != 0)
         listInstances(parameter);
diff --git a/engines/glk/alan3/decode.cpp b/engines/glk/alan3/decode.cpp
index c06d19a..233228b 100644
--- a/engines/glk/alan3/decode.cpp
+++ b/engines/glk/alan3/decode.cpp
@@ -93,7 +93,7 @@ int decodeChar(void)
   f = (((long)(value-low)+1)*freq[0]-1)/range;
 
   /* Find the symbol */
-  for (symbol = 1; freq[symbol] > f; symbol++);
+  for (symbol = 1; (int)freq[symbol] > f; ++symbol) {}
 
   high = low + range*freq[symbol-1]/freq[0]-1;
   low = low + range*freq[symbol]/freq[0];
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index eb01870..7f0fe2b 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -67,9 +67,6 @@ Common::SeekableReadStream *textFile;
 #define WIDTH 80
 
 
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static char logFileName[256] = "";
-
 /*======================================================================*/
 void setStyle(int style)
 {
@@ -88,7 +85,7 @@ void setStyle(int style)
 void print(Aword fpos, Aword len)
 {
     char str[2*WIDTH];            /* String buffer */
-    int outlen = 0;               /* Current output length */
+    uint outlen = 0;              /* Current output length */
     int ch = 0;
     int i;
     long savfp = 0;     /* Temporary saved text file position */
@@ -282,15 +279,15 @@ void quitGame(void)
 /*======================================================================*/
 void restartGame(void)
 {
-    Aint previousLocation = current.location;
 #ifdef TODO
-    current.location = where(HERO, DIRECT);
+	Aint previousLocation = current.location;
+	current.location = where(HERO, DIRECT);
     para();
     if (confirm(M_REALLY)) {
         longjmp(restartLabel, TRUE);
     }
     current.location = previousLocation;
-#lse
+#else
 	::error("TODO: restartGame");
 #endif
 }
@@ -303,7 +300,7 @@ void cancelEvent(Aword theEvent)
     int i;
 
     for (i = eventQueueTop-1; i>=0; i--)
-        if (eventQueue[i].event == theEvent) {
+        if (eventQueue[i].event == (int)theEvent) {
             while (i < eventQueueTop-1) {
                 eventQueue[i].event = eventQueue[i+1].event;
                 eventQueue[i].after = eventQueue[i+1].after;
@@ -337,7 +334,7 @@ static void moveEvent(int to, int from) {
 /*======================================================================*/
 void schedule(Aword event, Aword where, Aword after)
 {
-    int i;
+    uint i;
 
     if (event == 0) syserr("NULL event");
 
@@ -347,7 +344,7 @@ void schedule(Aword event, Aword where, Aword after)
         increaseEventQueue();
 
     /* Bubble this event down */
-    for (i = eventQueueTop; i >= 1 && eventQueue[i-1].after <= after; i--) {
+    for (i = eventQueueTop; i >= 1 && eventQueue[i-1].after <= (int)after; i--) {
         moveEvent(i, i-1);
     }
 
@@ -378,7 +375,7 @@ static char *stripCharsFromStringForwards(int count, char *initialString, char *
     char *strippedString;
     char *rest;
 
-    if (count > strlen(initialString))
+    if (count > (int)strlen(initialString))
         stripPosition = strlen(initialString);
     else
         stripPosition = count;
@@ -395,7 +392,7 @@ static char *stripCharsFromStringBackwards(Aint count, char *initialString, char
     char *strippedString;
     char *rest;
 
-    if (count > strlen(initialString))
+    if (count > (int)strlen(initialString))
         stripPosition = 0;
     else
         stripPosition = strlen(initialString)-count;
@@ -419,7 +416,7 @@ static int skipWordForwards(char *string, int position)
 {
     char separators[] = " .,?";
 
-    int i;
+    uint i;
 
     for (i = position; i<=strlen(string) && strchr(separators, string[i]) == NULL; i++)
         ;
@@ -469,7 +466,7 @@ static int countTrailingBlanks(char *string, int position) {
     int skippedChars, i;
     skippedChars = 0;
 
-    if (position > strlen(string)-1)
+    if (position > (int)strlen(string)-1)
         syserr("position > length in countTrailingBlanks");
     for (i = position; i >= 0 && string[i] == ' '; i--)
         skippedChars++;
@@ -536,7 +533,7 @@ Aptr strip(bool stripFromBeginningNotEnd, int count, bool stripWordsNotChars, in
 
 /*======================================================================*/
 int getContainerMember(int container, int index, bool directly) {
-    Aint i;
+    uint i;
     Aint count = 0;
 
     for (i = 1; i <= header->instanceMax; i++) {
@@ -599,7 +596,7 @@ void playSound(int sound)
 /*======================================================================*/
 void empty(int cnt, int whr)
 {
-    int i;
+    uint i;
 
     for (i = 1; i <= header->instanceMax; i++)
         if (isIn(i, cnt, DIRECT))
@@ -716,15 +713,13 @@ bool streq(char a[], char b[])
 
 /*======================================================================*/
 void startTranscript(void) {
-    time_t tick;
-
     if (logFile != NULL)
         return;
 
-	Common::String target = g_vm->getTargetName() + ".log";
+	Common::String filename = g_vm->getTargetName() + ".log";
 
 	uint fileUsage = transcriptOption ? fileusage_Transcript : fileusage_InputRecord;
-	frefid_t logFileRef = g_vm->glk_fileref_create_by_name(fileUsage, logFileName, 0);
+	frefid_t logFileRef = g_vm->glk_fileref_create_by_name(fileUsage, filename.c_str(), 0);
 	logFile = g_vm->glk_stream_open_file(logFileRef, filemode_Write, 0);
 
 	if (logFile == NULL) {
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index 49bc72d..761c74a 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -93,7 +93,7 @@ bool isALocation(int instance)
 
 bool isLiteral(int instance)
 {
-  return instance > header->instanceMax;
+  return instance > (int)header->instanceMax;
 }
 
 bool isANumeric(int instance)
@@ -118,7 +118,7 @@ void setInstanceAttribute(int instance, int attribute, Aptr value)
 {
     char str[80];
 
-    if (instance > 0 && instance <= header->instanceMax) {
+    if (instance > 0 && instance <= (int)header->instanceMax) {
         setAttribute(admin[instance].attributes, attribute, value);
         if (isALocation(instance) && attribute != VISITSATTRIBUTE)
             /* If it wasn't the VISITSATTRIBUTE the location may have
@@ -173,7 +173,7 @@ Aptr getInstanceAttribute(int instance, int attribute)
     if (isLiteral(instance))
         return literalAttribute(instance, attribute);
     else {
-        if (instance > 0 && instance <= header->instanceMax) {
+        if (instance > 0 && instance <= (int)header->instanceMax) {
             if (attribute == -1)
                 return locationOf(instance);
             else
@@ -208,7 +208,7 @@ static void verifyInstance(int instance, char *action) {
     if (instance == 0) {
         sprintf(message, "Can't %s instance (%d).", action, instance);
         syserr(message);
-    } else if (instance > header->instanceMax) {
+    } else if (instance > (int)header->instanceMax) {
         sprintf(message, "Can't %s instance (%d > instanceMax).", action, instance);
         syserr(message);
     }
@@ -290,20 +290,20 @@ bool isAt(int instance, int other, ATrans trans)
     if (isALocation(instance)) {
         /* Nested locations */
         /* TODO - What if the other is not a location? */
-        int current = admin[instance].location;
+        int curr = admin[instance].location;
         switch (trans) {
         case DIRECT:
             return admin[instance].location == other;
         case INDIRECT:
-            if (current == other)
+            if (curr == other)
                 return FALSE;
-            current = admin[current].location;
+            curr = admin[curr].location;
         case TRANSITIVE:
-            while (current != 0) {
-                if (current == other)
+            while (curr != 0) {
+                if (curr == other)
                     return TRUE;
                 else
-                    current = admin[current].location;
+                    curr = admin[curr].location;
             }
             return FALSE;
         }
@@ -321,12 +321,12 @@ bool isAt(int instance, int other, ATrans trans)
         }
         case TRANSITIVE: {
             int location = locationOf(instance);
-            int current = other;
-            while (current != 0) {
-                if (current == location)
+            int curr = other;
+            while (curr != 0) {
+                if (curr == location)
                     return TRUE;
                 else
-                    current = admin[current].location;
+                    curr = admin[curr].location;
             }
             return FALSE;
         }
@@ -340,28 +340,28 @@ bool isAt(int instance, int other, ATrans trans)
             return positionOf(instance) == admin[other].location;
         case INDIRECT: {
             int location = locationOf(instance);
-            int current = other;
-            if (location == current)
+            int curr = other;
+            if (location == curr)
                 return FALSE;
             else
-                current = admin[current].location;
-            while (current != 0) {
-                if (current == location)
+                curr = admin[curr].location;
+            while (curr != 0) {
+                if (curr == location)
                     return TRUE;
                 else
-                    current = admin[current].location;
+                    curr = admin[curr].location;
             }
             return FALSE;
         }
         case TRANSITIVE: {
             int location = locationOf(other);
-            int current = locationOf(instance);
+            int curr = locationOf(instance);
             bool ok = FALSE;
-            while (current != 0 && !ok) {
-                if (current == location)
+            while (curr != 0 && !ok) {
+                if (curr == location)
                     ok = TRUE;
                 else
-                    current = admin[current].location;
+                    curr = admin[curr].location;
             }
             return ok;
         }
@@ -530,7 +530,7 @@ static char *wordWithCode(int classBit, int code) {
     char str[50];
 
     for (w = 0; w < dictionarySize; w++)
-        if (dictionary[w].code == code && ((classBit&dictionary[w].classBits) != 0))
+        if (dictionary[w].code == (Aword)code && ((classBit&dictionary[w].classBits) != 0))
             return (char *)pointerTo(dictionary[w].string);
     sprintf(str, "Could not find word of class %d with code %d.", classBit, code);
     syserr(str);
@@ -804,7 +804,7 @@ static bool descriptionCheck(int instance)
 /*======================================================================*/
 void describeInstances(void)
 {
-    int i;
+    uint i;
     int lastInstanceFound = 0;
     int found = 0;
 
@@ -899,7 +899,7 @@ static void locateLocation(Aword loc, Aword whr)
 
     /* Ensure this does not create a recursive location chain */
     while (l != 0) {
-        if (admin[l].location == loc)
+        if (admin[l].location == (int)loc)
             apperr("Locating a location that would create a recursive loop of locations containing each other.");
         else
             l = admin[l].location;
@@ -1011,7 +1011,7 @@ static void locateActor(Aint movingActor, Aint whr)
 
     /* Before leaving, remember that we visited the location */
     if (!isPreBeta5(header->version))
-        if (movingActor == HERO)
+        if (movingActor == (int)HERO)
             incrementVisits(where(HERO, DIRECT));
 
     /* TODO Actors locating into containers is dubious, anyway as it
@@ -1035,7 +1035,7 @@ static void locateActor(Aint movingActor, Aint whr)
     current.instance = previousInstance;
     current.actor = previousActor;
 
-    if (movingActor == HERO) {
+    if (movingActor == (int)HERO) {
         if (shouldBeDescribed())
             look();
         else
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index 56f6966..e4e98fd 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -975,10 +975,10 @@ void interpret(Aaddr adr)
                 break;
             }
             case I_SAYSTR: {
-                Aptr adr = pop(stack);
+                Aptr sayAddr = pop(stack);
                 if (traceInstructionOption)
-                    printf("SAYSTR\t%7ld\t\ty\t", (long)adr);
-                sayString((char *)fromAptr(adr));
+                    printf("SAYSTR\t%7ld\t\ty\t", (long)sayAddr);
+                sayString((char *)fromAptr(sayAddr));
                 if (traceInstructionOption)
                     printf("\n\t\t\t\t\t\t");
                 break;
diff --git a/engines/glk/alan3/location.cpp b/engines/glk/alan3/location.cpp
index 59dccd9..eca9580 100644
--- a/engines/glk/alan3/location.cpp
+++ b/engines/glk/alan3/location.cpp
@@ -58,7 +58,7 @@ void go(int location, int dir)
     theExit = (ExitEntry *) pointerTo(instances[location].exits);
     if (instances[location].exits != 0)
         while (!isEndOfArray(theExit)) {
-            if (theExit->code == dir) {
+            if (theExit->code == (uint)dir) {
                 ok = TRUE;
                 if (theExit->checks != 0) {
                     if (traceSectionOption)
@@ -73,7 +73,7 @@ void go(int location, int dir)
                         interpret(theExit->action);
                     }
                     /* Still at the same place? */
-                    if (where(HERO, TRANSITIVE) == oldloc) {
+                    if (where(HERO, TRANSITIVE) == (int)oldloc) {
                         if (traceSectionOption)
                             traceExit(location, dir, "Moving");
                         locate(HERO, theExit->target);
@@ -97,7 +97,7 @@ bool exitto(int to, int from)
         return FALSE; /* No exits */
     
     for (theExit = (ExitEntry *) pointerTo(instances[from].exits); !isEndOfArray(theExit); theExit++)
-        if (theExit->target == to)
+        if (theExit->target == (uint)to)
             return TRUE;
     
     return FALSE;
@@ -107,7 +107,7 @@ bool exitto(int to, int from)
 /*======================================================================*/
 void look(void)
 {
-    int i;
+    uint i;
 
     /* Set describe flag for all objects and actors */
     for (i = 1; i <= header->instanceMax; i++)
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index a81082e..3697ac6 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -217,17 +217,17 @@ static void setupHeader(ACodeHeader tmphdr) {
 
 /*----------------------------------------------------------------------*/
 static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
-    int i;
+	int i;
     /* No memory allocated yet? */
     if (memory == NULL) {
         memory = (Aword *)allocate(tmphdr.size * sizeof(Aword));
     }
 
 	memTop = tmphdr.size;
-	if (sizeof(Aword) * tmphdr.size > codfil->size())
+	if ((int)(sizeof(Aword) * tmphdr.size) > codfil->size())
 		syserr("Could not read all ACD code.");
 
-	for (Aword i = 0; i < tmphdr.size; ++i)
+	for (i = 0; i < (int)tmphdr.size; ++i)
 		memory[i] = codfil->readUint32LE();
 
     /* Calculate checksum */
@@ -280,13 +280,13 @@ char *decodedGameVersion(char version[]) {
 }
 
 /*----------------------------------------------------------------------*/
-static void incompatibleDevelopmentVersion(ACodeHeader *header) {
+static void incompatibleDevelopmentVersion(ACodeHeader *hdr) {
     char str[80];
     sprintf(str, "Incompatible version of ACODE program. Development versions always require exact match. Game is %ld.%ld%s%ld, interpreter %ld.%ld%s%ld!",
-            (long)(header->version[0]),
-            (long)(header->version[1]),
-            decodeState(header->version[3]),
-            (long)(header->version[2]),
+            (long)(hdr->version[0]),
+            (long)(hdr->version[1]),
+            decodeState(hdr->version[3]),
+            (long)(hdr->version[2]),
             (long)alan.version.version,
             (long)alan.version.revision,
             alan.version.state,
@@ -296,11 +296,11 @@ static void incompatibleDevelopmentVersion(ACodeHeader *header) {
 
 
 /*----------------------------------------------------------------------*/
-static void incompatibleVersion(ACodeHeader *header) {
+static void incompatibleVersion(ACodeHeader *hdr) {
     char str[80];
     sprintf(str, "Incompatible version of ACODE program. Game is %ld.%ld, interpreter %ld.%ld.",
-            (long)(header->version[0]),
-            (long)(header->version[1]),
+            (long)(hdr->version[0]),
+            (long)(hdr->version[1]),
             (long)alan.version.version,
             (long)alan.version.revision);
     apperr(str);
@@ -332,7 +332,7 @@ static void nonDevelopmentRunningDevelopmentStateGame(char version[]) {
 
 
 /*======================================================================*/
-void checkVersion(ACodeHeader *header)
+void checkVersion(ACodeHeader *hdr)
 {
     /* Strategy for version matching is:
        1) Development interpreters/games require exact match
@@ -351,7 +351,7 @@ void checkVersion(ACodeHeader *header)
     bool developmentVersion;
     bool alphaVersion;
     int compareLength;
-    char gameState = header->version[3];
+    char gameState = hdr->version[3];
 
     /* Construct our own version */
     interpreterVersion[0] = alan.version.version;
@@ -363,10 +363,10 @@ void checkVersion(ACodeHeader *header)
     if (debugOption && !regressionTestOption) {
         printf("<Version of '%s' is %d.%d%s%d!>\n",
                adventureFileName,
-               (int)header->version[0],
-               (int)header->version[1],
-               decodeState(header->version[3]),
-               (int)header->version[2]);
+               (int)hdr->version[0],
+               (int)hdr->version[1],
+               decodeState(hdr->version[3]),
+               (int)hdr->version[2]);
         newline();
     }
 
@@ -377,21 +377,21 @@ void checkVersion(ACodeHeader *header)
 
     if (gameState == 'd' && !developmentVersion)
         /* Development state game requires development state interpreter... */
-        nonDevelopmentRunningDevelopmentStateGame(header->version);
+        nonDevelopmentRunningDevelopmentStateGame(hdr->version);
     else {
         /* Compatible if version, revision (and correction if dev state) match... */
-        if (memcmp(header->version, interpreterVersion, compareLength) != 0) {
+        if (memcmp(hdr->version, interpreterVersion, compareLength) != 0) {
             /* Mismatch! */
             if (!ignoreErrorOption) {
                 if (developmentVersion)
-                    incompatibleDevelopmentVersion(header);
+                    incompatibleDevelopmentVersion(hdr);
                 else
-                    incompatibleVersion(header);
+                    incompatibleVersion(hdr);
             } else
                 output("<WARNING! Incompatible version of ACODE program.>\n");
         } else if (developmentVersion && gameState != 'd')
             /* ... unless interpreter is development and game not */
-            incompatibleDevelopmentVersion(header);
+            incompatibleDevelopmentVersion(hdr);
         else if (alphaVersion && gameState != 'a') {
             /* If interpreter is alpha version and the game is later, warn! */
             alphaRunningLaterGame(gameState);
@@ -517,7 +517,7 @@ static void initStrings(void)
 /*----------------------------------------------------------------------*/
 static Aint sizeOfAttributeData(void)
 {
-    int i;
+    uint i;
     int size = 0;
 
     for (i=1; i<=header->instanceMax; i++) {
@@ -541,7 +541,7 @@ static AttributeEntry *initializeAttributes(int awordSize)
 {
     Aword *attributeArea = (Aword *)allocate(awordSize*sizeof(Aword));
     Aword *currentAttributeArea = attributeArea;
-    int i;
+    uint i;
 
     for (i=1; i<=header->instanceMax; i++) {
         AttributeHeaderEntry *originalAttribute = (AttributeHeaderEntry *)pointerTo(instances[i].initialAttributes);
@@ -566,7 +566,7 @@ static AttributeEntry *initializeAttributes(int awordSize)
 /*----------------------------------------------------------------------*/
 static void initDynamicData(void)
 {
-    int instanceId;
+    uint instanceId;
 
     /* Allocate for administrative table */
     admin = (AdminEntry *)allocate((header->instanceMax+1)*sizeof(AdminEntry));
@@ -603,7 +603,7 @@ static void runInitialize(Aint theInstance) {
 
 /*----------------------------------------------------------------------*/
 static void initializeInstances() {
-    int instanceId;
+    uint instanceId;
 
     /* Set initial locations */
     for (instanceId = 1; instanceId <= header->instanceMax; instanceId++) {
@@ -642,28 +642,6 @@ static void start(void)
 /*----------------------------------------------------------------------*/
 static void openFiles(void)
 {
-    char str[256];
-
-    /* 
-	Open Acode file
-    strcpy(codfnm, adventureFileName);
-    if ((codfil = fopen(codfnm, READ_MODE)) == NULL) {
-        strcpy(str, "Can't open adventure code file '");
-        strcat(str, codfnm);
-        strcat(str, "'.");
-        playererr(str);
-    }
-
-    // Open Text file
-    strcpy(txtfnm, adventureFileName);
-    if ((textFile = fopen(txtfnm, READ_MODE)) == NULL) {
-        strcpy(str, "Can't open adventure text data file '");
-        strcat(str, txtfnm);
-        strcat(str, "'.");
-        apperr(str);
-    }
-	*/
-
     /* If logging open log file */
     if (transcriptOption || logOption) {
         startTranscript();
@@ -744,7 +722,7 @@ static void moveActor(int theActor)
     current.actor = theActor;
     current.instance = theActor;
     current.location = where(theActor, TRANSITIVE);
-    if (theActor == HERO) {
+    if (theActor == (int)HERO) {
 #ifdef TODO
 		/* Ask him! */
         if (setjmp(forfeitLabel) == 0) {
@@ -815,9 +793,7 @@ static void moveActor(int theActor)
 #define ERROR_RETURNED (setjmp(returnLabel) != NO_JUMP_RETURN)
 
 /*======================================================================*/
-void run(void)
-{
-    int i;
+void run(void) {
     static Stack theStack = NULL; /* Needs to survive longjmp() */
 
     openFiles();
@@ -879,7 +855,7 @@ void run(void)
             resetAndEvaluateRules(rules, header->version);
 
             /* Then all the other actors... */
-            for (i = 1; i <= header->instanceMax; i++)
+            for (uint i = 1; i <= header->instanceMax; i++)
                 if (i != header->theHero && isAActor(i)) {
                     moveActor(i);
                     resetAndEvaluateRules(rules, header->version);
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index 20ab604..efe4e31 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -143,7 +143,7 @@ void clear(void)
 
 /*----------------------------------------------------------------------*/
 static void capitalizeFirst(char *str) {
-    int i = 0;
+    uint i = 0;
 
     /* Skip over space... */
     while (i < strlen(str) && isSpace(str[i])) i++;
@@ -167,10 +167,10 @@ void printAndLog(const char *string)
     if (!onStatusLine && transcriptOption) {
 #ifdef HAVE_GLK
         // TODO Is this assuming only 70-char wide windows for GLK?
-        if (strlen(string) > 70-column) {
+        if ((int)strlen(string) > 70-column) {
             stringCopy = strdup(string);  /* Make sure we can write NULLs */
             stringPart = stringCopy;
-            while (strlen(stringPart) > 70-column) {
+            while ((int)strlen(stringPart) > 70-column) {
                 int p;
                 for (p = 70-column; p>0 && !isspace((int)stringPart[p]); p--);
                 stringPart[p] = '\0';
diff --git a/engines/glk/alan3/params.cpp b/engines/glk/alan3/params.cpp
index 3cbf05d..4b94009 100644
--- a/engines/glk/alan3/params.cpp
+++ b/engines/glk/alan3/params.cpp
@@ -207,7 +207,7 @@ void addParameterToParameterArray(ParameterArray theArray, Parameter *theParamet
 {
     if (theArray == NULL) syserr("Adding to null parameter array");
 
-    int i;
+    uint i;
 
     for (i = 0; !isEndOfArray(&theArray[i]) && i < MAXINSTANCE; i++)
         ;
diff --git a/engines/glk/alan3/reverse.cpp b/engines/glk/alan3/reverse.cpp
index 64e0ea0..d31e7c3 100644
--- a/engines/glk/alan3/reverse.cpp
+++ b/engines/glk/alan3/reverse.cpp
@@ -107,7 +107,7 @@ void reverse(Aword *w)          /* IN - The ACODE word to reverse bytes in */
 static void reverseTable(Aword adr, int elementSize)
 {
   Aword *e = &memory[adr];
-  int i;
+  uint i;
 
   if (elementSize < sizeof(Aword) || elementSize % sizeof(Aword) != 0)
       syserr("***Wrong size in 'reverseTable()' ***");
@@ -531,30 +531,30 @@ static void reversePreAlpha5Header(Pre3_0alpha5Header *hdr)
 /*----------------------------------------------------------------------*/
 static void reversePreAlpha5() {
     /* NOTE that the reversePreXXX() have different header definitions */
-    Pre3_0alpha5Header *header = (Pre3_0alpha5Header *)memory;
+    Pre3_0alpha5Header *hdr = (Pre3_0alpha5Header *)memory;
 
-    reversePreAlpha5Header(header);
-    memorySize = header->size;
+    reversePreAlpha5Header(hdr);
+    memorySize = hdr->size;
 
-    reverseDictionary(header->dictionary);
-    reverseSyntaxTable(header->syntaxTableAddress, header->version);
-    reverseParameterTable(header->parameterMapAddress);
-    reverseVerbs(header->verbTableAddress);
-    reverseClasses(header->classTableAddress);
-    reverseInstances(header->instanceTableAddress);
-    reverseScrs(header->scriptTableAddress);
-    reverseContainers(header->containerTableAddress);
-    reverseEvts(header->eventTableAddress);
-    reverseRuls(header->ruleTableAddress);
-    reverseTable(header->stringInitTable, sizeof(StringInitEntry));
-    reverseSetInitTable(header->setInitTable);
-    reverseTable(header->sourceFileTable, sizeof(SourceFileEntry));
-    reverseTable(header->sourceLineTable, sizeof(SourceLineEntry));
-    reverseStms(header->start);
-    reverseMsgs(header->messageTableAddress);
+    reverseDictionary(hdr->dictionary);
+    reverseSyntaxTable(hdr->syntaxTableAddress, hdr->version);
+    reverseParameterTable(hdr->parameterMapAddress);
+    reverseVerbs(hdr->verbTableAddress);
+    reverseClasses(hdr->classTableAddress);
+    reverseInstances(hdr->instanceTableAddress);
+    reverseScrs(hdr->scriptTableAddress);
+    reverseContainers(hdr->containerTableAddress);
+    reverseEvts(hdr->eventTableAddress);
+    reverseRuls(hdr->ruleTableAddress);
+    reverseTable(hdr->stringInitTable, sizeof(StringInitEntry));
+    reverseSetInitTable(hdr->setInitTable);
+    reverseTable(hdr->sourceFileTable, sizeof(SourceFileEntry));
+    reverseTable(hdr->sourceLineTable, sizeof(SourceLineEntry));
+    reverseStms(hdr->start);
+    reverseMsgs(hdr->messageTableAddress);
 
-    reverseTable(header->scores, sizeof(Aword));
-    reverseTable(header->freq, sizeof(Aword));
+    reverseTable(hdr->scores, sizeof(Aword));
+    reverseTable(hdr->freq, sizeof(Aword));
 }
 
 
@@ -572,30 +572,30 @@ static void reversePreBeta2Header(Pre3_0beta2Header *hdr)
 /*----------------------------------------------------------------------*/
 static void reversePreBeta2() {
     /* NOTE that the reversePreXXX() have different header definitions */
-    Pre3_0beta2Header *header = (Pre3_0beta2Header *)memory;
+    Pre3_0beta2Header *hdr = (Pre3_0beta2Header *)memory;
 
-    reversePreBeta2Header(header);
-    memorySize = header->size;
+    reversePreBeta2Header(hdr);
+    memorySize = hdr->size;
 
-    reverseDictionary(header->dictionary);
-    reverseSyntaxTable(header->syntaxTableAddress, header->version);
-    reverseParameterTable(header->parameterMapAddress);
-    reverseVerbs(header->verbTableAddress);
-    reverseClasses(header->classTableAddress);
-    reverseInstances(header->instanceTableAddress);
-    reverseScrs(header->scriptTableAddress);
-    reverseContainers(header->containerTableAddress);
-    reverseEvts(header->eventTableAddress);
-    reverseRuls(header->ruleTableAddress);
-    reverseTable(header->stringInitTable, sizeof(StringInitEntry));
-    reverseSetInitTable(header->setInitTable);
-    reverseTable(header->sourceFileTable, sizeof(SourceFileEntry));
-    reverseTable(header->sourceLineTable, sizeof(SourceLineEntry));
-    reverseStms(header->start);
-    reverseMsgs(header->messageTableAddress);
+    reverseDictionary(hdr->dictionary);
+    reverseSyntaxTable(hdr->syntaxTableAddress, hdr->version);
+    reverseParameterTable(hdr->parameterMapAddress);
+    reverseVerbs(hdr->verbTableAddress);
+    reverseClasses(hdr->classTableAddress);
+    reverseInstances(hdr->instanceTableAddress);
+    reverseScrs(hdr->scriptTableAddress);
+    reverseContainers(hdr->containerTableAddress);
+    reverseEvts(hdr->eventTableAddress);
+    reverseRuls(hdr->ruleTableAddress);
+    reverseTable(hdr->stringInitTable, sizeof(StringInitEntry));
+    reverseSetInitTable(hdr->setInitTable);
+    reverseTable(hdr->sourceFileTable, sizeof(SourceFileEntry));
+    reverseTable(hdr->sourceLineTable, sizeof(SourceLineEntry));
+    reverseStms(hdr->start);
+    reverseMsgs(hdr->messageTableAddress);
 
-    reverseTable(header->scores, sizeof(Aword));
-    reverseTable(header->freq, sizeof(Aword));
+    reverseTable(hdr->scores, sizeof(Aword));
+    reverseTable(hdr->freq, sizeof(Aword));
 }
 
 
@@ -611,43 +611,43 @@ void reverseHdr(ACodeHeader *hdr)
 
 
 /*----------------------------------------------------------------------*/
-static void reverseInstanceIdTable(ACodeHeader *header) {
-    reverseTable(header->instanceTableAddress+header->instanceMax*sizeof(InstanceEntry)/sizeof(Aword)+1, sizeof(Aword));
+static void reverseInstanceIdTable(ACodeHeader *hdr) {
+    reverseTable(hdr->instanceTableAddress+hdr->instanceMax*sizeof(InstanceEntry)/sizeof(Aword)+1, sizeof(Aword));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void reverseNative() {
-    /* NOTE that the reversePreXXX() have different header definitions */
-    ACodeHeader *header = (ACodeHeader *)memory;
-
-    reverseHdr(header);
-    memorySize = header->size;
-
-    reverseDictionary(header->dictionary);
-    reverseSyntaxTable(header->syntaxTableAddress, header->version);
-    if (header->debug && !isPreBeta3(header->version))
-        reverseParameterNames(header->parameterMapAddress);
-    reverseParameterTable(header->parameterMapAddress);
-    reverseVerbs(header->verbTableAddress);
-    reverseClasses(header->classTableAddress);
-    reverseInstances(header->instanceTableAddress);
-    if (header->debug && !isPreBeta3(header->version))
-        reverseInstanceIdTable(header);
-    reverseScrs(header->scriptTableAddress);
-    reverseContainers(header->containerTableAddress);
-    reverseEvts(header->eventTableAddress);
-    reverseRuls(header->ruleTableAddress);
-    reverseTable(header->stringInitTable, sizeof(StringInitEntry));
-    reverseSetInitTable(header->setInitTable);
-    reverseTable(header->sourceFileTable, sizeof(SourceFileEntry));
-    reverseTable(header->sourceLineTable, sizeof(SourceLineEntry));
-    reverseStms(header->prompt);
-    reverseStms(header->start);
-    reverseMsgs(header->messageTableAddress);
-
-    reverseTable(header->scores, sizeof(Aword));
-    reverseTable(header->freq, sizeof(Aword));
+    /* NOTE that the reversePreXXX() have different hdr definitions */
+    ACodeHeader *hdr = (ACodeHeader *)memory;
+
+    reverseHdr(hdr);
+    memorySize = hdr->size;
+
+    reverseDictionary(hdr->dictionary);
+    reverseSyntaxTable(hdr->syntaxTableAddress, hdr->version);
+    if (hdr->debug && !isPreBeta3(hdr->version))
+        reverseParameterNames(hdr->parameterMapAddress);
+    reverseParameterTable(hdr->parameterMapAddress);
+    reverseVerbs(hdr->verbTableAddress);
+    reverseClasses(hdr->classTableAddress);
+    reverseInstances(hdr->instanceTableAddress);
+    if (hdr->debug && !isPreBeta3(hdr->version))
+        reverseInstanceIdTable(hdr);
+    reverseScrs(hdr->scriptTableAddress);
+    reverseContainers(hdr->containerTableAddress);
+    reverseEvts(hdr->eventTableAddress);
+    reverseRuls(hdr->ruleTableAddress);
+    reverseTable(hdr->stringInitTable, sizeof(StringInitEntry));
+    reverseSetInitTable(hdr->setInitTable);
+    reverseTable(hdr->sourceFileTable, sizeof(SourceFileEntry));
+    reverseTable(hdr->sourceLineTable, sizeof(SourceLineEntry));
+    reverseStms(hdr->prompt);
+    reverseStms(hdr->start);
+    reverseMsgs(hdr->messageTableAddress);
+
+    reverseTable(hdr->scores, sizeof(Aword));
+    reverseTable(hdr->freq, sizeof(Aword));
 }
 
 
@@ -662,13 +662,13 @@ static void reverseNative() {
   */
 void reverseACD(void)
 {
-  ACodeHeader *header = (ACodeHeader *)memory;
+  ACodeHeader *hdr = (ACodeHeader *)memory;
   char version[4];
   int i;
 
   /* Make a copy of the version marking to reverse */
   for (i = 0; i <= 3; i++)
-      version[i] = header->version[i];
+      version[i] = hdr->version[i];
   reverseWord((Aword*)&version);
 
   if (isPreAlpha5(version))
diff --git a/engines/glk/alan3/rules.cpp b/engines/glk/alan3/rules.cpp
index 4f2d60e..29c98c8 100644
--- a/engines/glk/alan3/rules.cpp
+++ b/engines/glk/alan3/rules.cpp
@@ -52,9 +52,9 @@ static int ruleCount;
 static RulesAdmin *rulesAdmin; /* Table for administration of the rules */
 
 /*----------------------------------------------------------------------*/
-static void clearRulesAdmin(int ruleCount) {
+static void clearRulesAdmin(int numRules) {
     int r;
-    for (r = 0; r < ruleCount; r++) {
+    for (r = 0; r < numRules; r++) {
         rulesAdmin[r].lastEval = FALSE;
         rulesAdmin[r].alreadyRun = FALSE;
     }
@@ -62,11 +62,11 @@ static void clearRulesAdmin(int ruleCount) {
 
 
 /*----------------------------------------------------------------------*/
-static void initRulesAdmin(int ruleCount) {
+static void initRulesAdmin(int numRules) {
     int r;
 
-    rulesAdmin = (RulesAdmin *)allocate(ruleCount*sizeof(RulesAdmin)+sizeof(EOF));
-    for (r = 0; r < ruleCount; r++)
+    rulesAdmin = (RulesAdmin *)allocate(numRules*sizeof(RulesAdmin)+sizeof(EOF));
+    for (r = 0; r < numRules; r++)
         ;
     setEndOfArray(&rulesAdmin[r]);
 }
@@ -167,33 +167,6 @@ static void evaluateRulesPreBeta2(void)
 
 
 /*----------------------------------------------------------------------*/
-static void evaluateRulesBeta2New(void) {
-    int i;
-
-    for (i = 1; !isEndOfArray(&rules[i-1]); i++)
-        rules[i-1].alreadyRun = FALSE;
-
-    current.location = NOWHERE;
-    current.actor = 0;
-
-    anyRuleRun = FALSE;
-
-    for (i = 1; !isEndOfArray(&rules[i-1]); i++) {
-        bool evaluated_value = evaluate(rules[i-1].exp);
-        traceRuleEvaluation(i);
-        rules[i-1].alreadyRun = evaluated_value;
-    }
-    for (i = 1; !isEndOfArray(&rules[i-1]); i++) {
-        if (rules[i-1].alreadyRun) {
-            traceRuleExecution(i);
-            interpret(rules[i-1].stms);
-            anyRuleRun = TRUE;
-        }
-    }
-}
-
-
-/*----------------------------------------------------------------------*/
 /* This is how beta2 thought rules should be evaluated:
  */
 static void evaluateRulesBeta2(void)
@@ -241,7 +214,7 @@ void resetRules() {
 
 
 /*======================================================================*/
-void evaluateRules(RuleEntry rules[]) {
+void evaluateRules(RuleEntry ruleList[]) {
     bool change = TRUE;
     int rule;
 
@@ -250,15 +223,15 @@ void evaluateRules(RuleEntry rules[]) {
 
     while (change) {
         change = FALSE;
-        for (rule = 1; !isEndOfArray(&rules[rule-1]); rule++) {
+        for (rule = 1; !isEndOfArray(&ruleList[rule-1]); rule++) {
             traceRuleEvaluation(rule);
-            bool evaluated_value = evaluate(rules[rule-1].exp);
+            bool evaluated_value = evaluate(ruleList[rule-1].exp);
             traceRuleResult(rule, evaluated_value);
             if (evaluated_value == true && rulesAdmin[rule-1].lastEval == false
                 && !rulesAdmin[rule-1].alreadyRun) {
                 change = TRUE;
                 traceRuleExecution(rule);
-                interpret(rules[rule-1].stms);
+                interpret(ruleList[rule-1].stms);
                 rulesAdmin[rule-1].alreadyRun = TRUE;
                 anyRuleRun = TRUE;
             } else {
@@ -272,14 +245,14 @@ void evaluateRules(RuleEntry rules[]) {
 
 
 /*=======================================================================*/
-void resetAndEvaluateRules(RuleEntry rules[], char *version) {
+void resetAndEvaluateRules(RuleEntry ruleList[], char *version) {
     if (isPreBeta2(version))
         evaluateRulesPreBeta2();
     else if (isPreBeta3(version))
         evaluateRulesBeta2();
     else {
         resetRules();
-        evaluateRules(rules);
+        evaluateRules(ruleList);
     }
 }
 
diff --git a/engines/glk/alan3/state.cpp b/engines/glk/alan3/state.cpp
index 4112659..3b8acff 100644
--- a/engines/glk/alan3/state.cpp
+++ b/engines/glk/alan3/state.cpp
@@ -99,42 +99,42 @@ static int countSets(void) {
 
 
 /*----------------------------------------------------------------------*/
-static void deallocateSets(GameState *gameState) {
+static void deallocateSets(GameState *gState) {
     int count = countSets();
     int i;
 
     for (i = 0; i < count; i++)
-        freeSet(gameState->sets[i]);
-    deallocate(gameState->sets);
+        freeSet(gState->sets[i]);
+    deallocate(gState->sets);
 }
 
 /*======================================================================*/
-void deallocateGameState(GameState *gameState) {
+void deallocateGameState(GameState *gState) {
 
-    deallocate(gameState->admin);
-    deallocate(gameState->attributes);
+    deallocate(gState->admin);
+    deallocate(gState->attributes);
 
-    if (gameState->eventQueueTop > 0) {
-        deallocate(gameState->eventQueue);
-        gameState->eventQueue = NULL;
+    if (gState->eventQueueTop > 0) {
+        deallocate(gState->eventQueue);
+        gState->eventQueue = NULL;
     }
-    if (gameState->scores)
-        deallocate(gameState->scores);
+    if (gState->scores)
+        deallocate(gState->scores);
 
-    deallocateStrings(gameState);
-    deallocateSets(gameState);
+    deallocateStrings(gState);
+    deallocateSets(gState);
 
-    memset(gameState, 0, sizeof(GameState));
+    memset(gState, 0, sizeof(GameState));
 }
 
 
 /*======================================================================*/
 void forgetGameState(void) {
-    char *playerCommand;
-    popGameState(stateStack, &gameState, &playerCommand);
+    char *playerCmd;
+    popGameState(stateStack, &gameState, &playerCmd);
     deallocateGameState(&gameState);
-    if (playerCommand != NULL)
-        deallocate(playerCommand);
+    if (playerCmd != NULL)
+        deallocate(playerCmd);
 }
 
 
diff --git a/engines/glk/alan3/sysdep.cpp b/engines/glk/alan3/sysdep.cpp
index 94132a7..7e9dc48 100644
--- a/engines/glk/alan3/sysdep.cpp
+++ b/engines/glk/alan3/sysdep.cpp
@@ -63,9 +63,6 @@ size_t strftime (
 
 #endif
 
-
-#ifdef HAVE_GLK
-
 /* Note to Glk maintainers: 'native' characters are used for output, in this
    case, Glk's Latin-1.  ISO characters are Alan's internal representation,
    stored in the .A3C file, and must be converted to native before printing.
@@ -74,7 +71,7 @@ size_t strftime (
    move to Unicode).
  */
 
-static char spaceCharacters[] =
+static const byte spaceCharacters[] =
 {
   0x0A, /* linefeed */
   0x20, /* space */
@@ -82,7 +79,7 @@ static char spaceCharacters[] =
   0x00
 };
 
-static char lowerCaseCharacters[] =
+static const byte lowerCaseCharacters[] =
 {
   0x61, /* a */  0x62, /* b */  0x63, /* c */  0x64, /* d */
   0x65, /* e */  0x66, /* f */  0x67, /* g */  0x68, /* h */
@@ -113,7 +110,7 @@ static char lowerCaseCharacters[] =
    Are they really considered LC?
  */
 
-static char upperCaseCharacters[] =
+static const byte upperCaseCharacters[] =
 {
   0x41, /* A */  0x42, /* B */  0x43, /* C */  0x44, /* D */
   0x45, /* E */  0x46, /* F */  0x47, /* G */  0x48, /* H */
@@ -140,18 +137,6 @@ static char upperCaseCharacters[] =
   0x00
 };
 
-#else
-
-/* Theses work on native character sets */
-
-static unsigned char spaceCharacters[] = " \t\n";
-
-/* Use native characters */
-static const char lowerCaseCharacters[] = "abcdefghijklmnopqrstuvwxyzàáâãäåæçéêëìíîïðñòóôõöøùúûüýþÿ";
-
-static const char upperCaseCharacters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÛÝÞß";
-
-#endif
 
 int isSpace(unsigned int c)              /* IN - Native character to test */
 {
@@ -161,13 +146,13 @@ int isSpace(unsigned int c)              /* IN - Native character to test */
 
 int isLower(unsigned int c)              /* IN - Native character to test */
 {
-    return (c != '\0' && strchr((char *)lowerCaseCharacters, c) != 0);
+    return (c != '\0' && strchr((const char *)lowerCaseCharacters, c) != 0);
 }
 
 
 int isUpper(unsigned int c)              /* IN - Native character to test */
 {
-    return (c != '\0' && strchr((char *)upperCaseCharacters, c) != 0);
+    return (c != '\0' && strchr((const char *)upperCaseCharacters, c) != 0);
 }
 
 int isLetter(unsigned int c)             /* IN - Native character to test */
@@ -203,7 +188,8 @@ int toLower(unsigned int c)              /* IN - Native character to convert */
 #endif
 }
 
-int toUpper(unsigned int c)              /* IN - Native character to convert */
+/* IN - Native character to convert */
+int toUpper(unsigned int c)
 {
 #ifdef HAVE_GLK
   return g_vm->glk_char_to_upper(c);
@@ -254,9 +240,8 @@ char *strupp(char str[])        /* INOUT - Native string to convert */
 
 int isLowerCase(unsigned int c)          /* IN - ISO character to test */
 {
-  static char lowerCaseCharacters[] = "abcdefghijklmnopqrstuvwxyz\340\341\342\343\344\345\346\347\351\352\353\354\355\356\357\360\361\362\363\364\365\366\370\371\372\373\374\375\376\377";
-  int i;
-  for (i = 0; i < strlen(lowerCaseCharacters); i++)
+  uint i;
+  for (i = 0; i < strlen((const char *)lowerCaseCharacters); i++)
     if (((unsigned int)lowerCaseCharacters[i]) == c) return 1;
   return 0;
 }
@@ -264,9 +249,8 @@ int isLowerCase(unsigned int c)          /* IN - ISO character to test */
 
 int isUpperCase(unsigned int c)          /* IN - ISO character to test */
 {
-    //static char upperCaseCharacters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337";
-  int i;
-  for (i = 0; i < strlen(upperCaseCharacters); i++)
+  uint i;
+  for (i = 0; i < strlen((const char *)upperCaseCharacters); i++)
     if (upperCaseCharacters[i] == c) return 1;
   return 0;
 }
@@ -337,7 +321,7 @@ void toIso(char copy[], /* OUT - Mapped  string */
 	   char original[],	/* IN - string to convert */
 	   int charset)		/* IN - the current character set */
 {
-static unsigned char macMap[256]
+static const unsigned char macMap[256]
 = {
 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0A,0x0E,0x0F,
 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
@@ -356,7 +340,7 @@ static unsigned char macMap[256]
 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F};
 
-static unsigned char dosMap[256]
+static const unsigned char dosMap[256]
 = {
 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0A,0x0E,0x0F,
 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
@@ -407,7 +391,7 @@ void fromIso(char copy[],       /* OUT - Mapped string */
 	     char original[])   /* IN - string to convert */
 {
 #if ISO == 0
-  static unsigned char map[256]
+  static const unsigned char map[256]
 #if defined __mac__
     = {
       0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0D,0x0B,0x0C,0x0D,0x0E,0x0F,
diff --git a/engines/glk/glulxe/serial.cpp b/engines/glk/glulxe/serial.cpp
index 983053a..74685fb 100644
--- a/engines/glk/glulxe/serial.cpp
+++ b/engines/glk/glulxe/serial.cpp
@@ -233,12 +233,12 @@ uint Glulxe::perform_restoreundo() {
 }
 
 Common::Error Glulxe::writeGameData(Common::WriteStream *ws) {
+#ifdef TODO
 	dest_t dest;
 	int ix;
 	uint res = 0, lx, val;
 	uint memstart = 0, memlen = 0, stackstart = 0, stacklen = 0;
 	uint heapstart = 0, heaplen = 0, filestart = 0, filelen = 0;
-#ifdef TODO
 	stream_get_iosys(&val, &lx);
 	if (val != 2) {
 		/* Not using the Glk I/O system, so bail. This function only
@@ -357,11 +357,13 @@ Common::Error Glulxe::writeGameData(Common::WriteStream *ws) {
 	}
 
 	/* All done. */
-#endif
 	return res ? Common::kUnknownError : Common::kNoError;
+#endif
+	return Common::kUnknownError;
 }
 
 Common::Error Glulxe::readSaveData(Common::SeekableReadStream *rs) {
+#ifdef TODO
 	dest_t dest;
 	int ix;
 	uint lx = 0, res, val;
@@ -369,7 +371,6 @@ Common::Error Glulxe::readSaveData(Common::SeekableReadStream *rs) {
 	uint heapsumlen = 0;
 	uint *heapsumarr = nullptr;
 	bool fromshell = false;
-#ifdef TODO
 	/* If profiling is enabled and active then fail. */
 #if VM_PROFILING
 	if (profile_profiling_active())


Commit: 305330bda7e755f141805a4e0e45f74820e980e1
    https://github.com/scummvm/scummvm/commit/305330bda7e755f141805a4e0e45f74820e980e1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:07-07:00

Commit Message:
GLK: ALAN3: Change EOF to a uint32 EOD to fix compiler warnings

Changed paths:
    engines/glk/alan3/acode.h
    engines/glk/alan3/act.cpp
    engines/glk/alan3/alt_info.cpp
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/decode.cpp
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/lists.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/output.cpp
    engines/glk/alan3/params.cpp
    engines/glk/alan3/parse.cpp
    engines/glk/alan3/rules.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/state.cpp


diff --git a/engines/glk/alan3/acode.h b/engines/glk/alan3/acode.h
index a399d3c..0c40460 100644
--- a/engines/glk/alan3/acode.h
+++ b/engines/glk/alan3/acode.h
@@ -118,7 +118,10 @@ typedef int WordKind;
 
 
 /* Syntax element classifications */
-#define EOS (-2)		/* End Of Syntax */
+// End of file/data
+#define EOD (uint32)-1
+// End Of Syntax
+#define EOS (uint32)-2
 
 /* Syntax element flag bits */
 #define MULTIPLEBIT 0x1
diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
index 1c89e35..cc1fe92 100644
--- a/engines/glk/alan3/act.cpp
+++ b/engines/glk/alan3/act.cpp
@@ -107,7 +107,7 @@ void action(int verb, Parameter parameters[], Parameter multipleMatches[])
             // TODO: if execution for one parameter aborts we should return here, not to top level
             if (setjmp(returnLabel) == NO_JUMP_RETURN)
                 executeCommand(verb, parameters);
-            if (multipleMatches[i+1].instance != EOF)
+            if (multipleMatches[i+1].instance != EOD)
                 para();
         }
         memcpy(returnLabel, savedReturnLabel, sizeof(returnLabel));
diff --git a/engines/glk/alan3/alt_info.cpp b/engines/glk/alan3/alt_info.cpp
index b9e2dc0..5a87cbb 100644
--- a/engines/glk/alan3/alt_info.cpp
+++ b/engines/glk/alan3/alt_info.cpp
@@ -285,7 +285,7 @@ static VerbEntry *findVerbEntry(int verbCode, VerbEntry *entries) {
     VerbEntry *verbEntry;
     for (verbEntry = entries; !isEndOfArray(verbEntry); verbEntry++) {
         if (verbEntry->code < 0) {
-            /* Verb codes are negative for Meta verbs, if so they are also 1 off to avoid EOF */
+            /* Verb codes are negative for Meta verbs, if so they are also 1 off to avoid EOD */
             if (abs(verbEntry->code)-1 == verbCode)
                 return verbEntry;
         } else {
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index 7e017ab..c196897 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -284,7 +284,7 @@ static int sourceFileNumber(char *fileName) {
     SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
     int n;
 
-    for (n = 0; *(Aword*)&entries[n] != EOF; n++) {
+    for (n = 0; *(Aword*)&entries[n] != EOD; n++) {
         char *entryName;
         entryName = getStringFromFile(entries[n].fpos, entries[n].len);
         if (strcmp(entryName, fileName) == 0) return n;
@@ -522,7 +522,7 @@ void showSourceLine(int fileNumber, int line) {
 static void listFiles() {
     SourceFileEntry *entry;
     int i = 0;
-    for (entry = (SourceFileEntry *)pointerTo(header->sourceFileTable); *((Aword*)entry) != EOF; entry++) {
+    for (entry = (SourceFileEntry *)pointerTo(header->sourceFileTable); *((Aword*)entry) != EOD; entry++) {
         printf("  %2d : %s\n", i, sourceFileName(i));
         i++;
     }
@@ -598,7 +598,7 @@ static void setBreakpoint(int file, int line) {
             int lineIndex = findSourceLineIndex((SourceLineEntry *)pointerTo(header->sourceLineTable), file, line);
             SourceLineEntry *entry = (SourceLineEntry *)pointerTo(header->sourceLineTable);
             char leadingText[100] = "Breakpoint";
-            if (entry[lineIndex].file == EOF) {
+            if (entry[lineIndex].file == EOD) {
                 printf("Line %d not available\n", line);
             } else {
                 if (entry[lineIndex].line != line)
diff --git a/engines/glk/alan3/decode.cpp b/engines/glk/alan3/decode.cpp
index 233228b..4fe2af7 100644
--- a/engines/glk/alan3/decode.cpp
+++ b/engines/glk/alan3/decode.cpp
@@ -37,7 +37,7 @@ Aword *freq;            /* Cumulative character frequencies */
 /* Bit output */
 static int decodeBuffer;	/* Bits to be input */
 static int bitsToGo;		/* Bits still in buffer */
-static int garbageBits;		/* Bits past EOF */
+static int garbageBits;		/* Bits past EOD */
 
 
 static int inputBit(void)
@@ -47,8 +47,8 @@ static int inputBit(void)
   /* More bits available ? */
   if (!bitsToGo) {
 	/* No, so get more */
-	 decodeBuffer = (textFile->pos() >= textFile->size()) ? EOF : textFile->readByte();
-    if (decodeBuffer == EOF) {
+	 decodeBuffer = (textFile->pos() >= textFile->size()) ? EOD : textFile->readByte();
+    if (decodeBuffer == EOD) {
       garbageBits++;
       if (garbageBits > VALUEBITS-2)
 	syserr("Error in encoded data file.");
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index 761c74a..a761b56 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -161,7 +161,7 @@ static Aptr literalAttribute(int literal, int attribute)
         else
             return getAttribute(admin[header->instanceMax].attributes, attribute);
     }
-    return(EOF);
+    return(EOD);
 }
 
 
@@ -183,7 +183,7 @@ Aptr getInstanceAttribute(int instance, int attribute)
             syserr(str);
         }
     }
-    return(EOF);
+    return(EOD);
 }
 
 
@@ -462,10 +462,10 @@ void sayInstance(int instance)
 
     /* Find the id in the parameters... */
     if (params != NULL)
-        for (p = 0; params[p].code != EOF; p++)
+        for (p = 0; params[p].code != EOD; p++)
             if (params[p].code == instance) {
                 /* Found it so.. */
-                if (params[p].firstWord == EOF) /* Any words he used? */
+                if (params[p].firstWord == EOD) /* Any words he used? */
                     break;      /* No... */
                 else {              /* Yes, so use them... */
                     char *capitalized;
diff --git a/engines/glk/alan3/lists.cpp b/engines/glk/alan3/lists.cpp
index bb330c3..c42e90e 100644
--- a/engines/glk/alan3/lists.cpp
+++ b/engines/glk/alan3/lists.cpp
@@ -30,16 +30,16 @@ void initArray(void *array) {
 	implementationOfSetEndOfArray((Aword *)array);
 }
 
-/* How to know we are at end of a table or array, first Aword == EOF */
+/* How to know we are at end of a table or array, first Aword == EOD */
 void implementationOfSetEndOfArray(Aword *adr)
 {
-	*adr = EOF;
+	*adr = EOD;
 }
 
 
 bool implementationOfIsEndOfList(Aword *adr)
 {
-	return *adr == EOF;
+	return *adr == EOD;
 }
 
 int lengthOfArrayImplementation(void *array_of_any_type, int element_size_in_bytes) {
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 3697ac6..a3be710 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -82,20 +82,20 @@ VerbEntry *vrbs;		/* Verb table pointer */
 void checkobj(Aword *obj) {
     Aword oldobj;
 
-    if (*obj != EOF)
+    if (*obj != EOD)
         return;
 
-    oldobj = EOF;
+    oldobj = EOD;
     for (cur.obj = OBJMIN; cur.obj <= OBJMAX; cur.obj++) {
         /* If an object is present and it is possible to perform his action */
         if (isHere(cur.obj) && possible())
-            if (oldobj == EOF)
+            if (oldobj == EOD)
                 oldobj = cur.obj;
             else
                 error(WANT);          /* And we didn't find multiple objects */
     }
 
-    if (oldobj == EOF)
+    if (oldobj == EOD)
         error(WANT);              /* But we found ONE */
 
     *obj = cur.obj = oldobj;
@@ -526,7 +526,7 @@ static Aint sizeOfAttributeData(void)
             size += AwordSizeOf(AttributeEntry);
             attribute++;
         }
-        size += 1;			/* For EOF */
+        size += 1;			/* For EOD */
     }
 
     if (size != header->attributesAreaSize
@@ -553,7 +553,7 @@ static AttributeEntry *initializeAttributes(int awordSize)
             currentAttributeArea += AwordSizeOf(AttributeEntry);
             originalAttribute++;
         }
-        *((Aword*)currentAttributeArea) = EOF;
+        *((Aword*)currentAttributeArea) = EOD;
         currentAttributeArea += 1;
     }
 
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index efe4e31..e6f921e 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -271,7 +271,7 @@ static void sayParameter(int p, int form)
             apperr("Nonexistent parameter referenced.");
 
 #ifdef ALWAYS_SAY_PARAMETERS_USING_PLAYER_WORDS
-    if (params[p].firstWord != EOF) /* Any words he used? */
+    if (params[p].firstWord != EOD) /* Any words he used? */
         /* Yes, so use them... */
         sayPlayerWordsForParameter(p);
     else
diff --git a/engines/glk/alan3/params.cpp b/engines/glk/alan3/params.cpp
index 4b94009..d1d97a7 100644
--- a/engines/glk/alan3/params.cpp
+++ b/engines/glk/alan3/params.cpp
@@ -280,7 +280,7 @@ void copyReferencesToParameterArray(Aint references[], Parameter parameterArray[
 
     for (i = 0; !isEndOfArray(&references[i]); i++) {
         parameterArray[i].instance = references[i];
-        parameterArray[i].firstWord = EOF; /* Ensure that there is no word that can be used */
+        parameterArray[i].firstWord = EOD; /* Ensure that there is no word that can be used */
     }
     setEndOfArray(&parameterArray[i]);
 }
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp
index fe42bc9..5faa50c 100644
--- a/engines/glk/alan3/parse.cpp
+++ b/engines/glk/alan3/parse.cpp
@@ -214,7 +214,7 @@ static void errorButAfterAll(int butWordIndex) {
 /*----------------------------------------------------------------------*/
 static Aint findInstanceForNoun(int wordIndex) {
     DictionaryEntry *d = &dictionary[wordIndex];
-    if (d->nounRefs == 0 || d->nounRefs == EOF)
+    if (d->nounRefs == 0 || d->nounRefs == EOD)
         syserr("No references for noun");
     return *(Aint*) pointerTo(d->nounRefs);
 }
@@ -1351,7 +1351,7 @@ static int pronounWordForInstance(int instance) {
     for (w = 0; w < dictionarySize; w++)
         if (isPronoun(w)) {
             Aword *reference = (Aword *)pointerTo(dictionary[w].pronounRefs);
-            while (*reference != EOF) {
+            while (*reference != EOD) {
                 if (*reference == (Aword)instance)
                     return dictionary[w].code;
                 reference++;
diff --git a/engines/glk/alan3/rules.cpp b/engines/glk/alan3/rules.cpp
index 29c98c8..96dd33d 100644
--- a/engines/glk/alan3/rules.cpp
+++ b/engines/glk/alan3/rules.cpp
@@ -65,7 +65,7 @@ static void clearRulesAdmin(int numRules) {
 static void initRulesAdmin(int numRules) {
     int r;
 
-    rulesAdmin = (RulesAdmin *)allocate(numRules*sizeof(RulesAdmin)+sizeof(EOF));
+    rulesAdmin = (RulesAdmin *)allocate(numRules*sizeof(RulesAdmin)+sizeof(EOD));
     for (r = 0; r < numRules; r++)
         ;
     setEndOfArray(&rulesAdmin[r]);
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 9c63202..4f3855a 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -93,7 +93,7 @@ static int lookup(char wrd[]) {
         }
     }
     unknown(wrd);
-    return (EOF);
+    return (int)EOD;
 }
 
 
diff --git a/engines/glk/alan3/state.cpp b/engines/glk/alan3/state.cpp
index 3b8acff..f7fc2eb 100644
--- a/engines/glk/alan3/state.cpp
+++ b/engines/glk/alan3/state.cpp
@@ -70,7 +70,7 @@ static int countStrings(void) {
     int count = 0;
 
     if (header->stringInitTable != 0)
-        for (entry = (StringInitEntry *)pointerTo(header->stringInitTable); *(Aword *)entry != EOF; entry++)
+        for (entry = (StringInitEntry *)pointerTo(header->stringInitTable); *(Aword *)entry != EOD; entry++)
             count++;
     return(count);
 }
@@ -92,7 +92,7 @@ static int countSets(void) {
     int count = 0;
 
     if (header->setInitTable != 0)
-        for (entry = (SetInitEntry *)pointerTo(header->setInitTable); *(Aword *)entry != EOF; entry++)
+        for (entry = (SetInitEntry *)pointerTo(header->setInitTable); *(Aword *)entry != EOD; entry++)
             count++;
     return(count);
 }
@@ -251,7 +251,7 @@ static void freeCurrentSetAttributes(void) {
     SetInitEntry *entry;
 
     if (header->setInitTable == 0) return;
-    for (entry = (SetInitEntry *)pointerTo(header->setInitTable); *(Aword *)entry != EOF; entry++) {
+    for (entry = (SetInitEntry *)pointerTo(header->setInitTable); *(Aword *)entry != EOD; entry++) {
         Aptr attributeValue = getAttribute(admin[entry->instanceCode].attributes, entry->attributeCode);
         freeSet((Set*)fromAptr(attributeValue));
     }
@@ -279,7 +279,7 @@ static void freeCurrentStringAttributes(void) {
     StringInitEntry *entry;
 
     if (header->stringInitTable == 0) return;
-    for (entry = (StringInitEntry *)pointerTo(header->stringInitTable); *(Aword *)entry != EOF; entry++) {
+    for (entry = (StringInitEntry *)pointerTo(header->stringInitTable); *(Aword *)entry != EOD; entry++) {
         Aptr attributeValue = getAttribute(admin[entry->instanceCode].attributes, entry->attributeCode);
         deallocate(fromAptr(attributeValue));
     }


Commit: 2de068a98aaeb8a1e9e8f2e719b5ff6ebf858b44
    https://github.com/scummvm/scummvm/commit/2de068a98aaeb8a1e9e8f2e719b5ff6ebf858b44
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:07-07:00

Commit Message:
GLK: ALAN3: Further warning fixes

Changed paths:
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/args.cpp
    engines/glk/alan3/container.cpp
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/decode.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/glkstart.cpp
    engines/glk/alan3/glkstart.h
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/output.cpp
    engines/glk/alan3/parse.cpp
    engines/glk/alan3/readline.cpp
    engines/glk/alan3/reverse.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/sysdep.cpp
    engines/glk/alan3/syserr.cpp
    engines/glk/alan3/syserr.h
    engines/glk/alan3/utils.cpp
    engines/glk/alan3/utils.h


diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index d5a062b..c7c4c6c 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -25,6 +25,7 @@
 #include "glk/alan3/main.h"
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/options.h"
+#include "glk/alan3/syserr.h"
 #include "common/system.h"
 #include "common/config-manager.h"
 #include "common/translation.h"
@@ -58,6 +59,9 @@ Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, g
 	logOption = false;
 	statusLineOption = true;
 	regressionTestOption = false;
+
+	// syserr
+	setSyserrHandler(nullptr);
 }
 
 void Alan3::runGame() {
diff --git a/engines/glk/alan3/args.cpp b/engines/glk/alan3/args.cpp
index 7a020cd..12cf1e8 100644
--- a/engines/glk/alan3/args.cpp
+++ b/engines/glk/alan3/args.cpp
@@ -37,7 +37,7 @@ char *adventureName;        /* The name of the game */
 char *adventureFileName;
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
+#if 0
 /*======================================================================*/
 char *gameName(char *fullPathName) {
     char *foundGameName = "";
@@ -148,7 +148,7 @@ static void switches(int argc, char *argv[])
         }
     }
 }
-
+#endif
 
 /*----------------------------------------------------------------------*/
 bool differentInterpreterName(char *string) {
diff --git a/engines/glk/alan3/container.cpp b/engines/glk/alan3/container.cpp
index b9508f5..365455c 100644
--- a/engines/glk/alan3/container.cpp
+++ b/engines/glk/alan3/container.cpp
@@ -101,7 +101,7 @@ bool passesContainerLimits(Aint theContainer, Aint theAddedInstance) {
 
     if (containers[props].limits != 0) { /* Any limits at all? */
         for (limit = (LimitEntry *) pointerTo(containers[props].limits); !isEndOfArray(limit); limit++)
-            if (limit->atr == 1-I_COUNT) { /* TODO This is actually some encoding of the attribute number, right? */
+            if ((int)limit->atr == 1-I_COUNT) { /* TODO This is actually some encoding of the attribute number, right? */
                 if (countInContainer(theContainer) >= (int)limit->val) {
                     interpret(limit->stms);
                     return(FALSE);
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index c196897..25de184 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -118,7 +118,7 @@ static void sayInstanceNumberAndName(int ins) {
 
 
 /*----------------------------------------------------------------------*/
-static void sayLocationOfInstance(int ins, char *prefix) {
+static void sayLocationOfInstance(int ins, const char *prefix) {
     if (admin[ins].location == 0)
         return;
     else {
@@ -598,7 +598,7 @@ static void setBreakpoint(int file, int line) {
             int lineIndex = findSourceLineIndex((SourceLineEntry *)pointerTo(header->sourceLineTable), file, line);
             SourceLineEntry *entry = (SourceLineEntry *)pointerTo(header->sourceLineTable);
             char leadingText[100] = "Breakpoint";
-            if (entry[lineIndex].file == EOD) {
+            if (entry[lineIndex].file == (Aint)EOD) {
                 printf("Line %d not available\n", line);
             } else {
                 if (entry[lineIndex].line != line)
@@ -684,13 +684,13 @@ void restoreInfo(void)
 #define TRACE_STACK_COMMAND 't'
 
 typedef struct DebugParseEntry {
-    char *command;
-    char *parameter;
+    const char *command;
+	const char *parameter;
     char code;
-    char *helpText;
+	const char *helpText;
 } DebugParseEntry;
 
-static DebugParseEntry commandEntries[] = {
+static const DebugParseEntry commandEntries[] = {
     {"help", "", HELP_COMMAND, "this help"},
     {"?", "", HELP_COMMAND, "d:o"},
     {"break", "[[file:]n]", BREAK_COMMAND, "set breakpoint at source line [n] (optionally in [file])"},
@@ -708,16 +708,16 @@ static DebugParseEntry commandEntries[] = {
     {"exit", "", EXIT_COMMAND, "exit to game, enter 'debug' to get back"},
     {"x", "", EXIT_COMMAND, "d:o"},
     {"quit", "", QUIT_COMMAND, "quit game"},
-    {NULL, NULL}
+    {NULL, NULL, '\0', NULL}
 };
 
-static DebugParseEntry traceSubcommand[] = {
+static const DebugParseEntry traceSubcommand[] = {
     {"source", "", TRACE_SOURCE_COMMAND, ""},
     {"section", "", TRACE_SECTION_COMMAND, ""},
     {"instructions", "", TRACE_INSTRUCTION_COMMAND, ""},
     {"pushs", "", TRACE_PUSH_COMMAND, ""},
     {"stacks", "", TRACE_STACK_COMMAND, ""},
-    {NULL, NULL}
+    {NULL, NULL, '\0', NULL}
 };
 
 
@@ -733,7 +733,7 @@ static char *spaces(int length) {
 
 
 /*----------------------------------------------------------------------*/
-static char *padding(DebugParseEntry *entry, int maxLength) {
+static char *padding(const DebugParseEntry *entry, int maxLength) {
     return spaces(maxLength-strlen(entry->command)-strlen(entry->parameter));
 }
 
@@ -743,7 +743,7 @@ static void handleHelpCommand() {
     if (!regressionTestOption)
         output(alan.longHeader);
 
-    DebugParseEntry *entry = commandEntries;
+    const DebugParseEntry *entry = commandEntries;
 
     int maxLength = 0;
     for (entry = commandEntries; entry->command != NULL; entry++) {
@@ -761,7 +761,7 @@ static void handleHelpCommand() {
 
 
 /*----------------------------------------------------------------------*/
-static DebugParseEntry *findEntry(char *command, DebugParseEntry *entry) {
+static const DebugParseEntry *findEntry(char *command, const DebugParseEntry *entry) {
     while (entry->command != NULL) {
         if (strncasecmp(command, entry->command, strlen(command)) == 0)
             return entry;
@@ -773,7 +773,7 @@ static DebugParseEntry *findEntry(char *command, DebugParseEntry *entry) {
 
 /*----------------------------------------------------------------------*/
 static char parseDebugCommand(char *command) {
-    DebugParseEntry *entry = findEntry(command, commandEntries);
+    const DebugParseEntry *entry = findEntry(command, commandEntries);
     if (entry != NULL) {
         if (strlen(command) < strlen(entry->command)) {
             /* See if there are any more partial matches */
@@ -812,7 +812,7 @@ static void readCommand(char buf[]) {
 
 /*----------------------------------------------------------------------*/
 static void displaySourceLocation(int line, int fileNumber) {
-    char *cause;
+    const char *cause;
     if (anyOutput) newline();
     if (breakpointIndex(fileNumber, line) != -1)
         cause = "Breakpoint hit at";
@@ -871,7 +871,7 @@ static void toggleStackTrace() {
 /*----------------------------------------------------------------------*/
 static int parseTraceCommand() {
     char *subcommand = strtok(NULL, "");
-    DebugParseEntry *entry;
+    const DebugParseEntry *entry;
     if (subcommand == 0)
         return UNKNOWN_COMMAND;
     else {
@@ -889,7 +889,7 @@ static int parseTraceCommand() {
 
 
 /*----------------------------------------------------------------------*/
-static char *printTraceState(bool state) {
+static const char *printTraceState(bool state) {
     if (state)
         return "on  - Traces";
     else
diff --git a/engines/glk/alan3/decode.cpp b/engines/glk/alan3/decode.cpp
index 4fe2af7..41afbdd 100644
--- a/engines/glk/alan3/decode.cpp
+++ b/engines/glk/alan3/decode.cpp
@@ -48,7 +48,7 @@ static int inputBit(void)
   if (!bitsToGo) {
 	/* No, so get more */
 	 decodeBuffer = (textFile->pos() >= textFile->size()) ? EOD : textFile->readByte();
-    if (decodeBuffer == EOD) {
+    if (decodeBuffer == (int)EOD) {
       garbageBits++;
       if (garbageBits > VALUEBITS-2)
 	syserr("Error in encoded data file.");
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index 7f0fe2b..f37cc2f 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -340,8 +340,10 @@ void schedule(Aword event, Aword where, Aword after)
 
     cancelEvent(event);
     /* Check for overflow */
-    if (eventQueue == NULL || eventQueueTop == eventQueueSize)
+    if (eventQueue == nullptr || eventQueueTop == eventQueueSize) {
         increaseEventQueue();
+		assert(eventQueue);
+	}
 
     /* Bubble this event down */
     for (i = eventQueueTop; i >= 1 && eventQueue[i-1].after <= (int)after; i--) {
@@ -713,35 +715,33 @@ bool streq(char a[], char b[])
 
 /*======================================================================*/
 void startTranscript(void) {
-    if (logFile != NULL)
-        return;
-
-	Common::String filename = g_vm->getTargetName() + ".log";
-
-	uint fileUsage = transcriptOption ? fileusage_Transcript : fileusage_InputRecord;
-	frefid_t logFileRef = g_vm->glk_fileref_create_by_name(fileUsage, filename.c_str(), 0);
-	logFile = g_vm->glk_stream_open_file(logFileRef, filemode_Write, 0);
-
-	if (logFile == NULL) {
-        transcriptOption = FALSE;
-        logOption = FALSE;
-	} else {
-		transcriptOption = TRUE;
+    if (logFile == NULL) {
+		Common::String filename = g_vm->getTargetName() + ".log";
+
+		uint fileUsage = transcriptOption ? fileusage_Transcript : fileusage_InputRecord;
+		frefid_t logFileRef = g_vm->glk_fileref_create_by_name(fileUsage, filename.c_str(), 0);
+		logFile = g_vm->glk_stream_open_file(logFileRef, filemode_Write, 0);
+
+		if (logFile == NULL) {
+			transcriptOption = FALSE;
+			logOption = FALSE;
+		} else {
+			transcriptOption = TRUE;
+		}
 	}
 }
 
 
 /*======================================================================*/
 void stopTranscript(void) {
-    if (logFile == NULL)
-        return;
-
-	if (transcriptOption|| logOption)
-		delete logFile;
+	if (logFile != NULL) {
+		if (transcriptOption|| logOption)
+			delete logFile;
 
-    logFile = NULL;
-    transcriptOption = FALSE;
-    logOption = FALSE;
+		logFile = NULL;
+		transcriptOption = FALSE;
+		logOption = FALSE;
+	}
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/glkstart.cpp b/engines/glk/alan3/glkstart.cpp
index 0c54cfd..da20f0f 100644
--- a/engines/glk/alan3/glkstart.cpp
+++ b/engines/glk/alan3/glkstart.cpp
@@ -42,7 +42,7 @@
 namespace Glk {
 namespace Alan3 {
 
-glkunix_argumentlist_t glkunix_arguments[] = {
+const glkunix_argumentlist_t glkunix_arguments[] = {
     { "-l", glkunix_arg_NoValue, "-l: log player command and game output" },
     { "-c", glkunix_arg_NoValue, "-c: log player commands to a file" },
     { "-n", glkunix_arg_NoValue, "-n: no status line" },
diff --git a/engines/glk/alan3/glkstart.h b/engines/glk/alan3/glkstart.h
index 4420bea..2bc2e9c 100644
--- a/engines/glk/alan3/glkstart.h
+++ b/engines/glk/alan3/glkstart.h
@@ -60,9 +60,9 @@ namespace Alan3 {
 #define glkunix_arg_NumberValue (4)
 
 struct glkunix_argumentlist_t {
-    char *name;
+    const char *name;
     int argtype;
-    char *desc;
+	const char *desc;
 };
 
 struct glkunix_startup_t {
@@ -71,7 +71,7 @@ struct glkunix_startup_t {
 };
 
 /* The list of command-line arguments; this should be defined in your code. */
-extern glkunix_argumentlist_t glkunix_arguments[];
+extern const glkunix_argumentlist_t glkunix_arguments[];
 
 /* The external function; this should be defined in your code. */
 extern int glkunix_startup_code(glkunix_startup_t *data);
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index a761b56..d2670f3 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -202,7 +202,7 @@ Set *getInstanceSetAttribute(int instance, int attribute)
 
 
 /*----------------------------------------------------------------------*/
-static void verifyInstance(int instance, char *action) {
+static void verifyInstance(int instance, const char *action) {
     char message[200];
 
     if (instance == 0) {
@@ -1053,7 +1053,7 @@ static void locateActor(Aint movingActor, Aint whr)
 
 
 /*----------------------------------------------------------------------*/
-static void traceExtract(int instance, int containerId, char *what) {
+static void traceExtract(int instance, int containerId, const char *what) {
     if (traceSectionOption) {
         printf("\n<EXTRACT from ");
         traceSay(instance);
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index e4e98fd..457f75d 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -71,7 +71,7 @@ void setInterpreterStack(Stack theStack)
 
 
 /*----------------------------------------------------------------------*/
-static void traceInstruction(char *str, ...) {
+static void traceInstruction(const char *str, ...) {
     va_list args;
 
     if (traceInstructionOption) {
@@ -236,7 +236,7 @@ static void depexec(Aword v)
 {
     int lev = 1;
     Aword i;
-    char *instructionString = "DEPELSE";
+    const char *instructionString = "DEPELSE";
 
     if (!v) {
         /* The expression was not true, skip to next CASE on the same
@@ -306,13 +306,13 @@ static void depcase(void)
 
 
 /*----------------------------------------------------------------------*/
-static char *booleanValue(Abool value) {
+static const char *booleanValue(Abool value) {
     if (value) return "   TRUE";
     else return "  FALSE";
 }
 
 /*----------------------------------------------------------------------*/
-static char *stringValue(Aptr address) {
+static const char *stringValue(Aptr address) {
     static char string[1000];
 
     sprintf(string, "0x%lx (\"%s\")\t\t", (unsigned long) address, (char *)fromAptr(address));
@@ -320,7 +320,7 @@ static char *stringValue(Aptr address) {
 }
 
 /*----------------------------------------------------------------------*/
-static char *pointerValue(Aptr address) {
+static const char *pointerValue(Aptr address) {
     static char string[100];
 
     sprintf(string, "@%6lx",(unsigned long) address);
@@ -365,7 +365,7 @@ static void traceInstanceTopValue() {
 }
 
 /*----------------------------------------------------------------------*/
-static char *transitivityFlag(ATrans value) {
+static const char *transitivityFlag(ATrans value) {
     switch (value) {
     case TRANSITIVE:
         return "Transitive";
@@ -379,7 +379,7 @@ static char *transitivityFlag(ATrans value) {
 }
 
 /*----------------------------------------------------------------------*/
-static char *printForm(SayForm form) {
+static const char *printForm(SayForm form) {
     switch (form) {
     case SAY_SIMPLE: return "-";
     case SAY_INDEFINITE: return "An";
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index a3be710..030579f 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -153,11 +153,7 @@ static void runPendingEvents(void)
 
 \*----------------------------------------------------------------------*/
 
-
 Common::SeekableReadStream *codfil;
-static char codfnm[256] = "";
-static char txtfnm[256] = "";
-
 
 /*----------------------------------------------------------------------
   Calculate where to start calculating the CRC. Is different for
@@ -255,7 +251,7 @@ static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
 
 
 /*----------------------------------------------------------------------*/
-static char *decodeState(int c) {
+static const char *decodeState(int c) {
     static char state[3] = "\0\0";
     switch (c) {
     case 0: return ".";
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index e6f921e..be27484 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -142,14 +142,15 @@ void clear(void)
 
 
 /*----------------------------------------------------------------------*/
-static void capitalizeFirst(char *str) {
+static void capitalizeFirst(Common::String &str) {
     uint i = 0;
 
-    /* Skip over space... */
-    while (i < strlen(str) && isSpace(str[i])) i++;
-    if (i < strlen(str)) {
-        str[i] = toUpper(str[i]);
-        capitalize = FALSE;
+    // Skip over space...
+    while (i < str.size() && isSpace(str[i])) i++;
+
+	if (i < str.size()) {
+		str.setChar(toUpper(str[i]), i);
+        capitalize = false;
     }
 }
 
@@ -194,13 +195,14 @@ void printAndLog(const char *string)
 
 
 /*----------------------------------------------------------------------*/
-static void justify(char str[])
-{
+static void justify(const char *str) {
+	Common::String tempStr(str);
+
     if (capitalize)
-        capitalizeFirst(str);
+        capitalizeFirst(tempStr);
 
 #ifdef HAVE_GLK
-    printAndLog(str);
+    printAndLog(tempStr.c_str());
 #else
     int i;
     char ch;
@@ -230,7 +232,7 @@ static void justify(char str[])
     }
     printAndLog(str);     /* Print tail */
 #endif
-    col = col + strlen(str);  /* Update column */
+    col = col + tempStr.size();  // Update column
 }
 
 
@@ -370,7 +372,7 @@ static char *printSymbol(char str[]) /* IN - The string starting with '$' */
             break;
         case 'v':
             space();
-            justify((char *)pointerTo(dictionary[verbWord].string));
+            justify((const char *)pointerTo(dictionary[verbWord].string));
             needSpace = TRUE;       /* We did print something non-white */
             break;
         case 'p':
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp
index 5faa50c..a1967e6 100644
--- a/engines/glk/alan3/parse.cpp
+++ b/engines/glk/alan3/parse.cpp
@@ -224,7 +224,7 @@ static void errorNoSuch(Parameter parameter) {
 
     /* If there was no instance, assume the last word used is the noun,
      * then find any instance with the noun he used */
-    if (parameter.instance == -1)
+    if (parameter.instance == (Aid)-1)
         parameter.instance = 0;
     if (parameter.instance == 0)
         parameter.instance = findInstanceForNoun(playerWords[parameter.lastWord].code);
@@ -745,7 +745,7 @@ static ElementEntry *elementForParameter(ElementEntry *elms) {
 
 /*----------------------------------------------------------------------*/
 static ElementEntry *elementForEndOfSyntax(ElementEntry *elms) {
-    while (!isEndOfArray(elms) && elms->code != EOS)
+    while (!isEndOfArray(elms) && (Aword)elms->code != EOS)
         elms++;
     if (isEndOfArray(elms)) /* No match for EOS! */
         return NULL;
diff --git a/engines/glk/alan3/readline.cpp b/engines/glk/alan3/readline.cpp
index 552e3b5..fa965bb 100644
--- a/engines/glk/alan3/readline.cpp
+++ b/engines/glk/alan3/readline.cpp
@@ -147,7 +147,9 @@ bool readline(char buffer[])
                     }
                     break;
 #endif
-                }
+				default:
+					break;
+				}
             } while (event.type != evtype_LineInput);
         if (buffer[0] == '@') {
             buffer[event.val1] = 0;
diff --git a/engines/glk/alan3/reverse.cpp b/engines/glk/alan3/reverse.cpp
index d31e7c3..2a0cd42 100644
--- a/engines/glk/alan3/reverse.cpp
+++ b/engines/glk/alan3/reverse.cpp
@@ -78,7 +78,7 @@ Aword reversed(Aword w) /* IN - The ACODE word to swap bytes of */
 #else
   Aword s;                      /* The swapped ACODE word */
   char *wp, *sp;
-  int i;
+  uint i;
 
   wp = (char *) &w;
   sp = (char *) &s;
@@ -109,7 +109,7 @@ static void reverseTable(Aword adr, int elementSize)
   Aword *e = &memory[adr];
   uint i;
 
-  if (elementSize < sizeof(Aword) || elementSize % sizeof(Aword) != 0)
+  if (elementSize < (int)sizeof(Aword) || elementSize % (int)sizeof(Aword) != 0)
       syserr("***Wrong size in 'reverseTable()' ***");
 
   if (adr == 0) return;
@@ -351,7 +351,7 @@ static void reverseElms(Aword adr)
   if (!isEndOfArray(e)) {
     reverseTable(adr, sizeof(ElementEntry));
     while (!isEndOfArray(e)) {
-      if (e->code == EOS) reverseRestrictions(e->next);
+      if ((uint)e->code == EOS) reverseRestrictions(e->next);
       else reverseElms(e->next);
       e++;
     }
@@ -520,7 +520,7 @@ static void reverseSetInitTable(Aaddr adr)
 /*----------------------------------------------------------------------*/
 static void reversePreAlpha5Header(Pre3_0alpha5Header *hdr)
 {
-  int i;
+  uint i;
 
   /* Reverse all words in the header except the tag */
   for (i = 1; i < sizeof(*hdr)/sizeof(Aword); i++)
@@ -561,7 +561,7 @@ static void reversePreAlpha5() {
 /*----------------------------------------------------------------------*/
 static void reversePreBeta2Header(Pre3_0beta2Header *hdr)
 {
-  int i;
+  uint i;
 
   /* Reverse all words in the header except the tag */
   for (i = 1; i < sizeof(*hdr)/sizeof(Aword); i++)
@@ -602,7 +602,7 @@ static void reversePreBeta2() {
 /*======================================================================*/
 void reverseHdr(ACodeHeader *hdr)
 {
-  int i;
+  uint i;
 
   /* Reverse all words in the header except the tag and the version marking */
   for (i = 1; i < sizeof(*hdr)/sizeof(Aword); i++)
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 4f3855a..64c0e62 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -78,7 +78,7 @@ static void unknown(char tok[]) {
 static int number(char tok[]) {
     int i;
 	
-    sscanf(tok, "%d", &i);
+    (void)sscanf(tok, "%d", &i);
     return i;
 }
 
diff --git a/engines/glk/alan3/sysdep.cpp b/engines/glk/alan3/sysdep.cpp
index 7e9dc48..6b66393 100644
--- a/engines/glk/alan3/sysdep.cpp
+++ b/engines/glk/alan3/sysdep.cpp
@@ -140,7 +140,7 @@ static const byte upperCaseCharacters[] =
 
 int isSpace(unsigned int c)              /* IN - Native character to test */
 {
-    return (c != '\0' && strchr((char *)spaceCharacters, c) != 0);
+    return (c != '\0' && strchr((const char *)spaceCharacters, c) != 0);
 }
 
 
@@ -471,7 +471,7 @@ int littleEndian() {
 
 /*======================================================================*/
 char *baseNameStart(char *fullPathName) {
-  static char *delimiters = "\\>]/:";
+  const char *delimiters = "\\>]/:";
   int i;
 
   for (i = strlen(fullPathName)-1; i > 0; i--)
diff --git a/engines/glk/alan3/syserr.cpp b/engines/glk/alan3/syserr.cpp
index 2fceba6..9ebd3973 100644
--- a/engines/glk/alan3/syserr.cpp
+++ b/engines/glk/alan3/syserr.cpp
@@ -30,10 +30,10 @@
 namespace Glk {
 namespace Alan3 {
 
-static void (*handler)(char *) = NULL;
+static void (*handler)(const char *);
 
 /*----------------------------------------------------------------------*/
-static void runtimeError(char *errorClassification, char *errorDescription, char *blurb) {
+static void runtimeError(const char *errorClassification, const char *errorDescription, const char *blurb) {
   output("$n$nAs you enter the twilight zone of Adventures, you stumble \
 and fall to your knees. In front of you, you can vaguely see the outlines \
 of an Adventure that never was.$n$n");
@@ -54,7 +54,7 @@ of an Adventure that never was.$n$n");
 
 
 /*======================================================================*/
-void setSyserrHandler(void (*f)(char *))
+void setSyserrHandler(void (*f)(const char *))
 {
   handler = f;
 }
@@ -62,11 +62,11 @@ void setSyserrHandler(void (*f)(char *))
 
 /*======================================================================*/
 // TODO Make syserr() use ... as printf()
-void syserr(char *description)
+void syserr(const char *description)
 {
     lin = 0;
     if (handler == NULL) {
-        char *blurb = "<If you are the creator of this piece of Interactive Fiction, \
+		const char *blurb = "<If you are the creator of this piece of Interactive Fiction, \
 please help debug this Alan system error. Collect *all* the sources, and, if possible, an \
 exact transcript of the commands that led to this error, in a zip-file and send \
 it to support at alanif.se. Thank you!>";
@@ -77,10 +77,10 @@ it to support at alanif.se. Thank you!>";
 
 
 /*======================================================================*/
-void apperr(char *description)
+void apperr(const char *description)
 {
     if (handler == NULL) {
-        char *blurb = "<If you are playing this piece of Interactive Fiction, \
+		const char *blurb = "<If you are playing this piece of Interactive Fiction, \
 please help the author to debug this programming error. Send an exact \
 transcript of the commands that led to this error to the author. Thank you! \
 If you *are* the author, then you have to figure this out before releasing the game.>";
@@ -90,10 +90,10 @@ If you *are* the author, then you have to figure this out before releasing the g
 }
 
 /*======================================================================*/
-void playererr(char *description)
+void playererr(const char *description)
 {
     if (handler == NULL) {
-        char *blurb = "<You have probably done something that is not exactly right.>";
+        const char *blurb = "<You have probably done something that is not exactly right.>";
         runtimeError("PLAYER ERROR: ", description, blurb);
     } else
         handler(description);
diff --git a/engines/glk/alan3/syserr.h b/engines/glk/alan3/syserr.h
index 84c2178..3202600 100644
--- a/engines/glk/alan3/syserr.h
+++ b/engines/glk/alan3/syserr.h
@@ -29,10 +29,10 @@ namespace Glk {
 namespace Alan3 {
 
 /* Functions: */
-extern void syserr(char *msg);
-extern void apperr(char *msg);
-extern void playererr(char *msg);
-extern void setSyserrHandler(void (*handler)(char *));
+extern void syserr(const char *msg);
+extern void apperr(const char *msg);
+extern void playererr(const char *msg);
+extern void setSyserrHandler(void (*handler)(const char *));
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/utils.cpp b/engines/glk/alan3/utils.cpp
index bcbaa47..9b9b6ed 100644
--- a/engines/glk/alan3/utils.cpp
+++ b/engines/glk/alan3/utils.cpp
@@ -69,7 +69,7 @@ void printVersion(int buildNumber) {
 
 
 /*======================================================================*/
-void usage(char *programName)
+void usage(const char *programName)
 {
 #if (BUILD+0) != 0
     printVersion(BUILD);
@@ -100,7 +100,7 @@ void usage(char *programName)
 #define FNM_CASEFOLD 0
 #endif
 /*======================================================================*/
-bool match(char *pattern, char *input) {
+bool match(const char *pattern, char *input) {
     return fnmatch(pattern, input, FNM_CASEFOLD) == 0;
 }
 
diff --git a/engines/glk/alan3/utils.h b/engines/glk/alan3/utils.h
index 1a6d470..f103436 100644
--- a/engines/glk/alan3/utils.h
+++ b/engines/glk/alan3/utils.h
@@ -32,9 +32,9 @@ namespace Alan3 {
 
 /* FUNCTIONS: */
 extern void terminate(int code);
-extern void usage(char *programName);
+extern void usage(const char *programName);
 extern void printVersion(int buildNumber);
-extern bool match(char *pattern, char *input);
+extern bool match(const char *pattern, char *input);
 
 } // End of namespace Alan3
 } // End of namespace Glk


Commit: aebf25661076eaa382b3025f0123f6ceb7cf920b
    https://github.com/scummvm/scummvm/commit/aebf25661076eaa382b3025f0123f6ceb7cf920b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:07-07:00

Commit Message:
GLK: ALAN3: Removal of #ifdef blocks

Changed paths:
    engines/glk/alan3/args.h
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/glkio.h
    engines/glk/alan3/glkstart.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/output.cpp
    engines/glk/alan3/readline.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/sysdep.cpp
    engines/glk/alan3/sysdep.h
    engines/glk/alan3/term.cpp
    engines/glk/alan3/utils.cpp


diff --git a/engines/glk/alan3/args.h b/engines/glk/alan3/args.h
index f70cf3a..690f675 100644
--- a/engines/glk/alan3/args.h
+++ b/engines/glk/alan3/args.h
@@ -31,11 +31,7 @@ namespace Glk {
 namespace Alan3 {
 
 #ifndef PROGNAME
-#ifdef HAVE_GARGLK
 #define PROGNAME "alan3"
-#else
-#define PROGNAME "arun"
-#endif
 #endif
 
 /* DATA */
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index 25de184..53895f1 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -66,9 +66,7 @@ static void showAttributes(AttributeEntry *attrib)
     i = 1;
     for (at = attrib; !isEndOfArray(at); at++) {
         sprintf(str, "$i$t%s[%d] = %d", (char *) pointerTo(at->id), at->code, (int)at->value);
-#if ISO == 0
-        fromIso(str, str);
-#endif
+
         output(str);
         i++;
     }
@@ -238,47 +236,6 @@ static void showObject(int obj)
 
 }
 
-#ifdef UNDEF_WHEN_NEEDED
-/*----------------------------------------------------------------------*/
-static void showcnts(void)
-{
-    char str[80];
-    int cnt;
-
-    output("Containers:");
-    for (cnt = 1; cnt <= header->containerMax; cnt++) {
-        sprintf(str, "$i%3d: ", cnt);
-        output(str);
-        if (containers[cnt].owner != 0)
-            say(containers[cnt].owner);
-    }
-
-}
-
-/*----------------------------------------------------------------------*/
-static void showContainer(int cnt)
-{
-    char str[80];
-
-    if (cnt < 1 || cnt > header->containerMax) {
-        sprintf(str, "Container number out of range. Between 1 and %d, please.", header->containerMax);
-        output(str);
-        return;
-    }
-
-    sprintf(str, "Container %d :", cnt);
-    output(str);
-    if (containers[cnt].owner != 0) {
-        cnt = containers[cnt].owner;
-        say(cnt);
-        sprintf(str, "$iLocation: %d", where(cnt, TRUE));
-        output(str);
-    }
-    showContents(cnt);
-}
-#endif
-
-
 /*----------------------------------------------------------------------*/
 static int sourceFileNumber(char *fileName) {
     SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
@@ -437,9 +394,7 @@ static void showEvents(void)
     output("Events:");
     for (event = 1; event <= header->eventMax; event++) {
         sprintf(str, "$i%d [%s]:", event, (char *)pointerTo(events[event].id));
-#if ISO == 0
-        fromIso(str, str);
-#endif
+
         output(str);
         scheduled = FALSE;
         for (i = 0; i < eventQueueTop; i++)
@@ -796,11 +751,7 @@ static void readCommand(char buf[]) {
     do {
         output("adbg> ");
 
-#ifdef USE_READLINE
         if (!readline(buf)) {
-#else
-        if (fgets(buf, 255, stdin) == NULL) {
-#endif
             newline();
             quitGame();
         }
@@ -1042,10 +993,7 @@ void debug(bool calledFromBreakpoint, int line, int fileNumber)
     static bool warned = FALSE;
 
     saveInfo();
-
-#ifdef HAVE_GLK
     g_vm->glk_set_style(style_Preformatted);
-#endif
 
     if (calledFromBreakpoint)
         displaySourceLocation(line, fileNumber);
@@ -1090,10 +1038,7 @@ void debug(bool calledFromBreakpoint, int line, int fileNumber)
     }
 
  exit_debug:
-#ifdef HAVE_GLK
 	g_vm->glk_set_style(style_Normal);
-#endif
-    ;
 }
 
 
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index f37cc2f..445b00d 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -68,9 +68,7 @@ Common::SeekableReadStream *textFile;
 
 
 /*======================================================================*/
-void setStyle(int style)
-{
-#ifdef HAVE_GLK
+void setStyle(int style) {
     switch (style) {
     case NORMAL_STYLE: g_vm->glk_set_style(style_Normal); break;
     case EMPHASIZED_STYLE: g_vm->glk_set_style(style_Emphasized); break;
@@ -78,7 +76,6 @@ void setStyle(int style)
     case ALERT_STYLE: g_vm->glk_set_style(style_Alert); break;
     case QUOTE_STYLE: g_vm->glk_set_style(style_BlockQuote); break;
     }
-#endif
 }
 
 /*======================================================================*/
@@ -126,9 +123,7 @@ void print(Aword fpos, Aword len)
                     break;
             }
             str[i] = '\0';
-#if ISO == 0
-            fromIso(str, str);
-#endif
+
             output(str);
         }
 
@@ -243,11 +238,8 @@ void quitGame(void)
         col = 1;
         statusline();
         printMessage(M_QUITACTION);
-#ifdef USE_READLINE
+
         if (!readline(buf)) terminate(0);
-#else
-        if (gets(buf) == NULL) terminate(0);
-#endif
         if (strcasecmp(buf, "restart") == 0)
             longjmp(restartLabel, TRUE);
         else if (strcasecmp(buf, "restore") == 0) {
@@ -558,9 +550,7 @@ int getContainerMember(int container, int index, bool directly) {
 
 
 /*======================================================================*/
-void showImage(int image, int align)
-{
-#ifdef HAVE_GLK
+void showImage(int image, int align) {
     uint ecode;
 
     if ((g_vm->glk_gestalt(gestalt_Graphics, 0) == 1) &&
@@ -570,14 +560,12 @@ void showImage(int image, int align)
         ecode = g_vm->glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
         (void)ecode;
     }
-#endif
 }
 
 
 /*======================================================================*/
 void playSound(int sound)
 {
-#ifdef HAVE_GLK
 #ifdef GLK_MODULE_SOUND
     static schanid_t soundChannel = NULL;
 
@@ -590,11 +578,9 @@ void playSound(int sound)
         }
     }
 #endif
-#endif
 }
 
 
-
 /*======================================================================*/
 void empty(int cnt, int whr)
 {
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index 5bcd6e6..b77e659 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -40,15 +40,6 @@ extern winid_t glkStatusWin;
 #define printf glkio_printf
 extern void glkio_printf(const char *, ...);
 
-#ifdef MAP_STDIO_TO_GLK
-#define fgetc(stream) glk_get_char_stream(stream)
-#define rewind(stream) glk_stream_set_position(stream, 0, seekmode_Start);
-#define fwrite(buf, elementSize, count, stream) glk_put_buffer_stream(stream, buf, elementSize*count);
-#define fread(buf, elementSize, count, stream) glk_get_buffer_stream(stream, buf, elementSize*count);
-#define fclose(stream) glk_stream_close(stream, NULL)
-#define fgets(buff, len, stream) glk_get_line_stream(stream, buff, len)
-#endif
-
 } // End of namespace Alan3
 } // End of namespace Glk
 
diff --git a/engines/glk/alan3/glkstart.cpp b/engines/glk/alan3/glkstart.cpp
index da20f0f..d4f7dcb 100644
--- a/engines/glk/alan3/glkstart.cpp
+++ b/engines/glk/alan3/glkstart.cpp
@@ -21,24 +21,15 @@
  */
 
 #include "glk/alan3/glkstart.h"
+#include "glk/alan3/alan_version.h"
 #include "glk/alan3/alan3.h"
 #include "glk/alan3/args.h"
 #include "glk/alan3/main.h"
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/resources.h"
 #include "glk/alan3/utils.h"
- //#include "glk/alan3/gi_blorb.h"
 #include "glk/streams.h"
 
-#ifdef HAVE_WINGLK
-#include "glk/alan3/WinGlk.h"
-#endif
-
-
-#ifdef HAVE_GARGLK
-#include "glk/alan3/alan_version.h"
-#endif
-
 namespace Glk {
 namespace Alan3 {
 
@@ -64,9 +55,7 @@ static void openGlkWindows() {
             printf("FATAL ERROR: Cannot open initial window");
 			g_vm->glk_exit();
     }
-#ifdef HAVE_GARGLK
-   glk_stylehint_set (wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
-#endif
+
     glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
                                    winmethod_Fixed, 1, wintype_TextGrid, 0);
 	g_vm->glk_set_window(glkStatusWin);
@@ -107,23 +96,8 @@ int glkunix_startup_code(glkunix_startup_t *data) {
     /* first, open a window for error output */
     openGlkWindows();
 
-#ifdef HAVE_GARGLK
-#if (BUILD+0) != 0
-    {
-        char name[100];
-        sprintf(name, "%s-%d", alan.shortHeader, BUILD);
-        garglk_set_program_name(name);
-    }
-#else
-	garglk_set_program_name(alan.shortHeader);
-#endif
-	char info[80];
-	sprintf(info, "%s Interpreter by Thomas Nilefalk\n", alan.shortHeader);
-	garglk_set_program_info(info);
-#endif
-
     /* now process the command line arguments */
-    args(data->argc, data->argv);
+    //args(data->argc, data->argv);
 
     if (adventureFileName == NULL || strcmp(adventureFileName, "") == 0) {
         printf("You should supply a game file to play.\n");
@@ -137,73 +111,5 @@ int glkunix_startup_code(glkunix_startup_t *data) {
     return TRUE;
 }
 
-
-
-#ifdef HAVE_WINGLK
-static int argCount;
-static char *argumentVector[10];
-
-/*----------------------------------------------------------------------*/
-static void splitArgs(char *commandLine) {
-    unsigned char *cp = (unsigned char *)commandLine;
-
-    while (*cp) {
-        while (*cp && isspace(*cp)) cp++;
-        if (*cp) {
-            argumentVector[argCount++] = (char *)cp;
-            if (*cp == '"') {
-                do {
-                    cp++;
-                } while (*cp != '"');
-                cp++;
-            } else
-                while (*cp && !isspace(*cp))
-                    cp++;
-            if (*cp) {
-                *cp = '\0';
-                cp++;
-            }
-        }
-    }
-}
-
-
-/*======================================================================*/
-int winglk_startup_code(const char* cmdline)
-{
-    char windowTitle[200];
-
-    /* Process the command line arguments */
-    argumentVector[0] = "";
-    argCount = 1;
-
-    splitArgs(strdup(cmdline));
-
-    args(argCount, argumentVector);
-
-
-    if (adventureFileName == NULL || strcmp(adventureFileName, "") == 0) {
-        adventureFileName = (char*)winglk_get_initial_filename(NULL, "Arun : Select an Alan game file",
-                                                               "Alan Game Files (*.a3c)|*.a3c||");
-        if (adventureFileName == NULL) {
-            terminate(0);
-        }
-        adventureName = gameName(adventureFileName);
-    }
-
-    winglk_app_set_name("WinArun");
-    winglk_set_gui(IDR_ARUN);
-
-    sprintf(windowTitle, "WinArun : %s", adventureName);
-    winglk_window_set_title(windowTitle);
-    openGlkWindows();
-
-    /* Open any possible blorb resource file */
-    openResourceFile();
-
-    return TRUE;
-}
-#endif
-
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 030579f..e22c5be 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -66,46 +66,6 @@ VerbEntry *vrbs;		/* Verb table pointer */
 /* PRIVATE DATA */
 #define STACKSIZE 100
 
-
-
-#ifdef CHECKOBJ
-/*======================================================================
-
-  checkobj()
-
-  Check that the object given is valid, else print an error message
-  or find out what he wanted.
-
-  This routine is not used any longer, kept for sentimental reasons ;-)
-
-*/
-void checkobj(Aword *obj) {
-    Aword oldobj;
-
-    if (*obj != EOD)
-        return;
-
-    oldobj = EOD;
-    for (cur.obj = OBJMIN; cur.obj <= OBJMAX; cur.obj++) {
-        /* If an object is present and it is possible to perform his action */
-        if (isHere(cur.obj) && possible())
-            if (oldobj == EOD)
-                oldobj = cur.obj;
-            else
-                error(WANT);          /* And we didn't find multiple objects */
-    }
-
-    if (oldobj == EOD)
-        error(WANT);              /* But we found ONE */
-
-    *obj = cur.obj = oldobj;
-    output("($o)");             /* Then he surely meant this object */
-}
-#endif
-
-
-
-
 /*----------------------------------------------------------------------*
  *
  * Event Handling
@@ -232,9 +192,6 @@ static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
         crc += (memory[i]>>8)&0xff;
         crc += (memory[i]>>16)&0xff;
         crc += (memory[i]>>24)&0xff;
-#ifdef CRCLOG
-        printf("%6x\t%6lx\t%6lx\n", i, crc, memory[i]);
-#endif
     }
     if (crc != tmphdr.acdcrc) {
         sprintf(err, "Checksum error in Acode (.a3c) file (0x%lx instead of 0x%lx).",
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index be27484..16f1c1e 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -56,7 +56,6 @@ strid_t logFile;
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 
 
-#if defined(HAVE_GLK) || defined(RUNNING_UNITTESTS)
 /*----------------------------------------------------------------------*/
 static int updateColumn(int currentColumn, const char *string) {
     const char *newlinePosition = strrchr(string, '\n');
@@ -65,46 +64,22 @@ static int updateColumn(int currentColumn, const char *string) {
     else
         return currentColumn + strlen(string);
 }
-#endif
 
 
 /*======================================================================*/
 void setSubHeaderStyle(void) {
-#ifdef HAVE_GLK
     g_vm->glk_set_style(style_Subheader);
-#endif
 }
 
 
 /*======================================================================*/
 void setNormalStyle(void) {
-#ifdef HAVE_GLK
 	g_vm->glk_set_style(style_Normal);
-#endif
 }
 
 /*======================================================================*/
 void newline(void) {
-#ifndef HAVE_GLK
-    char buf[256];
-
-    if (!regressionTestOption && lin == pageLength - 1) {
-		printAndLog("\n");
-        needSpace = FALSE;
-        col = 0;
-        lin = 0;
-        printMessage(M_MORE);
-        statusline();
-        fflush(stdout);
-        fgets(buf, 256, stdin);
-        getPageSize();
-    } else
-        printAndLog("\n");
-
-    lin++;
-#else
     printAndLog("\n");
-#endif
     col = 1;
     needSpace = FALSE;
 }
@@ -114,11 +89,9 @@ void newline(void) {
 void para(void)
 {
     /* Make a new paragraph, i.e one empty line (one or two newlines). */
-
-#ifdef HAVE_GLK
     if (g_vm->glk_gestalt(gestalt_Graphics, 0) == 1)
 		g_vm->glk_window_flow_break(glkMainWin);
-#endif
+
     if (col != 1)
         newline();
     newline();
@@ -127,17 +100,8 @@ void para(void)
 
 
 /*======================================================================*/
-void clear(void)
-{
-#ifdef HAVE_GLK
+void clear(void) {
 	g_vm->glk_window_clear(glkMainWin);
-#else
-#ifdef HAVE_ANSI
-    if (!statusLineOption) return;
-    printf("\x1b[2J");
-    printf("\x1b[%d;1H", pageLength);
-#endif
-#endif
 }
 
 
@@ -156,17 +120,13 @@ static void capitalizeFirst(Common::String &str) {
 
 
 /*======================================================================*/
-void printAndLog(const char *string)
-{
-#ifdef HAVE_GLK
+void printAndLog(const char *string) {
     static int column = 0;
     char *stringCopy;
     char *stringPart;
-#endif
 
     printf("%s", string);
     if (!onStatusLine && transcriptOption) {
-#ifdef HAVE_GLK
         // TODO Is this assuming only 70-char wide windows for GLK?
         if ((int)strlen(string) > 70-column) {
             stringCopy = strdup(string);  /* Make sure we can write NULLs */
@@ -187,9 +147,6 @@ void printAndLog(const char *string)
 			g_vm->glk_put_string_stream(logFile, string);
             column = updateColumn(column, string);
         }
-#else
-        fprintf(logFile, "%s", string);
-#endif
     }
 }
 
@@ -201,37 +158,7 @@ static void justify(const char *str) {
     if (capitalize)
         capitalizeFirst(tempStr);
 
-#ifdef HAVE_GLK
     printAndLog(tempStr.c_str());
-#else
-    int i;
-    char ch;
-
-    if (col >= pageWidth && !skipSpace)
-        newline();
-
-    while (strlen(str) > pageWidth - col) {
-        i = pageWidth - col - 1;
-        while (!isSpace(str[i]) && i > 0) /* First find wrap point */
-            i--;
-        if (i == 0 && col == 1) /* If it doesn't fit at all */
-            /* Wrap immediately after this word */
-            while (!isSpace(str[i]) && str[i] != '\0')
-                i++;
-        if (i > 0) {        /* If it fits ... */
-            ch = str[i];      /* Save space or NULL */
-            str[i] = '\0';        /* Terminate string */
-            printAndLog(str);     /* and print it */
-            skipSpace = FALSE;        /* If skipping, now we're done */
-            str[i] = ch;      /* Restore character */
-            /* Skip white after printed portion */
-            for (str = &str[i]; isSpace(str[0]) && str[0] != '\0'; str++);
-        }
-        newline();          /* Then start a new line */
-        while(isSpace(str[0])) str++; /* Skip any leading space on next part */
-    }
-    printAndLog(str);     /* Print tail */
-#endif
     col = col + tempStr.size();  // Update column
 }
 
@@ -496,11 +423,8 @@ bool confirm(MsgKind msgno)
        it could be affirmative, but for now any input is NOT! */
     printMessage(msgno);
 
-#ifdef USE_READLINE
-    if (!readline(buf)) return TRUE;
-#else
-    if (gets(buf) == NULL) return TRUE;
-#endif
+    if (!readline(buf))
+		return TRUE;
     col = 1;
 
     return (buf[0] == '\0');
diff --git a/engines/glk/alan3/readline.cpp b/engines/glk/alan3/readline.cpp
index fa965bb..4fb7a89 100644
--- a/engines/glk/alan3/readline.cpp
+++ b/engines/glk/alan3/readline.cpp
@@ -54,10 +54,6 @@ bool readline(char buffer[])
     static bool readingCommands = FALSE;
     static frefid_t commandFileRef;
     static strid_t commandFile;
-#ifdef HAVE_WINGLK
-    static frefid_t logFileRef;
-    INT_PTR e;
-#endif
 
     if (readingCommands) {
         if (g_vm->glk_get_line_stream(commandFile, buffer, 255) == 0) {
@@ -80,73 +76,7 @@ bool readline(char buffer[])
                 case evtype_Arrange:
                     statusline();
                     break;
-#ifdef HAVE_WINGLK
-                case winglk_evtype_GuiInput:
-                    switch (event.val1) {
-                    case ID_MENU_RESTART:
-                        restartGame();
-                        break;
-                    case ID_MENU_SAVE:
-                        glk_set_style(style_Input);
-                        printf("save\n");
-                        glk_set_style(style_Normal);
-                        save();
-                        para();
-                        printf("> ");
-                        break;
-                    case ID_MENU_RESTORE:
-                        glk_set_style(style_Input);
-                        printf("restore\n");
-                        glk_set_style(style_Normal);
-                        restore();
-                        look();
-                        para();
-                        printf("> ");
-                        break;
-                    case ID_MENU_RECORD:
-                        if (transcriptOption || logOption) {
-                            glk_stream_close(logFile, NULL);
-                            transcriptOption = FALSE;
-                            logOption = FALSE;
-                        }
-                        logFileRef = glk_fileref_create_by_prompt(fileusage_InputRecord+fileusage_TextMode, filemode_Write, 0);
-                        if (logFileRef == NULL) break;
-                        logFile = glk_stream_open_file(logFileRef, filemode_Write, 0);
-                        if (logFile != NULL)
-                            logOption = TRUE;
-                        break;
-                    case ID_MENU_PLAYBACK:
-                        commandFileRef = glk_fileref_create_by_prompt(fileusage_InputRecord+fileusage_TextMode, filemode_Read, 0);
-                        if (commandFileRef == NULL) break;
-                        commandFile = glk_stream_open_file(commandFileRef, filemode_Read, 0);
-                        if (commandFile != NULL)
-                            if (glk_get_line_stream(commandFile, buffer, 255) != 0) {
-                                readingCommands = TRUE;
-                                printf(buffer);
-                                return TRUE;
-                            }
-                        break;
-                    case ID_MENU_TRANSCRIPT:
-                        if (transcriptOption || logOption) {
-                            glk_stream_close(logFile, NULL);
-                            transcriptOption = FALSE;
-                            logOption = FALSE;
-                        }
-                        logFileRef = glk_fileref_create_by_prompt(fileusage_Transcript+fileusage_TextMode, filemode_Write, 0);
-                        if (logFileRef == NULL) break;
-                        logFile = glk_stream_open_file(logFileRef, filemode_Write, 0);
-                        if (logFile != NULL) {
-                            transcriptOption = TRUE;
-                            glk_put_string_stream(logFile, "> ");
-                        }
-                        break;
-                    case ID_MENU_ABOUT:
-                        e = DialogBox(myInstance, MAKEINTRESOURCE(IDD_ABOUT), NULL, &AboutDialogProc);
-                        (void)e;
-                        break;
-                    }
-                    break;
-#endif
+
 				default:
 					break;
 				}
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 64c0e62..9eb40d9 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -62,10 +62,7 @@ void forceNewPlayerInput() {
 static void unknown(char tok[]) {
     char *str = strdup(tok);
     Parameter *messageParameters = newParameterArray();
-	
-#if ISO == 0
-    fromIso(str, str);
-#endif
+
     addParameterForString(messageParameters, str);
     printMessageWithParameters(M_UNKNOWN_WORD, messageParameters);
 	deallocate(messageParameters);
@@ -150,12 +147,7 @@ static void getLine(void) {
         } else
             printAndLog("> ");
 
-#ifdef USE_READLINE
         if (!readline(buf)) {
-#else
-        fflush(stdout);
-        if (fgets(buf, LISTLEN, stdin) == NULL) {
-#endif
             newline();
             quitGame();
         }
@@ -177,11 +169,7 @@ static void getLine(void) {
 		::error("TODO: empty command");
 #endif
 		
-#if ISO == 0
-        toIso(isobuf, buf, NATIVECHARSET);
-#else
         strcpy(isobuf, buf);
-#endif
         token = gettoken(isobuf);
         if (token != NULL) {
             if (strcmp("debug", token) == 0 && header->debug) {
diff --git a/engines/glk/alan3/sysdep.cpp b/engines/glk/alan3/sysdep.cpp
index 6b66393..0966d54 100644
--- a/engines/glk/alan3/sysdep.cpp
+++ b/engines/glk/alan3/sysdep.cpp
@@ -28,41 +28,6 @@
 namespace Glk {
 namespace Alan3 {
 
-#ifdef __vms__
-
-char *strdup(char str[])                /* IN - String to duplicate */
-{
-  char *new = (char *) malloc(strlen(str)+1);
-
-  if (!new)
-    syserr("Out of memory");
-  strcpy(new, str);
-  return new;
-}
-
-#endif
-
-
-#ifdef __vms__
-
-/* Cheat implementation of strftime */
-size_t strftime (
-		 char *outbuf,
-		 size_t len,
-		 const char *format,
-		 const struct tm *t)
-{
-  char buf[100];
-  time_t ticks;
-
-  time(&ticks);
-  strcpy(buf, ctime(&ticks));
-  buf[strlen(buf)-1] = '\0';
-  strcpy(outbuf, &buf[4]);
-}
-
-#endif
-
 /* Note to Glk maintainers: 'native' characters are used for output, in this
    case, Glk's Latin-1.  ISO characters are Alan's internal representation,
    stored in the .A3C file, and must be converted to native before printing.
@@ -138,86 +103,34 @@ static const byte upperCaseCharacters[] =
 };
 
 
-int isSpace(unsigned int c)              /* IN - Native character to test */
-{
+int isSpace(unsigned int c) {
     return (c != '\0' && strchr((const char *)spaceCharacters, c) != 0);
 }
 
 
-int isLower(unsigned int c)              /* IN - Native character to test */
-{
+int isLower(unsigned int c) {
     return (c != '\0' && strchr((const char *)lowerCaseCharacters, c) != 0);
 }
 
 
-int isUpper(unsigned int c)              /* IN - Native character to test */
-{
+int isUpper(unsigned int c) {
     return (c != '\0' && strchr((const char *)upperCaseCharacters, c) != 0);
 }
 
-int isLetter(unsigned int c)             /* IN - Native character to test */
-{
+int isLetter(unsigned int c) {
   return(c != '\0' && (isLower(c)? !0: isUpper(c)));
 }
 
 
-int toLower(unsigned int c)              /* IN - Native character to convert */
-{
-#ifdef HAVE_GLK
+int toLower(unsigned int c) {
   return g_vm->glk_char_to_lower(c);
-#else
-#ifdef __dos__
-  char *cp;
-
-  if ((cp = strchr(upperCaseCharacters, c)) != 0)
-    return(lowerCaseCharacters[cp-upperCaseCharacters]);
-  else
-    return c;
-#else
-#ifdef __mac__
-  char *cp;
-
-  if ((cp = strchr(upperCaseCharacters, c)) != 0)
-    return(lowerCaseCharacters[cp-upperCaseCharacters]);
-  else
-    return c;
-#else
-  return (isUpper(c)? c + ('a' - 'A'): c);
-#endif
-#endif
-#endif
 }
 
-/* IN - Native character to convert */
-int toUpper(unsigned int c)
-{
-#ifdef HAVE_GLK
+int toUpper(unsigned int c) {
   return g_vm->glk_char_to_upper(c);
-#else
-#ifdef __dos__
-  char *cp;
-
-  if ((cp = strchr(lowerCaseCharacters, c)) != 0)
-    return(upperCaseCharacters[cp-lowerCaseCharacters]);
-  else
-    return c;
-#else
-#ifdef __mac__
-  char *cp;
-
-  if ((cp = strchr(lowerCaseCharacters, c)) != 0)
-    return(upperCaseCharacters[cp-lowerCaseCharacters]);
-  else
-    return c;
-#else
-  return (isLower(c)? c - ('a' - 'A'): c);
-#endif
-#endif
-#endif
 }
 
-char *strlow(char str[])        /* INOUT - Native string to convert */
-{
+char *strlow(char str[]) {
   char *s;
 
   for (s = str; *s; s++)
@@ -226,8 +139,7 @@ char *strlow(char str[])        /* INOUT - Native string to convert */
 }
 
 
-char *strupp(char str[])        /* INOUT - Native string to convert */
-{
+char *strupp(char str[]) {
   char *s;
 
   for (s = str; *s; s++)
@@ -238,8 +150,7 @@ char *strupp(char str[])        /* INOUT - Native string to convert */
 
 /* The following work on ISO characters */
 
-int isLowerCase(unsigned int c)          /* IN - ISO character to test */
-{
+int isLowerCase(unsigned int c) {
   uint i;
   for (i = 0; i < strlen((const char *)lowerCaseCharacters); i++)
     if (((unsigned int)lowerCaseCharacters[i]) == c) return 1;
@@ -247,8 +158,7 @@ int isLowerCase(unsigned int c)          /* IN - ISO character to test */
 }
 
 
-int isUpperCase(unsigned int c)          /* IN - ISO character to test */
-{
+int isUpperCase(unsigned int c) {
   uint i;
   for (i = 0; i < strlen((const char *)upperCaseCharacters); i++)
     if (upperCaseCharacters[i] == c) return 1;
@@ -256,26 +166,22 @@ int isUpperCase(unsigned int c)          /* IN - ISO character to test */
 }
 
 
-int isISOLetter(int c)          /* IN - ISO character to test */
-{
+int isISOLetter(int c) {
   return (isLowerCase(c) || isUpperCase(c));
 }
 
 
-char IsoToLowerCase(int c)         /* IN - ISO character to convert */
-{
+char IsoToLowerCase(int c) {
   return (isUpperCase(c)? c + ('a' - 'A'): c);
 }
 
 
-char IsoToUpperCase(int c)         /* IN - ISO character to convert */
-{
+char IsoToUpperCase(int c) {
   return (isLowerCase(c)? c - ('a' - 'A'): c);
 }
 
 
-char *stringLower(char str[])   /* INOUT - ISO string to convert */
-{
+char *stringLower(char str[]) {
   char *s;
 
   for (s = str; *s; s++)
@@ -284,8 +190,7 @@ char *stringLower(char str[])   /* INOUT - ISO string to convert */
 }
 
 
-char *stringUpper(char str[])   /* INOUT - ISO string to convert */
-{
+char *stringUpper(char str[]) {
   char *s;
 
   for (s = str; *s; s++)
@@ -387,60 +292,9 @@ static const unsigned char dosMap[256]
   interpreter so character set is known at compile time.
 
   */
-void fromIso(char copy[],       /* OUT - Mapped string */
-	     char original[])   /* IN - string to convert */
-{
-#if ISO == 0
-  static const unsigned char map[256]
-#if defined __mac__
-    = {
-      0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0D,0x0B,0x0C,0x0D,0x0E,0x0F,
-      0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
-      0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
-      0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
-      0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
-      0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
-      0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
-      0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
-      0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
-      0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
-      0xCA,0xC1,0xA2,0xA3,0xB0,0xB4,0xBA,0xA4,0xAC,0xA9,0xBB,0xC7,0xC2,0xD0,0xA8,0xD1,
-      0xA1,0xB1,0xAA,0xD5,0xAB,0xB5,0xA6,0xA5,0xD4,0xA0,0xBC,0xC8,0xD9,0xDA,0xDB,0xC0,
-      0xCB,0xDC,0xD7,0xCC,0x80,0x81,0xAE,0x82,0xC5,0x83,0xB7,0xC9,0xB3,0xB2,0xC3,0xC4,
-      0xC6,0x84,0xDD,0xDE,0xBD,0xCD,0x85,0xAD,0xAF,0xD3,0xD2,0xDF,0x86,0xCE,0xB8,0xA7,
-      0x88,0x87,0x89,0x8B,0x8A,0x8C,0xBE,0x8D,0x8F,0x8E,0x90,0x91,0x93,0x92,0x94,0x95,
-      0xB6,0x96,0x98,0x97,0x99,0x9B,0x9A,0xD6,0xBF,0x9D,0x9C,0x9E,0x9F,0xCF,0xB9,0xD8}
-#else
-#if defined __dos__
-  = {
-    0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0D,0x0B,0x0C,0x0D,0x0E,0x0F,
-    0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
-    0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
-    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
-    0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
-    0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
-    0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
-    0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
-    0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
-    0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
-    0xFF,0xD0,0x9B,0x9C,0xE5,0x9D,0x9F,0xD1,0xF7,0xE0,0xA6,0xAE,0xFB,0xD2,0xE7,0xFA,
-    0xF8,0xF1,0xFD,0xD3,0xFE,0xE6,0xE3,0xF9,0xD4,0xD5,0xA7,0xAF,0xAC,0xAB,0xF0,0xA8,
-    0xA9,0xAA,0xEF,0xD6,0x8E,0x8F,0x92,0x80,0xE2,0x90,0xE4,0xEE,0xF5,0xF4,0xD7,0xAD,
-    0xE9,0xA5,0xD8,0xD9,0xEA,0xE8,0x99,0xEC,0xED,0xF2,0xF3,0xDA,0x9A,0xDB,0x9E,0xE1,
-    0x85,0xA0,0x83,0xDC,0x84,0x86,0x91,0x87,0x8A,0x82,0x88,0x89,0x8D,0xA1,0x8C,0x8B,
-    0xEB,0xA4,0x95,0xA2,0x93,0xDD,0x94,0xF6,0xDE,0x97,0xA3,0x96,0x81,0xDF,0xFC,0x98}
-#endif
-    ;
-#endif
-    unsigned char *o, *c;
-
-    for (o = (unsigned char *)original, c = (unsigned char *)copy; *o; o++, c++)
-      *c = map[*o];
-    *c = '\0';
-#else
+void fromIso(char copy[], char original[]) {
     if (copy != original)
       (void)strcpy(copy, original);
-#endif
 }
 
 
@@ -450,12 +304,11 @@ void fromIso(char copy[],       /* OUT - Mapped string */
   Converts the incoming string to the native character set from any of
   the others. The original is in the current character set which in
   the case of the compiler might be other than the native.
-
+  copy - Mapped  string
+  original - string to convert
+  charset - the current character set
   */
-void toNative(char copy[],	/* OUT - Mapped  string */
-	      char original[],	/* IN - string to convert */
-	      int charset)	/* IN - the current character set */
-{
+void toNative(char copy[], char original[], int charset) {
   toIso(copy, original, charset);
   if (NATIVECHARSET != 0)
     fromIso(copy, copy);
diff --git a/engines/glk/alan3/sysdep.h b/engines/glk/alan3/sysdep.h
index 747201c..a0c2f7a 100644
--- a/engines/glk/alan3/sysdep.h
+++ b/engines/glk/alan3/sysdep.h
@@ -90,71 +90,14 @@ namespace Alan3 {
 #define WRITE_MODE "wb"
 
 
-/****************************/
-/* Allocates cleared bytes? */
-/****************************/
-
-#ifdef __CYGWIN__
-#define NOTCALLOC
-#endif
-
-#ifdef __MINGW32__
-#define NOTCALLOC
-#endif
-
-#ifdef __unix__
-#define NOTCALLOC
-#endif
-
-
-/****************/
-/* Have termio? */
 /****************/
 
-#ifdef HAVE_GLK
-#  undef HAVE_TERMIO   /* don't need TERMIO */
-#else
-#  ifdef __CYGWIN__
-#    define HAVE_TERMIO
-#  endif
-#  ifdef __unix__
-#    define HAVE_TERMIO
-#  endif
-#endif
-
-/*******************************/
-/* Is ANSI control available? */
-/*******************************/
+/* don't need TERMIO */
+#undef HAVE_TERMIO
+/* don't need ANSI */
+#undef HAVE_ANSI
 
-#ifdef HAVE_GLK
-#  undef HAVE_ANSI /* don't need ANSI */
-#else
-#  ifdef __CYGWIN__
-#    define HAVE_ANSI
-#  endif
-#endif
-
-/******************************/
-/* Use the READLINE function? */
-/******************************/
 #define USE_READLINE
-#ifdef SOME_PLATFORM_WHICH_CANT_USE_READLINE
-#  undef USE_READLINE
-#endif
-
-/* Special cases and definition overrides */
-#ifdef __unix__
-#define MULTI
-#endif
-
-
-#ifdef __dos__
-
-/* Return codes */
-#define EXIT_SUCCESS 0
-#define EXIT_FAILURE  1
-
-#endif
 
 
 /* Native character functions */
diff --git a/engines/glk/alan3/term.cpp b/engines/glk/alan3/term.cpp
index 6a6d256..24e9a88 100644
--- a/engines/glk/alan3/term.cpp
+++ b/engines/glk/alan3/term.cpp
@@ -42,48 +42,13 @@ bool onStatusLine = FALSE; /* To know if where printing the status line or not *
   from the header.
 
  */
-void getPageSize(void)
-{
-#ifdef HAVE_GLK
+void getPageSize(void) {
   pageLength = 0;
   pageWidth = 0;
-
-#else
-#ifdef HAVE_TERMIO
-
-#ifdef __linux__
-extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;
-#else
-extern int ioctl();
-#endif
-  struct winsize win;
-  int ecode;
-
-  ecode = ioctl(1, TIOCGWINSZ, &win);
-
-  if (ecode != 0 || win.ws_row == 0)
-    pageLength = header->pageLength;
-  else
-    pageLength = win.ws_row;
-
-  if (ecode != 0 || win.ws_col == 0)
-    pageWidth = header->pageWidth;
-  else
-    pageWidth = win.ws_col;
-
-#else
-
-  pageLength = header->pageLength;
-  pageWidth = header->pageWidth;
-
-#endif
-#endif
 }
 
 /*======================================================================*/
-void statusline(void)
-{
-#ifdef HAVE_GLK
+void statusline(void) {
   uint32 glkWidth;
   char line[100];
   int pcol = col;
@@ -96,13 +61,6 @@ void statusline(void)
   g_vm->glk_window_clear(glkStatusWin);
   g_vm->glk_window_get_size(glkStatusWin, &glkWidth, NULL);
 
-#ifdef HAVE_GARGLK
-  int i;
-  glk_set_style(style_User1);
-  for (i = 0; i < glkWidth; i++)
-    glk_put_char(' ');
-#endif
-
   onStatusLine = TRUE;
   col = 1;
   g_vm->glk_window_move_cursor(glkStatusWin, 1, 0);
@@ -121,37 +79,6 @@ void statusline(void)
   onStatusLine = FALSE;
 
   g_vm->glk_set_window(glkMainWin);
-#else
-#ifdef HAVE_ANSI
-  char line[100];
-  int i;
-  int pcol = col;
-
-  if (!statusLineOption) return;
-  /* ansi_position(1,1); ansi_bold_on(); */
-  printf("\x1b[1;1H");
-  printf("\x1b[7m");
-
-  onStatusLine = TRUE;
-  col = 1;
-  sayInstance(where(HERO, FALSE));
-
-  if (header->maximumScore > 0)
-    sprintf(line, "Score %d(%d)/%d moves", current.score, header->maximumScore, current.tick);
-  else
-    sprintf(line, "%ld moves", (long)current.tick);
-  for (i=0; i < pageWidth - col - strlen(line); i++) putchar(' ');
-  printf(line);
-  printf("\x1b[m");
-  printf("\x1b[%d;1H", pageLength);
-
-  needSpace = FALSE;
-  capitalize = TRUE;
-
-  onStatusLine = FALSE;
-  col = pcol;
-#endif
-#endif
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/utils.cpp b/engines/glk/alan3/utils.cpp
index 9b9b6ed..4b01b46 100644
--- a/engines/glk/alan3/utils.cpp
+++ b/engines/glk/alan3/utils.cpp
@@ -42,8 +42,7 @@ namespace Alan3 {
   return buffers...
 
  */
-void terminate(int code)
-{
+void terminate(int code) {
     newline();
 
     terminateStateStack();
@@ -53,11 +52,7 @@ void terminate(int code)
     if (memory)
         deallocate(memory);
 
-#ifdef HAVE_GLK
     g_vm->glk_exit();
-#else
-    exit(code);
-#endif
 }
 
 /*======================================================================*/
@@ -79,9 +74,8 @@ void usage(const char *programName)
     printf("\n\nUsage:\n\n");
     printf("    %s [<switches>] <adventure>\n\n", programName);
     printf("where the possible optional switches are:\n");
-#ifdef HAVE_GLK
+
     g_vm->glk_set_style(style_Preformatted);
-#endif
     printf("    -v       verbose mode\n");
     printf("    -l       log transcript to a file\n");
     printf("    -c       log player commands to a file\n");
@@ -90,9 +84,7 @@ void usage(const char *programName)
     printf("    -t[<n>]  trace game execution, higher <n> gives more trace\n");
     printf("    -i       ignore version and checksum errors\n");
     printf("    -r       make regression test easier (don't timestamp, page break, randomize...)\n");
-#ifdef HAVE_GLK
     g_vm->glk_set_style(style_Normal);
-#endif
 }
 
 


Commit: dc40211ec5e54d01f7cb822940714ed6e6da36d5
    https://github.com/scummvm/scummvm/commit/dc40211ec5e54d01f7cb822940714ed6e6da36d5
Author: dreammaster (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Proper indentation & formatting

Changed paths:
    engines/glk/alan3/acode.h
    engines/glk/alan3/act.cpp
    engines/glk/alan3/actor.cpp
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/alan3.h
    engines/glk/alan3/alan_version.cpp
    engines/glk/alan3/alt_info.cpp
    engines/glk/alan3/alt_info.h
    engines/glk/alan3/args.cpp
    engines/glk/alan3/attribute.cpp
    engines/glk/alan3/checkentry.cpp
    engines/glk/alan3/checkentry.h
    engines/glk/alan3/class.cpp
    engines/glk/alan3/class.h
    engines/glk/alan3/compatibility.cpp
    engines/glk/alan3/container.cpp
    engines/glk/alan3/current.h
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/debug.h
    engines/glk/alan3/decode.cpp
    engines/glk/alan3/dictionary.cpp
    engines/glk/alan3/event.h
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/fnmatch.cpp
    engines/glk/alan3/glkstart.cpp
    engines/glk/alan3/glkstart.h
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/instance.h
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/lists.cpp
    engines/glk/alan3/literal.cpp
    engines/glk/alan3/literal.h
    engines/glk/alan3/location.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/main.h
    engines/glk/alan3/memory.cpp
    engines/glk/alan3/msg.cpp
    engines/glk/alan3/msg.h
    engines/glk/alan3/output.cpp
    engines/glk/alan3/parameter_position.cpp
    engines/glk/alan3/parameter_position.h
    engines/glk/alan3/params.cpp
    engines/glk/alan3/params.h
    engines/glk/alan3/parse.cpp
    engines/glk/alan3/readline.cpp
    engines/glk/alan3/resources.h
    engines/glk/alan3/reverse.cpp
    engines/glk/alan3/rules.cpp
    engines/glk/alan3/rules.h
    engines/glk/alan3/save.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/set.cpp
    engines/glk/alan3/set.h
    engines/glk/alan3/stack.cpp
    engines/glk/alan3/stack.h
    engines/glk/alan3/state.cpp
    engines/glk/alan3/state_stack.cpp
    engines/glk/alan3/syntax.cpp
    engines/glk/alan3/sysdep.cpp
    engines/glk/alan3/sysdep.h
    engines/glk/alan3/syserr.cpp
    engines/glk/alan3/term.cpp
    engines/glk/alan3/types.cpp
    engines/glk/alan3/types.h
    engines/glk/alan3/utils.cpp
    engines/glk/alan3/version.h
    engines/glk/alan3/word.cpp
    engines/glk/alan3/word.h


diff --git a/engines/glk/alan3/acode.h b/engines/glk/alan3/acode.h
index 0c40460..079ea87 100644
--- a/engines/glk/alan3/acode.h
+++ b/engines/glk/alan3/acode.h
@@ -30,19 +30,19 @@ namespace Alan3 {
 
 #define ACODEEXTENSION ".a3c"
 
-typedef uint32 Aptr;		 /* Type for an ACODE memory address used in the structures */
+typedef uint32 Aptr;         /* Type for an ACODE memory address used in the structures */
 /* TODO: Here's the major 32->64bit problem: Aptrs are 32 bit to fit
    into the 32-bit structure of the Amachine, but sometimes this is
    used to store a *real* pointer value, which on 64-bit machines are
    64bits. */
 
-typedef uint32 Aword;		/* Type for an ACODE word */
-typedef uint32 Aaddr;		/* Type for an ACODE address */
-typedef uint32 Aid;			/* Type for an ACODE Instance Id value */
-typedef int32 Abool;		/* Type for an ACODE Boolean value */
-typedef int32 Aint;			/* Type for an ACODE Integer value */
-typedef int32 Aset;			/* Type for an ACODE Set value */
-typedef int CodeValue;		/* Definition for the packing process */
+typedef uint32 Aword;       /* Type for an ACODE word */
+typedef uint32 Aaddr;       /* Type for an ACODE address */
+typedef uint32 Aid;         /* Type for an ACODE Instance Id value */
+typedef int32 Abool;        /* Type for an ACODE Boolean value */
+typedef int32 Aint;         /* Type for an ACODE Integer value */
+typedef int32 Aset;         /* Type for an ACODE Set value */
+typedef int CodeValue;      /* Definition for the packing process */
 
 #ifndef TRUE
 #define TRUE (0==0)
@@ -63,9 +63,9 @@ typedef int CodeValue;		/* Definition for the packing process */
 #define TOPVALUE (((CodeValue)1<<VALUEBITS) - 1) /* Highest value possible */
 
 /* Half and quarter points in the code value range */
-#define ONEQUARTER (TOPVALUE/4+1)	/* Point after first quarter */
-#define HALF (2*ONEQUARTER)		/* Point after first half */
-#define THREEQUARTER (3*ONEQUARTER)	/* Point after third quarter */
+#define ONEQUARTER (TOPVALUE/4+1)   /* Point after first quarter */
+#define HALF (2*ONEQUARTER)     /* Point after first half */
+#define THREEQUARTER (3*ONEQUARTER) /* Point after third quarter */
 
 
 /* AMACHINE Word Classes, bit positions */
@@ -129,40 +129,40 @@ typedef int WordKind;
 
 
 /* Parameter Classes */
-enum ClaKind {		/* NOTE! These must have the same order as */
-    CLA_OBJ = 1,			/* the name classes in NAM.H */
-    CLA_CNT = (int)CLA_OBJ<<1,
-    CLA_ACT = (int)CLA_CNT<<1,
-    CLA_NUM = (int)CLA_ACT<<1,
-    CLA_STR = (int)CLA_NUM<<1,
-    CLA_COBJ = (int)CLA_STR<<1,
-    CLA_CACT = (int)CLA_COBJ<<1
+enum ClaKind {      /* NOTE! These must have the same order as */
+	CLA_OBJ = 1,            /* the name classes in NAM.H */
+	CLA_CNT = (int)CLA_OBJ << 1,
+	CLA_ACT = (int)CLA_CNT << 1,
+	CLA_NUM = (int)CLA_ACT << 1,
+	CLA_STR = (int)CLA_NUM << 1,
+	CLA_COBJ = (int)CLA_STR << 1,
+	CLA_CACT = (int)CLA_COBJ << 1
 };
 
 
 /* Verb Qualifiers */
 enum QualClass {
-    Q_DEFAULT,
-    Q_AFTER,
-    Q_BEFORE,
-    Q_ONLY
+	Q_DEFAULT,
+	Q_AFTER,
+	Q_BEFORE,
+	Q_ONLY
 };
 
 
 /* The AMACHINE Operations */
 enum OpClass {
-    C_CONST,
-    C_STMOP,
-    C_CURVAR
+	C_CONST,
+	C_STMOP,
+	C_CURVAR
 };
 
 /* AMACHINE Text Styles */
 enum TextStyle {
-    NORMAL_STYLE,
-    EMPHASIZED_STYLE,
-    PREFORMATTED_STYLE,
-    ALERT_STYLE,
-    QUOTE_STYLE
+	NORMAL_STYLE,
+	EMPHASIZED_STYLE,
+	PREFORMATTED_STYLE,
+	ALERT_STYLE,
+	QUOTE_STYLE
 };
 
 
@@ -171,138 +171,138 @@ enum TextStyle {
 #define CURVAR(op) ((((Aword)C_CURVAR)<<28)|((Aword)op))
 
 enum InstClass {
-    I_LINE,                    /* Source line debug info */
-    I_PRINT,                   /* Print a string from the text file */
-    I_STYLE,                   /* Set output text style */
-    I_QUIT,
-    I_LOOK,
-    I_SAVE,
-    I_RESTORE,
-    I_LIST,                     /* List contents of a container */
-    I_EMPTY,
-    I_SCORE,
-    I_VISITS,
-    I_SCHEDULE,
-    I_CANCEL,
-    I_LOCATE,
-    I_MAKE,                     /* Set a boolean attribute to the */
-                                /* value on top of stack */
-    I_SET,                      /* Set a numeric attribute to the */
-                                /* value on top of stack */
-    I_SETSTR,                   /* Set a string valued attribute to */
-                                /* the string on top of stack, */
-                                /* deallocate current contents first */
-    I_SETSET,                   /* Set a Set valued attribute to */
-                                /* the Set on top of stack, */
-                                /* deallocate current contents first */
-    I_NEWSET,                   /* Push a new, empty set at the top of stack */
-    I_ATTRIBUTE,                /* Push the value of an attribute */
-    I_ATTRSTR,                  /* Push a copy of a string attribute */
-    I_ATTRSET,                  /* Push a copy of a set attribute */
-    I_UNION,                    /* Add a set from the top of stack to a */
-                                /* set valued attribute */
-    I_GETSTR,                   /* Get a string contents from text
+	I_LINE,                    /* Source line debug info */
+	I_PRINT,                   /* Print a string from the text file */
+	I_STYLE,                   /* Set output text style */
+	I_QUIT,
+	I_LOOK,
+	I_SAVE,
+	I_RESTORE,
+	I_LIST,                     /* List contents of a container */
+	I_EMPTY,
+	I_SCORE,
+	I_VISITS,
+	I_SCHEDULE,
+	I_CANCEL,
+	I_LOCATE,
+	I_MAKE,                     /* Set a boolean attribute to the */
+	/* value on top of stack */
+	I_SET,                      /* Set a numeric attribute to the */
+	/* value on top of stack */
+	I_SETSTR,                   /* Set a string valued attribute to */
+	/* the string on top of stack, */
+	/* deallocate current contents first */
+	I_SETSET,                   /* Set a Set valued attribute to */
+	/* the Set on top of stack, */
+	/* deallocate current contents first */
+	I_NEWSET,                   /* Push a new, empty set at the top of stack */
+	I_ATTRIBUTE,                /* Push the value of an attribute */
+	I_ATTRSTR,                  /* Push a copy of a string attribute */
+	I_ATTRSET,                  /* Push a copy of a set attribute */
+	I_UNION,                    /* Add a set from the top of stack to a */
+	/* set valued attribute */
+	I_GETSTR,                   /* Get a string contents from text
                                    file, create a copy and push it
                                    on top of stack */
-    I_INCR,                     /* Increase an attribute */
-    I_DECR,                     /* Decrease a numeric attribute */
-    I_INCLUDE,			        /* Include a value in the set on stack top */
-    I_EXCLUDE,			        /* Remove a value from the set on stack top */
-    I_SETSIZE,                  /* Push number of members in a set */
-    I_SETMEMB,                  /* Push the member with index <top>-1
+	I_INCR,                     /* Increase an attribute */
+	I_DECR,                     /* Decrease a numeric attribute */
+	I_INCLUDE,                  /* Include a value in the set on stack top */
+	I_EXCLUDE,                  /* Remove a value from the set on stack top */
+	I_SETSIZE,                  /* Push number of members in a set */
+	I_SETMEMB,                  /* Push the member with index <top>-1
                                    from set <top> */
-    I_CONTSIZE,                 /* Push number of members in a container */
-    I_CONTMEMB,                 /* Push the member with index <top>-1
+	I_CONTSIZE,                 /* Push number of members in a container */
+	I_CONTMEMB,                 /* Push the member with index <top>-1
                                    from container <top> */
-    I_USE,
-    I_STOP,
-    I_AT,
-    I_IN,
-    I_INSET,
-    I_HERE,
-    I_NEARBY,
-    I_NEAR,
-    I_WHERE,                    /* Current position of an instance */
-    I_LOCATION,                 /* The *location* an instance is at */
-    I_DESCRIBE,
-    I_SAY,
-    I_SAYINT,
-    I_SAYSTR,
-    I_IF,
-    I_ELSE,
-    I_ENDIF,
-    I_AND,
-    I_OR,
-    I_NE,
-    I_EQ,
-    I_STREQ,			/* String compare */
-    I_STREXACT,			/* Exact match */
-    I_LE,
-    I_GE,
-    I_LT,
-    I_GT,
-    I_PLUS,
-    I_MINUS,
-    I_MULT,
-    I_DIV,
-    I_NOT,
-    I_UMINUS,
-    I_RND,
-    I_RETURN,
-    I_SYSTEM,
-    I_RESTART,
-    I_BTW,
-    I_CONTAINS,
-    I_DUP,
-    I_DEPEND,
-    I_DEPCASE,
-    I_DEPEXEC,
-    I_DEPELSE,
-    I_ENDDEP,
-    I_ISA,
-    I_FRAME,
-    I_SETLOCAL,
-    I_GETLOCAL,
-    I_ENDFRAME,
-    I_LOOP,
-    I_LOOPNEXT,
-    I_LOOPEND,
-    I_SUM,                /* Aggregates: */
-    I_MAX,
-    I_MIN,
-    I_COUNT,              /* COUNT aggregate & limit meta-attribute */
-    I_SHOW,
-    I_PLAY,
-    I_CONCAT,
-    I_STRIP,
-    I_POP,
+	I_USE,
+	I_STOP,
+	I_AT,
+	I_IN,
+	I_INSET,
+	I_HERE,
+	I_NEARBY,
+	I_NEAR,
+	I_WHERE,                    /* Current position of an instance */
+	I_LOCATION,                 /* The *location* an instance is at */
+	I_DESCRIBE,
+	I_SAY,
+	I_SAYINT,
+	I_SAYSTR,
+	I_IF,
+	I_ELSE,
+	I_ENDIF,
+	I_AND,
+	I_OR,
+	I_NE,
+	I_EQ,
+	I_STREQ,            /* String compare */
+	I_STREXACT,         /* Exact match */
+	I_LE,
+	I_GE,
+	I_LT,
+	I_GT,
+	I_PLUS,
+	I_MINUS,
+	I_MULT,
+	I_DIV,
+	I_NOT,
+	I_UMINUS,
+	I_RND,
+	I_RETURN,
+	I_SYSTEM,
+	I_RESTART,
+	I_BTW,
+	I_CONTAINS,
+	I_DUP,
+	I_DEPEND,
+	I_DEPCASE,
+	I_DEPEXEC,
+	I_DEPELSE,
+	I_ENDDEP,
+	I_ISA,
+	I_FRAME,
+	I_SETLOCAL,
+	I_GETLOCAL,
+	I_ENDFRAME,
+	I_LOOP,
+	I_LOOPNEXT,
+	I_LOOPEND,
+	I_SUM,                /* Aggregates: */
+	I_MAX,
+	I_MIN,
+	I_COUNT,              /* COUNT aggregate & limit meta-attribute */
+	I_SHOW,
+	I_PLAY,
+	I_CONCAT,
+	I_STRIP,
+	I_POP,
 	I_TRANSCRIPT,
-    I_DUPSTR              /* Duplicate the string on the top of the stack */
+	I_DUPSTR              /* Duplicate the string on the top of the stack */
 };
 
 enum SayForm {
-    SAY_SIMPLE,
-    SAY_DEFINITE,
-    SAY_INDEFINITE,
-    SAY_NEGATIVE,
-    SAY_PRONOUN
+	SAY_SIMPLE,
+	SAY_DEFINITE,
+	SAY_INDEFINITE,
+	SAY_NEGATIVE,
+	SAY_PRONOUN
 };
 
 enum VarClass {
-    V_PARAM,
-    V_CURLOC,
-    V_CURACT,
-    V_CURVRB,
-    V_SCORE,
-    V_CURRENT_INSTANCE,
-    V_MAX_INSTANCE
+	V_PARAM,
+	V_CURLOC,
+	V_CURACT,
+	V_CURVRB,
+	V_SCORE,
+	V_CURRENT_INSTANCE,
+	V_MAX_INSTANCE
 };
 
 /* For transitivity in HERE, IN etc. */
 enum ATrans {
-    TRANSITIVE = 0,
-    DIRECT = 1,
-    INDIRECT = 2
+	TRANSITIVE = 0,
+	DIRECT = 1,
+	INDIRECT = 2
 };
 
 /* Predefined attributes, one is for containers and the other for locations
@@ -320,76 +320,76 @@ enum ATrans {
 #define AwordSizeOf(x) (sizeof(x)/sizeof(Aword))
 
 struct ArticleEntry {
-    Aaddr address;		/* Address of article code */
-    Abool isForm;		/* Is the article a complete form? */
-};
-
-struct ClassEntry {	/* CLASS TABLE */
-    Aword code;             /* Own code */
-    Aaddr id;               /* Address to identifier string */
-    Aint parent;            /* Code for the parent class, 0 if none */
-    Aaddr name;             /* Address to name printing code */
-    Aint pronoun;           /* Code for the pronoun word */
-    Aaddr initialize;		/* Address to initialization statements */
-    Aaddr descriptionChecks;     /* Address of description checks */
-    Aaddr description;           /* Address of description code */
-    ArticleEntry definite;       /* Definite article entry */
-    ArticleEntry indefinite;     /* Indefinite article entry */
-    ArticleEntry negative;       /* Negative article entry */
-    Aaddr mentioned;		/* Address of code for Mentioned clause */
-    Aaddr verbs;            /* Address of verb table */
-    Aaddr entered;          /* Address of code for Entered clause */
-};
-
-struct InstanceEntry {	/* INSTANCE TABLE */
-    Aint code;                  /* Own code */
-    Aaddr id;                   /* Address to identifier string */
-    Aint parent;                /* Code for the parent class, 0 if none */
-    Aaddr name;                 /* Address to name printing code */
-    Aint pronoun;               /* Word code for the pronoun */
-    Aint initialLocation;       /* Code for current location */
-    Aaddr initialize;           /* Address to initialization statements */
-    Aint container;             /* Code for a possible container property */
-    Aaddr initialAttributes;	/* Address of attribute list */
-    Aaddr checks;		        /* Address of description checks */
-    Aaddr description;          /* Address of description code */
-    ArticleEntry definite;	    /* Definite article entry */
-    ArticleEntry indefinite;    /* Indefinite article entry */
-    ArticleEntry negative;	    /* Negative article entry */
-    Aaddr mentioned;		    /* Address to short description code */
-    Aaddr verbs;                /* Address of local verb list */
-    Aaddr entered;              /* Address of entered code (location only) */
-    Aaddr exits;		        /* Address of exit list */
-};
-
-struct AttributeEntry {			/* ATTRIBUTE LIST */
-    Aint code;                  /* Its code */
-    Aptr value;                 /* Its value, a string has a dynamic
+	Aaddr address;      /* Address of article code */
+	Abool isForm;       /* Is the article a complete form? */
+};
+
+struct ClassEntry { /* CLASS TABLE */
+	Aword code;             /* Own code */
+	Aaddr id;               /* Address to identifier string */
+	Aint parent;            /* Code for the parent class, 0 if none */
+	Aaddr name;             /* Address to name printing code */
+	Aint pronoun;           /* Code for the pronoun word */
+	Aaddr initialize;       /* Address to initialization statements */
+	Aaddr descriptionChecks;     /* Address of description checks */
+	Aaddr description;           /* Address of description code */
+	ArticleEntry definite;       /* Definite article entry */
+	ArticleEntry indefinite;     /* Indefinite article entry */
+	ArticleEntry negative;       /* Negative article entry */
+	Aaddr mentioned;        /* Address of code for Mentioned clause */
+	Aaddr verbs;            /* Address of verb table */
+	Aaddr entered;          /* Address of code for Entered clause */
+};
+
+struct InstanceEntry {  /* INSTANCE TABLE */
+	Aint code;                  /* Own code */
+	Aaddr id;                   /* Address to identifier string */
+	Aint parent;                /* Code for the parent class, 0 if none */
+	Aaddr name;                 /* Address to name printing code */
+	Aint pronoun;               /* Word code for the pronoun */
+	Aint initialLocation;       /* Code for current location */
+	Aaddr initialize;           /* Address to initialization statements */
+	Aint container;             /* Code for a possible container property */
+	Aaddr initialAttributes;    /* Address of attribute list */
+	Aaddr checks;               /* Address of description checks */
+	Aaddr description;          /* Address of description code */
+	ArticleEntry definite;      /* Definite article entry */
+	ArticleEntry indefinite;    /* Indefinite article entry */
+	ArticleEntry negative;      /* Negative article entry */
+	Aaddr mentioned;            /* Address to short description code */
+	Aaddr verbs;                /* Address of local verb list */
+	Aaddr entered;              /* Address of entered code (location only) */
+	Aaddr exits;                /* Address of exit list */
+};
+
+struct AttributeEntry {         /* ATTRIBUTE LIST */
+	Aint code;                  /* Its code */
+	Aptr value;                 /* Its value, a string has a dynamic
                                    string pointer, a set has a pointer
                                    to a dynamically allocated set */
-    Aaddr id;                   /* Address to the name */
+	Aaddr id;                   /* Address to the name */
 };
 
-struct AttributeHeaderEntry {	/* ATTRIBUTE LIST in header */
-    Aint code;                          /* Its code */
-    Aword value;                /* Its value, a string has a dynamic
+struct AttributeHeaderEntry {   /* ATTRIBUTE LIST in header */
+	Aint code;                          /* Its code */
+	Aword value;                /* Its value, a string has a dynamic
                                    string pointer, a set has a pointer
                                    to a dynamically allocated set */
-    Aaddr id;                   /* Address to the name */
+	Aaddr id;                   /* Address to the name */
 };
 
-struct ExitEntry {	/* EXIT TABLE structure */
-    Aword code;             /* Direction code */
-    Aaddr checks;           /* Address of check table */
-    Aaddr action;           /* Address of action code */
-    Aword target;           /* Id for the target location */
+struct ExitEntry {  /* EXIT TABLE structure */
+	Aword code;             /* Direction code */
+	Aaddr checks;           /* Address of check table */
+	Aaddr action;           /* Address of action code */
+	Aword target;           /* Id for the target location */
 };
 
 
 struct RuleEntry {      /* RULE TABLE */
-  Abool alreadyRun;
-  Aaddr exp;                    /* Address to expression code */
-  Aaddr stms;                   /* Address to run */
+	Abool alreadyRun;
+	Aaddr exp;                    /* Address to expression code */
+	Aaddr stms;                   /* Address to run */
 };
 
 
@@ -398,102 +398,102 @@ struct RuleEntry {      /* RULE TABLE */
 #define RESTRICTIONCLASS_STRING (-4)
 
 struct RestrictionEntry {         /* PARAMETER RESTRICTION TABLE */
-    Aint parameterNumber;         /* Parameter number */
-    Aint _class;                  /* Parameter class code */
-    Aaddr stms;                   /* Exception statements */
+	Aint parameterNumber;         /* Parameter number */
+	Aint _class;                  /* Parameter class code */
+	Aaddr stms;                   /* Exception statements */
 };
 
-struct ContainerEntry {	/* CONTAINER TABLE */
-    Aword owner;                /* Owner instance index */
-    Aint _class;                /* Class to allow in container */
-    Aaddr limits;               /* Address to limit check code */
-    Aaddr header;               /* Address to header code */
-    Aaddr empty;                /* Address to code for header when empty */
-    Aaddr extractChecks;        /* Address to check before extracting */
-    Aaddr extractStatements;    /* Address to execute when extracting */
+struct ContainerEntry { /* CONTAINER TABLE */
+	Aword owner;                /* Owner instance index */
+	Aint _class;                /* Class to allow in container */
+	Aaddr limits;               /* Address to limit check code */
+	Aaddr header;               /* Address to header code */
+	Aaddr empty;                /* Address to code for header when empty */
+	Aaddr extractChecks;        /* Address to check before extracting */
+	Aaddr extractStatements;    /* Address to execute when extracting */
 };
 
 
-struct ElementEntry {	/* SYNTAX ELEMENT TABLES */
-    Aint code;                  /* Code for this element, 0 -> parameter */
-    Aword flags;                /* Flags for multiple/omni (if parameter), syntax number/verb of EOS */
-    Aaddr next;                 /* Address to next element table ... */
-                                /* ... or restrictions if code == EOS */
+struct ElementEntry {   /* SYNTAX ELEMENT TABLES */
+	Aint code;                  /* Code for this element, 0 -> parameter */
+	Aword flags;                /* Flags for multiple/omni (if parameter), syntax number/verb of EOS */
+	Aaddr next;                 /* Address to next element table ... */
+	/* ... or restrictions if code == EOS */
 };
 
-struct SyntaxEntryPreBeta2 {	/* SYNTAX TABLE */
-    Aint code;                          /* Code for verb word */
-    Aaddr elms;                         /* Address to element tables */
+struct SyntaxEntryPreBeta2 {    /* SYNTAX TABLE */
+	Aint code;                          /* Code for verb word */
+	Aaddr elms;                         /* Address to element tables */
 };
 
 struct SyntaxEntry {     /* SYNTAX TABLE */
-    Aint code;                   /* Code for verb word, or 0 if starting with parameter */
-    Aaddr elms;                  /* Address to element tables */
-    Aaddr parameterNameTable;    /* Address to a table of id-addresses giving the names of the parameters */
+	Aint code;                   /* Code for verb word, or 0 if starting with parameter */
+	Aaddr elms;                  /* Address to element tables */
+	Aaddr parameterNameTable;    /* Address to a table of id-addresses giving the names of the parameters */
 };
 
-struct ParameterMapEntry {	/* PARAMETER MAPPING TABLE */
-    Aint syntaxNumber;
-    Aaddr parameterMapping;
-    Aint verbCode;
+struct ParameterMapEntry {  /* PARAMETER MAPPING TABLE */
+	Aint syntaxNumber;
+	Aaddr parameterMapping;
+	Aint verbCode;
 };
 
-struct EventEntry {	/* EVENT TABLE */
-    Aaddr id;                   /* Address to name string */
-    Aaddr code;
+struct EventEntry { /* EVENT TABLE */
+	Aaddr id;                   /* Address to name string */
+	Aaddr code;
 };
 
-struct ScriptEntry {	/* SCRIPT TABLE */
-    Aaddr id;                   /* Address to name string */
-    Aint code;			/* Script number */
-    Aaddr description;		/* Optional description statements */
-    Aaddr steps;		/* Address to steps */
+struct ScriptEntry {    /* SCRIPT TABLE */
+	Aaddr id;                   /* Address to name string */
+	Aint code;          /* Script number */
+	Aaddr description;      /* Optional description statements */
+	Aaddr steps;        /* Address to steps */
 };
 
-struct StepEntry {	/* STEP TABLE */
-    Aaddr after;		/* Expression to say after how many ticks? */
-    Aaddr exp;			/* Expression to condition saying when */
-    Aaddr stms;			/* Address to the actual code */
+struct StepEntry {  /* STEP TABLE */
+	Aaddr after;        /* Expression to say after how many ticks? */
+	Aaddr exp;          /* Expression to condition saying when */
+	Aaddr stms;         /* Address to the actual code */
 };
 
-struct AltEntry {	/* VERB ALTERNATIVE TABLE */
-    Aword qual;			/* Verb execution qualifier */
-    Aint param;			/* Parameter number */
-    Aaddr checks;		/* Address of the check table */
-    Aaddr action;		/* Address of the action code */
+struct AltEntry {   /* VERB ALTERNATIVE TABLE */
+	Aword qual;         /* Verb execution qualifier */
+	Aint param;         /* Parameter number */
+	Aaddr checks;       /* Address of the check table */
+	Aaddr action;       /* Address of the action code */
 };
 
 struct SourceFileEntry { /* SOURCE FILE NAME TABLE */
-    Aint fpos;
-    Aint len;
+	Aint fpos;
+	Aint len;
 };
 
 struct SourceLineEntry { /* SOURCE LINE TABLE */
-    Aint file;
-    Aint line;
+	Aint file;
+	Aint line;
 };
 
 struct StringInitEntry { /* STRING INITIALISATION TABLE */
-    Aword fpos;                  /* File position */
-    Aword len;                   /* Length */
-    Aint instanceCode;           /* Where to store it */
-    Aint attributeCode;
+	Aword fpos;                  /* File position */
+	Aword len;                   /* Length */
+	Aint instanceCode;           /* Where to store it */
+	Aint attributeCode;
 };
 
-struct SetInitEntry {	/* SET INITIALISATION TABLE */
-    Aint size;                  /* Size of the initial set */
-    Aword setAddress;           /* Address to the initial set */
-    Aint instanceCode;          /* Where to store it */
-    Aint attributeCode;
+struct SetInitEntry {   /* SET INITIALISATION TABLE */
+	Aint size;                  /* Size of the initial set */
+	Aword setAddress;           /* Address to the initial set */
+	Aint instanceCode;          /* Where to store it */
+	Aint attributeCode;
 };
 
 struct DictionaryEntry { /* Dictionary */
-    Aaddr string;                /* ACODE address to string */
-    Aword classBits;             /* Word class */
-    Aword code;
-    Aaddr adjectiveRefs;        /* Address to reference list */
-    Aaddr nounRefs;             /* Address to reference list */
-    Aaddr pronounRefs;          /* Address to reference list */
+	Aaddr string;                /* ACODE address to string */
+	Aword classBits;             /* Word class */
+	Aword code;
+	Aaddr adjectiveRefs;        /* Address to reference list */
+	Aaddr nounRefs;             /* Address to reference list */
+	Aaddr pronounRefs;          /* Address to reference list */
 };
 
 
@@ -501,222 +501,222 @@ struct DictionaryEntry { /* Dictionary */
 /* AMACHINE Header */
 
 struct ACodeHeader {
-    /* Important info */
-    char tag[4];              /* "ALAN" */
-    char version[4];          /* Version of compiler */
-    Aword uid;                /* Unique id of the compiled game */
-    Aword size;               /* Size of ACD-file in Awords */
-    /* Options */
-    Abool pack;               /* Is the text packed and encoded ? */
-    Aword stringOffset;       /* Offset to string data in game file */
-    Aword pageLength;         /* Length of a displayed page */
-    Aword pageWidth;          /* and width */
-    Aword debug;              /* Option: debug */
-    /* Data structures */
-    Aaddr classTableAddress;
-    Aword classMax;
-    Aword entityClassId;
-    Aword thingClassId;
-    Aword objectClassId;
-    Aword locationClassId;
-    Aword actorClassId;
-    Aword literalClassId;
-    Aword integerClassId;
-    Aword stringClassId;
-    Aaddr instanceTableAddress;	/* Instance table */
-    Aword instanceMax;          /* Highest number of an instance */
-    Aword theHero;              /* The hero instance code (id) */
-    Aaddr containerTableAddress;
-    Aword containerMax;
-    Aaddr scriptTableAddress;
-    Aword scriptMax;
-    Aaddr eventTableAddress;
-    Aword eventMax;
-    Aaddr syntaxTableAddress;
-    Aaddr parameterMapAddress;
-    Aword syntaxMax;
-    Aaddr dictionary;
-    Aaddr verbTableAddress;
-    Aaddr ruleTableAddress;
-    Aaddr messageTableAddress;
-    /* Miscellaneous */
-    Aint attributesAreaSize;	/* Size of attribute data area in Awords */
-    Aint maxParameters;		/* Maximum number of parameters in any syntax */
-    Aaddr stringInitTable;	/* String init table address */
-    Aaddr setInitTable;		/* Set init table address */
-    Aaddr start;		/* Address to Start code */
-    Aword maximumScore;		/* Maximum score */
-    Aaddr scores;		/* Score table */
-    Aint scoreCount;		/* Max index into scores table */
-    Aaddr sourceFileTable;	/* Table of fpos/len for source filenames */
-    Aaddr sourceLineTable;	/* Table of available source lines to break on */
-    Aaddr freq;			/* Address to Char freq's for coding */
-    Aword acdcrc;		/* Checksum for acd code (excl. hdr) */
-    Aword txtcrc;		/* Checksum for text data file */
-    Aaddr ifids;		/* Address to IFIDS */
-    Aaddr prompt;
+	/* Important info */
+	char tag[4];              /* "ALAN" */
+	char version[4];          /* Version of compiler */
+	Aword uid;                /* Unique id of the compiled game */
+	Aword size;               /* Size of ACD-file in Awords */
+	/* Options */
+	Abool pack;               /* Is the text packed and encoded ? */
+	Aword stringOffset;       /* Offset to string data in game file */
+	Aword pageLength;         /* Length of a displayed page */
+	Aword pageWidth;          /* and width */
+	Aword debug;              /* Option: debug */
+	/* Data structures */
+	Aaddr classTableAddress;
+	Aword classMax;
+	Aword entityClassId;
+	Aword thingClassId;
+	Aword objectClassId;
+	Aword locationClassId;
+	Aword actorClassId;
+	Aword literalClassId;
+	Aword integerClassId;
+	Aword stringClassId;
+	Aaddr instanceTableAddress; /* Instance table */
+	Aword instanceMax;          /* Highest number of an instance */
+	Aword theHero;              /* The hero instance code (id) */
+	Aaddr containerTableAddress;
+	Aword containerMax;
+	Aaddr scriptTableAddress;
+	Aword scriptMax;
+	Aaddr eventTableAddress;
+	Aword eventMax;
+	Aaddr syntaxTableAddress;
+	Aaddr parameterMapAddress;
+	Aword syntaxMax;
+	Aaddr dictionary;
+	Aaddr verbTableAddress;
+	Aaddr ruleTableAddress;
+	Aaddr messageTableAddress;
+	/* Miscellaneous */
+	Aint attributesAreaSize;    /* Size of attribute data area in Awords */
+	Aint maxParameters;     /* Maximum number of parameters in any syntax */
+	Aaddr stringInitTable;  /* String init table address */
+	Aaddr setInitTable;     /* Set init table address */
+	Aaddr start;        /* Address to Start code */
+	Aword maximumScore;     /* Maximum score */
+	Aaddr scores;       /* Score table */
+	Aint scoreCount;        /* Max index into scores table */
+	Aaddr sourceFileTable;  /* Table of fpos/len for source filenames */
+	Aaddr sourceLineTable;  /* Table of available source lines to break on */
+	Aaddr freq;         /* Address to Char freq's for coding */
+	Aword acdcrc;       /* Checksum for acd code (excl. hdr) */
+	Aword txtcrc;       /* Checksum for text data file */
+	Aaddr ifids;        /* Address to IFIDS */
+	Aaddr prompt;
 };
 
 struct Pre3_0beta2Header {
-    /* Important info */
-    char tag[4];		/* "ALAN" */
-    char version[4];		/* Version of compiler */
-    Aword uid;			/* Unique id of the compiled game */
-    Aword size;			/* Size of ACD-file in Awords */
-    /* Options */
-    Abool pack;			/* Is the text packed ? */
-    Aword stringOffset;		/* Offset to string data in game file */
-    Aword pageLength;		/* Length of a page */
-    Aword pageWidth;		/* and width */
-    Aword debug;		/* Option: debug */
-    /* Data structures */
-    Aaddr classTableAddress;	/* Class table */
-    Aword classMax;		/* Number of classes */
-    Aword entityClassId;
-    Aword thingClassId;
-    Aword objectClassId;
-    Aword locationClassId;
-    Aword actorClassId;
-    Aword literalClassId;
-    Aword integerClassId;
-    Aword stringClassId;
-    Aaddr instanceTableAddress;	/* Instance table */
-    Aword instanceMax;		/* Highest number of an instance */
-    Aword theHero;		/* The hero instance code (id) */
-    Aaddr containerTableAddress;
-    Aword containerMax;
-    Aaddr scriptTableAddress;
-    Aword scriptMax;
-    Aaddr eventTableAddress;
-    Aword eventMax;
-    Aaddr syntaxTableAddress;
-    Aaddr parameterMapAddress;
-    Aword syntaxMax;
-    Aaddr dictionary;
-    Aaddr verbTableAddress;
-    Aaddr ruleTableAddress;
-    Aaddr messageTableAddress;
-    /* Miscellaneous */
-    Aint attributesAreaSize;	/* Size of attribute data area in Awords */
-    Aint maxParameters;		/* Maximum number of parameters in any syntax */
-    Aaddr stringInitTable;	/* String init table address */
-    Aaddr setInitTable;		/* Set init table address */
-    Aaddr start;		/* Address to Start code */
-    Aword maximumScore;		/* Maximum score */
-    Aaddr scores;		/* Score table */
-    Aint scoreCount;		/* Max index into scores table */
-    Aaddr sourceFileTable;	/* Table of fpos/len for source filenames */
-    Aaddr sourceLineTable;	/* Table of available source lines to break on */
-    Aaddr freq;			/* Address to Char freq's for coding */
-    Aword acdcrc;		/* Checksum for acd code (excl. hdr) */
-    Aword txtcrc;		/* Checksum for text data file */
-    Aaddr ifids;		/* Address to IFIDS */
+	/* Important info */
+	char tag[4];        /* "ALAN" */
+	char version[4];        /* Version of compiler */
+	Aword uid;          /* Unique id of the compiled game */
+	Aword size;         /* Size of ACD-file in Awords */
+	/* Options */
+	Abool pack;         /* Is the text packed ? */
+	Aword stringOffset;     /* Offset to string data in game file */
+	Aword pageLength;       /* Length of a page */
+	Aword pageWidth;        /* and width */
+	Aword debug;        /* Option: debug */
+	/* Data structures */
+	Aaddr classTableAddress;    /* Class table */
+	Aword classMax;     /* Number of classes */
+	Aword entityClassId;
+	Aword thingClassId;
+	Aword objectClassId;
+	Aword locationClassId;
+	Aword actorClassId;
+	Aword literalClassId;
+	Aword integerClassId;
+	Aword stringClassId;
+	Aaddr instanceTableAddress; /* Instance table */
+	Aword instanceMax;      /* Highest number of an instance */
+	Aword theHero;      /* The hero instance code (id) */
+	Aaddr containerTableAddress;
+	Aword containerMax;
+	Aaddr scriptTableAddress;
+	Aword scriptMax;
+	Aaddr eventTableAddress;
+	Aword eventMax;
+	Aaddr syntaxTableAddress;
+	Aaddr parameterMapAddress;
+	Aword syntaxMax;
+	Aaddr dictionary;
+	Aaddr verbTableAddress;
+	Aaddr ruleTableAddress;
+	Aaddr messageTableAddress;
+	/* Miscellaneous */
+	Aint attributesAreaSize;    /* Size of attribute data area in Awords */
+	Aint maxParameters;     /* Maximum number of parameters in any syntax */
+	Aaddr stringInitTable;  /* String init table address */
+	Aaddr setInitTable;     /* Set init table address */
+	Aaddr start;        /* Address to Start code */
+	Aword maximumScore;     /* Maximum score */
+	Aaddr scores;       /* Score table */
+	Aint scoreCount;        /* Max index into scores table */
+	Aaddr sourceFileTable;  /* Table of fpos/len for source filenames */
+	Aaddr sourceLineTable;  /* Table of available source lines to break on */
+	Aaddr freq;         /* Address to Char freq's for coding */
+	Aword acdcrc;       /* Checksum for acd code (excl. hdr) */
+	Aword txtcrc;       /* Checksum for text data file */
+	Aaddr ifids;        /* Address to IFIDS */
 };
 
 struct Pre3_0alpha5Header {
-    /* Important info */
-    char tag[4];		/* "ALAN" */
-    char version[4];		/* Version of compiler */
-    Aword uid;			/* Unique id of the compiled game */
-    Aword size;			/* Size of ACD-file in Awords */
-    /* Options */
-    Abool pack;			/* Is the text packed ? */
-    Aword stringOffset;		/* Offset to string data in game file */
-    Aword pageLength;		/* Length of a page */
-    Aword pageWidth;		/* and width */
-    Aword debug;		/* Option: debug */
-    /* Data structures */
-    Aaddr classTableAddress;	/* Class table */
-    Aword classMax;		/* Number of classes */
-    Aword entityClassId;
-    Aword thingClassId;
-    Aword objectClassId;
-    Aword locationClassId;
-    Aword actorClassId;
-    Aword literalClassId;
-    Aword integerClassId;
-    Aword stringClassId;
-    Aaddr instanceTableAddress;	/* Instance table */
-    Aword instanceMax;		/* Highest number of an instance */
-    Aword theHero;		/* The hero instance code (id) */
-    Aaddr containerTableAddress;
-    Aword containerMax;
-    Aaddr scriptTableAddress;
-    Aword scriptMax;
-    Aaddr eventTableAddress;
-    Aword eventMax;
-    Aaddr syntaxTableAddress;
-    Aaddr parameterMapAddress;
-    Aword syntaxMax;
-    Aaddr dictionary;
-    Aaddr verbTableAddress;
-    Aaddr ruleTableAddress;
-    Aaddr messageTableAddress;
-    /* Miscellaneous */
-    Aint attributesAreaSize;	/* Size of attribute data area in Awords */
-    Aint maxParameters;		/* Maximum number of parameters in any syntax */
-    Aaddr stringInitTable;	/* String init table address */
-    Aaddr setInitTable;		/* Set init table address */
-    Aaddr start;		/* Address to Start code */
-    Aword maximumScore;		/* Maximum score */
-    Aaddr scores;		/* Score table */
-    Aint scoreCount;		/* Max index into scores table */
-    Aaddr sourceFileTable;	/* Table of fpos/len for source filenames */
-    Aaddr sourceLineTable;	/* Table of available source lines to break on */
-    Aaddr freq;			/* Address to Char freq's for coding */
-    Aword acdcrc;		/* Checksum for acd code (excl. hdr) */
-    Aword txtcrc;		/* Checksum for text data file */
+	/* Important info */
+	char tag[4];        /* "ALAN" */
+	char version[4];        /* Version of compiler */
+	Aword uid;          /* Unique id of the compiled game */
+	Aword size;         /* Size of ACD-file in Awords */
+	/* Options */
+	Abool pack;         /* Is the text packed ? */
+	Aword stringOffset;     /* Offset to string data in game file */
+	Aword pageLength;       /* Length of a page */
+	Aword pageWidth;        /* and width */
+	Aword debug;        /* Option: debug */
+	/* Data structures */
+	Aaddr classTableAddress;    /* Class table */
+	Aword classMax;     /* Number of classes */
+	Aword entityClassId;
+	Aword thingClassId;
+	Aword objectClassId;
+	Aword locationClassId;
+	Aword actorClassId;
+	Aword literalClassId;
+	Aword integerClassId;
+	Aword stringClassId;
+	Aaddr instanceTableAddress; /* Instance table */
+	Aword instanceMax;      /* Highest number of an instance */
+	Aword theHero;      /* The hero instance code (id) */
+	Aaddr containerTableAddress;
+	Aword containerMax;
+	Aaddr scriptTableAddress;
+	Aword scriptMax;
+	Aaddr eventTableAddress;
+	Aword eventMax;
+	Aaddr syntaxTableAddress;
+	Aaddr parameterMapAddress;
+	Aword syntaxMax;
+	Aaddr dictionary;
+	Aaddr verbTableAddress;
+	Aaddr ruleTableAddress;
+	Aaddr messageTableAddress;
+	/* Miscellaneous */
+	Aint attributesAreaSize;    /* Size of attribute data area in Awords */
+	Aint maxParameters;     /* Maximum number of parameters in any syntax */
+	Aaddr stringInitTable;  /* String init table address */
+	Aaddr setInitTable;     /* Set init table address */
+	Aaddr start;        /* Address to Start code */
+	Aword maximumScore;     /* Maximum score */
+	Aaddr scores;       /* Score table */
+	Aint scoreCount;        /* Max index into scores table */
+	Aaddr sourceFileTable;  /* Table of fpos/len for source filenames */
+	Aaddr sourceLineTable;  /* Table of available source lines to break on */
+	Aaddr freq;         /* Address to Char freq's for coding */
+	Aword acdcrc;       /* Checksum for acd code (excl. hdr) */
+	Aword txtcrc;       /* Checksum for text data file */
 };
 
 /* Error message numbers */
 enum MsgKind {
-    M_UNKNOWN_WORD,
-    M_WHAT,
-    M_WHAT_WORD,
-    M_MULTIPLE,
-    M_NOUN,
-    M_AFTER_BUT,
-    M_BUT_ALL,
-    M_NOT_MUCH,
-    M_WHICH_ONE_START,
-    M_WHICH_ONE_COMMA,
-    M_WHICH_ONE_OR,
-    M_NO_SUCH,
-    M_NO_WAY,
-    M_CANT0,
-    M_SEE_START,
-    M_SEE_COMMA,
-    M_SEE_AND,
-    M_SEE_END,
-    M_CONTAINS,
-    M_CARRIES,
-    M_CONTAINS_COMMA,
-    M_CONTAINS_AND,
-    M_CONTAINS_END,
-    M_EMPTY,
-    M_EMPTYHANDED,
-    M_CANNOTCONTAIN,
-    M_SCORE,
-    M_MORE,
-    M_AGAIN,
-    M_SAVEWHERE,
-    M_SAVEOVERWRITE,
-    M_SAVEFAILED,
-    M_RESTOREFROM,
-    M_SAVEMISSING,
-    M_NOTASAVEFILE,
-    M_SAVEVERS,
-    M_SAVENAME,
-    M_REALLY,
-    M_QUITACTION,
-    M_UNDONE,
-    M_NO_UNDO,
-    M_WHICH_PRONOUN_START,
-    M_WHICH_PRONOUN_FIRST,
+	M_UNKNOWN_WORD,
+	M_WHAT,
+	M_WHAT_WORD,
+	M_MULTIPLE,
+	M_NOUN,
+	M_AFTER_BUT,
+	M_BUT_ALL,
+	M_NOT_MUCH,
+	M_WHICH_ONE_START,
+	M_WHICH_ONE_COMMA,
+	M_WHICH_ONE_OR,
+	M_NO_SUCH,
+	M_NO_WAY,
+	M_CANT0,
+	M_SEE_START,
+	M_SEE_COMMA,
+	M_SEE_AND,
+	M_SEE_END,
+	M_CONTAINS,
+	M_CARRIES,
+	M_CONTAINS_COMMA,
+	M_CONTAINS_AND,
+	M_CONTAINS_END,
+	M_EMPTY,
+	M_EMPTYHANDED,
+	M_CANNOTCONTAIN,
+	M_SCORE,
+	M_MORE,
+	M_AGAIN,
+	M_SAVEWHERE,
+	M_SAVEOVERWRITE,
+	M_SAVEFAILED,
+	M_RESTOREFROM,
+	M_SAVEMISSING,
+	M_NOTASAVEFILE,
+	M_SAVEVERS,
+	M_SAVENAME,
+	M_REALLY,
+	M_QUITACTION,
+	M_UNDONE,
+	M_NO_UNDO,
+	M_WHICH_PRONOUN_START,
+	M_WHICH_PRONOUN_FIRST,
 	M_IMPOSSIBLE_WITH,
-    M_CONTAINMENT_LOOP,
-    M_CONTAINMENT_LOOP2,
-    MSGMAX
+	M_CONTAINMENT_LOOP,
+	M_CONTAINMENT_LOOP2,
+	MSGMAX
 };
 
 #define NO_MSG MSGMAX
diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
index cc1fe92..1b92234 100644
--- a/engines/glk/alan3/act.cpp
+++ b/engines/glk/alan3/act.cpp
@@ -32,93 +32,91 @@ namespace Glk {
 namespace Alan3 {
 
 /*----------------------------------------------------------------------*/
-static void executeCommand(int verb, Parameter parameters[])
-{
-    static AltInfo *altInfos = NULL; /* Need to survive lots of different exits...*/
-    int altIndex;
-
-    /* Did we leave anything behind last time... */
-    if (altInfos != NULL)
-        free(altInfos);
-
-    altInfos = findAllAlternatives(verb, parameters);
-
-    if (anyCheckFailed(altInfos, EXECUTE_CHECK_BODY_ON_FAIL))
-        return;
-
-    /* Check for anything to execute... */
-    if (!anythingToExecute(altInfos))
-        error(M_CANT0);
-
-    /* Now perform actions! First try any BEFORE or ONLY from inside out */
-    for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
-        if (altInfos[altIndex].alt != 0) // TODO Can this ever be NULL? Why?
-            if (altInfos[altIndex].alt->qual == (Aword)Q_BEFORE
-                || altInfos[altIndex].alt->qual == (Aword)Q_ONLY) {
-                if (!executedOk(&altInfos[altIndex]))
-                    abortPlayerCommand();
-                if (altInfos[altIndex].alt->qual == (Aword)Q_ONLY)
-                    return;
-            }
-    }
-        
-    /* Then execute any not declared as AFTER, i.e. the default */
-    for (altIndex = 0; !altInfos[altIndex].end; altIndex++) {
-        if (altInfos[altIndex].alt != 0)
-            if (altInfos[altIndex].alt->qual != (Aword)Q_AFTER)
-                if (!executedOk(&altInfos[altIndex]))
-                    abortPlayerCommand();
-    }
-        
-    /* Finally, the ones declared as AFTER */
-    for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
-        if (altInfos[altIndex].alt != 0)
-            if (!executedOk(&altInfos[altIndex]))
-                abortPlayerCommand();
-    }
+static void executeCommand(int verb, Parameter parameters[]) {
+	static AltInfo *altInfos = NULL; /* Need to survive lots of different exits...*/
+	int altIndex;
+
+	/* Did we leave anything behind last time... */
+	if (altInfos != NULL)
+		free(altInfos);
+
+	altInfos = findAllAlternatives(verb, parameters);
+
+	if (anyCheckFailed(altInfos, EXECUTE_CHECK_BODY_ON_FAIL))
+		return;
+
+	/* Check for anything to execute... */
+	if (!anythingToExecute(altInfos))
+		error(M_CANT0);
+
+	/* Now perform actions! First try any BEFORE or ONLY from inside out */
+	for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
+		if (altInfos[altIndex].alt != 0) // TODO Can this ever be NULL? Why?
+			if (altInfos[altIndex].alt->qual == (Aword)Q_BEFORE
+			        || altInfos[altIndex].alt->qual == (Aword)Q_ONLY) {
+				if (!executedOk(&altInfos[altIndex]))
+					abortPlayerCommand();
+				if (altInfos[altIndex].alt->qual == (Aword)Q_ONLY)
+					return;
+			}
+	}
+
+	/* Then execute any not declared as AFTER, i.e. the default */
+	for (altIndex = 0; !altInfos[altIndex].end; altIndex++) {
+		if (altInfos[altIndex].alt != 0)
+			if (altInfos[altIndex].alt->qual != (Aword)Q_AFTER)
+				if (!executedOk(&altInfos[altIndex]))
+					abortPlayerCommand();
+	}
+
+	/* Finally, the ones declared as AFTER */
+	for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
+		if (altInfos[altIndex].alt != 0)
+			if (!executedOk(&altInfos[altIndex]))
+				abortPlayerCommand();
+	}
 }
 
 
 /*======================================================================
- 
+
   action()
- 
+
   Execute the command. Handles acting on multiple items
   such as ALL, THEM or lists of objects.
- 
+
 */
-void action(int verb, Parameter parameters[], Parameter multipleMatches[])
-{
-    int multiplePosition;
+void action(int verb, Parameter parameters[], Parameter multipleMatches[]) {
+	int multiplePosition;
 #ifdef TODO
 	char marker[10];
 #endif
 
-    multiplePosition = findMultiplePosition(parameters);
-    if (multiplePosition != -1) {
+	multiplePosition = findMultiplePosition(parameters);
+	if (multiplePosition != -1) {
 #ifdef TODO
 		jmp_buf savedReturnLabel;
-        memcpy(savedReturnLabel, returnLabel, sizeof(returnLabel));
-        sprintf(marker, "($%d)", multiplePosition+1); /* Prepare a printout with $1/2/3 */
-        for (int i = 0; !isEndOfArray(&multipleMatches[i]); i++) {
-            copyParameter(&parameters[multiplePosition], &multipleMatches[i]);
-            setGlobalParameters(parameters); /* Need to do this here since the marker use them */
-            output(marker);
-            // TODO: if execution for one parameter aborts we should return here, not to top level
-            if (setjmp(returnLabel) == NO_JUMP_RETURN)
-                executeCommand(verb, parameters);
-            if (multipleMatches[i+1].instance != EOD)
-                para();
-        }
-        memcpy(returnLabel, savedReturnLabel, sizeof(returnLabel));
-        parameters[multiplePosition].instance = 0;
+		memcpy(savedReturnLabel, returnLabel, sizeof(returnLabel));
+		sprintf(marker, "($%d)", multiplePosition + 1); /* Prepare a printout with $1/2/3 */
+		for (int i = 0; !isEndOfArray(&multipleMatches[i]); i++) {
+			copyParameter(&parameters[multiplePosition], &multipleMatches[i]);
+			setGlobalParameters(parameters); /* Need to do this here since the marker use them */
+			output(marker);
+			// TODO: if execution for one parameter aborts we should return here, not to top level
+			if (setjmp(returnLabel) == NO_JUMP_RETURN)
+				executeCommand(verb, parameters);
+			if (multipleMatches[i + 1].instance != EOD)
+				para();
+		}
+		memcpy(returnLabel, savedReturnLabel, sizeof(returnLabel));
+		parameters[multiplePosition].instance = 0;
 #else
 		::error("TODO: action");
 #endif
-    } else {
-        setGlobalParameters(parameters);
-        executeCommand(verb, parameters);
-    }
+	} else {
+		setGlobalParameters(parameters);
+		executeCommand(verb, parameters);
+	}
 
 }
 
diff --git a/engines/glk/alan3/actor.cpp b/engines/glk/alan3/actor.cpp
index 5152305..ff4d89f 100644
--- a/engines/glk/alan3/actor.cpp
+++ b/engines/glk/alan3/actor.cpp
@@ -33,49 +33,48 @@ namespace Alan3 {
 
 /*======================================================================*/
 ScriptEntry *scriptOf(int actor) {
-    ScriptEntry *scr;
+	ScriptEntry *scr;
 
-    if (admin[actor].script != 0) {
-        for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++)
-            if (scr->code == admin[actor].script)
-                break;
-        if (!isEndOfArray(scr))
-            return scr;
-    }
-    return NULL;
+	if (admin[actor].script != 0) {
+		for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++)
+			if (scr->code == admin[actor].script)
+				break;
+		if (!isEndOfArray(scr))
+			return scr;
+	}
+	return NULL;
 }
 
 
 /*======================================================================*/
 StepEntry *stepOf(int actor) {
-    StepEntry *step;
-    ScriptEntry *scr = scriptOf(actor);
+	StepEntry *step;
+	ScriptEntry *scr = scriptOf(actor);
 
-    if (scr == NULL) return NULL;
+	if (scr == NULL) return NULL;
 
-    step = (StepEntry*)pointerTo(scr->steps);
-    step = &step[admin[actor].step];
+	step = (StepEntry *)pointerTo(scr->steps);
+	step = &step[admin[actor].step];
 
-    return step;
+	return step;
 }
 
 
 /*======================================================================*/
-void describeActor(int actor)
-{
-    ScriptEntry *script = scriptOf(actor);
+void describeActor(int actor) {
+	ScriptEntry *script = scriptOf(actor);
 
-    if (script != NULL && script->description != 0)
-        interpret(script->description);
-    else if (hasDescription(actor))
-        describeAnything(actor);
-    else {
-        printMessageWithInstanceParameter(M_SEE_START, actor);
-        printMessage(M_SEE_END);
-        if (instances[actor].container != 0)
-            describeContainer(actor);
-    }
-    admin[actor].alreadyDescribed = TRUE;
+	if (script != NULL && script->description != 0)
+		interpret(script->description);
+	else if (hasDescription(actor))
+		describeAnything(actor);
+	else {
+		printMessageWithInstanceParameter(M_SEE_START, actor);
+		printMessage(M_SEE_END);
+		if (instances[actor].container != 0)
+			describeContainer(actor);
+	}
+	admin[actor].alreadyDescribed = TRUE;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index c7c4c6c..4dd9191 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -41,7 +41,7 @@ namespace Alan3 {
 Alan3 *g_vm = nullptr;
 
 Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
-		vm_exited_cleanly(false), _restartFlag(false), _saveSlot(-1), _pendingLook(false) {
+	vm_exited_cleanly(false), _restartFlag(false), _saveSlot(-1), _pendingLook(false) {
 	g_vm = this;
 //	txtfil = nullptr;
 //	logfil = nullptr;
@@ -86,42 +86,42 @@ bool Alan3::initialize() {
 	glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
 	                                     winmethod_Fixed, 1, wintype_TextGrid, 0);
 	g_vm->glk_set_window(glkMainWin);
-/*
-	// Set up the code file to point to the already opened game file
-	codfil = &_gameFile;
-	strncpy(codfnm, getFilename().c_str(), 255);
-	codfnm[255] = '\0';
-
-	if (_gameFile.size() < 8) {
-		GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
-		return false;
-	}
-
-	if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
-		GUIErrorMessage(_("This is not a valid Alan3 file."));
-		return false;
-	}
-
-	// Open up the text file
-	txtfil = new Common::File();
-	if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
-		GUIErrorMessage("Could not open adventure text data file");
-		delete txtfil;
-		return false;
-	}
-
-	// Check for a save being loaded directly from the launcher
-	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
-*/
+	/*
+	    // Set up the code file to point to the already opened game file
+	    codfil = &_gameFile;
+	    strncpy(codfnm, getFilename().c_str(), 255);
+	    codfnm[255] = '\0';
+
+	    if (_gameFile.size() < 8) {
+	        GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
+	        return false;
+	    }
+
+	    if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
+	        GUIErrorMessage(_("This is not a valid Alan3 file."));
+	        return false;
+	    }
+
+	    // Open up the text file
+	    txtfil = new Common::File();
+	    if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
+	        GUIErrorMessage("Could not open adventure text data file");
+	        delete txtfil;
+	        return false;
+	    }
+
+	    // Check for a save being loaded directly from the launcher
+	    _saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+	*/
 	return true;
 }
 
 void Alan3::deinitialize() {
 	free(memory);
-/*
-	delete txtfil;
-	delete logfil;
-*/
+	/*
+	    delete txtfil;
+	    delete logfil;
+	*/
 }
 
 Common::Error Alan3::readSaveData(Common::SeekableReadStream *rs) {
diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
index ea8548a..f4bb7a5 100644
--- a/engines/glk/alan3/alan3.h
+++ b/engines/glk/alan3/alan3.h
@@ -68,12 +68,16 @@ public:
 	/**
 	 * Flag for the game to restart
 	 */
-	void setRestart(bool flag) { _restartFlag = flag; }
+	void setRestart(bool flag) {
+		_restartFlag = flag;
+	}
 
 	/**
 	 * Returns whether the game should restart
 	 */
-	bool shouldRestart() const { return _restartFlag; }
+	bool shouldRestart() const {
+		return _restartFlag;
+	}
 
 	/**
 	 * Returns the running interpreter type
diff --git a/engines/glk/alan3/alan_version.cpp b/engines/glk/alan3/alan_version.cpp
index bb244ec..016d5cc 100644
--- a/engines/glk/alan3/alan_version.cpp
+++ b/engines/glk/alan3/alan_version.cpp
@@ -26,16 +26,16 @@ namespace Glk {
 namespace Alan3 {
 
 const Product alan = {
-  "Alan",
-  "Adventure Language System",
-  "Alan 3.0beta6",
-  "Alan 3.0beta6 -- Adventure Language System (2017-09-08 10:18)",
-  "2017-09-08",
-  "10:18:25",
-  "Thomas",
-  "thoni64",
-  "cygwin32",
-  {"3.0beta6", 3, 0, 6, 1504858705, "beta"}
+	"Alan",
+	"Adventure Language System",
+	"Alan 3.0beta6",
+	"Alan 3.0beta6 -- Adventure Language System (2017-09-08 10:18)",
+	"2017-09-08",
+	"10:18:25",
+	"Thomas",
+	"thoni64",
+	"cygwin32",
+	{"3.0beta6", 3, 0, 6, 1504858705, "beta"}
 };
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/alt_info.cpp b/engines/glk/alan3/alt_info.cpp
index 5a87cbb..d9e8bd2 100644
--- a/engines/glk/alan3/alt_info.cpp
+++ b/engines/glk/alan3/alt_info.cpp
@@ -44,337 +44,328 @@ typedef AltInfo *AltInfoFinder(int verb, Parameter parameters[]);
 
 
 /*======================================================================*/
-void primeAltInfo(AltInfo *altInfo, int level, int parameter, int instance, int cls)
-{
-    altInfo->level = level;
-    altInfo->parameter = parameter;
-    altInfo->instance = instance;
-    altInfo->_class = cls;
-    altInfo->done = FALSE;
-    altInfo->end = FALSE;
+void primeAltInfo(AltInfo *altInfo, int level, int parameter, int instance, int cls) {
+	altInfo->level = level;
+	altInfo->parameter = parameter;
+	altInfo->instance = instance;
+	altInfo->_class = cls;
+	altInfo->done = FALSE;
+	altInfo->end = FALSE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void traceInstanceAndItsClass(Aid instance, Aid cls)
-{
-    traceSay(instance);
-    printf("[%d]", instance);
-    if (cls != NO_CLASS)
-        printf(", inherited from %s[%d]", idOfClass(cls), cls);
+static void traceInstanceAndItsClass(Aid instance, Aid cls) {
+	traceSay(instance);
+	printf("[%d]", instance);
+	if (cls != NO_CLASS)
+		printf(", inherited from %s[%d]", idOfClass(cls), cls);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void traceAltInfo(AltInfo *alt) {
-    switch (alt->level) {
-    case GLOBAL_LEVEL:
-        printf("GLOBAL");
-        break;
-    case LOCATION_LEVEL:
-        printf("in (location) ");
-        traceInstanceAndItsClass(current.location, alt->_class);
-        break;
-    case PARAMETER_LEVEL: {
+	switch (alt->level) {
+	case GLOBAL_LEVEL:
+		printf("GLOBAL");
+		break;
+	case LOCATION_LEVEL:
+		printf("in (location) ");
+		traceInstanceAndItsClass(current.location, alt->_class);
+		break;
+	case PARAMETER_LEVEL: {
 		char *parameterName = parameterNameInSyntax(current.verb, alt->parameter);
 		if (parameterName != NULL)
 			printf("in parameter %s(#%d)=", parameterName, alt->parameter);
 		else
 			printf("in parameter #%d=", alt->parameter);
-        traceInstanceAndItsClass(globalParameters[alt->parameter-1].instance, alt->_class);
-        break;
+		traceInstanceAndItsClass(globalParameters[alt->parameter - 1].instance, alt->_class);
+		break;
+	}
 	}
-    }
 }
 
 
 /*----------------------------------------------------------------------*/
-static void traceVerbCheck(AltInfo *alt, bool execute)
-{
-    if (traceSectionOption && execute) {
-        printf("\n<VERB %d, ", current.verb);
-        traceAltInfo(alt);
-        printf(", CHECK:>\n");
-    }
+static void traceVerbCheck(AltInfo *alt, bool execute) {
+	if (traceSectionOption && execute) {
+		printf("\n<VERB %d, ", current.verb);
+		traceAltInfo(alt);
+		printf(", CHECK:>\n");
+	}
 }
 
 
 /*======================================================================*/
-bool checkFailed(AltInfo *altInfo, bool execute)
-{
-    if (altInfo->alt != NULL && altInfo->alt->checks != 0) {
-        traceVerbCheck(altInfo, execute);
-        // TODO Why does this not generate a regression error with !
-        // Need a new regression case?
-        fail = FALSE;
-        if (checksFailed(altInfo->alt->checks, execute)) return TRUE;
-        if (fail) return TRUE;
-    }
-    return FALSE;
+bool checkFailed(AltInfo *altInfo, bool execute) {
+	if (altInfo->alt != NULL && altInfo->alt->checks != 0) {
+		traceVerbCheck(altInfo, execute);
+		// TODO Why does this not generate a regression error with !
+		// Need a new regression case?
+		fail = FALSE;
+		if (checksFailed(altInfo->alt->checks, execute)) return TRUE;
+		if (fail) return TRUE;
+	}
+	return FALSE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void traceVerbExecution(AltInfo *alt)
-{
-    if (traceSectionOption) {
-        printf("\n<VERB %d, ", current.verb);
-        traceAltInfo(alt);
-        printf(", DOES");
-        switch (alt->alt->qual) {
-        case Q_BEFORE: printf(" (BEFORE)");
-            break;
-        case Q_ONLY: printf(" (ONLY)");
-            break;
-        case Q_AFTER: printf(" (AFTER)");
-            break;
-        case Q_DEFAULT:
-            break;
-        }
-        printf(":>\n");
-    }
+static void traceVerbExecution(AltInfo *alt) {
+	if (traceSectionOption) {
+		printf("\n<VERB %d, ", current.verb);
+		traceAltInfo(alt);
+		printf(", DOES");
+		switch (alt->alt->qual) {
+		case Q_BEFORE:
+			printf(" (BEFORE)");
+			break;
+		case Q_ONLY:
+			printf(" (ONLY)");
+			break;
+		case Q_AFTER:
+			printf(" (AFTER)");
+			break;
+		case Q_DEFAULT:
+			break;
+		}
+		printf(":>\n");
+	}
 }
 
 
 /*======================================================================*/
-bool executedOk(AltInfo *altInfo)
-{
-    fail = FALSE;
-    if (!altInfo->done && altInfo->alt->action != 0) {
-        traceVerbExecution(altInfo);
-        current.instance = altInfo->instance;
-        interpret(altInfo->alt->action);
-    }
-    altInfo->done = TRUE;
-    return !fail;
+bool executedOk(AltInfo *altInfo) {
+	fail = FALSE;
+	if (!altInfo->done && altInfo->alt->action != 0) {
+		traceVerbExecution(altInfo);
+		current.instance = altInfo->instance;
+		interpret(altInfo->alt->action);
+	}
+	altInfo->done = TRUE;
+	return !fail;
 }
 
 
 /*======================================================================*/
 bool canBeExecuted(AltInfo *altInfo) {
-    return altInfo->alt != NULL && altInfo->alt->action != 0;
+	return altInfo->alt != NULL && altInfo->alt->action != 0;
 }
 
 
 /*======================================================================*/
 AltInfo *duplicateAltInfoArray(AltInfo original[]) {
-    int size;
-    AltInfo *duplicate;
-	
-    for (size = 0; original[size].end != TRUE; size++)
-        ;
-    size++;
-    duplicate = (AltInfo *)allocate(size*sizeof(AltInfo));
-    memcpy(duplicate, original, size*sizeof(AltInfo));
-    return duplicate;
+	int size;
+	AltInfo *duplicate;
+
+	for (size = 0; original[size].end != TRUE; size++)
+		;
+	size++;
+	duplicate = (AltInfo *)allocate(size * sizeof(AltInfo));
+	memcpy(duplicate, original, size * sizeof(AltInfo));
+	return duplicate;
 }
 
 
 /*======================================================================*/
-int lastAltInfoIndex(AltInfo altInfo[])
-{
-    int altIndex;
-	
-    /* Loop to last alternative */
-    for (altIndex = -1; !altInfo[altIndex+1].end; altIndex++)
-        ;
-    return altIndex;
+int lastAltInfoIndex(AltInfo altInfo[]) {
+	int altIndex;
+
+	/* Loop to last alternative */
+	for (altIndex = -1; !altInfo[altIndex + 1].end; altIndex++)
+		;
+	return altIndex;
 }
 
 
 /*----------------------------------------------------------------------*/
 static AltInfo *nextFreeAltInfo(AltInfoArray altInfos) {
-    return &altInfos[lastAltInfoIndex(altInfos)+1];
+	return &altInfos[lastAltInfoIndex(altInfos) + 1];
 }
 
 
 /*----------------------------------------------------------------------*/
 static void addAlternative(AltInfoArray altInfos, int verb, int level, Aint parameterNumber, Aint theClass, Aid theInstance, AltEntryFinder finder) {
-    AltInfo *altInfoP = nextFreeAltInfo(altInfos);
-	
-    altInfoP->alt = (*finder)(verb, parameterNumber, theInstance, theClass);
-    if (altInfoP->alt != NULL) {
-        primeAltInfo(altInfoP, level, parameterNumber, theInstance, theClass);
-        altInfoP[1].end = TRUE;
-    }
+	AltInfo *altInfoP = nextFreeAltInfo(altInfos);
+
+	altInfoP->alt = (*finder)(verb, parameterNumber, theInstance, theClass);
+	if (altInfoP->alt != NULL) {
+		primeAltInfo(altInfoP, level, parameterNumber, theInstance, theClass);
+		altInfoP[1].end = TRUE;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void addGlobalAlternatives(AltInfoArray altInfos, int verb, AltEntryFinder finder ) {
-    addAlternative(altInfos, verb, GLOBAL_LEVEL, NO_PARAMETER, NO_CLASS, NO_INSTANCE, finder);
+static void addGlobalAlternatives(AltInfoArray altInfos, int verb, AltEntryFinder finder) {
+	addAlternative(altInfos, verb, GLOBAL_LEVEL, NO_PARAMETER, NO_CLASS, NO_INSTANCE, finder);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void addAlternativesFromParents(AltInfoArray altInfos, int verb, int level, Aint parameterNumber, Aint theClass, Aid theInstance, AltEntryFinder finder){
-    if (classes[theClass].parent != 0)
-        addAlternativesFromParents(altInfos, verb, level,
-                                   parameterNumber,
-                                   classes[theClass].parent,
-                                   theInstance,
-                                   finder);
-	
-    addAlternative(altInfos, verb, level, parameterNumber, theClass, theInstance, finder);
+static void addAlternativesFromParents(AltInfoArray altInfos, int verb, int level, Aint parameterNumber, Aint theClass, Aid theInstance, AltEntryFinder finder) {
+	if (classes[theClass].parent != 0)
+		addAlternativesFromParents(altInfos, verb, level,
+		                           parameterNumber,
+		                           classes[theClass].parent,
+		                           theInstance,
+		                           finder);
+
+	addAlternative(altInfos, verb, level, parameterNumber, theClass, theInstance, finder);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void addAlternativesFromLocation(AltInfoArray altInfos, int verb, Aid location, AltEntryFinder finder) {
-    if (admin[location].location != 0)
-        addAlternativesFromLocation(altInfos, verb, admin[location].location, finder);
-	
-    addAlternativesFromParents(altInfos, verb,
-                               LOCATION_LEVEL,
-                               NO_PARAMETER,
-                               instances[location].parent,
-                               location,
-                               finder);
-	
-    addAlternative(altInfos, verb, LOCATION_LEVEL, NO_PARAMETER, NO_CLASS, location, finder);
+	if (admin[location].location != 0)
+		addAlternativesFromLocation(altInfos, verb, admin[location].location, finder);
+
+	addAlternativesFromParents(altInfos, verb,
+	                           LOCATION_LEVEL,
+	                           NO_PARAMETER,
+	                           instances[location].parent,
+	                           location,
+	                           finder);
+
+	addAlternative(altInfos, verb, LOCATION_LEVEL, NO_PARAMETER, NO_CLASS, location, finder);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void addAlternativesFromParameter(AltInfoArray altInfos, int verb, Parameter parameters[], int parameterNumber, AltEntryFinder finder) {
-    Aid parent;
-    Aid theInstance = parameters[parameterNumber-1].instance;
-	
-    if (isLiteral(theInstance))
-        parent = literals[literalFromInstance(theInstance)]._class;
-    else
-        parent = instances[theInstance].parent;
-    addAlternativesFromParents(altInfos, verb, PARAMETER_LEVEL, parameterNumber, parent, theInstance, finder);
-	
-    if (!isLiteral(theInstance))
-        addAlternative(altInfos, verb, PARAMETER_LEVEL, parameterNumber, NO_CLASS, theInstance, finder);
+	Aid parent;
+	Aid theInstance = parameters[parameterNumber - 1].instance;
+
+	if (isLiteral(theInstance))
+		parent = literals[literalFromInstance(theInstance)]._class;
+	else
+		parent = instances[theInstance].parent;
+	addAlternativesFromParents(altInfos, verb, PARAMETER_LEVEL, parameterNumber, parent, theInstance, finder);
+
+	if (!isLiteral(theInstance))
+		addAlternative(altInfos, verb, PARAMETER_LEVEL, parameterNumber, NO_CLASS, theInstance, finder);
 }
 
 
 /*======================================================================*/
-bool anyCheckFailed(AltInfoArray altInfo, bool execute)
-{
-    int altIndex;
-    
-    if (altInfo != NULL)
-	for (altIndex = 0; !altInfo[altIndex].end; altIndex++) {
-	    current.instance = altInfo[altIndex].instance;
-	    if (checkFailed(&altInfo[altIndex], execute))
-		return TRUE;
-	}
-    return FALSE;
+bool anyCheckFailed(AltInfoArray altInfo, bool execute) {
+	int altIndex;
+
+	if (altInfo != NULL)
+		for (altIndex = 0; !altInfo[altIndex].end; altIndex++) {
+			current.instance = altInfo[altIndex].instance;
+			if (checkFailed(&altInfo[altIndex], execute))
+				return TRUE;
+		}
+	return FALSE;
 }
 
 
 /*======================================================================*/
-bool anythingToExecute(AltInfo altInfo[])
-{
-    int altIndex;
-	
-    /* Check for anything to execute... */
-    if (altInfo != NULL)
-	for (altIndex = 0; !altInfo[altIndex].end; altIndex++)
-	    if (canBeExecuted(&altInfo[altIndex]))
-		return TRUE;
-    return FALSE;
+bool anythingToExecute(AltInfo altInfo[]) {
+	int altIndex;
+
+	/* Check for anything to execute... */
+	if (altInfo != NULL)
+		for (altIndex = 0; !altInfo[altIndex].end; altIndex++)
+			if (canBeExecuted(&altInfo[altIndex]))
+				return TRUE;
+	return FALSE;
 }
 
 
 /*----------------------------------------------------------------------*/
 static VerbEntry *findVerbEntry(int verbCode, VerbEntry *entries) {
-    VerbEntry *verbEntry;
-    for (verbEntry = entries; !isEndOfArray(verbEntry); verbEntry++) {
-        if (verbEntry->code < 0) {
-            /* Verb codes are negative for Meta verbs, if so they are also 1 off to avoid EOD */
-            if (abs(verbEntry->code)-1 == verbCode)
-                return verbEntry;
-        } else {
-            if (verbEntry->code == verbCode)
-                return verbEntry;
-        }
-    }
-    return NULL;
+	VerbEntry *verbEntry;
+	for (verbEntry = entries; !isEndOfArray(verbEntry); verbEntry++) {
+		if (verbEntry->code < 0) {
+			/* Verb codes are negative for Meta verbs, if so they are also 1 off to avoid EOD */
+			if (abs(verbEntry->code) - 1 == verbCode)
+				return verbEntry;
+		} else {
+			if (verbEntry->code == verbCode)
+				return verbEntry;
+		}
+	}
+	return NULL;
 }
 
 
 /*----------------------------------------------------------------------*/
-static AltEntry *findAlternative(Aaddr verbTableAddress, int verbCode, int parameterNumber)
-{
-    AltEntry *alt;
-    VerbEntry *verbEntry;
-	
-    if (verbTableAddress == 0) return NULL;
-
-    verbEntry = findVerbEntry(verbCode, (VerbEntry *) pointerTo(verbTableAddress));
-    if (verbEntry != NULL)
-        for (alt = (AltEntry *) pointerTo(verbEntry->alts); !isEndOfArray(alt); alt++) {
-            if (alt->param == parameterNumber || alt->param == 0) {
-                if (verbEntry->code < 0) current.meta = TRUE;
-                return alt;
-            }
-        }
-    return NULL;
+static AltEntry *findAlternative(Aaddr verbTableAddress, int verbCode, int parameterNumber) {
+	AltEntry *alt;
+	VerbEntry *verbEntry;
+
+	if (verbTableAddress == 0) return NULL;
+
+	verbEntry = findVerbEntry(verbCode, (VerbEntry *) pointerTo(verbTableAddress));
+	if (verbEntry != NULL)
+		for (alt = (AltEntry *) pointerTo(verbEntry->alts); !isEndOfArray(alt); alt++) {
+			if (alt->param == parameterNumber || alt->param == 0) {
+				if (verbEntry->code < 0) current.meta = TRUE;
+				return alt;
+			}
+		}
+	return NULL;
 }
 
 
 /*----------------------------------------------------------------------*/
-static AltEntry *alternativeFinder(int verb, int parameterNumber, int theInstance, int theClass)
-{
-    if (theClass != NO_CLASS)
-        return findAlternative(classes[theClass].verbs, verb, parameterNumber);
-    else if (theInstance != NO_INSTANCE)
-        return findAlternative(instances[theInstance].verbs, verb, parameterNumber);
-    else
-        return findAlternative(header->verbTableAddress, verb, parameterNumber);
+static AltEntry *alternativeFinder(int verb, int parameterNumber, int theInstance, int theClass) {
+	if (theClass != NO_CLASS)
+		return findAlternative(classes[theClass].verbs, verb, parameterNumber);
+	else if (theInstance != NO_INSTANCE)
+		return findAlternative(instances[theInstance].verbs, verb, parameterNumber);
+	else
+		return findAlternative(header->verbTableAddress, verb, parameterNumber);
 }
 
 
 /*======================================================================*/
 AltInfo *findAllAlternatives(int verb, Parameter parameters[]) {
-    int parameterNumber;
-    AltInfo altInfos[1000];
-    altInfos[0].end = TRUE;
-    
-    addGlobalAlternatives(altInfos, verb, &alternativeFinder);
-	
-    addAlternativesFromLocation(altInfos, verb, current.location, &alternativeFinder);
-
-    for (parameterNumber = 1; !isEndOfArray(&parameters[parameterNumber-1]); parameterNumber++) {
-        addAlternativesFromParameter(altInfos, verb, parameters, parameterNumber, &alternativeFinder);
-    }
-    return duplicateAltInfoArray(altInfos);
+	int parameterNumber;
+	AltInfo altInfos[1000];
+	altInfos[0].end = TRUE;
+
+	addGlobalAlternatives(altInfos, verb, &alternativeFinder);
+
+	addAlternativesFromLocation(altInfos, verb, current.location, &alternativeFinder);
+
+	for (parameterNumber = 1; !isEndOfArray(&parameters[parameterNumber - 1]); parameterNumber++) {
+		addAlternativesFromParameter(altInfos, verb, parameters, parameterNumber, &alternativeFinder);
+	}
+	return duplicateAltInfoArray(altInfos);
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool possibleWithFinder(int verb, Parameter parameters[], AltInfoFinder *finder) {
-    bool anything;
-    AltInfo *allAlternatives;
+	bool anything;
+	AltInfo *allAlternatives;
 
-    allAlternatives = finder(verb, parameters);
+	allAlternatives = finder(verb, parameters);
 
-    // TODO Need to do this since anyCheckFailed() call execute() which assumes the global parameters
-    setGlobalParameters(parameters);
-    if (anyCheckFailed(allAlternatives, DONT_EXECUTE_CHECK_BODY_ON_FAIL))
-        anything = FALSE;
-    else
-	anything = anythingToExecute(allAlternatives);
+	// TODO Need to do this since anyCheckFailed() call execute() which assumes the global parameters
+	setGlobalParameters(parameters);
+	if (anyCheckFailed(allAlternatives, DONT_EXECUTE_CHECK_BODY_ON_FAIL))
+		anything = FALSE;
+	else
+		anything = anythingToExecute(allAlternatives);
 
-    if (allAlternatives != NULL)
-      deallocate(allAlternatives);
+	if (allAlternatives != NULL)
+		deallocate(allAlternatives);
 
-    return(anything);
+	return (anything);
 }
 
 
 
 /*======================================================================*/
-bool possible(int verb, Parameter inParameters[], ParameterPosition parameterPositions[])
-{
-    // This is a wrapper for possibleWithFinder() which is used in unit tests
-    // possible() should be used "for real".
+bool possible(int verb, Parameter inParameters[], ParameterPosition parameterPositions[]) {
+	// This is a wrapper for possibleWithFinder() which is used in unit tests
+	// possible() should be used "for real".
 
-    return possibleWithFinder(verb, inParameters, findAllAlternatives);
+	return possibleWithFinder(verb, inParameters, findAllAlternatives);
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/alt_info.h b/engines/glk/alan3/alt_info.h
index de99585..2a7dd0c 100644
--- a/engines/glk/alan3/alt_info.h
+++ b/engines/glk/alan3/alt_info.h
@@ -51,14 +51,14 @@ namespace Alan3 {
 /* Types */
 
 struct AltInfo {
-	bool end;		/* Indicator of end in AltInfoArray, first empty has TRUE here */
+	bool end;       /* Indicator of end in AltInfoArray, first empty has TRUE here */
 	AltEntry *alt;
 	bool done;
-	Aint level;		/* 0 - Global, 1 - location, 2 - parameter */
-	Aid _class;		/* In which class, only used for tracing */
-	Aid instance;	/* In which instance the Alternative was found,
-					   used to set current.instance and tracing */
-	Aid parameter;	   /* In which parameter, only used for tracing */
+	Aint level;     /* 0 - Global, 1 - location, 2 - parameter */
+	Aid _class;     /* In which class, only used for tracing */
+	Aid instance;   /* In which instance the Alternative was found,
+                       used to set current.instance and tracing */
+	Aid parameter;     /* In which parameter, only used for tracing */
 };
 
 typedef AltEntry *(*AltEntryFinder)(int verb, int parameterNumber, int theInstance, int theClass);
diff --git a/engines/glk/alan3/args.cpp b/engines/glk/alan3/args.cpp
index 12cf1e8..5ccf0fc 100644
--- a/engines/glk/alan3/args.cpp
+++ b/engines/glk/alan3/args.cpp
@@ -40,119 +40,122 @@ char *adventureFileName;
 #if 0
 /*======================================================================*/
 char *gameName(char *fullPathName) {
-    char *foundGameName = "";
+	char *foundGameName = "";
 
-    if (fullPathName != NULL) {
-        foundGameName = strdup(baseNameStart(fullPathName));
-        foundGameName[strlen(foundGameName)-4] = '\0'; /* Strip off .A3C */
-    }
+	if (fullPathName != NULL) {
+		foundGameName = strdup(baseNameStart(fullPathName));
+		foundGameName[strlen(foundGameName) - 4] = '\0'; /* Strip off .A3C */
+	}
 
-    if (foundGameName[0] == '.' && foundGameName[1] == '/')
-        strcpy(foundGameName, &foundGameName[2]);
+	if (foundGameName[0] == '.' && foundGameName[1] == '/')
+		strcpy(foundGameName, &foundGameName[2]);
 
-    return foundGameName;
+	return foundGameName;
 }
 
 
 /*----------------------------------------------------------------------*/
 static char *removeQuotes(char *argument) {
-    char *str = strdup(&argument[1]);
-    str[strlen(str)-1] = '\0';
-    return str;
+	char *str = strdup(&argument[1]);
+	str[strlen(str) - 1] = '\0';
+	return str;
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool isQuoted(char *argument) {
-    return argument[0] == '"' && strlen(argument) > 2;
+	return argument[0] == '"' && strlen(argument) > 2;
 }
 
 
 /*----------------------------------------------------------------------*/
 static char *addAcodeExtension(char *advFilename) {
-    if (strlen(advFilename) < strlen(ACODEEXTENSION)
-        || compareStrings(&advFilename[strlen(advFilename)-4], ACODEEXTENSION) != 0) {
-        advFilename = (char *)realloc(advFilename, strlen(advFilename)+strlen(ACODEEXTENSION)+1);
-        strcat(advFilename, ACODEEXTENSION);
-    }
-    return advFilename;
+	if (strlen(advFilename) < strlen(ACODEEXTENSION)
+	        || compareStrings(&advFilename[strlen(advFilename) - 4], ACODEEXTENSION) != 0) {
+		advFilename = (char *)realloc(advFilename, strlen(advFilename) + strlen(ACODEEXTENSION) + 1);
+		strcat(advFilename, ACODEEXTENSION);
+	}
+	return advFilename;
 }
 
 
 
 /*----------------------------------------------------------------------*/
-static void switches(int argc, char *argv[])
-{
-    int i;
-
-    for (i = 1; i < argc; i++) {
-        char *argument = argv[i];
-
-        if (argument[0] == '-') {
-            switch (toLower(argument[1]))
-                {
-                case 'i':
-                    ignoreErrorOption = TRUE;
-                    break;
-                case 't':
-                    traceSectionOption = TRUE;
-                    switch (argument[2]) {
-                    case '9':
-                    case '8':
-                    case '7':
-                    case '6':
-                    case '5' : traceStackOption = TRUE;
-                    case '4' : tracePushOption = TRUE;
-                    case '3' : traceInstructionOption = TRUE;
-                    case '2' : traceSourceOption = TRUE;
-                    case '\0':
-                    case '1': traceSectionOption = TRUE;
-                    }
-                    break;
-                case 'd':
-                    debugOption = TRUE;
-                    break;
-                case 'l':
-                    transcriptOption = TRUE;
-                    logOption = FALSE;
-                    break;
-                case 'v':
-                    verboseOption = TRUE;
-                    break;
-                case 'n':
-                    statusLineOption = FALSE;
-                    break;
-                case 'c':
-                    logOption = TRUE;
-                    transcriptOption = FALSE;
-                    break;
-                case 'r':
-                    regressionTestOption = TRUE;
-                    break;
-                default:
-                    printf("Unrecognized switch, -%c\n", argument[1]);
-                    usage(argv[0]);
-                    terminate(0);
-                }
-        } else {
-
-            if (isQuoted(argument))
-                adventureFileName = removeQuotes(argument);
-            else
-                adventureFileName = strdup(argument);
-
-            adventureFileName = addAcodeExtension(adventureFileName);
-
-            adventureName = gameName(adventureFileName);
-
-        }
-    }
+static void switches(int argc, char *argv[]) {
+	int i;
+
+	for (i = 1; i < argc; i++) {
+		char *argument = argv[i];
+
+		if (argument[0] == '-') {
+			switch (toLower(argument[1])) {
+			case 'i':
+				ignoreErrorOption = TRUE;
+				break;
+			case 't':
+				traceSectionOption = TRUE;
+				switch (argument[2]) {
+				case '9':
+				case '8':
+				case '7':
+				case '6':
+				case '5' :
+					traceStackOption = TRUE;
+				case '4' :
+					tracePushOption = TRUE;
+				case '3' :
+					traceInstructionOption = TRUE;
+				case '2' :
+					traceSourceOption = TRUE;
+				case '\0':
+				case '1':
+					traceSectionOption = TRUE;
+				}
+				break;
+			case 'd':
+				debugOption = TRUE;
+				break;
+			case 'l':
+				transcriptOption = TRUE;
+				logOption = FALSE;
+				break;
+			case 'v':
+				verboseOption = TRUE;
+				break;
+			case 'n':
+				statusLineOption = FALSE;
+				break;
+			case 'c':
+				logOption = TRUE;
+				transcriptOption = FALSE;
+				break;
+			case 'r':
+				regressionTestOption = TRUE;
+				break;
+			default:
+				printf("Unrecognized switch, -%c\n", argument[1]);
+				usage(argv[0]);
+				terminate(0);
+			}
+		} else {
+
+			if (isQuoted(argument))
+				adventureFileName = removeQuotes(argument);
+			else
+				adventureFileName = strdup(argument);
+
+			adventureFileName = addAcodeExtension(adventureFileName);
+
+			adventureName = gameName(adventureFileName);
+
+		}
+	}
 }
 #endif
 
 /*----------------------------------------------------------------------*/
 bool differentInterpreterName(char *string) {
-    return strcasecmp(string, PROGNAME) != 0;
+	return strcasecmp(string, PROGNAME) != 0;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/attribute.cpp b/engines/glk/alan3/attribute.cpp
index 1e5a6dd..f467585 100644
--- a/engines/glk/alan3/attribute.cpp
+++ b/engines/glk/alan3/attribute.cpp
@@ -29,34 +29,31 @@ namespace Glk {
 namespace Alan3 {
 
 /*----------------------------------------------------------------------*/
-static AttributeEntry *findAttribute(AttributeEntry *attributeTable, int attributeCode)
-{
-  AttributeEntry *attribute = attributeTable;
-  while (attribute->code != attributeCode) {
-    attribute++;
-    if (isEndOfArray(attribute))
-      syserr("Attribute not found.");
-  }
-  return attribute;
+static AttributeEntry *findAttribute(AttributeEntry *attributeTable, int attributeCode) {
+	AttributeEntry *attribute = attributeTable;
+	while (attribute->code != attributeCode) {
+		attribute++;
+		if (isEndOfArray(attribute))
+			syserr("Attribute not found.");
+	}
+	return attribute;
 }
 
 
 /*======================================================================*/
-Aptr getAttribute(AttributeEntry *attributeTable, int attributeCode)
-{
-  AttributeEntry *attribute = findAttribute(attributeTable, attributeCode);
+Aptr getAttribute(AttributeEntry *attributeTable, int attributeCode) {
+	AttributeEntry *attribute = findAttribute(attributeTable, attributeCode);
 
-  return attribute->value;
+	return attribute->value;
 }
 
 
 /*======================================================================*/
-void setAttribute(AttributeEntry *attributeTable, int attributeCode, Aptr newValue)
-{
-  AttributeEntry *attribute = findAttribute(attributeTable, attributeCode);
+void setAttribute(AttributeEntry *attributeTable, int attributeCode, Aptr newValue) {
+	AttributeEntry *attribute = findAttribute(attributeTable, attributeCode);
 
-  attribute->value = newValue;
-  gameStateChanged = TRUE;
+	attribute->value = newValue;
+	gameStateChanged = TRUE;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/checkentry.cpp b/engines/glk/alan3/checkentry.cpp
index 51a839c..6a49128 100644
--- a/engines/glk/alan3/checkentry.cpp
+++ b/engines/glk/alan3/checkentry.cpp
@@ -29,24 +29,23 @@ namespace Glk {
 namespace Alan3 {
 
 /*======================================================================*/
-bool checksFailed(Aaddr adr, bool execute)
-{
-    CheckEntry *chk = (CheckEntry *) pointerTo(adr);
-    if (chk->exp == 0) {
-        if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
-            interpret(chk->stms);
-        return TRUE;
-    } else {
-        while (!isEndOfArray(chk)) {
-            if (!evaluate(chk->exp)) {
-                if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
-                    interpret(chk->stms);
-                return TRUE;
-            }
-            chk++;
-        }
-        return FALSE;
-    }
+bool checksFailed(Aaddr adr, bool execute) {
+	CheckEntry *chk = (CheckEntry *) pointerTo(adr);
+	if (chk->exp == 0) {
+		if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
+			interpret(chk->stms);
+		return TRUE;
+	} else {
+		while (!isEndOfArray(chk)) {
+			if (!evaluate(chk->exp)) {
+				if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
+					interpret(chk->stms);
+				return TRUE;
+			}
+			chk++;
+		}
+		return FALSE;
+	}
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/checkentry.h b/engines/glk/alan3/checkentry.h
index a39558f..f5bcff1 100644
--- a/engines/glk/alan3/checkentry.h
+++ b/engines/glk/alan3/checkentry.h
@@ -38,8 +38,8 @@ namespace Alan3 {
 
 /* TYPES */
 struct CheckEntry { /* CHECK TABLE */
-  Aaddr exp;            /* ACODE address to expression code */
-  Aaddr stms;           /* ACODE address to statement code */
+	Aaddr exp;            /* ACODE address to expression code */
+	Aaddr stms;           /* ACODE address to statement code */
 };
 
 
diff --git a/engines/glk/alan3/class.cpp b/engines/glk/alan3/class.cpp
index b23d8ac..12d7d43 100644
--- a/engines/glk/alan3/class.cpp
+++ b/engines/glk/alan3/class.cpp
@@ -31,7 +31,7 @@ ClassEntry *classes; /* Class table pointer */
 
 /*======================================================================*/
 char *idOfClass(int theClass) {
-    return (char *)pointerTo(classes[theClass].id);
+	return (char *)pointerTo(classes[theClass].id);
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/class.h b/engines/glk/alan3/class.h
index a6ff071..9895a1c 100644
--- a/engines/glk/alan3/class.h
+++ b/engines/glk/alan3/class.h
@@ -29,7 +29,7 @@ namespace Glk {
 namespace Alan3 {
 
 /* DATA */
-extern ClassEntry *classes;		/* Class table pointer */
+extern ClassEntry *classes;     /* Class table pointer */
 
 /* FUNCTIONS */
 extern char *idOfClass(int theClass);
diff --git a/engines/glk/alan3/compatibility.cpp b/engines/glk/alan3/compatibility.cpp
index a8efb47..4668d6e 100644
--- a/engines/glk/alan3/compatibility.cpp
+++ b/engines/glk/alan3/compatibility.cpp
@@ -27,42 +27,42 @@ namespace Alan3 {
 
 /*----------------------------------------------------------------------*/
 static bool is3_0Alpha(char version[]) {
-    return version[3] == 3 && version[2] == 0 && version[0] == 'a';
+	return version[3] == 3 && version[2] == 0 && version[0] == 'a';
 }
 
 /*----------------------------------------------------------------------*/
 static bool is3_0Beta(char version[]) {
-    return version[3] == 3 && version[2] == 0 && version[0] == 'b';
+	return version[3] == 3 && version[2] == 0 && version[0] == 'b';
 }
 
 /*----------------------------------------------------------------------*/
 static int correction(char version[]) {
-    return version[1];
+	return version[1];
 }
 
 /*======================================================================*/
 bool isPreAlpha5(char version[4]) {
-    return is3_0Alpha(version) && correction(version) <5;
+	return is3_0Alpha(version) && correction(version) < 5;
 }
 
 /*======================================================================*/
 bool isPreBeta2(char version[4]) {
-    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) == 1);
+	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) == 1);
 }
 
 /*======================================================================*/
 bool isPreBeta3(char version[4]) {
-    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 2);
+	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 2);
 }
 
 /*======================================================================*/
 bool isPreBeta4(char version[4]) {
-    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 3);
+	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 3);
 }
 
 /*======================================================================*/
 bool isPreBeta5(char version[4]) {
-    return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 4);
+	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 4);
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/container.cpp b/engines/glk/alan3/container.cpp
index 365455c..36469a3 100644
--- a/engines/glk/alan3/container.cpp
+++ b/engines/glk/alan3/container.cpp
@@ -38,152 +38,148 @@ ContainerEntry *containers;  /* Container table pointer */
 
 
 /*----------------------------------------------------------------------*/
-static int countInContainer(int containerIndex)	/* IN - the container to count in */
-{
-    int j = 0;
-
-    for (uint instanceIndex = 1; instanceIndex <= header->instanceMax; instanceIndex++)
-        if (isIn(instanceIndex, containerIndex, DIRECT))
-            /* Then it's in this container also */
-            j++;
-    return(j);
+static int countInContainer(int containerIndex) { /* IN - the container to count in */
+	int j = 0;
+
+	for (uint instanceIndex = 1; instanceIndex <= header->instanceMax; instanceIndex++)
+		if (isIn(instanceIndex, containerIndex, DIRECT))
+			/* Then it's in this container also */
+			j++;
+	return (j);
 }
 
 
 /*----------------------------------------------------------------------*/
 static int sumAttributeInContainer(
-                                   Aint containerIndex,			/* IN - the container to sum */
-                                   Aint attributeIndex			/* IN - the attribute to sum over */
-                                   ) {
-    uint instanceIndex;
-    int sum = 0;
-
-    for (instanceIndex = 1; instanceIndex <= header->instanceMax; instanceIndex++)
-        if (isIn(instanceIndex, containerIndex, DIRECT)) {	/* Then it's directly in this cont */
-            if (instances[instanceIndex].container != 0)	/* This is also a container! */
-                sum = sum + sumAttributeInContainer(instanceIndex, attributeIndex);
-            sum = sum + getInstanceAttribute(instanceIndex, attributeIndex);
-        }
-    return(sum);
+    Aint containerIndex,         /* IN - the container to sum */
+    Aint attributeIndex          /* IN - the attribute to sum over */
+) {
+	uint instanceIndex;
+	int sum = 0;
+
+	for (instanceIndex = 1; instanceIndex <= header->instanceMax; instanceIndex++)
+		if (isIn(instanceIndex, containerIndex, DIRECT)) {  /* Then it's directly in this cont */
+			if (instances[instanceIndex].container != 0)    /* This is also a container! */
+				sum = sum + sumAttributeInContainer(instanceIndex, attributeIndex);
+			sum = sum + getInstanceAttribute(instanceIndex, attributeIndex);
+		}
+	return (sum);
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool containerIsEmpty(int container)
-{
-    uint i;
-
-    for (i = 1; i <= header->instanceMax; i++)
-        if (isDescribable(i) && isIn(i, container, TRANSITIVE))
-            return FALSE;
-    return TRUE;
+static bool containerIsEmpty(int container) {
+	uint i;
+
+	for (i = 1; i <= header->instanceMax; i++)
+		if (isDescribable(i) && isIn(i, container, TRANSITIVE))
+			return FALSE;
+	return TRUE;
 }
 
 
 /*======================================================================*/
-void describeContainer(int container)
-{
-    if (!containerIsEmpty(container) && !isOpaque(container))
-        list(container);
+void describeContainer(int container) {
+	if (!containerIsEmpty(container) && !isOpaque(container))
+		list(container);
 }
 
 
 /*======================================================================*/
 bool passesContainerLimits(Aint theContainer, Aint theAddedInstance) {
-    LimitEntry *limit;
-    Aword props;
-
-    if (!isAContainer(theContainer))
-        syserr("Checking limits for a non-container.");
-
-    /* Find the container properties */
-    props = instances[theContainer].container;
-
-    if (containers[props].limits != 0) { /* Any limits at all? */
-        for (limit = (LimitEntry *) pointerTo(containers[props].limits); !isEndOfArray(limit); limit++)
-            if ((int)limit->atr == 1-I_COUNT) { /* TODO This is actually some encoding of the attribute number, right? */
-                if (countInContainer(theContainer) >= (int)limit->val) {
-                    interpret(limit->stms);
-                    return(FALSE);
-                }
-            } else {
-                if (sumAttributeInContainer(theContainer, limit->atr) + getInstanceAttribute(theAddedInstance, limit->atr) > limit->val) {
-                    interpret(limit->stms);
-                    return(FALSE);
-                }
-            }
-    }
-    return(TRUE);
+	LimitEntry *limit;
+	Aword props;
+
+	if (!isAContainer(theContainer))
+		syserr("Checking limits for a non-container.");
+
+	/* Find the container properties */
+	props = instances[theContainer].container;
+
+	if (containers[props].limits != 0) { /* Any limits at all? */
+		for (limit = (LimitEntry *) pointerTo(containers[props].limits); !isEndOfArray(limit); limit++)
+			if ((int)limit->atr == 1 - I_COUNT) { /* TODO This is actually some encoding of the attribute number, right? */
+				if (countInContainer(theContainer) >= (int)limit->val) {
+					interpret(limit->stms);
+					return (FALSE);
+				}
+			} else {
+				if (sumAttributeInContainer(theContainer, limit->atr) + getInstanceAttribute(theAddedInstance, limit->atr) > limit->val) {
+					interpret(limit->stms);
+					return (FALSE);
+				}
+			}
+	}
+	return (TRUE);
 }
 
 
 /*======================================================================*/
 int containerSize(int container, ATrans trans) {
-    Aword i;
-    Aint count = 0;
-
-    for (i = 1; i <= header->instanceMax; i++) {
-        if (isIn(i, container, trans))
-            count++;
-    }
-    return(count);
+	Aword i;
+	Aint count = 0;
+
+	for (i = 1; i <= header->instanceMax; i++) {
+		if (isIn(i, container, trans))
+			count++;
+	}
+	return (count);
 }
 
 /*======================================================================*/
-void list(int container)
-{
-    uint i;
-    Aword props;
-    Aword foundInstance[2] = {0,0};
-    int found = 0;
-    Aint previousThis = current.instance;
-
-    current.instance = container;
-
-    /* Find container table entry */
-    props = instances[container].container;
-    if (props == 0) syserr("Trying to list something not a container.");
-
-    for (i = 1; i <= header->instanceMax; i++) {
-        if (isDescribable(i)) {
-            /* We can only see objects and actors directly in this container... */
-            if (admin[i].location == container) { /* Yes, it's in this container */
-                if (found == 0) {
-                    if (containers[props].header != 0)
-                        interpret(containers[props].header);
-                    else {
-                        if (isAActor(containers[props].owner))
-                            printMessageWithInstanceParameter(M_CARRIES, containers[props].owner);
-                        else
-                            printMessageWithInstanceParameter(M_CONTAINS, containers[props].owner);
-                    }
-                    foundInstance[0] = i;
-                } else if (found == 1)
-                    foundInstance[1] = i;
-                else {
-                    printMessageWithInstanceParameter(M_CONTAINS_COMMA, i);
-                }
-                found++;
-            }
-        }
-    }
-
-    if (found > 0) {
-        if (found > 1)
-            printMessageWithInstanceParameter(M_CONTAINS_AND, foundInstance[1]);
-        printMessageWithInstanceParameter(M_CONTAINS_END, foundInstance[0]);
-    } else {
-        if (containers[props].empty != 0)
-            interpret(containers[props].empty);
-        else {
-            if (isAActor(containers[props].owner))
-                printMessageWithInstanceParameter(M_EMPTYHANDED, containers[props].owner);
-            else
-                printMessageWithInstanceParameter(M_EMPTY, containers[props].owner);
-        }
-    }
-    needSpace = TRUE;
-    current.instance = previousThis;
+void list(int container) {
+	uint i;
+	Aword props;
+	Aword foundInstance[2] = {0, 0};
+	int found = 0;
+	Aint previousThis = current.instance;
+
+	current.instance = container;
+
+	/* Find container table entry */
+	props = instances[container].container;
+	if (props == 0) syserr("Trying to list something not a container.");
+
+	for (i = 1; i <= header->instanceMax; i++) {
+		if (isDescribable(i)) {
+			/* We can only see objects and actors directly in this container... */
+			if (admin[i].location == container) { /* Yes, it's in this container */
+				if (found == 0) {
+					if (containers[props].header != 0)
+						interpret(containers[props].header);
+					else {
+						if (isAActor(containers[props].owner))
+							printMessageWithInstanceParameter(M_CARRIES, containers[props].owner);
+						else
+							printMessageWithInstanceParameter(M_CONTAINS, containers[props].owner);
+					}
+					foundInstance[0] = i;
+				} else if (found == 1)
+					foundInstance[1] = i;
+				else {
+					printMessageWithInstanceParameter(M_CONTAINS_COMMA, i);
+				}
+				found++;
+			}
+		}
+	}
+
+	if (found > 0) {
+		if (found > 1)
+			printMessageWithInstanceParameter(M_CONTAINS_AND, foundInstance[1]);
+		printMessageWithInstanceParameter(M_CONTAINS_END, foundInstance[0]);
+	} else {
+		if (containers[props].empty != 0)
+			interpret(containers[props].empty);
+		else {
+			if (isAActor(containers[props].owner))
+				printMessageWithInstanceParameter(M_EMPTYHANDED, containers[props].owner);
+			else
+				printMessageWithInstanceParameter(M_EMPTY, containers[props].owner);
+		}
+	}
+	needSpace = TRUE;
+	current.instance = previousThis;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/current.h b/engines/glk/alan3/current.h
index 3939816..8c98653 100644
--- a/engines/glk/alan3/current.h
+++ b/engines/glk/alan3/current.h
@@ -30,17 +30,17 @@ namespace Alan3 {
 
 /* TYPES */
 struct CurVars {
-    int syntax,
-        verb,
-        location,
-        actor,
-        instance,
-        tick,
-        score,
-        visits,
-        sourceLine,
-        sourceFile;
-    bool meta;
+	int syntax,
+	    verb,
+	    location,
+	    actor,
+	    instance,
+	    tick,
+	    score,
+	    visits,
+	    sourceLine,
+	    sourceFile;
+	bool meta;
 };
 
 /* DATA */
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index 53895f1..d090021 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -54,367 +54,353 @@ Breakpoint breakpoint[BREAKPOINTMAX];
 #define debugPrefix "adbg: "
 
 /*----------------------------------------------------------------------*/
-static void showAttributes(AttributeEntry *attrib)
-{
-    AttributeEntry *at;
-    int i;
-    char str[80];
-
-    if (attrib == 0)
-        return;
-
-    i = 1;
-    for (at = attrib; !isEndOfArray(at); at++) {
-        sprintf(str, "$i$t%s[%d] = %d", (char *) pointerTo(at->id), at->code, (int)at->value);
-
-        output(str);
-        i++;
-    }
+static void showAttributes(AttributeEntry *attrib) {
+	AttributeEntry *at;
+	int i;
+	char str[80];
+
+	if (attrib == 0)
+		return;
+
+	i = 1;
+	for (at = attrib; !isEndOfArray(at); at++) {
+		sprintf(str, "$i$t%s[%d] = %d", (char *) pointerTo(at->id), at->code, (int)at->value);
+
+		output(str);
+		i++;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showContents(int cnt)
-{
-    uint i;
-    char str[80];
-    Abool found = FALSE;
-
-    output("$iContains:");
-    for (i = 1; i <= header->instanceMax; i++) {
-        if (isIn(i, cnt, DIRECT)) { /* Yes, it's directly in this container */
-            if (!found)
-                found = TRUE;
-            output("$i$t");
-            say(i);
-            sprintf(str, "[%d] ", i);
-            output(str);
-        }
-    }
-    if (!found)
-        output("nothing");
+static void showContents(int cnt) {
+	uint i;
+	char str[80];
+	Abool found = FALSE;
+
+	output("$iContains:");
+	for (i = 1; i <= header->instanceMax; i++) {
+		if (isIn(i, cnt, DIRECT)) { /* Yes, it's directly in this container */
+			if (!found)
+				found = TRUE;
+			output("$i$t");
+			say(i);
+			sprintf(str, "[%d] ", i);
+			output(str);
+		}
+	}
+	if (!found)
+		output("nothing");
 }
 
 
 /*----------------------------------------------------------------------*/
 static char *idOfInstance(int instance) {
-    int base = header->instanceTableAddress+
-        header->instanceMax*sizeof(InstanceEntry)/sizeof(Aword)+1;
-    return (char *)&memory[memory[base+instance-1]];
+	int base = header->instanceTableAddress +
+	           header->instanceMax * sizeof(InstanceEntry) / sizeof(Aword) + 1;
+	return (char *)&memory[memory[base + instance - 1]];
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayInstanceNumberAndName(int ins) {
-    char buf[1000];
+	char buf[1000];
 
-    sprintf(buf, "[%d] %s (\"$$", ins, idOfInstance(ins));
-    output(buf);
-    say(ins);
-    output("$$\")");
+	sprintf(buf, "[%d] %s (\"$$", ins, idOfInstance(ins));
+	output(buf);
+	say(ins);
+	output("$$\")");
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayLocationOfInstance(int ins, const char *prefix) {
-    if (admin[ins].location == 0)
-        return;
-    else {
-        output(prefix);
-        if (isALocation(admin[ins].location)) {
-            output("at");
-            sayInstanceNumberAndName(admin[ins].location);
-            sayLocationOfInstance(admin[ins].location, prefix);
-        } else if (isAContainer(admin[ins].location)) {
-            if (isAObject(admin[ins].location))
-                output("in");
-            else if (isAActor(admin[ins].location))
-                output("carried by");
-            sayInstanceNumberAndName(admin[ins].location);
-            sayLocationOfInstance(admin[ins].location, prefix);
-        } else
-            output("Illegal location!");
-    }
+	if (admin[ins].location == 0)
+		return;
+	else {
+		output(prefix);
+		if (isALocation(admin[ins].location)) {
+			output("at");
+			sayInstanceNumberAndName(admin[ins].location);
+			sayLocationOfInstance(admin[ins].location, prefix);
+		} else if (isAContainer(admin[ins].location)) {
+			if (isAObject(admin[ins].location))
+				output("in");
+			else if (isAActor(admin[ins].location))
+				output("carried by");
+			sayInstanceNumberAndName(admin[ins].location);
+			sayLocationOfInstance(admin[ins].location, prefix);
+		} else
+			output("Illegal location!");
+	}
 }
 
 /*----------------------------------------------------------------------*/
 static void listInstance(int ins) {
-    output("$i");
-    sayInstanceNumberAndName(ins);
-    if (instances[ins].container)
-        output("(container)");
-    sayLocationOfInstance(ins, ", ");
+	output("$i");
+	sayInstanceNumberAndName(ins);
+	if (instances[ins].container)
+		output("(container)");
+	sayLocationOfInstance(ins, ", ");
 }
 
 
 /*----------------------------------------------------------------------*/
-static void listInstances(char *pattern)
-{
-    uint ins;
-    bool found = FALSE;
-
-    for (ins = 1; ins <= header->instanceMax; ins++) {
-        if (pattern == NULL || (pattern != NULL && match(pattern, idOfInstance(ins)))) {
-            if (!found) {
-                output("Instances:");
-                found = TRUE;
-            }
-            listInstance(ins);
-        }
-    }
-    if (pattern != NULL && !found)
-        output("No instances matched the pattern.");
+static void listInstances(char *pattern) {
+	uint ins;
+	bool found = FALSE;
+
+	for (ins = 1; ins <= header->instanceMax; ins++) {
+		if (pattern == NULL || (pattern != NULL && match(pattern, idOfInstance(ins)))) {
+			if (!found) {
+				output("Instances:");
+				found = TRUE;
+			}
+			listInstance(ins);
+		}
+	}
+	if (pattern != NULL && !found)
+		output("No instances matched the pattern.");
 }
 
 /*----------------------------------------------------------------------*/
-static void showInstance(int ins)
-{
-    char str[80];
-
-    if (ins > (int)header->instanceMax || ins < 1) {
-        sprintf(str, "Instance index %d is out of range.", ins);
-        output(str);
-        return;
-    }
-
-    output("The");
-    sayInstanceNumberAndName(ins);
-    if (instances[ins].parent) {
-        sprintf(str, "Isa %s[%d]", idOfClass(instances[ins].parent), instances[ins].parent);
-        output(str);
-    }
-
-    if (!isA(ins, header->locationClassId) || (isA(ins, header->locationClassId) && admin[ins].location != 0)) {
-        sprintf(str, "$iLocation:");
-        output(str);
-        needSpace = TRUE;
-        sayLocationOfInstance(ins, "");
-    }
-
-    output("$iAttributes:");
-    showAttributes(admin[ins].attributes);
-
-    if (instances[ins].container)
-        showContents(ins);
-
-    if (isA(ins, header->actorClassId)) {
-        if (admin[ins].script == 0)
-            output("$iIs idle");
-        else {
-            sprintf(str, "$iExecuting script: %d, Step: %d", admin[ins].script, admin[ins].step);
-            output(str);
-        }
-    }
+static void showInstance(int ins) {
+	char str[80];
+
+	if (ins > (int)header->instanceMax || ins < 1) {
+		sprintf(str, "Instance index %d is out of range.", ins);
+		output(str);
+		return;
+	}
+
+	output("The");
+	sayInstanceNumberAndName(ins);
+	if (instances[ins].parent) {
+		sprintf(str, "Isa %s[%d]", idOfClass(instances[ins].parent), instances[ins].parent);
+		output(str);
+	}
+
+	if (!isA(ins, header->locationClassId) || (isA(ins, header->locationClassId) && admin[ins].location != 0)) {
+		sprintf(str, "$iLocation:");
+		output(str);
+		needSpace = TRUE;
+		sayLocationOfInstance(ins, "");
+	}
+
+	output("$iAttributes:");
+	showAttributes(admin[ins].attributes);
+
+	if (instances[ins].container)
+		showContents(ins);
+
+	if (isA(ins, header->actorClassId)) {
+		if (admin[ins].script == 0)
+			output("$iIs idle");
+		else {
+			sprintf(str, "$iExecuting script: %d, Step: %d", admin[ins].script, admin[ins].step);
+			output(str);
+		}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void listObjects(void)
-{
-    uint obj;
-
-    output("Objects:");
-    for (obj = 1; obj <= header->instanceMax; obj++)
-        if (isAObject(obj))
-            listInstance(obj);
+static void listObjects(void) {
+	uint obj;
+
+	output("Objects:");
+	for (obj = 1; obj <= header->instanceMax; obj++)
+		if (isAObject(obj))
+			listInstance(obj);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showObject(int obj)
-{
-    char str[80];
+static void showObject(int obj) {
+	char str[80];
 
 
-    if (!isAObject(obj)) {
-        sprintf(str, "Instance %d is not an object", obj);
-        output(str);
-        return;
-    }
+	if (!isAObject(obj)) {
+		sprintf(str, "Instance %d is not an object", obj);
+		output(str);
+		return;
+	}
 
-    showInstance(obj);
+	showInstance(obj);
 
 }
 
 /*----------------------------------------------------------------------*/
 static int sourceFileNumber(char *fileName) {
-    SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
-    int n;
-
-    for (n = 0; *(Aword*)&entries[n] != EOD; n++) {
-        char *entryName;
-        entryName = getStringFromFile(entries[n].fpos, entries[n].len);
-        if (strcmp(entryName, fileName) == 0) return n;
-        entryName = baseNameStart(entryName);
-        if (strcmp(entryName, fileName) == 0) return n;
-    }
-    return -1;
+	SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
+	int n;
+
+	for (n = 0; * (Aword *)&entries[n] != EOD; n++) {
+		char *entryName;
+		entryName = getStringFromFile(entries[n].fpos, entries[n].len);
+		if (strcmp(entryName, fileName) == 0) return n;
+		entryName = baseNameStart(entryName);
+		if (strcmp(entryName, fileName) == 0) return n;
+	}
+	return -1;
 }
 
 
 
 /*----------------------------------------------------------------------*/
 static void printClassName(int c) {
-    output(idOfClass(c));
+	output(idOfClass(c));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void showClassInheritance(int c) {
-    char str[80];
-
-    if (classes[c].parent != 0) {
-        output(", Isa");
-        printClassName(classes[c].parent);
-        sprintf(str, "[%d]", classes[c].parent);
-        output(str);
-    }
+	char str[80];
+
+	if (classes[c].parent != 0) {
+		output(", Isa");
+		printClassName(classes[c].parent);
+		sprintf(str, "[%d]", classes[c].parent);
+		output(str);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showClass(int cla)
-{
-    char str[80];
-
-    if (cla < 1) {
-        sprintf(str, "Class index %d is out of range.", cla);
-        output(str);
-        return;
-    }
-
-    output("$t");
-    printClassName(cla);
-    sprintf(str, "[%d]", cla);
-    output(str);
-    showClassInheritance(cla);
+static void showClass(int cla) {
+	char str[80];
+
+	if (cla < 1) {
+		sprintf(str, "Class index %d is out of range.", cla);
+		output(str);
+		return;
+	}
+
+	output("$t");
+	printClassName(cla);
+	sprintf(str, "[%d]", cla);
+	output(str);
+	showClassInheritance(cla);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void listClass(int c)
-{
-    char str[80];
-
-    sprintf(str, "%3d: ", c);
-    output(str);
-    printClassName(c);
-    showClassInheritance(c);
+static void listClass(int c) {
+	char str[80];
+
+	sprintf(str, "%3d: ", c);
+	output(str);
+	printClassName(c);
+	showClassInheritance(c);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showClassHierarchy(int thisItem, int depth)
-{
-    int i;
-    uint child;
-
-    output("$i");
-    for (i=0; i < depth; i++)
-        output("$t");
-
-    listClass(thisItem);
-    for (child = 1; child <= header->classMax; child++) {
-        if (classes[child].parent == thisItem) {
-            showClassHierarchy(child, depth+1);
-        }
-    }
+static void showClassHierarchy(int thisItem, int depth) {
+	int i;
+	uint child;
+
+	output("$i");
+	for (i = 0; i < depth; i++)
+		output("$t");
+
+	listClass(thisItem);
+	for (child = 1; child <= header->classMax; child++) {
+		if (classes[child].parent == thisItem) {
+			showClassHierarchy(child, depth + 1);
+		}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void listLocations(void)
-{
-    uint loc;
-
-    output("Locations:");
-    for (loc = 1; loc <= header->instanceMax; loc++)
-        if (isALocation(loc))
-            listInstance(loc);
+static void listLocations(void) {
+	uint loc;
+
+	output("Locations:");
+	for (loc = 1; loc <= header->instanceMax; loc++)
+		if (isALocation(loc))
+			listInstance(loc);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showLocation(int loc)
-{
-    char str[80];
+static void showLocation(int loc) {
+	char str[80];
 
 
-    if (!isALocation(loc)) {
-        sprintf(str, "Instance %d is not a location.", loc);
-        output(str);
-        return;
-    }
+	if (!isALocation(loc)) {
+		sprintf(str, "Instance %d is not a location.", loc);
+		output(str);
+		return;
+	}
 
-    output("The ");
-    say(loc);
-    sprintf(str, "(%d) Isa location :", loc);
-    output(str);
+	output("The ");
+	say(loc);
+	sprintf(str, "(%d) Isa location :", loc);
+	output(str);
 
-    output("$iAttributes =");
-    showAttributes(admin[loc].attributes);
+	output("$iAttributes =");
+	showAttributes(admin[loc].attributes);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void listActors(void)
-{
-    uint act;
-
-    output("Actors:");
-    for (act = 1; act <= header->instanceMax; act++)
-        if (isAActor(act))
-            listInstance(act);
+static void listActors(void) {
+	uint act;
+
+	output("Actors:");
+	for (act = 1; act <= header->instanceMax; act++)
+		if (isAActor(act))
+			listInstance(act);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showActor(int act)
-{
-    char str[80];
+static void showActor(int act) {
+	char str[80];
 
-    if (!isAActor(act)) {
-        sprintf(str, "Instance %d is not an actor.", act);
-        output(str);
-        return;
-    }
+	if (!isAActor(act)) {
+		sprintf(str, "Instance %d is not an actor.", act);
+		output(str);
+		return;
+	}
 
-    showInstance(act);
+	showInstance(act);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showEvents(void)
-{
+static void showEvents(void) {
 	uint event;
 	int i;
-    char str[80];
-    bool scheduled;
-
-    output("Events:");
-    for (event = 1; event <= header->eventMax; event++) {
-        sprintf(str, "$i%d [%s]:", event, (char *)pointerTo(events[event].id));
-
-        output(str);
-        scheduled = FALSE;
-        for (i = 0; i < eventQueueTop; i++)
-            if ((scheduled = (eventQueue[i].event == (int)event)))
-                break;
-        if (scheduled) {
-            sprintf(str, "Scheduled for +%d, at ", eventQueue[i].after);
-            output(str);
-            say(eventQueue[i].where);
-        } else
-            output("Not scheduled.");
-    }
+	char str[80];
+	bool scheduled;
+
+	output("Events:");
+	for (event = 1; event <= header->eventMax; event++) {
+		sprintf(str, "$i%d [%s]:", event, (char *)pointerTo(events[event].id));
+
+		output(str);
+		scheduled = FALSE;
+		for (i = 0; i < eventQueueTop; i++)
+			if ((scheduled = (eventQueue[i].event == (int)event)))
+				break;
+		if (scheduled) {
+			sprintf(str, "Scheduled for +%d, at ", eventQueue[i].after);
+			output(str);
+			say(eventQueue[i].where);
+		} else
+			output("Not scheduled.");
+	}
 }
 
 
 /*======================================================================*/
 char *sourceFileName(int fileNumber) {
-    SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
+	SourceFileEntry *entries = (SourceFileEntry *)pointerTo(header->sourceFileTable);
 
-    return getStringFromFile(entries[fileNumber].fpos, entries[fileNumber].len);
+	return getStringFromFile(entries[fileNumber].fpos, entries[fileNumber].len);
 }
 
 
@@ -436,14 +422,14 @@ bool readLine(Common::SeekableReadStream *rs, char *line, int maxLen) {
 
 /*======================================================================*/
 char *readSourceLine(int file, int line) {
-    int count;
+	int count;
 #define SOURCELINELENGTH 1000
-    static char buffer[SOURCELINELENGTH];
+	static char buffer[SOURCELINELENGTH];
 
 	frefid_t sourceFileRef = g_vm->glk_fileref_create_by_name(fileusage_TextMode, sourceFileName(file), 0);
 	strid_t sourceFile = g_vm->glk_stream_open_file(sourceFileRef, filemode_Read, 0);
 
-    if (sourceFile != NULL) {
+	if (sourceFile != NULL) {
 		for (count = 0; count < line; count++) {
 			if (!readLine(*sourceFile, buffer, SOURCELINELENGTH))
 				return NULL;
@@ -456,129 +442,129 @@ char *readSourceLine(int file, int line) {
 		}
 
 		delete sourceFile;
-        return buffer;
-    }
+		return buffer;
+	}
 
 	return NULL;
 }
 
 /*======================================================================*/
 void showSourceLine(int fileNumber, int line) {
-    char *buffer = readSourceLine(fileNumber, line);
-    if (buffer != NULL) {
-        if (buffer[strlen(buffer)-1] == '\n')
-            buffer[strlen(buffer)-1] = '\0';
-        printf("<%05d>: %s", line, buffer);
-    }
+	char *buffer = readSourceLine(fileNumber, line);
+	if (buffer != NULL) {
+		if (buffer[strlen(buffer) - 1] == '\n')
+			buffer[strlen(buffer) - 1] = '\0';
+		printf("<%05d>: %s", line, buffer);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void listFiles() {
-    SourceFileEntry *entry;
-    int i = 0;
-    for (entry = (SourceFileEntry *)pointerTo(header->sourceFileTable); *((Aword*)entry) != EOD; entry++) {
-        printf("  %2d : %s\n", i, sourceFileName(i));
-        i++;
-    }
+	SourceFileEntry *entry;
+	int i = 0;
+	for (entry = (SourceFileEntry *)pointerTo(header->sourceFileTable); * ((Aword *)entry) != EOD; entry++) {
+		printf("  %2d : %s\n", i, sourceFileName(i));
+		i++;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static int findSourceLineIndex(SourceLineEntry *entry, int file, int line) {
-    /* Will return index to the closest line available */
-    int i = 0;
-
-    while (!isEndOfArray(&entry[i]) && entry[i].file != file)
-        i++;
-    while (!isEndOfArray(&entry[i]) && entry[i].file == file  && entry[i].line < line)
-        i++;
-    if (isEndOfArray(entry) || entry[i].file != file)
-        return i-1;
-    else
-        return i;
+	/* Will return index to the closest line available */
+	int i = 0;
+
+	while (!isEndOfArray(&entry[i]) && entry[i].file != file)
+		i++;
+	while (!isEndOfArray(&entry[i]) && entry[i].file == file  && entry[i].line < line)
+		i++;
+	if (isEndOfArray(entry) || entry[i].file != file)
+		return i - 1;
+	else
+		return i;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void listBreakpoints() {
-    int i;
-    bool found = FALSE;
-
-    for (i = 0; i < BREAKPOINTMAX; i++)
-        if (breakpoint[i].line != 0) {
-            if (!found)
-                printf("Breakpoints set:\n");
-            found = TRUE;
-            printf("    %s:%d\n", sourceFileName(breakpoint[i].file), breakpoint[i].line);
-        }
-    if (!found)
-        printf("No breakpoints set\n");
+	int i;
+	bool found = FALSE;
+
+	for (i = 0; i < BREAKPOINTMAX; i++)
+		if (breakpoint[i].line != 0) {
+			if (!found)
+				printf("Breakpoints set:\n");
+			found = TRUE;
+			printf("    %s:%d\n", sourceFileName(breakpoint[i].file), breakpoint[i].line);
+		}
+	if (!found)
+		printf("No breakpoints set\n");
 }
 
 
 /*======================================================================*/
 int breakpointIndex(int file, int line) {
-    int i;
+	int i;
 
-    for (i = 0; i < BREAKPOINTMAX; i++)
-        if (breakpoint[i].line == line && breakpoint[i].file == file)
-            return i;
-    return -1;
+	for (i = 0; i < BREAKPOINTMAX; i++)
+		if (breakpoint[i].line == line && breakpoint[i].file == file)
+			return i;
+	return -1;
 }
 
 
 /*----------------------------------------------------------------------*/
 static int availableBreakpointSlot() {
-    int i;
+	int i;
 
-    for (i = 0; i < BREAKPOINTMAX; i++)
-        if (breakpoint[i].line == 0)
-            return i;
-    return -1;
+	for (i = 0; i < BREAKPOINTMAX; i++)
+		if (breakpoint[i].line == 0)
+			return i;
+	return -1;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void setBreakpoint(int file, int line) {
-    int i = breakpointIndex(file, line);
-
-    if (i != -1)
-        printf("Breakpoint already set at %s:%d\n", sourceFileName(file), line);
-    else {
-        i = availableBreakpointSlot();
-        if (i == -1)
-            printf("No room for more breakpoints. Delete one first.\n");
-        else {
-            int lineIndex = findSourceLineIndex((SourceLineEntry *)pointerTo(header->sourceLineTable), file, line);
-            SourceLineEntry *entry = (SourceLineEntry *)pointerTo(header->sourceLineTable);
-            char leadingText[100] = "Breakpoint";
-            if (entry[lineIndex].file == (Aint)EOD) {
-                printf("Line %d not available\n", line);
-            } else {
-                if (entry[lineIndex].line != line)
-                    sprintf(leadingText, "Line %d not available, breakpoint instead", line);
-                breakpoint[i].file = entry[lineIndex].file;
-                breakpoint[i].line = entry[lineIndex].line;
-                printf("%s set at %s:%d\n", leadingText, sourceFileName(entry[lineIndex].file), entry[lineIndex].line);
-                showSourceLine(entry[lineIndex].file, entry[lineIndex].line);
-                printf("\n");
-            }
-        }
-    }
+	int i = breakpointIndex(file, line);
+
+	if (i != -1)
+		printf("Breakpoint already set at %s:%d\n", sourceFileName(file), line);
+	else {
+		i = availableBreakpointSlot();
+		if (i == -1)
+			printf("No room for more breakpoints. Delete one first.\n");
+		else {
+			int lineIndex = findSourceLineIndex((SourceLineEntry *)pointerTo(header->sourceLineTable), file, line);
+			SourceLineEntry *entry = (SourceLineEntry *)pointerTo(header->sourceLineTable);
+			char leadingText[100] = "Breakpoint";
+			if (entry[lineIndex].file == (Aint)EOD) {
+				printf("Line %d not available\n", line);
+			} else {
+				if (entry[lineIndex].line != line)
+					sprintf(leadingText, "Line %d not available, breakpoint instead", line);
+				breakpoint[i].file = entry[lineIndex].file;
+				breakpoint[i].line = entry[lineIndex].line;
+				printf("%s set at %s:%d\n", leadingText, sourceFileName(entry[lineIndex].file), entry[lineIndex].line);
+				showSourceLine(entry[lineIndex].file, entry[lineIndex].line);
+				printf("\n");
+			}
+		}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void deleteBreakpoint(int line, int file) {
-    int i = breakpointIndex(file, line);
-
-    if (i == -1)
-        printf("No breakpoint set at %s:%d\n", sourceFileName(file), line);
-    else {
-        breakpoint[i].line = 0;
-        printf("Breakpoint at %s:%d deleted\n", sourceFileName(file), line);
-    }
+	int i = breakpointIndex(file, line);
+
+	if (i == -1)
+		printf("No breakpoint set at %s:%d\n", sourceFileName(file), line);
+	else {
+		breakpoint[i].line = 0;
+		printf("Breakpoint at %s:%d deleted\n", sourceFileName(file), line);
+	}
 }
 
 
@@ -587,30 +573,35 @@ static bool saved_traceSection, saved_traceInstruction, saved_capitilize, saved_
 static int loc;
 
 /*======================================================================*/
-void saveInfo(void)
-{
-    /* Save some important things */
-    saved_capitilize = capitalize; capitalize = FALSE;
-    saved_traceSection = traceSectionOption; traceSectionOption = FALSE;
-    saved_traceSource = traceSourceOption; traceSourceOption = FALSE;
-    saved_traceInstruction = traceInstructionOption; traceInstructionOption = FALSE;
-    saved_tracePush = tracePushOption; tracePushOption = FALSE;
-    saved_traceStack = traceStackOption; traceStackOption = FALSE;
-    loc = current.location; current.location = where(HERO, DIRECT);
+void saveInfo(void) {
+	/* Save some important things */
+	saved_capitilize = capitalize;
+	capitalize = FALSE;
+	saved_traceSection = traceSectionOption;
+	traceSectionOption = FALSE;
+	saved_traceSource = traceSourceOption;
+	traceSourceOption = FALSE;
+	saved_traceInstruction = traceInstructionOption;
+	traceInstructionOption = FALSE;
+	saved_tracePush = tracePushOption;
+	tracePushOption = FALSE;
+	saved_traceStack = traceStackOption;
+	traceStackOption = FALSE;
+	loc = current.location;
+	current.location = where(HERO, DIRECT);
 }
 
 
 /*======================================================================*/
-void restoreInfo(void)
-{
-    /* Restore! */
-    capitalize = saved_capitilize;
-    traceSectionOption = saved_traceSection;
-    traceInstructionOption = saved_traceInstruction;
-    traceSourceOption = saved_traceSource;
-    tracePushOption = saved_tracePush;
-    traceStackOption = saved_traceStack;
-    current.location = loc;
+void restoreInfo(void) {
+	/* Restore! */
+	capitalize = saved_capitilize;
+	traceSectionOption = saved_traceSection;
+	traceInstructionOption = saved_traceInstruction;
+	traceSourceOption = saved_traceSource;
+	tracePushOption = saved_tracePush;
+	traceStackOption = saved_traceStack;
+	current.location = loc;
 }
 
 #define HELP_COMMAND 'H'
@@ -639,428 +630,478 @@ void restoreInfo(void)
 #define TRACE_STACK_COMMAND 't'
 
 typedef struct DebugParseEntry {
-    const char *command;
+	const char *command;
 	const char *parameter;
-    char code;
+	char code;
 	const char *helpText;
 } DebugParseEntry;
 
 static const DebugParseEntry commandEntries[] = {
-    {"help", "", HELP_COMMAND, "this help"},
-    {"?", "", HELP_COMMAND, "d:o"},
-    {"break", "[[file:]n]", BREAK_COMMAND, "set breakpoint at source line [n] (optionally in [file])"},
-    {"delete", "[[file:]n]", DELETE_COMMAND, "delete breakpoint at source line [n] (optionally in [file])"},
-    {"files", "", FILES_COMMAND, "list source files"},
-    {"events", "", EVENTS_COMMAND, "list events"},
-    {"classes", "", CLASSES_COMMAND, "list class hierarchy"},
-    {"instances", "[n]", INSTANCES_COMMAND, "list instance(s), all, wildcard, number or name"},
-    {"objects", "[n]", OBJECTS_COMMAND, "list instance(s) that are objects"},
-    {"actors", "[n]", ACTORS_COMMAND, "list instance(s) that are actors"},
-    {"locations", "[n]", LOCATIONS_COMMAND, "list instances that are locations"},
-    {"trace", "('source'|'section'|'instruction'|'push'|'stack')", TRACE_COMMAND, "toggle various traces"},
-    {"next", "", NEXT_COMMAND, "run game and stop at next source line"},
-    {"go", "", GO_COMMAND, "go another player turn"},
-    {"exit", "", EXIT_COMMAND, "exit to game, enter 'debug' to get back"},
-    {"x", "", EXIT_COMMAND, "d:o"},
-    {"quit", "", QUIT_COMMAND, "quit game"},
-    {NULL, NULL, '\0', NULL}
+	{"help", "", HELP_COMMAND, "this help"},
+	{"?", "", HELP_COMMAND, "d:o"},
+	{"break", "[[file:]n]", BREAK_COMMAND, "set breakpoint at source line [n] (optionally in [file])"},
+	{"delete", "[[file:]n]", DELETE_COMMAND, "delete breakpoint at source line [n] (optionally in [file])"},
+	{"files", "", FILES_COMMAND, "list source files"},
+	{"events", "", EVENTS_COMMAND, "list events"},
+	{"classes", "", CLASSES_COMMAND, "list class hierarchy"},
+	{"instances", "[n]", INSTANCES_COMMAND, "list instance(s), all, wildcard, number or name"},
+	{"objects", "[n]", OBJECTS_COMMAND, "list instance(s) that are objects"},
+	{"actors", "[n]", ACTORS_COMMAND, "list instance(s) that are actors"},
+	{"locations", "[n]", LOCATIONS_COMMAND, "list instances that are locations"},
+	{"trace", "('source'|'section'|'instruction'|'push'|'stack')", TRACE_COMMAND, "toggle various traces"},
+	{"next", "", NEXT_COMMAND, "run game and stop at next source line"},
+	{"go", "", GO_COMMAND, "go another player turn"},
+	{"exit", "", EXIT_COMMAND, "exit to game, enter 'debug' to get back"},
+	{"x", "", EXIT_COMMAND, "d:o"},
+	{"quit", "", QUIT_COMMAND, "quit game"},
+	{NULL, NULL, '\0', NULL}
 };
 
 static const DebugParseEntry traceSubcommand[] = {
-    {"source", "", TRACE_SOURCE_COMMAND, ""},
-    {"section", "", TRACE_SECTION_COMMAND, ""},
-    {"instructions", "", TRACE_INSTRUCTION_COMMAND, ""},
-    {"pushs", "", TRACE_PUSH_COMMAND, ""},
-    {"stacks", "", TRACE_STACK_COMMAND, ""},
-    {NULL, NULL, '\0', NULL}
+	{"source", "", TRACE_SOURCE_COMMAND, ""},
+	{"section", "", TRACE_SECTION_COMMAND, ""},
+	{"instructions", "", TRACE_INSTRUCTION_COMMAND, ""},
+	{"pushs", "", TRACE_PUSH_COMMAND, ""},
+	{"stacks", "", TRACE_STACK_COMMAND, ""},
+	{NULL, NULL, '\0', NULL}
 };
 
 
 static char *spaces(int length) {
-    static char buf[200];
-    int i;
+	static char buf[200];
+	int i;
 
-    for (i = 0; i<length; i++)
-        buf[i] = ' ';
-    buf[i] = '\0';
-    return buf;
+	for (i = 0; i < length; i++)
+		buf[i] = ' ';
+	buf[i] = '\0';
+	return buf;
 }
 
 
 /*----------------------------------------------------------------------*/
 static char *padding(const DebugParseEntry *entry, int maxLength) {
-    return spaces(maxLength-strlen(entry->command)-strlen(entry->parameter));
+	return spaces(maxLength - strlen(entry->command) - strlen(entry->parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleHelpCommand() {
-    if (!regressionTestOption)
-        output(alan.longHeader);
-
-    const DebugParseEntry *entry = commandEntries;
-
-    int maxLength = 0;
-    for (entry = commandEntries; entry->command != NULL; entry++) {
-        if (strlen(entry->command)+strlen(entry->parameter) > (uint)maxLength)
-            maxLength = strlen(entry->command)+strlen(entry->parameter);
-    }
-
-    output("$nADBG Commands (can be abbreviated):");
-    for (entry = commandEntries; entry->command != NULL; entry++) {
-        char buf[200];
-        sprintf(buf, "$i%s %s %s$n$t$t-- %s", entry->command, entry->parameter, padding(entry, maxLength), entry->helpText);
-        output(buf);
-    }
+	if (!regressionTestOption)
+		output(alan.longHeader);
+
+	const DebugParseEntry *entry = commandEntries;
+
+	int maxLength = 0;
+	for (entry = commandEntries; entry->command != NULL; entry++) {
+		if (strlen(entry->command) + strlen(entry->parameter) > (uint)maxLength)
+			maxLength = strlen(entry->command) + strlen(entry->parameter);
+	}
+
+	output("$nADBG Commands (can be abbreviated):");
+	for (entry = commandEntries; entry->command != NULL; entry++) {
+		char buf[200];
+		sprintf(buf, "$i%s %s %s$n$t$t-- %s", entry->command, entry->parameter, padding(entry, maxLength), entry->helpText);
+		output(buf);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static const DebugParseEntry *findEntry(char *command, const DebugParseEntry *entry) {
-    while (entry->command != NULL) {
-        if (strncasecmp(command, entry->command, strlen(command)) == 0)
-            return entry;
-        entry++;
-    }
-    return NULL;
+	while (entry->command != NULL) {
+		if (strncasecmp(command, entry->command, strlen(command)) == 0)
+			return entry;
+		entry++;
+	}
+	return NULL;
 }
 
 
 /*----------------------------------------------------------------------*/
 static char parseDebugCommand(char *command) {
-    const DebugParseEntry *entry = findEntry(command, commandEntries);
-    if (entry != NULL) {
-        if (strlen(command) < strlen(entry->command)) {
-            /* See if there are any more partial matches */
-            if (findEntry(command, entry+1) != NULL)
-                /* TODO: we should list the possible matches somehow */
-                return AMBIGUOUS_COMMAND;
-        }
-        return entry->code;
-    } else
-        return UNKNOWN_COMMAND;
+	const DebugParseEntry *entry = findEntry(command, commandEntries);
+	if (entry != NULL) {
+		if (strlen(command) < strlen(entry->command)) {
+			/* See if there are any more partial matches */
+			if (findEntry(command, entry + 1) != NULL)
+				/* TODO: we should list the possible matches somehow */
+				return AMBIGUOUS_COMMAND;
+		}
+		return entry->code;
+	} else
+		return UNKNOWN_COMMAND;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void readCommand(char buf[]) {
-    char c;
-
-    capitalize = FALSE;
-    if (anyOutput) newline();
-    do {
-        output("adbg> ");
-
-        if (!readline(buf)) {
-            newline();
-            quitGame();
-        }
-        lin = 1;
-        c = buf[0];
-    } while (c == '\0');
+	char c;
+
+	capitalize = FALSE;
+	if (anyOutput) newline();
+	do {
+		output("adbg> ");
+
+		if (!readline(buf)) {
+			newline();
+			quitGame();
+		}
+		lin = 1;
+		c = buf[0];
+	} while (c == '\0');
 }
 
 
 /*----------------------------------------------------------------------*/
 static void displaySourceLocation(int line, int fileNumber) {
-    const char *cause;
-    if (anyOutput) newline();
-    if (breakpointIndex(fileNumber, line) != -1)
-        cause = "Breakpoint hit at";
-    else
-        cause = "Stepping to";
-    printf("%s %s %s:%d\n", debugPrefix, cause, sourceFileName(fileNumber), line);
-    showSourceLine(fileNumber, line);
-    printf("\n");
-    anyOutput = FALSE;
+	const char *cause;
+	if (anyOutput) newline();
+	if (breakpointIndex(fileNumber, line) != -1)
+		cause = "Breakpoint hit at";
+	else
+		cause = "Stepping to";
+	printf("%s %s %s:%d\n", debugPrefix, cause, sourceFileName(fileNumber), line);
+	showSourceLine(fileNumber, line);
+	printf("\n");
+	anyOutput = FALSE;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void toggleSectionTrace() {
-    if ((saved_traceSection = !saved_traceSection))
-        printf("Section trace on.");
-    else
-        printf("Section trace off.");
+	if ((saved_traceSection = !saved_traceSection))
+		printf("Section trace on.");
+	else
+		printf("Section trace off.");
 }
 
 /*----------------------------------------------------------------------*/
 static void toggleInstructionTrace() {
-    if ((saved_traceInstruction = !saved_traceInstruction))
-        printf("Single instruction trace on.");
-    else
-        printf("Single instruction trace off.");
+	if ((saved_traceInstruction = !saved_traceInstruction))
+		printf("Single instruction trace on.");
+	else
+		printf("Single instruction trace off.");
 }
 
 /*----------------------------------------------------------------------*/
 static void toggleSourceTrace() {
-    if ((saved_traceSource = !saved_traceSource))
-        printf("Source code trace on.");
-    else
-        printf("Source code trace off.");
+	if ((saved_traceSource = !saved_traceSource))
+		printf("Source code trace on.");
+	else
+		printf("Source code trace off.");
 }
 
 
 /*----------------------------------------------------------------------*/
 static void togglePushTrace() {
-    if ((saved_tracePush = !saved_tracePush))
-        printf("Stack Push trace on.");
-    else
-        printf("Stack Push trace off.");
+	if ((saved_tracePush = !saved_tracePush))
+		printf("Stack Push trace on.");
+	else
+		printf("Stack Push trace off.");
 }
 
 
 /*----------------------------------------------------------------------*/
 static void toggleStackTrace() {
-    if ((saved_traceStack = !saved_traceStack))
-        printf("Full stack trace on.");
-    else
-        printf("Full stack trace off.");
+	if ((saved_traceStack = !saved_traceStack))
+		printf("Full stack trace on.");
+	else
+		printf("Full stack trace off.");
 }
 
 
 /*----------------------------------------------------------------------*/
 static int parseTraceCommand() {
-    char *subcommand = strtok(NULL, "");
-    const DebugParseEntry *entry;
-    if (subcommand == 0)
-        return UNKNOWN_COMMAND;
-    else {
-        entry = findEntry(subcommand, traceSubcommand);
-        if (entry != NULL) {
-            if (strlen(subcommand) < strlen(entry->command)) {
-                if (findEntry(subcommand, entry+1) != NULL)
-                    return AMBIGUOUS_COMMAND;
-            }
-            return entry->code;
-        } else
-            return UNKNOWN_COMMAND;
-    }
+	char *subcommand = strtok(NULL, "");
+	const DebugParseEntry *entry;
+	if (subcommand == 0)
+		return UNKNOWN_COMMAND;
+	else {
+		entry = findEntry(subcommand, traceSubcommand);
+		if (entry != NULL) {
+			if (strlen(subcommand) < strlen(entry->command)) {
+				if (findEntry(subcommand, entry + 1) != NULL)
+					return AMBIGUOUS_COMMAND;
+			}
+			return entry->code;
+		} else
+			return UNKNOWN_COMMAND;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static const char *printTraceState(bool state) {
-    if (state)
-        return "on  - Traces";
-    else
-        return "off - Doesn't trace";
+	if (state)
+		return "on  - Traces";
+	else
+		return "off - Doesn't trace";
 }
 
 /*----------------------------------------------------------------------*/
 static void printTrace(void) {
-    printf("Trace section     : %s entry to every section (check, description, event, actor, ...)\n", printTraceState(saved_traceSection));
-    printf("Trace source      : %s every source line executed\n", printTraceState(saved_traceSource));
-    printf("Trace instruction : %s every Amachine instruction executed\n", printTraceState(saved_traceInstruction));
-    printf("Trace push        : %s every push onto the Amachine stack\n", printTraceState(saved_tracePush));
-    printf("Trace stack       : %s the complete stack every time\n", printTraceState(saved_traceStack));
+	printf("Trace section     : %s entry to every section (check, description, event, actor, ...)\n", printTraceState(saved_traceSection));
+	printf("Trace source      : %s every source line executed\n", printTraceState(saved_traceSource));
+	printf("Trace instruction : %s every Amachine instruction executed\n", printTraceState(saved_traceInstruction));
+	printf("Trace push        : %s every push onto the Amachine stack\n", printTraceState(saved_tracePush));
+	printf("Trace stack       : %s the complete stack every time\n", printTraceState(saved_traceStack));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleTraceCommand() {
-    char subcommand = parseTraceCommand();
-
-    switch (subcommand) {
-    case TRACE_SECTION_COMMAND: toggleSectionTrace(); break;
-    case TRACE_SOURCE_COMMAND: toggleSourceTrace(); break;
-    case TRACE_INSTRUCTION_COMMAND: toggleInstructionTrace(); break;
-    case TRACE_PUSH_COMMAND: togglePushTrace(); break;
-    case TRACE_STACK_COMMAND: toggleStackTrace(); break;
-    case AMBIGUOUS_COMMAND: output("Ambiguous Trace subcommand abbreviation. ? for help."); break;
-    default: printTrace();
-    }
+	char subcommand = parseTraceCommand();
+
+	switch (subcommand) {
+	case TRACE_SECTION_COMMAND:
+		toggleSectionTrace();
+		break;
+	case TRACE_SOURCE_COMMAND:
+		toggleSourceTrace();
+		break;
+	case TRACE_INSTRUCTION_COMMAND:
+		toggleInstructionTrace();
+		break;
+	case TRACE_PUSH_COMMAND:
+		togglePushTrace();
+		break;
+	case TRACE_STACK_COMMAND:
+		toggleStackTrace();
+		break;
+	case AMBIGUOUS_COMMAND:
+		output("Ambiguous Trace subcommand abbreviation. ? for help.");
+		break;
+	default:
+		printTrace();
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleBreakCommand(int fileNumber) {
-    char *parameter = strtok(NULL, ":");
-    if (parameter != NULL && isalpha((int)parameter[0])) {
-        fileNumber = sourceFileNumber(parameter);
-        if (fileNumber == -1) {
-            printf("No such file: '%s'\n", parameter);
-            return;
-        }
-        parameter = strtok(NULL, "");
-    }
-    if (parameter == NULL)
-        listBreakpoints();
-    else
-        setBreakpoint(fileNumber, atoi(parameter));
+	char *parameter = strtok(NULL, ":");
+	if (parameter != NULL && isalpha((int)parameter[0])) {
+		fileNumber = sourceFileNumber(parameter);
+		if (fileNumber == -1) {
+			printf("No such file: '%s'\n", parameter);
+			return;
+		}
+		parameter = strtok(NULL, "");
+	}
+	if (parameter == NULL)
+		listBreakpoints();
+	else
+		setBreakpoint(fileNumber, atoi(parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleDeleteCommand(bool calledFromBreakpoint, int line, int fileNumber) {
-    char *parameter = strtok(NULL, "");
-    if (parameter == NULL) {
-        if (calledFromBreakpoint)
-            deleteBreakpoint(line, fileNumber);
-        else
-            printf("No current breakpoint to delete\n");
-    } else
-        deleteBreakpoint(atoi(parameter), fileNumber);
+	char *parameter = strtok(NULL, "");
+	if (parameter == NULL) {
+		if (calledFromBreakpoint)
+			deleteBreakpoint(line, fileNumber);
+		else
+			printf("No current breakpoint to delete\n");
+	} else
+		deleteBreakpoint(atoi(parameter), fileNumber);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleNextCommand(bool calledFromBreakpoint) {
-    stopAtNextLine = TRUE;
-    debugOption = FALSE;
-    if (!calledFromBreakpoint)
-        current.sourceLine = 0;
-    restoreInfo();
+	stopAtNextLine = TRUE;
+	debugOption = FALSE;
+	if (!calledFromBreakpoint)
+		current.sourceLine = 0;
+	restoreInfo();
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleLocationsCommand() {
-    char *parameter = strtok(NULL, "");
-    if (parameter == 0)
-        listLocations();
-    else
-        showLocation(atoi(parameter));
+	char *parameter = strtok(NULL, "");
+	if (parameter == 0)
+		listLocations();
+	else
+		showLocation(atoi(parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleActorsCommand() {
-    char *parameter = strtok(NULL, "");
-    if (parameter == NULL)
-        listActors();
-    else
-        showActor(atoi(parameter));
+	char *parameter = strtok(NULL, "");
+	if (parameter == NULL)
+		listActors();
+	else
+		showActor(atoi(parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleClassesCommand() {
-    char *parameter = strtok(NULL, "");
-    if (parameter == NULL || strchr(parameter, '*') != 0) {
-        output("Classes:");
-        showClassHierarchy(1, 0);
-        listInstances(parameter);
-    } else if (isdigit((int)parameter[0]))
-        showClass(atoi(parameter));
-    else {
-        printf("You have to give a class index to display. You can't use names (yet).");
-    }
+	char *parameter = strtok(NULL, "");
+	if (parameter == NULL || strchr(parameter, '*') != 0) {
+		output("Classes:");
+		showClassHierarchy(1, 0);
+		listInstances(parameter);
+	} else if (isdigit((int)parameter[0]))
+		showClass(atoi(parameter));
+	else {
+		printf("You have to give a class index to display. You can't use names (yet).");
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleObjectsCommand() {
-    char *parameter = strtok(NULL, "");
-    if (parameter == NULL)
-        listObjects();
-    else
-        showObject(atoi(parameter));
+	char *parameter = strtok(NULL, "");
+	if (parameter == NULL)
+		listObjects();
+	else
+		showObject(atoi(parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void handleInstancesCommand() {
-    char *parameter = strtok(NULL, "");
-    uint i;
-
-    if (parameter == NULL || strchr(parameter, '*') != 0)
-        listInstances(parameter);
-    else if (isdigit((int)parameter[0]))
-        showInstance(atoi(parameter));
-    else {
-        for (i = 1; i<header->instanceMax; i++)
-            if (strcmp(parameter, idOfInstance(i)) == 0) {
-                showInstance(i);
-                return;
-            }
-        printf("No instance named '%s'.", parameter);
-    }
+	char *parameter = strtok(NULL, "");
+	uint i;
+
+	if (parameter == NULL || strchr(parameter, '*') != 0)
+		listInstances(parameter);
+	else if (isdigit((int)parameter[0]))
+		showInstance(atoi(parameter));
+	else {
+		for (i = 1; i < header->instanceMax; i++)
+			if (strcmp(parameter, idOfInstance(i)) == 0) {
+				showInstance(i);
+				return;
+			}
+		printf("No instance named '%s'.", parameter);
+	}
 }
 
 /*----------------------------------------------------------------------*/
 static bool exactSameVersion() {
-    return header->version[3] == alan.version.version
-        && header->version[2] == alan.version.revision
-        && header->version[1] == alan.version.correction
-        && header->version[0] == alan.version.state[0];
+	return header->version[3] == alan.version.version
+	       && header->version[2] == alan.version.revision
+	       && header->version[1] == alan.version.correction
+	       && header->version[0] == alan.version.state[0];
 }
 
 
 /*======================================================================*/
-void debug(bool calledFromBreakpoint, int line, int fileNumber)
-{
-    static bool warned = FALSE;
-
-    saveInfo();
-    g_vm->glk_set_style(style_Preformatted);
-
-    if (calledFromBreakpoint)
-        displaySourceLocation(line, fileNumber);
-    else {
-        if (!exactSameVersion() && !warned && !regressionTestOption) {
-            printf("<WARNING: You are debugging a game which has version %s.>\n",
-                   decodedGameVersion(header->version));
-            printf("<That is not exactly the same as this interpreter (%s).>\n", alan.version.string);
-            printf("<This might cause a lot of trouble. Cross your fingers...>\n");
-            warned = TRUE;
-        }
-    }
-
-    while (TRUE) {
-
-        char commandLine[200];
-        readCommand(commandLine);
-        char *command = strtok(commandLine, " ");
-        char commandCode = parseDebugCommand(command);
-
-        switch (commandCode) {
-        case AMBIGUOUS_COMMAND: output("Ambiguous ADBG command abbreviation. ? for help."); break;
-        case ACTORS_COMMAND: handleActorsCommand(); break;
-        case BREAK_COMMAND: handleBreakCommand(fileNumber); break;
-        case CLASSES_COMMAND: handleClassesCommand(); break;
-        case DELETE_COMMAND: handleDeleteCommand(calledFromBreakpoint, line, fileNumber); break;
-        case EVENTS_COMMAND: showEvents(); break;
-        case EXIT_COMMAND: debugOption = FALSE; restoreInfo(); goto exit_debug;
-        case FILES_COMMAND: listFiles(); break;
-        case GO_COMMAND: restoreInfo(); goto exit_debug;
-        case HELP_COMMAND: handleHelpCommand(); break;
-        case INSTANCES_COMMAND: handleInstancesCommand(); break;
-        case TRACE_COMMAND: handleTraceCommand(); break;
-        case INSTRUCTION_TRACE_COMMAND: toggleInstructionTrace(); break;
-        case LOCATIONS_COMMAND: handleLocationsCommand(); break;
-        case NEXT_COMMAND: handleNextCommand(calledFromBreakpoint); goto exit_debug;
-        case OBJECTS_COMMAND: handleObjectsCommand(); break;
-        case QUIT_COMMAND: terminate(0); break;
-        case SECTION_TRACE_COMMAND: toggleSectionTrace(); break;
-        default: output("Unknown ADBG command. ? for help."); break;
-        }
-    }
-
- exit_debug:
+void debug(bool calledFromBreakpoint, int line, int fileNumber) {
+	static bool warned = FALSE;
+
+	saveInfo();
+	g_vm->glk_set_style(style_Preformatted);
+
+	if (calledFromBreakpoint)
+		displaySourceLocation(line, fileNumber);
+	else {
+		if (!exactSameVersion() && !warned && !regressionTestOption) {
+			printf("<WARNING: You are debugging a game which has version %s.>\n",
+			       decodedGameVersion(header->version));
+			printf("<That is not exactly the same as this interpreter (%s).>\n", alan.version.string);
+			printf("<This might cause a lot of trouble. Cross your fingers...>\n");
+			warned = TRUE;
+		}
+	}
+
+	while (TRUE) {
+
+		char commandLine[200];
+		readCommand(commandLine);
+		char *command = strtok(commandLine, " ");
+		char commandCode = parseDebugCommand(command);
+
+		switch (commandCode) {
+		case AMBIGUOUS_COMMAND:
+			output("Ambiguous ADBG command abbreviation. ? for help.");
+			break;
+		case ACTORS_COMMAND:
+			handleActorsCommand();
+			break;
+		case BREAK_COMMAND:
+			handleBreakCommand(fileNumber);
+			break;
+		case CLASSES_COMMAND:
+			handleClassesCommand();
+			break;
+		case DELETE_COMMAND:
+			handleDeleteCommand(calledFromBreakpoint, line, fileNumber);
+			break;
+		case EVENTS_COMMAND:
+			showEvents();
+			break;
+		case EXIT_COMMAND:
+			debugOption = FALSE;
+			restoreInfo();
+			goto exit_debug;
+		case FILES_COMMAND:
+			listFiles();
+			break;
+		case GO_COMMAND:
+			restoreInfo();
+			goto exit_debug;
+		case HELP_COMMAND:
+			handleHelpCommand();
+			break;
+		case INSTANCES_COMMAND:
+			handleInstancesCommand();
+			break;
+		case TRACE_COMMAND:
+			handleTraceCommand();
+			break;
+		case INSTRUCTION_TRACE_COMMAND:
+			toggleInstructionTrace();
+			break;
+		case LOCATIONS_COMMAND:
+			handleLocationsCommand();
+			break;
+		case NEXT_COMMAND:
+			handleNextCommand(calledFromBreakpoint);
+			goto exit_debug;
+		case OBJECTS_COMMAND:
+			handleObjectsCommand();
+			break;
+		case QUIT_COMMAND:
+			terminate(0);
+			break;
+		case SECTION_TRACE_COMMAND:
+			toggleSectionTrace();
+			break;
+		default:
+			output("Unknown ADBG command. ? for help.");
+			break;
+		}
+	}
+
+exit_debug:
 	g_vm->glk_set_style(style_Normal);
 }
 
 
 /*======================================================================*/
-void traceSay(int item)
-{
-    /*
-      Say something, but make sure we don't disturb anything and that it is
-      shown to the player. Needed for tracing. During debugging things are
-      set up to avoid this problem.
-    */
-
-    saveInfo();
-    needSpace = FALSE;
-    col = 1;
-    if (item == 0)
-        printf("$null$");
-    else
-        say(item);
-    needSpace = FALSE;
-    col = 1;
-    restoreInfo();
+void traceSay(int item) {
+	/*
+	  Say something, but make sure we don't disturb anything and that it is
+	  shown to the player. Needed for tracing. During debugging things are
+	  set up to avoid this problem.
+	*/
+
+	saveInfo();
+	needSpace = FALSE;
+	col = 1;
+	if (item == 0)
+		printf("$null$");
+	else
+		say(item);
+	needSpace = FALSE;
+	col = 1;
+	restoreInfo();
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/debug.h b/engines/glk/alan3/debug.h
index 3bebe27..3bfa32e 100644
--- a/engines/glk/alan3/debug.h
+++ b/engines/glk/alan3/debug.h
@@ -33,8 +33,8 @@ namespace Alan3 {
 /* Types: */
 
 struct Breakpoint {
-  int line;
-  int file;
+	int line;
+	int file;
 };
 
 
diff --git a/engines/glk/alan3/decode.cpp b/engines/glk/alan3/decode.cpp
index 41afbdd..286223c 100644
--- a/engines/glk/alan3/decode.cpp
+++ b/engines/glk/alan3/decode.cpp
@@ -35,101 +35,98 @@ Aword *freq;            /* Cumulative character frequencies */
 
 /* PRIVATE DATA */
 /* Bit output */
-static int decodeBuffer;	/* Bits to be input */
-static int bitsToGo;		/* Bits still in buffer */
-static int garbageBits;		/* Bits past EOD */
-
-
-static int inputBit(void)
-{
-  int bit;
-
-  /* More bits available ? */
-  if (!bitsToGo) {
-	/* No, so get more */
-	 decodeBuffer = (textFile->pos() >= textFile->size()) ? EOD : textFile->readByte();
-    if (decodeBuffer == (int)EOD) {
-      garbageBits++;
-      if (garbageBits > VALUEBITS-2)
-	syserr("Error in encoded data file.");
-    } else
-      bitsToGo = 8;		/* Another Char, 8 new bits */
-  }
-  bit = decodeBuffer&1;		/* Get next bit */
-  decodeBuffer = decodeBuffer>>1; /* and remove it */
-  bitsToGo--;
-  return bit;
+static int decodeBuffer;    /* Bits to be input */
+static int bitsToGo;        /* Bits still in buffer */
+static int garbageBits;     /* Bits past EOD */
+
+
+static int inputBit(void) {
+	int bit;
+
+	/* More bits available ? */
+	if (!bitsToGo) {
+		/* No, so get more */
+		decodeBuffer = (textFile->pos() >= textFile->size()) ? EOD : textFile->readByte();
+		if (decodeBuffer == (int)EOD) {
+			garbageBits++;
+			if (garbageBits > VALUEBITS - 2)
+				syserr("Error in encoded data file.");
+		} else
+			bitsToGo = 8;     /* Another Char, 8 new bits */
+	}
+	bit = decodeBuffer & 1;   /* Get next bit */
+	decodeBuffer = decodeBuffer >> 1; /* and remove it */
+	bitsToGo--;
+	return bit;
 }
 
 
 /* Current state of decoding */
 
-static CodeValue value;			/* Currently seen code value */
-static CodeValue low, high;		/* Current code region */
+static CodeValue value;         /* Currently seen code value */
+static CodeValue low, high;     /* Current code region */
 
 
-void startDecoding(void)
-{
-  int i;
+void startDecoding(void) {
+	int i;
 
-  bitsToGo = 0;
-  garbageBits = 0;
+	bitsToGo = 0;
+	garbageBits = 0;
 
-  value = 0;
-  for (i = 0; i < VALUEBITS; i++)
-    value = 2*value + inputBit();
-  low = 0;
-  high = TOPVALUE;
+	value = 0;
+	for (i = 0; i < VALUEBITS; i++)
+		value = 2 * value + inputBit();
+	low = 0;
+	high = TOPVALUE;
 }
 
 
-int decodeChar(void)
-{
-  long range;
-  int f;
-  int symbol;
-
-  range = (long)(high-low) + 1;
-  f = (((long)(value-low)+1)*freq[0]-1)/range;
-
-  /* Find the symbol */
-  for (symbol = 1; (int)freq[symbol] > f; ++symbol) {}
-
-  high = low + range*freq[symbol-1]/freq[0]-1;
-  low = low + range*freq[symbol]/freq[0];
-
-  for (;;) {
-    if (high < HALF)
-      ;
-    else if (low >= HALF) {
-      value = value - HALF;
-      low = low - HALF;
-      high = high - HALF;
-    } else if (low >= ONEQUARTER && high < THREEQUARTER) {
-      value = value - ONEQUARTER;
-      low = low - ONEQUARTER;
-      high = high - ONEQUARTER;
-    } else
-      break;
-
-    /* Scale up the range */
-    low = 2*low;
-    high = 2*high+1;
-    value = 2*value + inputBit();
-  }
-  return symbol-1;
+int decodeChar(void) {
+	long range;
+	int f;
+	int symbol;
+
+	range = (long)(high - low) + 1;
+	f = (((long)(value - low) + 1) * freq[0] - 1) / range;
+
+	/* Find the symbol */
+	for (symbol = 1; (int)freq[symbol] > f; ++symbol) {}
+
+	high = low + range * freq[symbol - 1] / freq[0] - 1;
+	low = low + range * freq[symbol] / freq[0];
+
+	for (;;) {
+		if (high < HALF)
+			;
+		else if (low >= HALF) {
+			value = value - HALF;
+			low = low - HALF;
+			high = high - HALF;
+		} else if (low >= ONEQUARTER && high < THREEQUARTER) {
+			value = value - ONEQUARTER;
+			low = low - ONEQUARTER;
+			high = high - ONEQUARTER;
+		} else
+			break;
+
+		/* Scale up the range */
+		low = 2 * low;
+		high = 2 * high + 1;
+		value = 2 * value + inputBit();
+	}
+	return symbol - 1;
 }
 
 
 
 /* Structure for saved decode info */
 struct DecodeInfo {
-  long fpos;
-  int buffer;
-  int bits;
-  CodeValue value;
-  CodeValue high;
-  CodeValue low;
+	long fpos;
+	int buffer;
+	int bits;
+	CodeValue value;
+	CodeValue high;
+	CodeValue low;
 };
 
 
@@ -141,18 +138,17 @@ struct DecodeInfo {
   restore and continue later.
 
  */
-void *pushDecode(void)
-{
-  DecodeInfo *info;
-
-  info = (DecodeInfo *)allocate(sizeof(DecodeInfo));
-  info->fpos = textFile->pos();
-  info->buffer = decodeBuffer;
-  info->bits = bitsToGo;
-  info->value = value;
-  info->high = high;
-  info->low = low;
-  return(info);
+void *pushDecode(void) {
+	DecodeInfo *info;
+
+	info = (DecodeInfo *)allocate(sizeof(DecodeInfo));
+	info->fpos = textFile->pos();
+	info->buffer = decodeBuffer;
+	info->bits = bitsToGo;
+	info->value = value;
+	info->high = high;
+	info->low = low;
+	return (info);
 }
 
 
@@ -164,18 +160,17 @@ void *pushDecode(void)
   continue after having decoded something else.
 
  */
-void popDecode(void *i)
-{
-  DecodeInfo *info = (DecodeInfo *) i;
-
-  textFile->seek(info->fpos);
-  decodeBuffer = info->buffer;
-  bitsToGo = info->bits;
-  value = info->value;
-  high = info->high;
-  low = info->low;
-
-  free(info);
+void popDecode(void *i) {
+	DecodeInfo *info = (DecodeInfo *) i;
+
+	textFile->seek(info->fpos);
+	decodeBuffer = info->buffer;
+	bitsToGo = info->bits;
+	value = info->value;
+	high = info->high;
+	low = info->low;
+
+	free(info);
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/dictionary.cpp b/engines/glk/alan3/dictionary.cpp
index 375b7f7..de9d40c 100644
--- a/engines/glk/alan3/dictionary.cpp
+++ b/engines/glk/alan3/dictionary.cpp
@@ -36,99 +36,99 @@ int conjWord;           /* First conjunction in dictionary, for ',' */
 /* Word class query methods, move to Word.c */
 /* Word classes are numbers but in the dictionary they are generated as bits */
 static bool isVerb(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&VERB_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & VERB_BIT) != 0;
 }
 
 bool isVerbWord(int wordIndex) {
-    return isVerb(playerWords[wordIndex].code);
+	return isVerb(playerWords[wordIndex].code);
 }
 
 bool isConjunction(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&CONJUNCTION_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & CONJUNCTION_BIT) != 0;
 }
 
 bool isConjunctionWord(int wordIndex) {
-    return isConjunction(playerWords[wordIndex].code);
+	return isConjunction(playerWords[wordIndex].code);
 }
 
 static bool isExcept(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&EXCEPT_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & EXCEPT_BIT) != 0;
 }
 
 bool isExceptWord(int wordIndex) {
-    return isExcept(playerWords[wordIndex].code);
+	return isExcept(playerWords[wordIndex].code);
 }
 
 static bool isThem(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&THEM_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & THEM_BIT) != 0;
 }
 
 bool isThemWord(int wordIndex) {
-    return isThem(playerWords[wordIndex].code);
+	return isThem(playerWords[wordIndex].code);
 }
 
 static bool isIt(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&IT_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & IT_BIT) != 0;
 }
 
 bool isItWord(int wordIndex) {
-    return isIt(playerWords[wordIndex].code);
+	return isIt(playerWords[wordIndex].code);
 }
 
 static bool isNoun(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&NOUN_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & NOUN_BIT) != 0;
 }
 
 bool isNounWord(int wordIndex) {
-    return isNoun(playerWords[wordIndex].code);
+	return isNoun(playerWords[wordIndex].code);
 }
 
 static bool isAdjective(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&ADJECTIVE_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & ADJECTIVE_BIT) != 0;
 }
 
 bool isAdjectiveWord(int wordIndex) {
-    return isAdjective(playerWords[wordIndex].code);
+	return isAdjective(playerWords[wordIndex].code);
 }
 
 static bool isPreposition(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&PREPOSITION_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & PREPOSITION_BIT) != 0;
 }
 
 bool isPrepositionWord(int wordIndex) {
-    return isPreposition(playerWords[wordIndex].code);
+	return isPreposition(playerWords[wordIndex].code);
 }
 
 bool isAll(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&ALL_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & ALL_BIT) != 0;
 }
 
 bool isAllWord(int wordIndex) {
-    return isAll(playerWords[wordIndex].code);
+	return isAll(playerWords[wordIndex].code);
 }
 
 static bool isDir(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&DIRECTION_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & DIRECTION_BIT) != 0;
 }
 
 bool isDirectionWord(int wordIndex) {
-    return isDir(playerWords[wordIndex].code);
+	return isDir(playerWords[wordIndex].code);
 }
 
 bool isNoise(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&NOISE_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & NOISE_BIT) != 0;
 }
 
 bool isPronoun(int wordCode) {
-  return wordCode < dictionarySize && (dictionary[wordCode].classBits&PRONOUN_BIT)!=0;
+	return wordCode < dictionarySize && (dictionary[wordCode].classBits & PRONOUN_BIT) != 0;
 }
 
 bool isPronounWord(int wordIndex) {
-    return isPronoun(playerWords[wordIndex].code);
+	return isPronoun(playerWords[wordIndex].code);
 }
 
 bool isLiteralWord(int wordIndex) {
-  return playerWords[wordIndex].code >= dictionarySize;
+	return playerWords[wordIndex].code >= dictionarySize;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/event.h b/engines/glk/alan3/event.h
index 4855548..0a76d3c 100644
--- a/engines/glk/alan3/event.h
+++ b/engines/glk/alan3/event.h
@@ -31,9 +31,9 @@ namespace Alan3 {
 
 /* TYPES */
 typedef struct EventQueueEntry { /* EVENT QUEUE ENTRIES */
-  int after;
-  int event;
-  int where;
+	int after;
+	int event;
+	int where;
 } EventQueueEntry;
 
 
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index 445b00d..e3e0e0c 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -69,50 +69,59 @@ Common::SeekableReadStream *textFile;
 
 /*======================================================================*/
 void setStyle(int style) {
-    switch (style) {
-    case NORMAL_STYLE: g_vm->glk_set_style(style_Normal); break;
-    case EMPHASIZED_STYLE: g_vm->glk_set_style(style_Emphasized); break;
-    case PREFORMATTED_STYLE: g_vm->glk_set_style(style_Preformatted); break;
-    case ALERT_STYLE: g_vm->glk_set_style(style_Alert); break;
-    case QUOTE_STYLE: g_vm->glk_set_style(style_BlockQuote); break;
-    }
+	switch (style) {
+	case NORMAL_STYLE:
+		g_vm->glk_set_style(style_Normal);
+		break;
+	case EMPHASIZED_STYLE:
+		g_vm->glk_set_style(style_Emphasized);
+		break;
+	case PREFORMATTED_STYLE:
+		g_vm->glk_set_style(style_Preformatted);
+		break;
+	case ALERT_STYLE:
+		g_vm->glk_set_style(style_Alert);
+		break;
+	case QUOTE_STYLE:
+		g_vm->glk_set_style(style_BlockQuote);
+		break;
+	}
 }
 
 /*======================================================================*/
-void print(Aword fpos, Aword len)
-{
-    char str[2*WIDTH];            /* String buffer */
-    uint outlen = 0;              /* Current output length */
-    int ch = 0;
-    int i;
-    long savfp = 0;     /* Temporary saved text file position */
-    static bool printFlag = FALSE; /* Printing already? */
-    bool savedPrintFlag = printFlag;
-    void *info = NULL;      /* Saved decoding info */
-
-
-    if (len == 0) return;
-
-    if (isHere(HERO, /*TRUE*/ DIRECT)) {   /* Check if the player will see it */
-        if (printFlag) {            /* Already printing? */
-            /* Save current text file position and/or decoding info */
-            if (header->pack)
-                info = pushDecode();
-            else
-                savfp = textFile->pos();
-        }
-        printFlag = TRUE;           /* We're printing now! */
-
-        /* Position to start of text */
-		textFile->seek(fpos+header->stringOffset);
-
-        if (header->pack)
-            startDecoding();
-        for (outlen = 0; outlen != len; outlen = outlen + strlen(str)) {
-            /* Fill the buffer from the beginning */
-            for (i = 0; i <= WIDTH || (i > WIDTH && ch != ' '); i++) {
-                if (outlen + i == len)  /* No more characters? */
-                    break;
+void print(Aword fpos, Aword len) {
+	char str[2 * WIDTH];          /* String buffer */
+	uint outlen = 0;              /* Current output length */
+	int ch = 0;
+	int i;
+	long savfp = 0;     /* Temporary saved text file position */
+	static bool printFlag = FALSE; /* Printing already? */
+	bool savedPrintFlag = printFlag;
+	void *info = NULL;      /* Saved decoding info */
+
+
+	if (len == 0) return;
+
+	if (isHere(HERO, /*TRUE*/ DIRECT)) {   /* Check if the player will see it */
+		if (printFlag) {            /* Already printing? */
+			/* Save current text file position and/or decoding info */
+			if (header->pack)
+				info = pushDecode();
+			else
+				savfp = textFile->pos();
+		}
+		printFlag = TRUE;           /* We're printing now! */
+
+		/* Position to start of text */
+		textFile->seek(fpos + header->stringOffset);
+
+		if (header->pack)
+			startDecoding();
+		for (outlen = 0; outlen != len; outlen = outlen + strlen(str)) {
+			/* Fill the buffer from the beginning */
+			for (i = 0; i <= WIDTH || (i > WIDTH && ch != ' '); i++) {
+				if (outlen + i == len)  /* No more characters? */
+					break;
 				if (header->pack)
 					ch = decodeChar();
 				else
@@ -120,104 +129,100 @@ void print(Aword fpos, Aword len)
 
 				str[i] = ch;
 				if (textFile->pos() >= textFile->size())      /* Or end of text? */
-                    break;
-            }
-            str[i] = '\0';
+					break;
+			}
+			str[i] = '\0';
 
-            output(str);
-        }
+			output(str);
+		}
 
-        /* And restore */
-        printFlag = savedPrintFlag;
-        if (printFlag) {
-            if (header->pack)
-                popDecode(info);
-            else
-                textFile->seek(savfp);
-        }
-    }
+		/* And restore */
+		printFlag = savedPrintFlag;
+		if (printFlag) {
+			if (header->pack)
+				popDecode(info);
+			else
+				textFile->seek(savfp);
+		}
+	}
 }
 
 
 /*======================================================================*/
-void sys(Aword fpos, Aword len)
-{
+void sys(Aword fpos, Aword len) {
 	::error("sys calls are unsupported");
 }
 
 
 /*======================================================================*/
-char *getStringFromFile(Aword fpos, Aword len)
-{
-    char *buf = (char *)allocate(len+1);
-    char *bufp = buf;
+char *getStringFromFile(Aword fpos, Aword len) {
+	char *buf = (char *)allocate(len + 1);
+	char *bufp = buf;
 
-    /* Position to start of text */
-    textFile->seek(fpos+header->stringOffset);
+	/* Position to start of text */
+	textFile->seek(fpos + header->stringOffset);
 
-    if (header->pack)
-        startDecoding();
-    while (len--)
-        if (header->pack)
-            *(bufp++) = decodeChar();
-        else
-            *(bufp++) = textFile->readByte();
+	if (header->pack)
+		startDecoding();
+	while (len--)
+		if (header->pack)
+			*(bufp++) = decodeChar();
+		else
+			*(bufp++) = textFile->readByte();
 
-    /* Terminate string with zero */
-    *bufp = '\0';
+	/* Terminate string with zero */
+	*bufp = '\0';
 
-    return buf;
+	return buf;
 }
 
 
 
 /*======================================================================*/
-void score(Aword sc)
-{
-    if (sc == 0) {
-        ParameterArray messageParameters = newParameterArray();
-        addParameterForInteger(messageParameters, current.score);
-        addParameterForInteger(messageParameters, header->maximumScore);
-        addParameterForInteger(messageParameters, current.tick);
-        printMessageWithParameters(M_SCORE, messageParameters);
-        freeParameterArray(messageParameters);
-    } else {
-        current.score += scores[sc-1];
-        scores[sc-1] = 0;
-        gameStateChanged = TRUE;
-    }
+void score(Aword sc) {
+	if (sc == 0) {
+		ParameterArray messageParameters = newParameterArray();
+		addParameterForInteger(messageParameters, current.score);
+		addParameterForInteger(messageParameters, header->maximumScore);
+		addParameterForInteger(messageParameters, current.tick);
+		printMessageWithParameters(M_SCORE, messageParameters);
+		freeParameterArray(messageParameters);
+	} else {
+		current.score += scores[sc - 1];
+		scores[sc - 1] = 0;
+		gameStateChanged = TRUE;
+	}
 }
 
 
 /*======================================================================*/
-void visits(Aword v)
-{
-    current.visits = v;
+void visits(Aword v) {
+	current.visits = v;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayUndoneCommand(char *words) {
-    static Parameter *messageParameters = NULL;
-    messageParameters = (Parameter *)ensureParameterArrayAllocated(messageParameters);
+	static Parameter *messageParameters = NULL;
+	messageParameters = (Parameter *)ensureParameterArrayAllocated(messageParameters);
 
-    current.location = where(HERO, DIRECT);
-    clearParameterArray(messageParameters);
-    addParameterForString(&messageParameters[0], words);
-    setEndOfArray(&messageParameters[1]);
-    printMessageWithParameters(M_UNDONE, messageParameters);
+	current.location = where(HERO, DIRECT);
+	clearParameterArray(messageParameters);
+	addParameterForString(&messageParameters[0], words);
+	setEndOfArray(&messageParameters[1]);
+	printMessageWithParameters(M_UNDONE, messageParameters);
 }
 
 
 /*======================================================================*/
 void undo(void) {
-    forgetGameState();
-    if (anySavedState()) {
-        recallGameState();
-        sayUndoneCommand(recreatePlayerCommand());
-    } else {
-        printMessage(M_NO_UNDO);
-    }
+	forgetGameState();
+	if (anySavedState()) {
+		recallGameState();
+		sayUndoneCommand(recreatePlayerCommand());
+	} else {
+		printMessage(M_NO_UNDO);
+	}
 #ifdef TODO
 	longjmp(returnLabel, UNDO_RETURN);
 #else
@@ -227,41 +232,40 @@ void undo(void) {
 
 
 /*======================================================================*/
-void quitGame(void)
-{
+void quitGame(void) {
 #ifdef TODO
 	char buf[80];
 
-    current.location = where(HERO, DIRECT);
-    para();
-    while (TRUE) {
-        col = 1;
-        statusline();
-        printMessage(M_QUITACTION);
-
-        if (!readline(buf)) terminate(0);
-        if (strcasecmp(buf, "restart") == 0)
-            longjmp(restartLabel, TRUE);
-        else if (strcasecmp(buf, "restore") == 0) {
-            restore();
-            return;
-        } else if (strcasecmp(buf, "quit") == 0) {
-            terminate(0);
-        } else if (strcasecmp(buf, "undo") == 0) {
-            if (gameStateChanged) {
-                rememberCommands();
-                rememberGameState();
-                undo();
-            } else {
-                if (anySavedState()) {
-                    recallGameState();
-                    sayUndoneCommand(playerWordsAsCommandString());
-                } else
-                    printMessage(M_NO_UNDO);
-                longjmp(returnLabel, UNDO_RETURN);
-            }
-        }
-    }
+	current.location = where(HERO, DIRECT);
+	para();
+	while (TRUE) {
+		col = 1;
+		statusline();
+		printMessage(M_QUITACTION);
+
+		if (!readline(buf)) terminate(0);
+		if (strcasecmp(buf, "restart") == 0)
+			longjmp(restartLabel, TRUE);
+		else if (strcasecmp(buf, "restore") == 0) {
+			restore();
+			return;
+		} else if (strcasecmp(buf, "quit") == 0) {
+			terminate(0);
+		} else if (strcasecmp(buf, "undo") == 0) {
+			if (gameStateChanged) {
+				rememberCommands();
+				rememberGameState();
+				undo();
+			} else {
+				if (anySavedState()) {
+					recallGameState();
+					sayUndoneCommand(playerWordsAsCommandString());
+				} else
+					printMessage(M_NO_UNDO);
+				longjmp(returnLabel, UNDO_RETURN);
+			}
+		}
+	}
 #endif
 	syserr("Fallthrough in QUIT");
 }
@@ -269,16 +273,15 @@ void quitGame(void)
 
 
 /*======================================================================*/
-void restartGame(void)
-{
+void restartGame(void) {
 #ifdef TODO
 	Aint previousLocation = current.location;
 	current.location = where(HERO, DIRECT);
-    para();
-    if (confirm(M_REALLY)) {
-        longjmp(restartLabel, TRUE);
-    }
-    current.location = previousLocation;
+	para();
+	if (confirm(M_REALLY)) {
+		longjmp(restartLabel, TRUE);
+	}
+	current.location = previousLocation;
 #else
 	::error("TODO: restartGame");
 #endif
@@ -287,258 +290,250 @@ void restartGame(void)
 
 
 /*======================================================================*/
-void cancelEvent(Aword theEvent)
-{
-    int i;
-
-    for (i = eventQueueTop-1; i>=0; i--)
-        if (eventQueue[i].event == (int)theEvent) {
-            while (i < eventQueueTop-1) {
-                eventQueue[i].event = eventQueue[i+1].event;
-                eventQueue[i].after = eventQueue[i+1].after;
-                eventQueue[i].where = eventQueue[i+1].where;
-                i++;
-            }
-            eventQueueTop--;
-            return;
-        }
+void cancelEvent(Aword theEvent) {
+	int i;
+
+	for (i = eventQueueTop - 1; i >= 0; i--)
+		if (eventQueue[i].event == (int)theEvent) {
+			while (i < eventQueueTop - 1) {
+				eventQueue[i].event = eventQueue[i + 1].event;
+				eventQueue[i].after = eventQueue[i + 1].after;
+				eventQueue[i].where = eventQueue[i + 1].where;
+				i++;
+			}
+			eventQueueTop--;
+			return;
+		}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void increaseEventQueue(void)
-{
-    eventQueue = (EventQueueEntry *)realloc(eventQueue, (eventQueueTop+2)*sizeof(EventQueueEntry));
-    if (eventQueue == NULL) syserr("Out of memory in increaseEventQueue()");
+static void increaseEventQueue(void) {
+	eventQueue = (EventQueueEntry *)realloc(eventQueue, (eventQueueTop + 2) * sizeof(EventQueueEntry));
+	if (eventQueue == NULL) syserr("Out of memory in increaseEventQueue()");
 
-    eventQueueSize = eventQueueTop + 2;
+	eventQueueSize = eventQueueTop + 2;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void moveEvent(int to, int from) {
-    eventQueue[to].event = eventQueue[from].event;
-    eventQueue[to].after = eventQueue[from].after;
-    eventQueue[to].where = eventQueue[from].where;
+	eventQueue[to].event = eventQueue[from].event;
+	eventQueue[to].after = eventQueue[from].after;
+	eventQueue[to].where = eventQueue[from].where;
 }
 
 
 /*======================================================================*/
-void schedule(Aword event, Aword where, Aword after)
-{
-    uint i;
+void schedule(Aword event, Aword where, Aword after) {
+	uint i;
 
-    if (event == 0) syserr("NULL event");
+	if (event == 0) syserr("NULL event");
 
-    cancelEvent(event);
-    /* Check for overflow */
-    if (eventQueue == nullptr || eventQueueTop == eventQueueSize) {
-        increaseEventQueue();
+	cancelEvent(event);
+	/* Check for overflow */
+	if (eventQueue == nullptr || eventQueueTop == eventQueueSize) {
+		increaseEventQueue();
 		assert(eventQueue);
 	}
 
-    /* Bubble this event down */
-    for (i = eventQueueTop; i >= 1 && eventQueue[i-1].after <= (int)after; i--) {
-        moveEvent(i, i-1);
-    }
+	/* Bubble this event down */
+	for (i = eventQueueTop; i >= 1 && eventQueue[i - 1].after <= (int)after; i--) {
+		moveEvent(i, i - 1);
+	}
 
-    eventQueue[i].after = after;
-    eventQueue[i].where = where;
-    eventQueue[i].event = event;
-    eventQueueTop++;
+	eventQueue[i].after = after;
+	eventQueue[i].where = where;
+	eventQueue[i].event = event;
+	eventQueueTop++;
 }
 
 
 // TODO Move to string.c?
 /*======================================================================*/
-Aptr concat(Aptr as1, Aptr as2)
-{
-    char *s1 = (char *)fromAptr(as1);
-    char *s2 = (char *)fromAptr(as2);
-    char *result = (char *)allocate(strlen((char*)s1)+strlen((char*)s2)+1);
-    strcpy(result, s1);
-    strcat(result, s2);
-    return toAptr(result);
+Aptr concat(Aptr as1, Aptr as2) {
+	char *s1 = (char *)fromAptr(as1);
+	char *s2 = (char *)fromAptr(as2);
+	char *result = (char *)allocate(strlen((char *)s1) + strlen((char *)s2) + 1);
+	strcpy(result, s1);
+	strcat(result, s2);
+	return toAptr(result);
 }
 
 
 /*----------------------------------------------------------------------*/
-static char *stripCharsFromStringForwards(int count, char *initialString, char **theRest)
-{
-    int stripPosition;
-    char *strippedString;
-    char *rest;
-
-    if (count > (int)strlen(initialString))
-        stripPosition = strlen(initialString);
-    else
-        stripPosition = count;
-    rest = strdup(&initialString[stripPosition]);
-    strippedString = strdup(initialString);
-    strippedString[stripPosition] = '\0';
-    *theRest = rest;
-    return strippedString;
+static char *stripCharsFromStringForwards(int count, char *initialString, char **theRest) {
+	int stripPosition;
+	char *strippedString;
+	char *rest;
+
+	if (count > (int)strlen(initialString))
+		stripPosition = strlen(initialString);
+	else
+		stripPosition = count;
+	rest = strdup(&initialString[stripPosition]);
+	strippedString = strdup(initialString);
+	strippedString[stripPosition] = '\0';
+	*theRest = rest;
+	return strippedString;
 }
 
 /*----------------------------------------------------------------------*/
 static char *stripCharsFromStringBackwards(Aint count, char *initialString, char **theRest) {
-    int stripPosition;
-    char *strippedString;
-    char *rest;
+	int stripPosition;
+	char *strippedString;
+	char *rest;
 
-    if (count > (int)strlen(initialString))
-        stripPosition = 0;
-    else
-        stripPosition = strlen(initialString)-count;
-    strippedString = strdup(&initialString[stripPosition]);
-    rest = strdup(initialString);
-    rest[stripPosition] = '\0';
-    *theRest = rest;
-    return strippedString;
+	if (count > (int)strlen(initialString))
+		stripPosition = 0;
+	else
+		stripPosition = strlen(initialString) - count;
+	strippedString = strdup(&initialString[stripPosition]);
+	rest = strdup(initialString);
+	rest[stripPosition] = '\0';
+	*theRest = rest;
+	return strippedString;
 }
 
 
 /*----------------------------------------------------------------------*/
 static int countLeadingBlanks(char *string, int position) {
-    static char blanks[] = " ";
-    return strspn(&string[position], blanks);
+	static char blanks[] = " ";
+	return strspn(&string[position], blanks);
 }
 
 
 /*----------------------------------------------------------------------*/
-static int skipWordForwards(char *string, int position)
-{
-    char separators[] = " .,?";
+static int skipWordForwards(char *string, int position) {
+	char separators[] = " .,?";
 
-    uint i;
+	uint i;
 
-    for (i = position; i<=strlen(string) && strchr(separators, string[i]) == NULL; i++)
-        ;
-    return i;
+	for (i = position; i <= strlen(string) && strchr(separators, string[i]) == NULL; i++)
+		;
+	return i;
 }
 
 
 /*----------------------------------------------------------------------*/
 static char *stripWordsFromStringForwards(Aint count, char *initialString, char **theRest) {
-    int skippedChars;
-    int position = 0;
-    char *stripped;
-    int i;
-
-    for (i = count; i>0; i--) {
-        /* Ignore any initial blanks */
-        skippedChars = countLeadingBlanks(initialString, position);
-        position += skippedChars;
-        position = skipWordForwards(initialString, position);
-    }
+	int skippedChars;
+	int position = 0;
+	char *stripped;
+	int i;
+
+	for (i = count; i > 0; i--) {
+		/* Ignore any initial blanks */
+		skippedChars = countLeadingBlanks(initialString, position);
+		position += skippedChars;
+		position = skipWordForwards(initialString, position);
+	}
 
-    stripped = (char *)allocate(position+1);
-    strncpy(stripped, initialString, position);
-    stripped[position] = '\0';
+	stripped = (char *)allocate(position + 1);
+	strncpy(stripped, initialString, position);
+	stripped[position] = '\0';
 
-    skippedChars = countLeadingBlanks(initialString, position);
-    *theRest = strdup(&initialString[position+skippedChars]);
+	skippedChars = countLeadingBlanks(initialString, position);
+	*theRest = strdup(&initialString[position + skippedChars]);
 
-    return(stripped);
+	return (stripped);
 }
 
 
 /*----------------------------------------------------------------------*/
-static int skipWordBackwards(char *string, int position)
-{
-    char separators[] = " .,?";
-    int i;
+static int skipWordBackwards(char *string, int position) {
+	char separators[] = " .,?";
+	int i;
 
-    for (i = position; i>0 && strchr(separators, string[i-1]) == NULL; i--)
-        ;
-    return i;
+	for (i = position; i > 0 && strchr(separators, string[i - 1]) == NULL; i--)
+		;
+	return i;
 }
 
 
 /*----------------------------------------------------------------------*/
 static int countTrailingBlanks(char *string, int position) {
-    int skippedChars, i;
-    skippedChars = 0;
+	int skippedChars, i;
+	skippedChars = 0;
 
-    if (position > (int)strlen(string)-1)
-        syserr("position > length in countTrailingBlanks");
-    for (i = position; i >= 0 && string[i] == ' '; i--)
-        skippedChars++;
-    return(skippedChars);
+	if (position > (int)strlen(string) - 1)
+		syserr("position > length in countTrailingBlanks");
+	for (i = position; i >= 0 && string[i] == ' '; i--)
+		skippedChars++;
+	return (skippedChars);
 }
 
 
 /*----------------------------------------------------------------------*/
 static char *stripWordsFromStringBackwards(Aint count, char *initialString, char **theRest) {
-    int skippedChars;
-    char *stripped;
-    int strippedLength;
-    int position = strlen(initialString);
-    int i;
-
-    for (i = count; i>0 && position>0; i--) {
-        position -= 1;
-        /* Ignore trailing blanks */
-        skippedChars = countTrailingBlanks(initialString, position);
-        if (position - skippedChars < 0) break; /* No more words to strip */
-        position -= skippedChars;
-        position = skipWordBackwards(initialString, position);
-    }
-
-    skippedChars = countLeadingBlanks(initialString, 0);
-    strippedLength = strlen(initialString)-position-skippedChars;
-    stripped = (char *)allocate(strippedLength+1);
-    strncpy(stripped, &initialString[position+skippedChars], strippedLength);
-    stripped[strippedLength] = '\0';
-
-    if (position > 0) {
-        skippedChars = countTrailingBlanks(initialString, position-1);
-        position -= skippedChars;
-    }
-    *theRest = strdup(initialString);
-    (*theRest)[position] = '\0';
-    return(stripped);
+	int skippedChars;
+	char *stripped;
+	int strippedLength;
+	int position = strlen(initialString);
+	int i;
+
+	for (i = count; i > 0 && position > 0; i--) {
+		position -= 1;
+		/* Ignore trailing blanks */
+		skippedChars = countTrailingBlanks(initialString, position);
+		if (position - skippedChars < 0) break; /* No more words to strip */
+		position -= skippedChars;
+		position = skipWordBackwards(initialString, position);
+	}
+
+	skippedChars = countLeadingBlanks(initialString, 0);
+	strippedLength = strlen(initialString) - position - skippedChars;
+	stripped = (char *)allocate(strippedLength + 1);
+	strncpy(stripped, &initialString[position + skippedChars], strippedLength);
+	stripped[strippedLength] = '\0';
+
+	if (position > 0) {
+		skippedChars = countTrailingBlanks(initialString, position - 1);
+		position -= skippedChars;
+	}
+	*theRest = strdup(initialString);
+	(*theRest)[position] = '\0';
+	return (stripped);
 }
 
 
 
 /*======================================================================*/
-Aptr strip(bool stripFromBeginningNotEnd, int count, bool stripWordsNotChars, int id, int atr)
-{
-    char *initialString = (char *)fromAptr(getInstanceAttribute(id, atr));
-    char *theStripped;
-    char *theRest;
-
-    if (stripFromBeginningNotEnd) {
-        if (stripWordsNotChars)
-            theStripped = stripWordsFromStringForwards(count, initialString, &theRest);
-        else
-            theStripped = stripCharsFromStringForwards(count, initialString, &theRest);
-    } else {
-        if (stripWordsNotChars)
-            theStripped = stripWordsFromStringBackwards(count, initialString, &theRest);
-        else
-            theStripped = stripCharsFromStringBackwards(count, initialString, &theRest);
-    }
-    setInstanceStringAttribute(id, atr, theRest);
-    return toAptr(theStripped);
+Aptr strip(bool stripFromBeginningNotEnd, int count, bool stripWordsNotChars, int id, int atr) {
+	char *initialString = (char *)fromAptr(getInstanceAttribute(id, atr));
+	char *theStripped;
+	char *theRest;
+
+	if (stripFromBeginningNotEnd) {
+		if (stripWordsNotChars)
+			theStripped = stripWordsFromStringForwards(count, initialString, &theRest);
+		else
+			theStripped = stripCharsFromStringForwards(count, initialString, &theRest);
+	} else {
+		if (stripWordsNotChars)
+			theStripped = stripWordsFromStringBackwards(count, initialString, &theRest);
+		else
+			theStripped = stripCharsFromStringBackwards(count, initialString, &theRest);
+	}
+	setInstanceStringAttribute(id, atr, theRest);
+	return toAptr(theStripped);
 }
 
 
 /*======================================================================*/
 int getContainerMember(int container, int index, bool directly) {
-    uint i;
-    Aint count = 0;
-
-    for (i = 1; i <= header->instanceMax; i++) {
-        if (isIn(i, container, DIRECT)) {
-            count++;
-            if (count == index)
-                return i;
-        }
-    }
-    apperr("Index not in container in 'containerMember()'");
-    return 0;
+	uint i;
+	Aint count = 0;
+
+	for (i = 1; i <= header->instanceMax; i++) {
+		if (isIn(i, container, DIRECT)) {
+			count++;
+			if (count == index)
+				return i;
+		}
+	}
+	apperr("Index not in container in 'containerMember()'");
+	return 0;
 }
 
 
@@ -551,157 +546,149 @@ int getContainerMember(int container, int index, bool directly) {
 
 /*======================================================================*/
 void showImage(int image, int align) {
-    uint ecode;
+	uint ecode;
 
-    if ((g_vm->glk_gestalt(gestalt_Graphics, 0) == 1) &&
-        (g_vm->glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
+	if ((g_vm->glk_gestalt(gestalt_Graphics, 0) == 1) &&
+	        (g_vm->glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
 		g_vm->glk_window_flow_break(glkMainWin);
-        printf("\n");
-        ecode = g_vm->glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
-        (void)ecode;
-    }
+		printf("\n");
+		ecode = g_vm->glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
+		(void)ecode;
+	}
 }
 
 
 /*======================================================================*/
-void playSound(int sound)
-{
+void playSound(int sound) {
 #ifdef GLK_MODULE_SOUND
-    static schanid_t soundChannel = NULL;
+	static schanid_t soundChannel = NULL;
 
-    if (g_vm->glk_gestalt(gestalt_Sound, 0) == 1) {
-        if (soundChannel == NULL)
-            soundChannel = g_vm->glk_schannel_create(0);
-        if (soundChannel != NULL) {
+	if (g_vm->glk_gestalt(gestalt_Sound, 0) == 1) {
+		if (soundChannel == NULL)
+			soundChannel = g_vm->glk_schannel_create(0);
+		if (soundChannel != NULL) {
 			g_vm->glk_schannel_stop(soundChannel);
-            (void)g_vm->glk_schannel_play(soundChannel, sound);
-        }
-    }
+			(void)g_vm->glk_schannel_play(soundChannel, sound);
+		}
+	}
 #endif
 }
 
 
 /*======================================================================*/
-void empty(int cnt, int whr)
-{
-    uint i;
+void empty(int cnt, int whr) {
+	uint i;
 
-    for (i = 1; i <= header->instanceMax; i++)
-        if (isIn(i, cnt, DIRECT))
-            locate(i, whr);
+	for (i = 1; i <= header->instanceMax; i++)
+		if (isIn(i, cnt, DIRECT))
+			locate(i, whr);
 }
 
 
 
 /*======================================================================*/
-void use(int actor, int script)
-{
-    char str[80];
-    StepEntry *step;
+void use(int actor, int script) {
+	char str[80];
+	StepEntry *step;
 
-    if (!isAActor(actor)) {
-        sprintf(str, "Instance is not an Actor (%d).", actor);
-        syserr(str);
-    }
+	if (!isAActor(actor)) {
+		sprintf(str, "Instance is not an Actor (%d).", actor);
+		syserr(str);
+	}
 
-    admin[actor].script = script;
-    admin[actor].step = 0;
-    step = stepOf(actor);
-    if (step != NULL && step->after != 0) {
-        admin[actor].waitCount = evaluate(step->after);
-    }
+	admin[actor].script = script;
+	admin[actor].step = 0;
+	step = stepOf(actor);
+	if (step != NULL && step->after != 0) {
+		admin[actor].waitCount = evaluate(step->after);
+	}
 
-    gameStateChanged = TRUE;
+	gameStateChanged = TRUE;
 }
 
 /*======================================================================*/
-void stop(int act)
-{
-    char str[80];
+void stop(int act) {
+	char str[80];
 
-    if (!isAActor(act)) {
-        sprintf(str, "Instance is not an Actor (%d).", act);
-        syserr(str);
-    }
+	if (!isAActor(act)) {
+		sprintf(str, "Instance is not an Actor (%d).", act);
+		syserr(str);
+	}
 
-    admin[act].script = 0;
-    admin[act].step = 0;
+	admin[act].script = 0;
+	admin[act].step = 0;
 
-    gameStateChanged = TRUE;
+	gameStateChanged = TRUE;
 }
 
 
 
 static int randomValue = 0;
 /*----------------------------------------------------------------------*/
-int randomInteger(int from, int to)
-{
-    if (regressionTestOption) {
-        int ret = from + randomValue;
-        /* Generate them in sequence */
-        if (ret > to) {
-            ret = from;
-            randomValue = 1;
-        } else if (ret == to)
-            randomValue = 0;
-        else
-            randomValue++;
-        return ret;
-    } else {
-        if (to == from)
-            return to;
-        else if (to > from)
-            return (rand()/10)%(to-from+1)+from;
-        else
-            return (rand()/10)%(from-to+1)+to;
-    }
+int randomInteger(int from, int to) {
+	if (regressionTestOption) {
+		int ret = from + randomValue;
+		/* Generate them in sequence */
+		if (ret > to) {
+			ret = from;
+			randomValue = 1;
+		} else if (ret == to)
+			randomValue = 0;
+		else
+			randomValue++;
+		return ret;
+	} else {
+		if (to == from)
+			return to;
+		else if (to > from)
+			return (rand() / 10) % (to - from + 1) + from;
+		else
+			return (rand() / 10) % (from - to + 1) + to;
+	}
 }
 
 
 
 /*----------------------------------------------------------------------*/
-bool between(int val, int low, int high)
-{
-    if (high > low)
-        return low <= val && val <= high;
-    else
-        return high <= val && val <= low;
+bool between(int val, int low, int high) {
+	if (high > low)
+		return low <= val && val <= high;
+	else
+		return high <= val && val <= low;
 }
 
 
 
 /*======================================================================*/
-bool contains(Aptr string, Aptr substring)
-{
-    bool found;
+bool contains(Aptr string, Aptr substring) {
+	bool found;
 
-    strlow((char *)fromAptr(string));
-    strlow((char *)fromAptr(substring));
+	strlow((char *)fromAptr(string));
+	strlow((char *)fromAptr(substring));
 
-    found = (strstr((char *)fromAptr(string), (char *)fromAptr(substring)) != 0);
+	found = (strstr((char *)fromAptr(string), (char *)fromAptr(substring)) != 0);
 
-    return found;
+	return found;
 }
 
 
 /*======================================================================*/
-bool streq(char a[], char b[])
-{
-    bool eq;
+bool streq(char a[], char b[]) {
+	bool eq;
 
-    strlow(a);
-    strlow(b);
+	strlow(a);
+	strlow(b);
 
-    eq = (strcmp(a, b) == 0);
+	eq = (strcmp(a, b) == 0);
 
-    return eq;
+	return eq;
 }
 
 
 
 /*======================================================================*/
 void startTranscript(void) {
-    if (logFile == NULL) {
+	if (logFile == NULL) {
 		Common::String filename = g_vm->getTargetName() + ".log";
 
 		uint fileUsage = transcriptOption ? fileusage_Transcript : fileusage_InputRecord;
@@ -721,7 +708,7 @@ void startTranscript(void) {
 /*======================================================================*/
 void stopTranscript(void) {
 	if (logFile != NULL) {
-		if (transcriptOption|| logOption)
+		if (transcriptOption || logOption)
 			delete logFile;
 
 		logFile = NULL;
diff --git a/engines/glk/alan3/fnmatch.cpp b/engines/glk/alan3/fnmatch.cpp
index 203a7bf..9705672 100644
--- a/engines/glk/alan3/fnmatch.cpp
+++ b/engines/glk/alan3/fnmatch.cpp
@@ -71,163 +71,162 @@ namespace Alan3 {
 static int rangematch(const char *, char, int, char **);
 
 int fnmatch(const char *pattern, const char *string, int flags) {
-        const char *stringstart;
-        char *newp;
-        char c, test;
-
-        for (stringstart = string;;)
-                switch (c = *pattern++) {
-                case EOS:
-                        if ((flags & FNM_LEADING_DIR) && *string == '/')
-                                return (0);
-                        return (*string == EOS ? 0 : FNM_NOMATCH);
-                case '?':
-                        if (*string == EOS)
-                                return (FNM_NOMATCH);
-                        if (*string == '/' && (flags & FNM_PATHNAME))
-                                return (FNM_NOMATCH);
-                        if (*string == '.' && (flags & FNM_PERIOD) &&
-                            (string == stringstart ||
-                            ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
-                                return (FNM_NOMATCH);
-                        ++string;
-                        break;
-                case '*':
-                        c = *pattern;
-                        /* Collapse multiple stars. */
-                        while (c == '*')
-                                c = *++pattern;
-
-                        if (*string == '.' && (flags & FNM_PERIOD) &&
-                            (string == stringstart ||
-                            ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
-                                return (FNM_NOMATCH);
-
-                        /* Optimize for pattern with * at end or before /. */
-                        if (c == EOS)
-                                if (flags & FNM_PATHNAME)
-                                        return ((flags & FNM_LEADING_DIR) ||
-                                            strchr(string, '/') == NULL ?
-                                            0 : FNM_NOMATCH);
-                                else
-                                        return (0);
-                        else if (c == '/' && flags & FNM_PATHNAME) {
-                                if ((string = strchr(string, '/')) == NULL)
-                                        return (FNM_NOMATCH);
-                                break;
-                        }
-
-                        /* General case, use recursion. */
-                        while ((test = *string) != EOS) {
-                                if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
-                                        return (0);
-                                if (test == '/' && flags & FNM_PATHNAME)
-                                        break;
-                                ++string;
-                        }
-                        return (FNM_NOMATCH);
-                case '[':
-                        if (*string == EOS)
-                                return (FNM_NOMATCH);
-                        if (*string == '/' && (flags & FNM_PATHNAME))
-                                return (FNM_NOMATCH);
-                        if (*string == '.' && (flags & FNM_PERIOD) &&
-                            (string == stringstart ||
-                            ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
-                                return (FNM_NOMATCH);
-
-                        switch (rangematch(pattern, *string, flags, &newp)) {
-                        case RANGE_ERROR:
-                                goto norm;
-                        case RANGE_MATCH:
-                                pattern = newp;
-                                break;
-                        case RANGE_NOMATCH:
-                                return (FNM_NOMATCH);
-                        }
-                        ++string;
-                        break;
-                case '\\':
-                        if (!(flags & FNM_NOESCAPE)) {
-                                if ((c = *pattern++) == EOS) {
-                                        c = '\\';
-                                        --pattern;
-                                }
-                        }
-                        /* FALLTHROUGH */
-                default:
-                norm:
-                        if (c == *string)
-                                ;
-                        else if ((flags & FNM_CASEFOLD) &&
-                                 (tolower((unsigned char)c) ==
-                                  tolower((unsigned char)*string)))
-                                ;
-                        else
-                                return (FNM_NOMATCH);
-                        string++;
-                        break;
-                }
-        /* NOTREACHED */
+	const char *stringstart;
+	char *newp;
+	char c, test;
+
+	for (stringstart = string;;)
+		switch (c = *pattern++) {
+		case EOS:
+			if ((flags & FNM_LEADING_DIR) && *string == '/')
+				return (0);
+			return (*string == EOS ? 0 : FNM_NOMATCH);
+		case '?':
+			if (*string == EOS)
+				return (FNM_NOMATCH);
+			if (*string == '/' && (flags & FNM_PATHNAME))
+				return (FNM_NOMATCH);
+			if (*string == '.' && (flags & FNM_PERIOD) &&
+			        (string == stringstart ||
+			         ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+				return (FNM_NOMATCH);
+			++string;
+			break;
+		case '*':
+			c = *pattern;
+			/* Collapse multiple stars. */
+			while (c == '*')
+				c = *++pattern;
+
+			if (*string == '.' && (flags & FNM_PERIOD) &&
+			        (string == stringstart ||
+			         ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+				return (FNM_NOMATCH);
+
+			/* Optimize for pattern with * at end or before /. */
+			if (c == EOS)
+				if (flags & FNM_PATHNAME)
+					return ((flags & FNM_LEADING_DIR) ||
+					        strchr(string, '/') == NULL ?
+					        0 : FNM_NOMATCH);
+				else
+					return (0);
+			else if (c == '/' && flags & FNM_PATHNAME) {
+				if ((string = strchr(string, '/')) == NULL)
+					return (FNM_NOMATCH);
+				break;
+			}
+
+			/* General case, use recursion. */
+			while ((test = *string) != EOS) {
+				if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
+					return (0);
+				if (test == '/' && flags & FNM_PATHNAME)
+					break;
+				++string;
+			}
+			return (FNM_NOMATCH);
+		case '[':
+			if (*string == EOS)
+				return (FNM_NOMATCH);
+			if (*string == '/' && (flags & FNM_PATHNAME))
+				return (FNM_NOMATCH);
+			if (*string == '.' && (flags & FNM_PERIOD) &&
+			        (string == stringstart ||
+			         ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+				return (FNM_NOMATCH);
+
+			switch (rangematch(pattern, *string, flags, &newp)) {
+			case RANGE_ERROR:
+				goto norm;
+			case RANGE_MATCH:
+				pattern = newp;
+				break;
+			case RANGE_NOMATCH:
+				return (FNM_NOMATCH);
+			}
+			++string;
+			break;
+		case '\\':
+			if (!(flags & FNM_NOESCAPE)) {
+				if ((c = *pattern++) == EOS) {
+					c = '\\';
+					--pattern;
+				}
+			}
+		/* FALLTHROUGH */
+		default:
+norm:
+			if (c == *string)
+				;
+			else if ((flags & FNM_CASEFOLD) &&
+			         (tolower((unsigned char)c) ==
+			          tolower((unsigned char)*string)))
+				;
+			else
+				return (FNM_NOMATCH);
+			string++;
+			break;
+		}
+	/* NOTREACHED */
 }
 
 static int
-rangematch(const char *pattern, char test, int flags, char **newp)
-{
-        int negate, ok;
-        char c, c2;
-
-        /*
-         * A bracket expression starting with an unquoted circumflex
-         * character produces unspecified results (IEEE 1003.2-1992,
-         * 3.13.2).  This implementation treats it like '!', for
-         * consistency with the regular expression syntax.
-         * J.T. Conklin (conklin at ngai.kaleida.com)
-         */
-        if ( (negate = (*pattern == '!' || *pattern == '^')) )
-                ++pattern;
-
-        if (flags & FNM_CASEFOLD)
-                test = tolower((unsigned char)test);
-
-        /*
-         * A right bracket shall lose its special meaning and represent
-         * itself in a bracket expression if it occurs first in the list.
-         * -- POSIX.2 2.8.3.2
-         */
-        ok = 0;
-        c = *pattern++;
-        do {
-                if (c == '\\' && !(flags & FNM_NOESCAPE))
-                        c = *pattern++;
-                if (c == EOS)
-                        return (RANGE_ERROR);
-
-                if (c == '/' && (flags & FNM_PATHNAME))
-                        return (RANGE_NOMATCH);
-
-                if (flags & FNM_CASEFOLD)
-                        c = tolower((unsigned char)c);
-
-                if (*pattern == '-'
-                    && (c2 = *(pattern+1)) != EOS && c2 != ']') {
-                        pattern += 2;
-                        if (c2 == '\\' && !(flags & FNM_NOESCAPE))
-                                c2 = *pattern++;
-                        if (c2 == EOS)
-                                return (RANGE_ERROR);
-
-                        if (flags & FNM_CASEFOLD)
-                                c2 = tolower((unsigned char)c2);
-
-                        if (c <= test && test <= c2)
-                                ok = 1;
-                } else if (c == test)
-                        ok = 1;
-        } while ((c = *pattern++) != ']');
-
-        *newp = const_cast<char *>(pattern);
-        return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
+rangematch(const char *pattern, char test, int flags, char **newp) {
+	int negate, ok;
+	char c, c2;
+
+	/*
+	 * A bracket expression starting with an unquoted circumflex
+	 * character produces unspecified results (IEEE 1003.2-1992,
+	 * 3.13.2).  This implementation treats it like '!', for
+	 * consistency with the regular expression syntax.
+	 * J.T. Conklin (conklin at ngai.kaleida.com)
+	 */
+	if ((negate = (*pattern == '!' || *pattern == '^')))
+		++pattern;
+
+	if (flags & FNM_CASEFOLD)
+		test = tolower((unsigned char)test);
+
+	/*
+	 * A right bracket shall lose its special meaning and represent
+	 * itself in a bracket expression if it occurs first in the list.
+	 * -- POSIX.2 2.8.3.2
+	 */
+	ok = 0;
+	c = *pattern++;
+	do {
+		if (c == '\\' && !(flags & FNM_NOESCAPE))
+			c = *pattern++;
+		if (c == EOS)
+			return (RANGE_ERROR);
+
+		if (c == '/' && (flags & FNM_PATHNAME))
+			return (RANGE_NOMATCH);
+
+		if (flags & FNM_CASEFOLD)
+			c = tolower((unsigned char)c);
+
+		if (*pattern == '-'
+		        && (c2 = *(pattern + 1)) != EOS && c2 != ']') {
+			pattern += 2;
+			if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+				c2 = *pattern++;
+			if (c2 == EOS)
+				return (RANGE_ERROR);
+
+			if (flags & FNM_CASEFOLD)
+				c2 = tolower((unsigned char)c2);
+
+			if (c <= test && test <= c2)
+				ok = 1;
+		} else if (c == test)
+			ok = 1;
+	} while ((c = *pattern++) != ']');
+
+	*newp = const_cast<char *>(pattern);
+	return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/glkstart.cpp b/engines/glk/alan3/glkstart.cpp
index d4f7dcb..f5f91a5 100644
--- a/engines/glk/alan3/glkstart.cpp
+++ b/engines/glk/alan3/glkstart.cpp
@@ -34,15 +34,15 @@ namespace Glk {
 namespace Alan3 {
 
 const glkunix_argumentlist_t glkunix_arguments[] = {
-    { "-l", glkunix_arg_NoValue, "-l: log player command and game output" },
-    { "-c", glkunix_arg_NoValue, "-c: log player commands to a file" },
-    { "-n", glkunix_arg_NoValue, "-n: no status line" },
-    { "-i", glkunix_arg_NoValue, "-i: ignore version and checksum errors" },
-    { "-d", glkunix_arg_NoValue, "-d: enter debug mode" },
-    { "-t", glkunix_arg_NoValue, "-t [<n>]: trace game execution, higher <n> gives more trace" },
-    { "-r", glkunix_arg_NoValue, "-r: refrain from printing timestamps and paging (making regression testing easier)" },
-    { "", glkunix_arg_ValueFollows, "filename: The game file to load." },
-    { NULL, glkunix_arg_End, NULL }
+	{ "-l", glkunix_arg_NoValue, "-l: log player command and game output" },
+	{ "-c", glkunix_arg_NoValue, "-c: log player commands to a file" },
+	{ "-n", glkunix_arg_NoValue, "-n: no status line" },
+	{ "-i", glkunix_arg_NoValue, "-i: ignore version and checksum errors" },
+	{ "-d", glkunix_arg_NoValue, "-d: enter debug mode" },
+	{ "-t", glkunix_arg_NoValue, "-t [<n>]: trace game execution, higher <n> gives more trace" },
+	{ "-r", glkunix_arg_NoValue, "-r: refrain from printing timestamps and paging (making regression testing easier)" },
+	{ "", glkunix_arg_ValueFollows, "filename: The game file to load." },
+	{ NULL, glkunix_arg_End, NULL }
 };
 
 /* Resources */
@@ -50,14 +50,14 @@ static strid_t resourceFile;
 
 /*----------------------------------------------------------------------*/
 static void openGlkWindows() {
-    glkMainWin = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
-    if (glkMainWin == NULL) {
-            printf("FATAL ERROR: Cannot open initial window");
-			g_vm->glk_exit();
-    }
-
-    glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
-                                   winmethod_Fixed, 1, wintype_TextGrid, 0);
+	glkMainWin = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
+	if (glkMainWin == NULL) {
+		printf("FATAL ERROR: Cannot open initial window");
+		g_vm->glk_exit();
+	}
+
+	glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
+	                                     winmethod_Fixed, 1, wintype_TextGrid, 0);
 	g_vm->glk_set_window(glkStatusWin);
 	g_vm->glk_set_style(style_Preformatted);
 	g_vm->glk_set_window(glkMainWin);
@@ -66,49 +66,49 @@ static void openGlkWindows() {
 /*----------------------------------------------------------------------*/
 static void openResourceFile() {
 #ifdef TODO
-    char *originalFileName = strdup(adventureFileName);
+	char *originalFileName = strdup(adventureFileName);
 	char *resourceFileName = originalFileName;
-    char *extension = strrchr(resourceFileName, '.');
-    frefid_t resourceFileRef;
+	char *extension = strrchr(resourceFileName, '.');
+	frefid_t resourceFileRef;
 //    giblorb_err_t ecode;
 
-    strcpy(extension, ".a3r");
+	strcpy(extension, ".a3r");
 
-    resourceFileRef = winglk_fileref_create_by_name(fileusage_BinaryMode,
-                                                    resourceFileName, 0, FALSE);
+	resourceFileRef = winglk_fileref_create_by_name(fileusage_BinaryMode,
+	                  resourceFileName, 0, FALSE);
 
 	if (glk_fileref_does_file_exist(resourceFileRef)) {
-        resourceFile = glk_stream_open_file(resourceFileRef, filemode_Read, 0);
-        ecode = giblorb_set_resource_map(resourceFile);
-        (void)ecode;
-    }
-    free(originalFileName);
+		resourceFile = glk_stream_open_file(resourceFileRef, filemode_Read, 0);
+		ecode = giblorb_set_resource_map(resourceFile);
+		(void)ecode;
+	}
+	free(originalFileName);
 #endif
 }
 
 
 /*======================================================================*/
 int glkunix_startup_code(glkunix_startup_t *data) {
-    g_vm->glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Weight, 0);
+	g_vm->glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Weight, 0);
 	g_vm->glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Oblique, 1);
 	g_vm->glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Indentation, 10);
 
-    /* first, open a window for error output */
-    openGlkWindows();
+	/* first, open a window for error output */
+	openGlkWindows();
 
-    /* now process the command line arguments */
-    //args(data->argc, data->argv);
+	/* now process the command line arguments */
+	//args(data->argc, data->argv);
 
-    if (adventureFileName == NULL || strcmp(adventureFileName, "") == 0) {
-        printf("You should supply a game file to play.\n");
-        usage("arun"); // TODO Find real programname from arguments
-        terminate(1);
-    }
+	if (adventureFileName == NULL || strcmp(adventureFileName, "") == 0) {
+		printf("You should supply a game file to play.\n");
+		usage("arun"); // TODO Find real programname from arguments
+		terminate(1);
+	}
 
-    /* Open any possible blorb resource file */
-    openResourceFile();
+	/* Open any possible blorb resource file */
+	openResourceFile();
 
-    return TRUE;
+	return TRUE;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/glkstart.h b/engines/glk/alan3/glkstart.h
index 2bc2e9c..0d91732 100644
--- a/engines/glk/alan3/glkstart.h
+++ b/engines/glk/alan3/glkstart.h
@@ -33,7 +33,7 @@
     with the various Unix Glk libraries -- at least, the three I wrote.
     (I encourage anyone writing a Unix Glk library to use this interface,
     but it's not part of the Glk spec.)
-    
+
     Because Glk is *almost* perfectly portable, this interface *almost*
     doesn't have to exist. In practice, it's small.
 */
@@ -60,14 +60,14 @@ namespace Alan3 {
 #define glkunix_arg_NumberValue (4)
 
 struct glkunix_argumentlist_t {
-    const char *name;
-    int argtype;
+	const char *name;
+	int argtype;
 	const char *desc;
 };
 
 struct glkunix_startup_t {
-    int argc;
-    char **argv;
+	int argc;
+	char **argv;
 };
 
 /* The list of command-line arguments; this should be defined in your code. */
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index d2670f3..89e3659 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -55,320 +55,300 @@ AttributeEntry *attributes; /* Dynamic attribute values */
 /* Instance query methods */
 
 /*======================================================================*/
-bool isA(int instance, int ancestor)
-{
-    int parent;
+bool isA(int instance, int ancestor) {
+	int parent;
 
-    if (isLiteral(instance))
-        parent = literals[instance-header->instanceMax]._class;
-    else
-        parent = instances[instance].parent;
-    while (parent != 0 && parent != ancestor)
-        parent = classes[parent].parent;
+	if (isLiteral(instance))
+		parent = literals[instance - header->instanceMax]._class;
+	else
+		parent = instances[instance].parent;
+	while (parent != 0 && parent != ancestor)
+		parent = classes[parent].parent;
 
-    return (parent != 0);
+	return (parent != 0);
 }
 
 
-bool isAObject(int instance)
-{
-  return isA(instance, OBJECT);
+bool isAObject(int instance) {
+	return isA(instance, OBJECT);
 }
 
-bool isAContainer(int instance)
-{
-    return instance != 0 && !isLiteral(instance) && instances[instance].container != 0;
+bool isAContainer(int instance) {
+	return instance != 0 && !isLiteral(instance) && instances[instance].container != 0;
 }
 
-bool isAActor(int instance)
-{
-  return isA(instance, ACTOR);
+bool isAActor(int instance) {
+	return isA(instance, ACTOR);
 }
 
-bool isALocation(int instance)
-{
-  return isA(instance, LOCATION);
+bool isALocation(int instance) {
+	return isA(instance, LOCATION);
 }
 
 
-bool isLiteral(int instance)
-{
-  return instance > (int)header->instanceMax;
+bool isLiteral(int instance) {
+	return instance > (int)header->instanceMax;
 }
 
-bool isANumeric(int instance)
-{
-  return isLiteral(instance) && literals[literalFromInstance(instance)].type == NUMERIC_LITERAL;
+bool isANumeric(int instance) {
+	return isLiteral(instance) && literals[literalFromInstance(instance)].type == NUMERIC_LITERAL;
 }
 
-bool isAString(int instance)
-{
-  return isLiteral(instance) && literals[literalFromInstance(instance)].type == STRING_LITERAL;
+bool isAString(int instance) {
+	return isLiteral(instance) && literals[literalFromInstance(instance)].type == STRING_LITERAL;
 }
 
 
 /*======================================================================*/
 bool isOpaque(int container) {
-    return getInstanceAttribute(container, OPAQUEATTRIBUTE);
+	return getInstanceAttribute(container, OPAQUEATTRIBUTE);
 }
 
 
 /*======================================================================*/
-void setInstanceAttribute(int instance, int attribute, Aptr value)
-{
-    char str[80];
+void setInstanceAttribute(int instance, int attribute, Aptr value) {
+	char str[80];
 
-    if (instance > 0 && instance <= (int)header->instanceMax) {
-        setAttribute(admin[instance].attributes, attribute, value);
-        if (isALocation(instance) && attribute != VISITSATTRIBUTE)
-            /* If it wasn't the VISITSATTRIBUTE the location may have
-               changed so describe next time */
-            admin[instance].visitsCount = 0;
-    } else {
-        sprintf(str, "Can't SET/MAKE instance (%d).", instance);
-        syserr(str);
-    }
+	if (instance > 0 && instance <= (int)header->instanceMax) {
+		setAttribute(admin[instance].attributes, attribute, value);
+		if (isALocation(instance) && attribute != VISITSATTRIBUTE)
+			/* If it wasn't the VISITSATTRIBUTE the location may have
+			   changed so describe next time */
+			admin[instance].visitsCount = 0;
+	} else {
+		sprintf(str, "Can't SET/MAKE instance (%d).", instance);
+		syserr(str);
+	}
 }
 
 
 /*======================================================================*/
-void setInstanceStringAttribute(int instance, int attribute, char *string)
-{
-    deallocate(fromAptr(getInstanceAttribute(instance, attribute)));
-    setInstanceAttribute(instance, attribute, toAptr(string));
+void setInstanceStringAttribute(int instance, int attribute, char *string) {
+	deallocate(fromAptr(getInstanceAttribute(instance, attribute)));
+	setInstanceAttribute(instance, attribute, toAptr(string));
 }
 
 
 /*======================================================================*/
-void setInstanceSetAttribute(int instance, int attribute, Aptr set)
-{
-    freeSet((Set *)fromAptr(getInstanceAttribute(instance, attribute)));
-    setInstanceAttribute(instance, attribute, set);
+void setInstanceSetAttribute(int instance, int attribute, Aptr set) {
+	freeSet((Set *)fromAptr(getInstanceAttribute(instance, attribute)));
+	setInstanceAttribute(instance, attribute, set);
 }
 
 
 /*----------------------------------------------------------------------*/
-static Aptr literalAttribute(int literal, int attribute)
-{
-    if (isPreBeta3(header->version)) {
-        if (attribute == 1)
-            return literals[literalFromInstance(literal)].value;
-        else
-            return 0;
-    } else {
-        if (attribute == 0)
-            return literals[literalFromInstance(literal)].value;
-        else
-            return getAttribute(admin[header->instanceMax].attributes, attribute);
-    }
-    return(EOD);
+static Aptr literalAttribute(int literal, int attribute) {
+	if (isPreBeta3(header->version)) {
+		if (attribute == 1)
+			return literals[literalFromInstance(literal)].value;
+		else
+			return 0;
+	} else {
+		if (attribute == 0)
+			return literals[literalFromInstance(literal)].value;
+		else
+			return getAttribute(admin[header->instanceMax].attributes, attribute);
+	}
+	return (EOD);
 }
 
 
 /*======================================================================*/
-Aptr getInstanceAttribute(int instance, int attribute)
-{
-    char str[80];
-
-    if (isLiteral(instance))
-        return literalAttribute(instance, attribute);
-    else {
-        if (instance > 0 && instance <= (int)header->instanceMax) {
-            if (attribute == -1)
-                return locationOf(instance);
-            else
-                return getAttribute(admin[instance].attributes, attribute);
-        } else {
-            sprintf(str, "Can't ATTRIBUTE item (%d).", instance);
-            syserr(str);
-        }
-    }
-    return(EOD);
+Aptr getInstanceAttribute(int instance, int attribute) {
+	char str[80];
+
+	if (isLiteral(instance))
+		return literalAttribute(instance, attribute);
+	else {
+		if (instance > 0 && instance <= (int)header->instanceMax) {
+			if (attribute == -1)
+				return locationOf(instance);
+			else
+				return getAttribute(admin[instance].attributes, attribute);
+		} else {
+			sprintf(str, "Can't ATTRIBUTE item (%d).", instance);
+			syserr(str);
+		}
+	}
+	return (EOD);
 }
 
 
 /*======================================================================*/
-char *getInstanceStringAttribute(int instance, int attribute)
-{
-    return strdup((char *)fromAptr(getInstanceAttribute(instance, attribute)));
+char *getInstanceStringAttribute(int instance, int attribute) {
+	return strdup((char *)fromAptr(getInstanceAttribute(instance, attribute)));
 }
 
 
 /*======================================================================*/
-Set *getInstanceSetAttribute(int instance, int attribute)
-{
-    return copySet((Set *)fromAptr(getInstanceAttribute(instance, attribute)));
+Set *getInstanceSetAttribute(int instance, int attribute) {
+	return copySet((Set *)fromAptr(getInstanceAttribute(instance, attribute)));
 }
 
 
 /*----------------------------------------------------------------------*/
 static void verifyInstance(int instance, const char *action) {
-    char message[200];
+	char message[200];
 
-    if (instance == 0) {
-        sprintf(message, "Can't %s instance (%d).", action, instance);
-        syserr(message);
-    } else if (instance > (int)header->instanceMax) {
-        sprintf(message, "Can't %s instance (%d > instanceMax).", action, instance);
-        syserr(message);
-    }
+	if (instance == 0) {
+		sprintf(message, "Can't %s instance (%d).", action, instance);
+		syserr(message);
+	} else if (instance > (int)header->instanceMax) {
+		sprintf(message, "Can't %s instance (%d > instanceMax).", action, instance);
+		syserr(message);
+	}
 }
 
 
 /*======================================================================*/
-bool isHere(int id, ATrans transitivity)
-{
-    verifyInstance(id, "HERE");
+bool isHere(int id, ATrans transitivity) {
+	verifyInstance(id, "HERE");
 
-    return isAt(id, current.location, transitivity);
+	return isAt(id, current.location, transitivity);
 }
 
 
 /*======================================================================*/
-bool isNearby(int instance, ATrans transitivity)
-{
-    verifyInstance(instance, "NEARBY");
+bool isNearby(int instance, ATrans transitivity) {
+	verifyInstance(instance, "NEARBY");
 
-    if (isALocation(instance))
-        return exitto(current.location, instance);
-    else
-        return exitto(current.location, where(instance, transitivity));
+	if (isALocation(instance))
+		return exitto(current.location, instance);
+	else
+		return exitto(current.location, where(instance, transitivity));
 }
 
 
 /*======================================================================*/
-bool isNear(int instance, int other, ATrans trans)
-{
-    Aint l1, l2;
+bool isNear(int instance, int other, ATrans trans) {
+	Aint l1, l2;
 
-    verifyInstance(instance, "NEAR");
+	verifyInstance(instance, "NEAR");
 
-    if (isALocation(instance))
-        l1 = instance;
-    else
-        l1 = where(instance, trans);
-    if (isALocation(other))
-        l2 = other;
-    else
-        l2 = where(other, trans);
-    return exitto(l2, l1);
+	if (isALocation(instance))
+		l1 = instance;
+	else
+		l1 = where(instance, trans);
+	if (isALocation(other))
+		l2 = other;
+	else
+		l2 = where(other, trans);
+	return exitto(l2, l1);
 }
 
 
 /*======================================================================*/
 /* Look in a container to see if the instance is in it. */
-bool isIn(int instance, int container, ATrans trans)
-{
-    int loc;
+bool isIn(int instance, int container, ATrans trans) {
+	int loc;
 
-    if (!isAContainer(container))
-        syserr("IN in a non-container.");
+	if (!isAContainer(container))
+		syserr("IN in a non-container.");
 
-    if (trans == DIRECT)
-        return admin[instance].location == container;
-    else {
-        loc = admin[instance].location;
-        if (trans == INDIRECT && loc != 0 && !isA(loc, LOCATION))
-            loc = admin[loc].location;
-        while (loc != 0 && !isA(loc, LOCATION))
-            if (loc == container)
-                return TRUE;
-            else
-                loc = admin[loc].location;
-        return FALSE;
-    }
+	if (trans == DIRECT)
+		return admin[instance].location == container;
+	else {
+		loc = admin[instance].location;
+		if (trans == INDIRECT && loc != 0 && !isA(loc, LOCATION))
+			loc = admin[loc].location;
+		while (loc != 0 && !isA(loc, LOCATION))
+			if (loc == container)
+				return TRUE;
+			else
+				loc = admin[loc].location;
+		return FALSE;
+	}
 }
 
 
 
 /*======================================================================*/
 /* Look see if an instance is AT another. */
-bool isAt(int instance, int other, ATrans trans)
-{
-    if (instance == 0 || other == 0) return FALSE;
-
-    if (isALocation(instance)) {
-        /* Nested locations */
-        /* TODO - What if the other is not a location? */
-        int curr = admin[instance].location;
-        switch (trans) {
-        case DIRECT:
-            return admin[instance].location == other;
-        case INDIRECT:
-            if (curr == other)
-                return FALSE;
-            curr = admin[curr].location;
-        case TRANSITIVE:
-            while (curr != 0) {
-                if (curr == other)
-                    return TRUE;
-                else
-                    curr = admin[curr].location;
-            }
-            return FALSE;
-        }
-        syserr("Unexpected value in switch in isAt() for location");
-        return FALSE;
-    } else if (isALocation(other)) {
-        /* Instance is not a location but other is */
-        switch (trans) {
-        case DIRECT:
-            return admin[instance].location == other;
-        case INDIRECT: {
-            if (admin[instance].location == other)
-                return FALSE;   /* Directly, so not Indirectly */
-            /* Fall through to transitive handling of the location */
-        }
-        case TRANSITIVE: {
-            int location = locationOf(instance);
-            int curr = other;
-            while (curr != 0) {
-                if (curr == location)
-                    return TRUE;
-                else
-                    curr = admin[curr].location;
-            }
-            return FALSE;
-        }
-        }
-        syserr("Unexpected value in switch in isAt() for non-location");
-        return FALSE;
-    } else {
-        /* Other is also not a location */
-        switch (trans) {
-        case DIRECT:
-            return positionOf(instance) == admin[other].location;
-        case INDIRECT: {
-            int location = locationOf(instance);
-            int curr = other;
-            if (location == curr)
-                return FALSE;
-            else
-                curr = admin[curr].location;
-            while (curr != 0) {
-                if (curr == location)
-                    return TRUE;
-                else
-                    curr = admin[curr].location;
-            }
-            return FALSE;
-        }
-        case TRANSITIVE: {
-            int location = locationOf(other);
-            int curr = locationOf(instance);
-            bool ok = FALSE;
-            while (curr != 0 && !ok) {
-                if (curr == location)
-                    ok = TRUE;
-                else
-                    curr = admin[curr].location;
-            }
-            return ok;
-        }
-        }
-        syserr("Unexpected value in switch in isAt() for non-location");
-        return FALSE;
-    }
+bool isAt(int instance, int other, ATrans trans) {
+	if (instance == 0 || other == 0) return FALSE;
+
+	if (isALocation(instance)) {
+		/* Nested locations */
+		/* TODO - What if the other is not a location? */
+		int curr = admin[instance].location;
+		switch (trans) {
+		case DIRECT:
+			return admin[instance].location == other;
+		case INDIRECT:
+			if (curr == other)
+				return FALSE;
+			curr = admin[curr].location;
+		case TRANSITIVE:
+			while (curr != 0) {
+				if (curr == other)
+					return TRUE;
+				else
+					curr = admin[curr].location;
+			}
+			return FALSE;
+		}
+		syserr("Unexpected value in switch in isAt() for location");
+		return FALSE;
+	} else if (isALocation(other)) {
+		/* Instance is not a location but other is */
+		switch (trans) {
+		case DIRECT:
+			return admin[instance].location == other;
+		case INDIRECT: {
+			if (admin[instance].location == other)
+				return FALSE;   /* Directly, so not Indirectly */
+			/* Fall through to transitive handling of the location */
+		}
+		case TRANSITIVE: {
+			int location = locationOf(instance);
+			int curr = other;
+			while (curr != 0) {
+				if (curr == location)
+					return TRUE;
+				else
+					curr = admin[curr].location;
+			}
+			return FALSE;
+		}
+		}
+		syserr("Unexpected value in switch in isAt() for non-location");
+		return FALSE;
+	} else {
+		/* Other is also not a location */
+		switch (trans) {
+		case DIRECT:
+			return positionOf(instance) == admin[other].location;
+		case INDIRECT: {
+			int location = locationOf(instance);
+			int curr = other;
+			if (location == curr)
+				return FALSE;
+			else
+				curr = admin[curr].location;
+			while (curr != 0) {
+				if (curr == location)
+					return TRUE;
+				else
+					curr = admin[curr].location;
+			}
+			return FALSE;
+		}
+		case TRANSITIVE: {
+			int location = locationOf(other);
+			int curr = locationOf(instance);
+			bool ok = FALSE;
+			while (curr != 0 && !ok) {
+				if (curr == location)
+					ok = TRUE;
+				else
+					curr = admin[curr].location;
+			}
+			return ok;
+		}
+		}
+		syserr("Unexpected value in switch in isAt() for non-location");
+		return FALSE;
+	}
 }
 
 
@@ -379,773 +359,747 @@ bool isAt(int instance, int other, ATrans trans)
    container that is somewhere, or a THING that is nowhere. It might
    also be an ENTITY which is always everywhere so take that to mean
    where the hero is. */
-int locationOf(int instance)
-{
-    int position;
-    int container = 0;
-
-    verifyInstance(instance, "get LOCATION of");
-
-    position = admin[instance].location;
-    while (position != 0 && !isALocation(position)) {
-        container = position;   /* Remember innermost container */
-        position = admin[position].location;
-    }
-    if (position > NOWHERE) /* It was a location so return that */
-        return position;
-    else {
-        /* If we did not find a location then it might be in a container */
-        if (container != 0)
-            instance = container;
-        /* If the instance or the container it was in is a THING then its nowhere. */
-        if (isA(instance, THING))
-            return NOWHERE;     /* #nowhere */
-        else if (isALocation(instance))
-            return NO_LOCATION; /* No location */
-        else
-            return locationOf(HERO);
-    }
+int locationOf(int instance) {
+	int position;
+	int container = 0;
+
+	verifyInstance(instance, "get LOCATION of");
+
+	position = admin[instance].location;
+	while (position != 0 && !isALocation(position)) {
+		container = position;   /* Remember innermost container */
+		position = admin[position].location;
+	}
+	if (position > NOWHERE) /* It was a location so return that */
+		return position;
+	else {
+		/* If we did not find a location then it might be in a container */
+		if (container != 0)
+			instance = container;
+		/* If the instance or the container it was in is a THING then its nowhere. */
+		if (isA(instance, THING))
+			return NOWHERE;     /* #nowhere */
+		else if (isALocation(instance))
+			return NO_LOCATION; /* No location */
+		else
+			return locationOf(HERO);
+	}
 }
 
 
 /*======================================================================*/
 /* Return the current position of an instance, directly or not */
 /* TODO: this will be a possible duplicate of where() */
-int positionOf(int instance)
-{
-    return admin[instance].location;
+int positionOf(int instance) {
+	return admin[instance].location;
 }
 
 
 /*======================================================================*/
 /* Return the current position of an instance, directly or not */
-int where(int instance, ATrans trans)
-{
-    verifyInstance(instance, "WHERE");
+int where(int instance, ATrans trans) {
+	verifyInstance(instance, "WHERE");
 
-    if (isALocation(instance))
-        return 0;
-    else if (trans == DIRECT)
-        return admin[instance].location;
-    else
-        return locationOf(instance);
+	if (isALocation(instance))
+		return 0;
+	else if (trans == DIRECT)
+		return admin[instance].location;
+	else
+		return locationOf(instance);
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool executeInheritedMentioned(int cls) {
-    if (cls == 0) return FALSE;
+	if (cls == 0) return FALSE;
 
-    if (classes[cls].mentioned) {
-        interpret(classes[cls].mentioned);
-        return TRUE;
-    } else
-        return executeInheritedMentioned(classes[cls].parent);
+	if (classes[cls].mentioned) {
+		interpret(classes[cls].mentioned);
+		return TRUE;
+	} else
+		return executeInheritedMentioned(classes[cls].parent);
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool mention(int instance) {
-    if (instances[instance].mentioned) {
-        interpret(instances[instance].mentioned);
-        return TRUE;
-    } else
-        return executeInheritedMentioned(instances[instance].parent);
+	if (instances[instance].mentioned) {
+		interpret(instances[instance].mentioned);
+		return TRUE;
+	} else
+		return executeInheritedMentioned(instances[instance].parent);
 }
 
 
 /*======================================================================*/
-void sayInstance(int instance)
-{
+void sayInstance(int instance) {
 #ifdef SAY_INSTANCE_WITH_PLAYER_WORDS_IF_PARAMETER
-    int p, i;
-
-    /* Find the id in the parameters... */
-    if (params != NULL)
-        for (p = 0; params[p].code != EOD; p++)
-            if (params[p].code == instance) {
-                /* Found it so.. */
-                if (params[p].firstWord == EOD) /* Any words he used? */
-                    break;      /* No... */
-                else {              /* Yes, so use them... */
-                    char *capitalized;
-                    /* Assuming the noun is the last word we can simply output the adjectives... */
-                    for (i = params[p].firstWord; i <= params[p].lastWord-1; i++)
-                        output((char *)pointerTo(dict[wrds[i]].wrd));
-                    /* ... and then the noun, capitalized if necessary */
-                    if (header->capitalizeNouns) {
-                        capitalized = strdup((char *)pointerTo(dict[wrds[params[p].lastWord]].wrd));
-                        capitalized[0] = IsoToUpperCase(capitalized[0]);
-                        output(capitalized);
-                        deallocate(capitalized);
-                    } else
-                        output((char *)pointerTo(dict[wrds[params[p].lastWord]].wrd));
-                }
-                return;
-            }
+	int p, i;
+
+	/* Find the id in the parameters... */
+	if (params != NULL)
+		for (p = 0; params[p].code != EOD; p++)
+			if (params[p].code == instance) {
+				/* Found it so.. */
+				if (params[p].firstWord == EOD) /* Any words he used? */
+					break;      /* No... */
+				else {              /* Yes, so use them... */
+					char *capitalized;
+					/* Assuming the noun is the last word we can simply output the adjectives... */
+					for (i = params[p].firstWord; i <= params[p].lastWord - 1; i++)
+						output((char *)pointerTo(dict[wrds[i]].wrd));
+					/* ... and then the noun, capitalized if necessary */
+					if (header->capitalizeNouns) {
+						capitalized = strdup((char *)pointerTo(dict[wrds[params[p].lastWord]].wrd));
+						capitalized[0] = IsoToUpperCase(capitalized[0]);
+						output(capitalized);
+						deallocate(capitalized);
+					} else
+						output((char *)pointerTo(dict[wrds[params[p].lastWord]].wrd));
+				}
+				return;
+			}
 #endif
-    if (!mention(instance))
-        interpret(instances[instance].name);
+	if (!mention(instance))
+		interpret(instances[instance].name);
 }
 
 
 /*======================================================================*/
-void sayInteger(int value)
-{
-    char buf[25];
+void sayInteger(int value) {
+	char buf[25];
 
-    if (isHere(HERO, /*FALSE*/ TRANSITIVE)) {
-        sprintf(buf, "%d", value);
-        output(buf);
-    }
+	if (isHere(HERO, /*FALSE*/ TRANSITIVE)) {
+		sprintf(buf, "%d", value);
+		output(buf);
+	}
 }
 
 
 /*======================================================================*/
-void sayString(char *string)
-{
-    if (isHere(HERO, /*FALSE*/ TRANSITIVE))
-        output(string);
-    deallocate(string);
+void sayString(char *string) {
+	if (isHere(HERO, /*FALSE*/ TRANSITIVE))
+		output(string);
+	deallocate(string);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayLiteral(int literal)
-{
-    char *str;
+static void sayLiteral(int literal) {
+	char *str;
 
-    if (isANumeric(literal))
-        sayInteger(literals[literal-header->instanceMax].value);
-    else {
-        str = (char *)strdup((char *)fromAptr(literals[literal-header->instanceMax].value));
-        sayString(str);
-    }
+	if (isANumeric(literal))
+		sayInteger(literals[literal - header->instanceMax].value);
+	else {
+		str = (char *)strdup((char *)fromAptr(literals[literal - header->instanceMax].value));
+		sayString(str);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static char *wordWithCode(int classBit, int code) {
-    int w;
-    char str[50];
+	int w;
+	char str[50];
 
-    for (w = 0; w < dictionarySize; w++)
-        if (dictionary[w].code == (Aword)code && ((classBit&dictionary[w].classBits) != 0))
-            return (char *)pointerTo(dictionary[w].string);
-    sprintf(str, "Could not find word of class %d with code %d.", classBit, code);
-    syserr(str);
-    return NULL;
+	for (w = 0; w < dictionarySize; w++)
+		if (dictionary[w].code == (Aword)code && ((classBit & dictionary[w].classBits) != 0))
+			return (char *)pointerTo(dictionary[w].string);
+	sprintf(str, "Could not find word of class %d with code %d.", classBit, code);
+	syserr(str);
+	return NULL;
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool sayInheritedDefiniteForm(int cls) {
-    if (cls == 0) {
-        syserr("No default definite article");
-        return FALSE;
-    } else {
-        if (classes[cls].definite.address) {
-            interpret(classes[cls].definite.address);
-            return classes[cls].definite.isForm;
-        } else
-            return sayInheritedDefiniteForm(classes[cls].parent);
-    }
+	if (cls == 0) {
+		syserr("No default definite article");
+		return FALSE;
+	} else {
+		if (classes[cls].definite.address) {
+			interpret(classes[cls].definite.address);
+			return classes[cls].definite.isForm;
+		} else
+			return sayInheritedDefiniteForm(classes[cls].parent);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayDefinite(int instance) {
-    if (instances[instance].definite.address) {
-        interpret(instances[instance].definite.address);
-        if (!instances[instance].definite.isForm)
-            sayInstance(instance);
-    } else
-        if (!sayInheritedDefiniteForm(instances[instance].parent))
-            sayInstance(instance);
+	if (instances[instance].definite.address) {
+		interpret(instances[instance].definite.address);
+		if (!instances[instance].definite.isForm)
+			sayInstance(instance);
+	} else if (!sayInheritedDefiniteForm(instances[instance].parent))
+		sayInstance(instance);
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool sayInheritedIndefiniteForm(int cls) {
-    if (cls == 0) {
-        syserr("No default indefinite article");
-        return FALSE;
-    } else {
-        if (classes[cls].indefinite.address) {
-            interpret(classes[cls].indefinite.address);
-            return classes[cls].indefinite.isForm;
-        } else
-            return sayInheritedIndefiniteForm(classes[cls].parent);
-    }
+	if (cls == 0) {
+		syserr("No default indefinite article");
+		return FALSE;
+	} else {
+		if (classes[cls].indefinite.address) {
+			interpret(classes[cls].indefinite.address);
+			return classes[cls].indefinite.isForm;
+		} else
+			return sayInheritedIndefiniteForm(classes[cls].parent);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayIndefinite(int instance) {
-    if (instances[instance].indefinite.address) {
-        interpret(instances[instance].indefinite.address);
-        if (!instances[instance].indefinite.isForm)
-            sayInstance(instance);
-    } else
-        if (!sayInheritedIndefiniteForm(instances[instance].parent))
-            sayInstance(instance);
+	if (instances[instance].indefinite.address) {
+		interpret(instances[instance].indefinite.address);
+		if (!instances[instance].indefinite.isForm)
+			sayInstance(instance);
+	} else if (!sayInheritedIndefiniteForm(instances[instance].parent))
+		sayInstance(instance);
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool sayInheritedNegativeForm(int cls) {
-    if (cls == 0) {
-        syserr("No default negative form");
-        return FALSE;
-    } else {
-        if (classes[cls].negative.address) {
-            interpret(classes[cls].negative.address);
-            return classes[cls].negative.isForm;
-        } else
-            return sayInheritedNegativeForm(classes[cls].parent);
-    }
+	if (cls == 0) {
+		syserr("No default negative form");
+		return FALSE;
+	} else {
+		if (classes[cls].negative.address) {
+			interpret(classes[cls].negative.address);
+			return classes[cls].negative.isForm;
+		} else
+			return sayInheritedNegativeForm(classes[cls].parent);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayNegative(int instance) {
-    if (instances[instance].negative.address) {
-        interpret(instances[instance].negative.address);
-        if (!instances[instance].negative.isForm)
-            sayInstance(instance);
-    } else
-        if (!sayInheritedNegativeForm(instances[instance].parent))
-            sayInstance(instance);
+	if (instances[instance].negative.address) {
+		interpret(instances[instance].negative.address);
+		if (!instances[instance].negative.isForm)
+			sayInstance(instance);
+	} else if (!sayInheritedNegativeForm(instances[instance].parent))
+		sayInstance(instance);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayInheritedPronoun(int instance) {
-    if (instance == 0)
-        syserr("No default pronoun");
-    else {
-        if (classes[instance].pronoun != 0)
-            output(wordWithCode(PRONOUN_BIT, classes[instance].pronoun));
-        else
-            sayInheritedPronoun(classes[instance].parent);
-    }
+	if (instance == 0)
+		syserr("No default pronoun");
+	else {
+		if (classes[instance].pronoun != 0)
+			output(wordWithCode(PRONOUN_BIT, classes[instance].pronoun));
+		else
+			sayInheritedPronoun(classes[instance].parent);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void sayPronoun(int instance) {
-    if (instances[instance].pronoun != 0)
-        output(wordWithCode(PRONOUN_BIT, instances[instance].pronoun));
-    else
-        sayInheritedPronoun(instances[instance].parent);
+	if (instances[instance].pronoun != 0)
+		output(wordWithCode(PRONOUN_BIT, instances[instance].pronoun));
+	else
+		sayInheritedPronoun(instances[instance].parent);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayArticleOrForm(int id, SayForm form)
-{
-    if (!isLiteral(id))
-        switch (form) {
-        case SAY_DEFINITE:
-            sayDefinite(id);
-            break;
-        case SAY_INDEFINITE:
-            sayIndefinite(id);
-            break;
-        case SAY_NEGATIVE:
-            sayNegative(id);
-            break;
-        case SAY_PRONOUN:
-            sayPronoun(id);
-            break;
-        case SAY_SIMPLE:
-            say(id);
-            break;
-        default:
-            syserr("Unexpected form in 'sayArticleOrForm()'");
-        }
-    else
-        say(id);
+static void sayArticleOrForm(int id, SayForm form) {
+	if (!isLiteral(id))
+		switch (form) {
+		case SAY_DEFINITE:
+			sayDefinite(id);
+			break;
+		case SAY_INDEFINITE:
+			sayIndefinite(id);
+			break;
+		case SAY_NEGATIVE:
+			sayNegative(id);
+			break;
+		case SAY_PRONOUN:
+			sayPronoun(id);
+			break;
+		case SAY_SIMPLE:
+			say(id);
+			break;
+		default:
+			syserr("Unexpected form in 'sayArticleOrForm()'");
+		}
+	else
+		say(id);
 }
 
 
 /*======================================================================*/
-void say(int instance)
-{
-    Aword previousInstance = current.instance;
-    current.instance = instance;
+void say(int instance) {
+	Aword previousInstance = current.instance;
+	current.instance = instance;
 
-    if (isHere(HERO, /*FALSE*/ TRANSITIVE)) {
-        if (isLiteral(instance))
-            sayLiteral(instance);
-        else {
-            verifyInstance(instance, "SAY");
-            sayInstance(instance);
-        }
-    }
-    current.instance = previousInstance;
+	if (isHere(HERO, /*FALSE*/ TRANSITIVE)) {
+		if (isLiteral(instance))
+			sayLiteral(instance);
+		else {
+			verifyInstance(instance, "SAY");
+			sayInstance(instance);
+		}
+	}
+	current.instance = previousInstance;
 }
 
 
 /*======================================================================*/
-void sayForm(int instance, SayForm form)
-{
-    Aword previousInstance = current.instance;
-    current.instance = instance;
+void sayForm(int instance, SayForm form) {
+	Aword previousInstance = current.instance;
+	current.instance = instance;
 
-    sayArticleOrForm(instance, form);
+	sayArticleOrForm(instance, form);
 
-    current.instance = previousInstance;
+	current.instance = previousInstance;
 }
 
 
 /*======================================================================*/
 bool isDescribable(int instance) {
-    return isAObject(instance) || isAActor(instance);
+	return isAObject(instance) || isAActor(instance);
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool inheritsDescriptionFrom(int cls)
-{
-    if (classes[cls].description != 0)
-        return TRUE;
-    else if (classes[cls].parent != 0)
-        return inheritsDescriptionFrom(classes[cls].parent);
-    else
-        return FALSE;
+static bool inheritsDescriptionFrom(int cls) {
+	if (classes[cls].description != 0)
+		return TRUE;
+	else if (classes[cls].parent != 0)
+		return inheritsDescriptionFrom(classes[cls].parent);
+	else
+		return FALSE;
 }
 
 
 /*======================================================================*/
-bool hasDescription(int instance)
-{
-    if (instances[instance].description != 0)
-        return TRUE;
-    else if (instances[instance].parent != 0)
-        return inheritsDescriptionFrom(instances[instance].parent);
-    else
-        return FALSE;
+bool hasDescription(int instance) {
+	if (instances[instance].description != 0)
+		return TRUE;
+	else if (instances[instance].parent != 0)
+		return inheritsDescriptionFrom(instances[instance].parent);
+	else
+		return FALSE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void describeClass(int instance)
-{
-    if (classes[instance].description != 0) {
-        /* This class has a description, run it */
-        interpret(classes[instance].description);
-    } else {
-        /* Search up the inheritance tree, if any, to find a description */
-        if (classes[instance].parent != 0)
-            describeClass(classes[instance].parent);
-    }
+static void describeClass(int instance) {
+	if (classes[instance].description != 0) {
+		/* This class has a description, run it */
+		interpret(classes[instance].description);
+	} else {
+		/* Search up the inheritance tree, if any, to find a description */
+		if (classes[instance].parent != 0)
+			describeClass(classes[instance].parent);
+	}
 }
 
 
 /*======================================================================*/
-void describeAnything(int instance)
-{
-    if (instances[instance].description != 0) {
-        /* This instance has its own description, run it */
-        interpret(instances[instance].description);
-    } else {
-        /* Search up the inheritance tree to find a description */
-        if (instances[instance].parent != 0)
-            describeClass(instances[instance].parent);
-    }
-    admin[instance].alreadyDescribed = TRUE;
+void describeAnything(int instance) {
+	if (instances[instance].description != 0) {
+		/* This instance has its own description, run it */
+		interpret(instances[instance].description);
+	} else {
+		/* Search up the inheritance tree to find a description */
+		if (instances[instance].parent != 0)
+			describeClass(instances[instance].parent);
+	}
+	admin[instance].alreadyDescribed = TRUE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void describeObject(int object)
-{
-    if (hasDescription(object))
-        describeAnything(object);
-    else {
-        printMessageWithInstanceParameter(M_SEE_START, object);
-        printMessage(M_SEE_END);
-        if (instances[object].container != 0)
-            describeContainer(object);
-    }
-    admin[object].alreadyDescribed = TRUE;
+static void describeObject(int object) {
+	if (hasDescription(object))
+		describeAnything(object);
+	else {
+		printMessageWithInstanceParameter(M_SEE_START, object);
+		printMessage(M_SEE_END);
+		if (instances[object].container != 0)
+			describeContainer(object);
+	}
+	admin[object].alreadyDescribed = TRUE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool inheritedDescriptionCheck(int cls)
-{
-    if (cls == 0) return TRUE;
-    if (!inheritedDescriptionCheck(classes[cls].parent)) return FALSE;
-    if (classes[cls].descriptionChecks == 0) return TRUE;
-    return !checksFailed(classes[cls].descriptionChecks, TRUE);
+static bool inheritedDescriptionCheck(int cls) {
+	if (cls == 0) return TRUE;
+	if (!inheritedDescriptionCheck(classes[cls].parent)) return FALSE;
+	if (classes[cls].descriptionChecks == 0) return TRUE;
+	return !checksFailed(classes[cls].descriptionChecks, TRUE);
 }
 
 /*----------------------------------------------------------------------*/
-static bool descriptionCheck(int instance)
-{
-    int previousInstance = current.instance;
-    bool r;
+static bool descriptionCheck(int instance) {
+	int previousInstance = current.instance;
+	bool r;
 
-    current.instance = instance;
-    if (inheritedDescriptionCheck(instances[instance].parent)) {
-        if (instances[instance].checks == 0)
-            r = TRUE;
-        else
-            r = !checksFailed(instances[instance].checks, TRUE);
-    } else
-        r = FALSE;
-    current.instance = previousInstance;
-    return r;
+	current.instance = instance;
+	if (inheritedDescriptionCheck(instances[instance].parent)) {
+		if (instances[instance].checks == 0)
+			r = TRUE;
+		else
+			r = !checksFailed(instances[instance].checks, TRUE);
+	} else
+		r = FALSE;
+	current.instance = previousInstance;
+	return r;
 }
 
 
 /*======================================================================*/
-void describeInstances(void)
-{
-    uint i;
-    int lastInstanceFound = 0;
-    int found = 0;
-
-    /* First describe every object here with its own description */
-    for (i = 1; i <= header->instanceMax; i++)
-        if (admin[i].location == current.location && isAObject(i) &&
-                !admin[i].alreadyDescribed && hasDescription(i))
-            describe(i);
-
-    /* Then list all things without a description */
-    for (i = 1; i <= header->instanceMax; i++)
-        if (admin[i].location == current.location
-                && !admin[i].alreadyDescribed
-                && isAObject(i)
-                && descriptionCheck(i)) {
-            if (found == 0)
-                printMessageWithInstanceParameter(M_SEE_START, i);
-            else if (found > 1)
-                printMessageWithInstanceParameter(M_SEE_COMMA, lastInstanceFound);
-            admin[i].alreadyDescribed = TRUE;
-
-            // TODO : isOpaque()
-            if (instances[i].container && containerSize(i, DIRECT) > 0 && !getInstanceAttribute(i, OPAQUEATTRIBUTE)) {
-                if (found > 0)
-                    printMessageWithInstanceParameter(M_SEE_AND, i);
-                printMessage(M_SEE_END);
-                describeContainer(i);
-                found = 0;
-                continue;       /* Actually start another list. */
-            }
-            found++;
-            lastInstanceFound = i;
-        }
-
-    if (found > 0) {
-        if (found > 1) {
-            printMessageWithInstanceParameter(M_SEE_AND, lastInstanceFound);
-        }
-        printMessage(M_SEE_END);
-    }
-
-    /* Finally all actors with a separate description */
-    for (i = 1; i <= header->instanceMax; i++)
-        if (admin[i].location == current.location && i != HERO && isAActor(i)
-        && !admin[i].alreadyDescribed)
-            describe(i);
-
-    /* Clear the describe flag for all instances */
-    for (i = 1; i <= header->instanceMax; i++)
-        admin[i].alreadyDescribed = FALSE;
+void describeInstances(void) {
+	uint i;
+	int lastInstanceFound = 0;
+	int found = 0;
+
+	/* First describe every object here with its own description */
+	for (i = 1; i <= header->instanceMax; i++)
+		if (admin[i].location == current.location && isAObject(i) &&
+		        !admin[i].alreadyDescribed && hasDescription(i))
+			describe(i);
+
+	/* Then list all things without a description */
+	for (i = 1; i <= header->instanceMax; i++)
+		if (admin[i].location == current.location
+		        && !admin[i].alreadyDescribed
+		        && isAObject(i)
+		        && descriptionCheck(i)) {
+			if (found == 0)
+				printMessageWithInstanceParameter(M_SEE_START, i);
+			else if (found > 1)
+				printMessageWithInstanceParameter(M_SEE_COMMA, lastInstanceFound);
+			admin[i].alreadyDescribed = TRUE;
+
+			// TODO : isOpaque()
+			if (instances[i].container && containerSize(i, DIRECT) > 0 && !getInstanceAttribute(i, OPAQUEATTRIBUTE)) {
+				if (found > 0)
+					printMessageWithInstanceParameter(M_SEE_AND, i);
+				printMessage(M_SEE_END);
+				describeContainer(i);
+				found = 0;
+				continue;       /* Actually start another list. */
+			}
+			found++;
+			lastInstanceFound = i;
+		}
+
+	if (found > 0) {
+		if (found > 1) {
+			printMessageWithInstanceParameter(M_SEE_AND, lastInstanceFound);
+		}
+		printMessage(M_SEE_END);
+	}
+
+	/* Finally all actors with a separate description */
+	for (i = 1; i <= header->instanceMax; i++)
+		if (admin[i].location == current.location && i != HERO && isAActor(i)
+		        && !admin[i].alreadyDescribed)
+			describe(i);
+
+	/* Clear the describe flag for all instances */
+	for (i = 1; i <= header->instanceMax; i++)
+		admin[i].alreadyDescribed = FALSE;
 }
 
 
 /*======================================================================*/
-bool describe(int instance)
-{
-    bool descriptionOk;
-    int previousInstance = current.instance;
-
-    current.instance = instance;
-    verifyInstance(instance, "DESCRIBE");
-    if (descriptionCheck(instance)) {
-        descriptionOk = TRUE;
-        if (isAObject(instance)) {
-            describeObject(instance);
-        } else if (isAActor(instance)) {
-            describeActor(instance);
-        } else
-            describeAnything(instance);
-    } else
-        descriptionOk = FALSE;
-    current.instance = previousInstance;
-    return descriptionOk;
+bool describe(int instance) {
+	bool descriptionOk;
+	int previousInstance = current.instance;
+
+	current.instance = instance;
+	verifyInstance(instance, "DESCRIBE");
+	if (descriptionCheck(instance)) {
+		descriptionOk = TRUE;
+		if (isAObject(instance)) {
+			describeObject(instance);
+		} else if (isAActor(instance)) {
+			describeActor(instance);
+		} else
+			describeAnything(instance);
+	} else
+		descriptionOk = FALSE;
+	current.instance = previousInstance;
+	return descriptionOk;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void locateIntoContainer(Aword theInstance, Aword theContainer) {
-    if (!isA(theInstance, containers[instances[theContainer].container]._class))
-        printMessageUsing2InstanceParameters(M_CANNOTCONTAIN, theContainer, theInstance);
-    else if (passesContainerLimits(theContainer, theInstance))
-        admin[theInstance].location = theContainer;
-    else
-        abortPlayerCommand();
+	if (!isA(theInstance, containers[instances[theContainer].container]._class))
+		printMessageUsing2InstanceParameters(M_CANNOTCONTAIN, theContainer, theInstance);
+	else if (passesContainerLimits(theContainer, theInstance))
+		admin[theInstance].location = theContainer;
+	else
+		abortPlayerCommand();
 }
 
 
 /*----------------------------------------------------------------------*/
-static void locateLocation(Aword loc, Aword whr)
-{
-    Aint l = whr;
+static void locateLocation(Aword loc, Aword whr) {
+	Aint l = whr;
 
-    /* Ensure this does not create a recursive location chain */
-    while (l != 0) {
-        if (admin[l].location == (int)loc)
-            apperr("Locating a location that would create a recursive loop of locations containing each other.");
-        else
-            l = admin[l].location;
-    }
-    admin[loc].location = whr;
+	/* Ensure this does not create a recursive location chain */
+	while (l != 0) {
+		if (admin[l].location == (int)loc)
+			apperr("Locating a location that would create a recursive loop of locations containing each other.");
+		else
+			l = admin[l].location;
+	}
+	admin[loc].location = whr;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void locateObject(Aword obj, Aword whr)
-{
-    if (isAContainer(whr)) { /* Into a container */
-        locateIntoContainer(obj, whr);
-    } else {
-        admin[obj].location = whr;
-        /* Make sure the location is described since it's changed */
-        admin[whr].visitsCount = 0;
-    }
+static void locateObject(Aword obj, Aword whr) {
+	if (isAContainer(whr)) { /* Into a container */
+		locateIntoContainer(obj, whr);
+	} else {
+		admin[obj].location = whr;
+		/* Make sure the location is described since it's changed */
+		admin[whr].visitsCount = 0;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void traceEnteredClass(Aint theClass, bool empty) {
-    printf("\n<ENTERED in class ");
-    printf("%s", idOfClass(theClass));
-    printf("[%d]%s>\n", theClass, empty?" is empty":":");
+	printf("\n<ENTERED in class ");
+	printf("%s", idOfClass(theClass));
+	printf("[%d]%s>\n", theClass, empty ? " is empty" : ":");
 }
 
 
 /*----------------------------------------------------------------------*/
 static void traceEnteredInstance(Aint instance, bool empty) {
-    printf("\n<ENTERED in instance ");
-    traceSay(instance);
-    printf("[%d]%s>\n", instance, empty?" is empty":"");
+	printf("\n<ENTERED in instance ");
+	traceSay(instance);
+	printf("[%d]%s>\n", instance, empty ? " is empty" : "");
 }
 
 
 /*----------------------------------------------------------------------*/
 static void executeInheritedEntered(Aint theClass) {
-    if (theClass == 0) return;
-    executeInheritedEntered(classes[theClass].parent);
-    if (traceSectionOption)
-        traceEnteredClass(theClass, classes[theClass].entered == 0);
-    if (classes[theClass].entered) {
-        interpret(classes[theClass].entered);
-    }
+	if (theClass == 0) return;
+	executeInheritedEntered(classes[theClass].parent);
+	if (traceSectionOption)
+		traceEnteredClass(theClass, classes[theClass].entered == 0);
+	if (classes[theClass].entered) {
+		interpret(classes[theClass].entered);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void executeEntered(Aint instance) {
-    int currentInstance = current.instance;
-    current.instance = instance;
-    if (admin[instance].location != 0)
-        executeEntered(admin[instance].location);
-    executeInheritedEntered(instances[instance].parent);
-    if (traceSectionOption)
-        traceEnteredInstance(instance, instances[instance].entered == 0);
-    if (instances[instance].entered != 0) {
-        interpret(instances[instance].entered);
-    }
-    current.instance = currentInstance;
+	int currentInstance = current.instance;
+	current.instance = instance;
+	if (admin[instance].location != 0)
+		executeEntered(admin[instance].location);
+	executeInheritedEntered(instances[instance].parent);
+	if (traceSectionOption)
+		traceEnteredInstance(instance, instances[instance].entered == 0);
+	if (instances[instance].entered != 0) {
+		interpret(instances[instance].entered);
+	}
+	current.instance = currentInstance;
 }
 
 
 /*----------------------------------------------------------------------*/
 static int getVisits(int location) {
-    return getInstanceAttribute(location, VISITSATTRIBUTE);
+	return getInstanceAttribute(location, VISITSATTRIBUTE);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void incrementVisits(int location) {
-    setInstanceAttribute(location, VISITSATTRIBUTE, getVisits(location)+1);
-    if (admin[location].location != 0)
-        /* Nested location, so increment that too */
-        incrementVisits(admin[location].location);
+	setInstanceAttribute(location, VISITSATTRIBUTE, getVisits(location) + 1);
+	if (admin[location].location != 0)
+		/* Nested location, so increment that too */
+		incrementVisits(admin[location].location);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void revisited(void) {
-    if (anyOutput)
-        para();
-    say(where(HERO, DIRECT));
-    printMessage(M_AGAIN);
-    newline();
-    describeInstances();
+	if (anyOutput)
+		para();
+	say(where(HERO, DIRECT));
+	printMessage(M_AGAIN);
+	newline();
+	describeInstances();
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool shouldBeDescribed(void) {
-    if (!isPreBeta5(header->version))
-        return getVisits(admin[HERO].location) % (current.visits+1) == 0
-            || admin[admin[HERO].location].visitsCount == 0;
-    else
-        return admin[admin[HERO].location].visitsCount % (current.visits+1) == 0;
+	if (!isPreBeta5(header->version))
+		return getVisits(admin[HERO].location) % (current.visits + 1) == 0
+		       || admin[admin[HERO].location].visitsCount == 0;
+	else
+		return admin[admin[HERO].location].visitsCount % (current.visits + 1) == 0;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void locateActor(Aint movingActor, Aint whr)
-{
-    Aint previousCurrentLocation = current.location;
-    Aint previousActorLocation = admin[movingActor].location;
-    Aint previousActor = current.actor;
-    Aint previousInstance = current.instance;
-
-    /* Before leaving, remember that we visited the location */
-    if (!isPreBeta5(header->version))
-        if (movingActor == (int)HERO)
-            incrementVisits(where(HERO, DIRECT));
-
-    /* TODO Actors locating into containers is dubious, anyway as it
-       is now it allows the hero to be located into a container. And what
-       happens with current location if so... */
-    if (isAContainer(whr))
-        locateIntoContainer(movingActor, whr);
-    else {
-        current.location = whr;
-        admin[movingActor].location = whr;
-    }
-
-    /* Now we have moved, so show what is needed... */
-    current.instance = current.location;
-
-    /* Execute possible entered */
-    current.actor = movingActor;
-    if (previousActorLocation != current.location) {
-        executeEntered(current.location);
-    }
-    current.instance = previousInstance;
-    current.actor = previousActor;
-
-    if (movingActor == (int)HERO) {
-        if (shouldBeDescribed())
-            look();
-        else
-            revisited();
-        admin[where(HERO, DIRECT)].visitsCount++;
-    } else
-        /* Ensure that the location will be described to the hero next time */
-        admin[whr].visitsCount = 0;
-
-    if (current.actor != movingActor)
-        current.location = previousCurrentLocation;
-
-    current.instance = previousInstance;
+static void locateActor(Aint movingActor, Aint whr) {
+	Aint previousCurrentLocation = current.location;
+	Aint previousActorLocation = admin[movingActor].location;
+	Aint previousActor = current.actor;
+	Aint previousInstance = current.instance;
+
+	/* Before leaving, remember that we visited the location */
+	if (!isPreBeta5(header->version))
+		if (movingActor == (int)HERO)
+			incrementVisits(where(HERO, DIRECT));
+
+	/* TODO Actors locating into containers is dubious, anyway as it
+	   is now it allows the hero to be located into a container. And what
+	   happens with current location if so... */
+	if (isAContainer(whr))
+		locateIntoContainer(movingActor, whr);
+	else {
+		current.location = whr;
+		admin[movingActor].location = whr;
+	}
+
+	/* Now we have moved, so show what is needed... */
+	current.instance = current.location;
+
+	/* Execute possible entered */
+	current.actor = movingActor;
+	if (previousActorLocation != current.location) {
+		executeEntered(current.location);
+	}
+	current.instance = previousInstance;
+	current.actor = previousActor;
+
+	if (movingActor == (int)HERO) {
+		if (shouldBeDescribed())
+			look();
+		else
+			revisited();
+		admin[where(HERO, DIRECT)].visitsCount++;
+	} else
+		/* Ensure that the location will be described to the hero next time */
+		admin[whr].visitsCount = 0;
+
+	if (current.actor != movingActor)
+		current.location = previousCurrentLocation;
+
+	current.instance = previousInstance;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void traceExtract(int instance, int containerId, const char *what) {
-    if (traceSectionOption) {
-        printf("\n<EXTRACT from ");
-        traceSay(instance);
-        printf("[%d, container %d], %s:>\n", instance, containerId, what);
-    }
+	if (traceSectionOption) {
+		printf("\n<EXTRACT from ");
+		traceSay(instance);
+		printf("[%d, container %d], %s:>\n", instance, containerId, what);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void containmentLoopError(int instance, int whr) {
-    ParameterArray parameters = newParameterArray();
-    if (isPreBeta4(header->version))
-        output("That would be to put something inside itself.");
-    else if (whr == instance) {
-        addParameterForInstance(parameters, instance);
-        printMessageWithParameters(M_CONTAINMENT_LOOP, parameters);
-    } else {
-        addParameterForInstance(parameters, instance);
-        addParameterForInstance(parameters, whr);
-        printMessageWithParameters(M_CONTAINMENT_LOOP2, parameters);
-    }
-    free(parameters);
-    error(NO_MSG);
+	ParameterArray parameters = newParameterArray();
+	if (isPreBeta4(header->version))
+		output("That would be to put something inside itself.");
+	else if (whr == instance) {
+		addParameterForInstance(parameters, instance);
+		printMessageWithParameters(M_CONTAINMENT_LOOP, parameters);
+	} else {
+		addParameterForInstance(parameters, instance);
+		addParameterForInstance(parameters, whr);
+		printMessageWithParameters(M_CONTAINMENT_LOOP2, parameters);
+	}
+	free(parameters);
+	error(NO_MSG);
 }
 
 
 /*----------------------------------------------------------------------*/
 static void runExtractStatements(int instance, int containerId) {
-    ContainerEntry *theContainer = &containers[containerId];
+	ContainerEntry *theContainer = &containers[containerId];
 
-    if (theContainer->extractStatements != 0) {
-        traceExtract(instance, containerId, "Executing");
-        interpret(theContainer->extractStatements);
-    }
+	if (theContainer->extractStatements != 0) {
+		traceExtract(instance, containerId, "Executing");
+		interpret(theContainer->extractStatements);
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static bool runExtractChecks(int instance, int containerId) {
-    ContainerEntry *theContainer = &containers[containerId];
+	ContainerEntry *theContainer = &containers[containerId];
 
-    if (theContainer->extractChecks != 0) {
-        traceExtract(instance, containerId, "Checking");
-        if (checksFailed(theContainer->extractChecks, EXECUTE_CHECK_BODY_ON_FAIL)) {
-            fail = TRUE;
-            return FALSE;       /* Failed! */
-        }
-    }
-    return TRUE;                /* Passed! */
+	if (theContainer->extractChecks != 0) {
+		traceExtract(instance, containerId, "Checking");
+		if (checksFailed(theContainer->extractChecks, EXECUTE_CHECK_BODY_ON_FAIL)) {
+			fail = TRUE;
+			return FALSE;       /* Failed! */
+		}
+	}
+	return TRUE;                /* Passed! */
 }
 
 
 /*======================================================================*/
-void locate(int instance, int whr)
-{
-    int containerId;
-    int previousInstance = current.instance;
-
-    verifyInstance(instance, "LOCATE");
-    verifyInstance(whr, "LOCATE AT");
-
-    /* Will this create a containment loop? */
-    if (whr == instance || (isAContainer(instance) && isIn(whr, instance, TRANSITIVE)))
-        containmentLoopError(instance, whr);
-
-    /* First check if the instance is in a container, if so run extract checks */
-    if (isAContainer(admin[instance].location)) {    /* In something? */
-        int loc = admin[instance].location;
-
-        /* Run all nested extraction checks */
-        while (isAContainer(loc)) {
-            current.instance = loc;
-            containerId = instances[loc].container;
-
-            if (!runExtractChecks(instance, containerId)) {
-                current.instance = previousInstance;
-                return;
-            }
-            runExtractStatements(instance, containerId);
-            loc = admin[loc].location;
-        }
-        current.instance = previousInstance;
-    }
-
-    if (isAActor(instance))
-        locateActor(instance, whr);
-    else if (isALocation(instance))
-        locateLocation(instance, whr);
-    else
-        locateObject(instance, whr);
-
-    gameStateChanged = TRUE;
+void locate(int instance, int whr) {
+	int containerId;
+	int previousInstance = current.instance;
+
+	verifyInstance(instance, "LOCATE");
+	verifyInstance(whr, "LOCATE AT");
+
+	/* Will this create a containment loop? */
+	if (whr == instance || (isAContainer(instance) && isIn(whr, instance, TRANSITIVE)))
+		containmentLoopError(instance, whr);
+
+	/* First check if the instance is in a container, if so run extract checks */
+	if (isAContainer(admin[instance].location)) {    /* In something? */
+		int loc = admin[instance].location;
+
+		/* Run all nested extraction checks */
+		while (isAContainer(loc)) {
+			current.instance = loc;
+			containerId = instances[loc].container;
+
+			if (!runExtractChecks(instance, containerId)) {
+				current.instance = previousInstance;
+				return;
+			}
+			runExtractStatements(instance, containerId);
+			loc = admin[loc].location;
+		}
+		current.instance = previousInstance;
+	}
+
+	if (isAActor(instance))
+		locateActor(instance, whr);
+	else if (isALocation(instance))
+		locateLocation(instance, whr);
+	else
+		locateObject(instance, whr);
+
+	gameStateChanged = TRUE;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/instance.h b/engines/glk/alan3/instance.h
index 2b5adb3..6c62bb5 100644
--- a/engines/glk/alan3/instance.h
+++ b/engines/glk/alan3/instance.h
@@ -32,13 +32,13 @@ namespace Alan3 {
 
 /* Types: */
 struct AdminEntry { /* Administrative data about instances */
-  Aint location;
-  AttributeEntry *attributes;
-  Abool alreadyDescribed;
-  Aint visitsCount;
-  Aint script;
-  Aint step;
-  Aint waitCount;
+	Aint location;
+	AttributeEntry *attributes;
+	Abool alreadyDescribed;
+	Aint visitsCount;
+	Aint script;
+	Aint step;
+	Aint waitCount;
 };
 
 
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index 457f75d..0421442 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -59,335 +59,332 @@ static void (*interpreterMock)(Aaddr adr) = NULL;
 
 /*======================================================================*/
 void setInterpreterMock(void (*mock)(Aaddr adr)) {
-    interpreterMock = mock;
+	interpreterMock = mock;
 }
 
 
 /*======================================================================*/
-void setInterpreterStack(Stack theStack)
-{
-    stack = theStack;
+void setInterpreterStack(Stack theStack) {
+	stack = theStack;
 }
 
 
 /*----------------------------------------------------------------------*/
 static void traceInstruction(const char *str, ...) {
-    va_list args;
+	va_list args;
 
-    if (traceInstructionOption) {
-        va_start(args, str);
+	if (traceInstructionOption) {
+		va_start(args, str);
 		Common::String msg = Common::String::format(str, args);
 		va_end(args);
 
 		printf("%s", msg.c_str());
-    }
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void traceSkip() {
-    printf("\n    : \t\t\t\t\t\t\t");
+	printf("\n    : \t\t\t\t\t\t\t");
 }
 
 
 /*----------------------------------------------------------------------*/
-static void interpretIf(Aword v)
-{
-    int lev = 1;
-    Aword i;
-
-    if (!v) {
-        /* Skip to next ELSE or ENDIF on same level */
-        if (traceInstructionOption) traceSkip();
-        while (TRUE) {
-            i = memory[pc++];
-            if (I_CLASS(i) == (Aword)C_STMOP)
-                switch (I_OP(i)) {
-                case I_ELSE:
-                    if (lev == 1) {
-                        if (traceInstructionOption)
-                            printf("\n%4x: ELSE\t\t\t\t\t\t", pc);
-                        return;
-                    }
-                    break;
-                case I_IF:
-                    lev++;
-                    break;
-                case I_ENDIF:
-                    lev--;
-                    if (lev == 0) {
-                        if (traceInstructionOption)
-                            printf("\n%4x: ENDIF\t\t\t\t\t\t", pc);
-                        return;
-                    }
-                    break;
-                }
-        }
-    }
+static void interpretIf(Aword v) {
+	int lev = 1;
+	Aword i;
+
+	if (!v) {
+		/* Skip to next ELSE or ENDIF on same level */
+		if (traceInstructionOption) traceSkip();
+		while (TRUE) {
+			i = memory[pc++];
+			if (I_CLASS(i) == (Aword)C_STMOP)
+				switch (I_OP(i)) {
+				case I_ELSE:
+					if (lev == 1) {
+						if (traceInstructionOption)
+							printf("\n%4x: ELSE\t\t\t\t\t\t", pc);
+						return;
+					}
+					break;
+				case I_IF:
+					lev++;
+					break;
+				case I_ENDIF:
+					lev--;
+					if (lev == 0) {
+						if (traceInstructionOption)
+							printf("\n%4x: ENDIF\t\t\t\t\t\t", pc);
+						return;
+					}
+					break;
+				}
+		}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void interpretElse(void)
-{
-    int lev = 1;
-    Aword i;
-
-    if (traceInstructionOption) traceSkip();
-    while (TRUE) {
-        /* Skip to ENDIF on the same level */
-        i = memory[pc++];
-        if (I_CLASS(i) == (Aword)C_STMOP)
-            switch (I_OP(i)) {
-            case I_ENDIF:
-                lev--;
-                if (lev == 0) return;
-                break;
-            case I_IF:
-                lev++;
-                break;
-            }
-    }
+static void interpretElse(void) {
+	int lev = 1;
+	Aword i;
+
+	if (traceInstructionOption) traceSkip();
+	while (TRUE) {
+		/* Skip to ENDIF on the same level */
+		i = memory[pc++];
+		if (I_CLASS(i) == (Aword)C_STMOP)
+			switch (I_OP(i)) {
+			case I_ENDIF:
+				lev--;
+				if (lev == 0) return;
+				break;
+			case I_IF:
+				lev++;
+				break;
+			}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void goToLOOPEND(void) {
-    int level = 1;
-    int i;
-
-    if (traceInstructionOption) traceSkip();
-    while (TRUE) {
-        /* Skip past LOOPEND on the same level */
-        i = memory[pc];
-        if (I_CLASS(i) == (Aword)C_STMOP)
-            switch (I_OP(i)) {
-            case I_LOOPEND:
-                level--;
-                if (level == 0)
-                    return;
-                break;
-            case I_LOOP:
-                level++;
-                break;
-            }
-        pc++;
-    }
+	int level = 1;
+	int i;
+
+	if (traceInstructionOption) traceSkip();
+	while (TRUE) {
+		/* Skip past LOOPEND on the same level */
+		i = memory[pc];
+		if (I_CLASS(i) == (Aword)C_STMOP)
+			switch (I_OP(i)) {
+			case I_LOOPEND:
+				level--;
+				if (level == 0)
+					return;
+				break;
+			case I_LOOP:
+				level++;
+				break;
+			}
+		pc++;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static void jumpBackToStartOfMatchingLOOP(void) {
-    int level = 1;
-    int i;
-
-    if (traceInstructionOption) traceSkip();
-    pc--;				/* Ignore the instruction we're on */
-    while (TRUE) {
-        /* Skip back past LOOP on the same level */
-        i = memory[--pc];
-        if (I_CLASS(i) == (Aword)C_STMOP)
-            switch (I_OP(i)) {
-            case I_LOOPEND:
-                level++;
-                break;
-            case I_LOOP:
-                level--;
-                if (level == 0) {
-                    return;
-                }
-                break;
-            }
-    }
+	int level = 1;
+	int i;
+
+	if (traceInstructionOption) traceSkip();
+	pc--;               /* Ignore the instruction we're on */
+	while (TRUE) {
+		/* Skip back past LOOP on the same level */
+		i = memory[--pc];
+		if (I_CLASS(i) == (Aword)C_STMOP)
+			switch (I_OP(i)) {
+			case I_LOOPEND:
+				level++;
+				break;
+			case I_LOOP:
+				level--;
+				if (level == 0) {
+					return;
+				}
+				break;
+			}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void nextLoop(void)
-{
-    goToLOOPEND();
+static void nextLoop(void) {
+	goToLOOPEND();
 }
 
 
 /*----------------------------------------------------------------------*/
-static void endLoop(Aint index, Aint limit)
-{
-    if (index < limit) {
-        index++;
-        push(stack, limit);
-        push(stack, index);
-        jumpBackToStartOfMatchingLOOP();
-        if (traceInstructionOption)
-            printf("\n%4x: LOOP\t\t\t\t\t\t", pc);
-        pc++;
-    }
+static void endLoop(Aint index, Aint limit) {
+	if (index < limit) {
+		index++;
+		push(stack, limit);
+		push(stack, index);
+		jumpBackToStartOfMatchingLOOP();
+		if (traceInstructionOption)
+			printf("\n%4x: LOOP\t\t\t\t\t\t", pc);
+		pc++;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void stackDup(void)
-{
-    push(stack, top(stack));
+static void stackDup(void) {
+	push(stack, top(stack));
 }
 
 
 /*----------------------------------------------------------------------*/
-static void depexec(Aword v)
-{
-    int lev = 1;
-    Aword i;
-    const char *instructionString = "DEPELSE";
-
-    if (!v) {
-        /* The expression was not true, skip to next CASE on the same
-           level which could be a DEPCASE or DEPELSE */
-        if (traceInstructionOption) printf("\n    : ");
-        while (TRUE) {
-            i = memory[pc++];
-            if (I_CLASS(i) == (Aword)C_STMOP)
-                switch (I_OP(i)) {
-                case I_DEPEND:
-                    lev++;
-                    break;
-                case I_ENDDEP:
-                    if (lev == 1) {
-                        pc--;
-                        if (traceInstructionOption)
-                            printf("\n%4x: ENDDEP", pc);
-                        return;
-                    } else
-                        lev--;
-                    break;
-                case I_DEPCASE:
-                    instructionString = "DEPCASE";
-                case I_DEPELSE:
-                    if (lev == 1) {
-                        if (traceInstructionOption)
-                            printf("\n%4x: %s", pc, instructionString);
-                        return;
-                    }
-                    break;
-                }
-        }
-    }
+static void depexec(Aword v) {
+	int lev = 1;
+	Aword i;
+	const char *instructionString = "DEPELSE";
+
+	if (!v) {
+		/* The expression was not true, skip to next CASE on the same
+		   level which could be a DEPCASE or DEPELSE */
+		if (traceInstructionOption) printf("\n    : ");
+		while (TRUE) {
+			i = memory[pc++];
+			if (I_CLASS(i) == (Aword)C_STMOP)
+				switch (I_OP(i)) {
+				case I_DEPEND:
+					lev++;
+					break;
+				case I_ENDDEP:
+					if (lev == 1) {
+						pc--;
+						if (traceInstructionOption)
+							printf("\n%4x: ENDDEP", pc);
+						return;
+					} else
+						lev--;
+					break;
+				case I_DEPCASE:
+					instructionString = "DEPCASE";
+				case I_DEPELSE:
+					if (lev == 1) {
+						if (traceInstructionOption)
+							printf("\n%4x: %s", pc, instructionString);
+						return;
+					}
+					break;
+				}
+		}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void depcase(void)
-{
-    int lev = 1;
-    Aword i;
-
-    /*
-      We have just executed a DEPCASE/DEPELSE clause as a result of a
-      DEPCASE catching so skip to end of DEPENDING block (next DEPEND
-      on same level) then return.
-    */
-
-    if (traceInstructionOption) printf("\n    : ");
-    while (TRUE) {
-        i = memory[pc++];
-        if (I_CLASS(i) == (Aword)C_STMOP)
-            switch (I_OP(i)) {
-            case I_DEPEND:
-                lev++;
-                break;
-            case I_ENDDEP:
-                lev--;
-                if (lev == 0) {
-                    pc--;
-                    return;
-                }
-                break;
-            }
-    }
+static void depcase(void) {
+	int lev = 1;
+	Aword i;
+
+	/*
+	  We have just executed a DEPCASE/DEPELSE clause as a result of a
+	  DEPCASE catching so skip to end of DEPENDING block (next DEPEND
+	  on same level) then return.
+	*/
+
+	if (traceInstructionOption) printf("\n    : ");
+	while (TRUE) {
+		i = memory[pc++];
+		if (I_CLASS(i) == (Aword)C_STMOP)
+			switch (I_OP(i)) {
+			case I_DEPEND:
+				lev++;
+				break;
+			case I_ENDDEP:
+				lev--;
+				if (lev == 0) {
+					pc--;
+					return;
+				}
+				break;
+			}
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
 static const char *booleanValue(Abool value) {
-    if (value) return "   TRUE";
-    else return "  FALSE";
+	if (value) return "   TRUE";
+	else return "  FALSE";
 }
 
 /*----------------------------------------------------------------------*/
 static const char *stringValue(Aptr address) {
-    static char string[1000];
+	static char string[1000];
 
-    sprintf(string, "0x%lx (\"%s\")\t\t", (unsigned long) address, (char *)fromAptr(address));
-    return string;
+	sprintf(string, "0x%lx (\"%s\")\t\t", (unsigned long) address, (char *)fromAptr(address));
+	return string;
 }
 
 /*----------------------------------------------------------------------*/
 static const char *pointerValue(Aptr address) {
-    static char string[100];
+	static char string[100];
 
-    sprintf(string, "@%6lx",(unsigned long) address);
-    return string;
+	sprintf(string, "@%6lx", (unsigned long) address);
+	return string;
 }
 
 /*----------------------------------------------------------------------*/
 static void traceStringTopValue() {
-    if (traceInstructionOption)
-        printf("\t=%s", stringValue(top(stack)));
+	if (traceInstructionOption)
+		printf("\t=%s", stringValue(top(stack)));
 }
 
 /*----------------------------------------------------------------------*/
 static void tracebooleanTopValue() {
-    if (traceInstructionOption) {
-        if (top(stack)) printf("\t=TRUE\t");
-        else printf("\t=FALSE\t");
-    }
+	if (traceInstructionOption) {
+		if (top(stack)) printf("\t=TRUE\t");
+		else printf("\t=FALSE\t");
+	}
 }
 
 /*----------------------------------------------------------------------*/
 static void traceIntegerTopValue() {
-    if (traceInstructionOption)
-        printf("\t=%ld\t", (long)top(stack));
+	if (traceInstructionOption)
+		printf("\t=%ld\t", (long)top(stack));
 }
 
 /*----------------------------------------------------------------------*/
 static void tracePointerTopValue() {
-    if (traceInstructionOption)
-        printf("\t=%s\t", pointerValue(top(stack)));
+	if (traceInstructionOption)
+		printf("\t=%s\t", pointerValue(top(stack)));
 }
 
 /*----------------------------------------------------------------------*/
 static void traceInstanceTopValue() {
-    if (traceInstructionOption) {
-        printf("\t=%ld ('", (long)top(stack));
-        traceSay(top(stack));
-        printf("')");
-        if (traceStackOption)
-            printf("\n\t\t\t\t\t\t\t");
-    }
+	if (traceInstructionOption) {
+		printf("\t=%ld ('", (long)top(stack));
+		traceSay(top(stack));
+		printf("')");
+		if (traceStackOption)
+			printf("\n\t\t\t\t\t\t\t");
+	}
 }
 
 /*----------------------------------------------------------------------*/
 static const char *transitivityFlag(ATrans value) {
-    switch (value) {
-    case TRANSITIVE:
-        return "Transitive";
-    case DIRECT:
-        return "Direct";
-    case INDIRECT:
-        return "Indirect";
-    }
-    syserr("Unexpected transitivity");
-    return "ERROR";
+	switch (value) {
+	case TRANSITIVE:
+		return "Transitive";
+	case DIRECT:
+		return "Direct";
+	case INDIRECT:
+		return "Indirect";
+	}
+	syserr("Unexpected transitivity");
+	return "ERROR";
 }
 
 /*----------------------------------------------------------------------*/
 static const char *printForm(SayForm form) {
-    switch (form) {
-    case SAY_SIMPLE: return "-";
-    case SAY_INDEFINITE: return "An";
-    case SAY_DEFINITE: return "The";
-    case SAY_NEGATIVE: return "No";
-    case SAY_PRONOUN: return "It";
-    }
-    return "**Unknown!!***";
+	switch (form) {
+	case SAY_SIMPLE:
+		return "-";
+	case SAY_INDEFINITE:
+		return "An";
+	case SAY_DEFINITE:
+		return "The";
+	case SAY_NEGATIVE:
+		return "No";
+	case SAY_PRONOUN:
+		return "It";
+	}
+	return "**Unknown!!***";
 }
 
 
@@ -396,14 +393,14 @@ int recursionDepth = 0;
 
 /*----------------------------------------------------------------------*/
 static void checkForRecursion(Aaddr adr) {
-    int i;
-
-    for (i = 0; i < recursionDepth; i++)
-        if (invocation[i] == adr)
-            apperr("Interpreter recursion.");
-    invocation[recursionDepth++] = adr;
-    if (recursionDepth > 1000)
-        syserr("Interpreter call stack too deep.");
+	int i;
+
+	for (i = 0; i < recursionDepth; i++)
+		if (invocation[i] == adr)
+			apperr("Interpreter recursion.");
+	invocation[recursionDepth++] = adr;
+	if (recursionDepth > 1000)
+		syserr("Interpreter call stack too deep.");
 }
 
 
@@ -417,995 +414,995 @@ static bool stillOnSameLine(Aint line, Aint file) {
 
 
 /*======================================================================*/
-void interpret(Aaddr adr)
-{
-    Aaddr oldpc;
-    Aword i;
-
-    /* Check for mock implementation */
-    if (interpreterMock != NULL) {
-        interpreterMock(adr);
-        return;
-    }
-
-    /* Sanity checks: */
-    if (adr == 0) syserr("Interpreting at address 0.");
-    checkForRecursion(adr);
-
-    if (traceInstructionOption)
-        printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++");
-
-    oldpc = pc;
-    pc = adr;
-    while(TRUE) {
-        if (pc > memTop)
-            syserr("Interpreting outside program.");
-
-        i = memory[pc++];
-
-        switch (I_CLASS(i)) {
-        case C_CONST:
-            if (tracePushOption) printf("\n%4x: PUSH  \t%7ld\t\t\t\t\t", pc-1, (long)I_OP(i));
-            push(stack, I_OP(i));
-            if (tracePushOption && traceStackOption)
-                dumpStack(stack);
-            break;
-        case C_CURVAR:
-            if (traceInstructionOption) printf("\n%4x: ", pc-1);
-            switch (I_OP(i)) {
-            case V_PARAM:
-                if (traceInstructionOption) printf("PARAM \t%7ld\t\t\t\t=%ld\t", (long)top(stack),
-                                             (long)globalParameters[top(stack)-1].instance);
-                push(stack, globalParameters[pop(stack)-1].instance);
-                break;
-            case V_CURLOC:
-                if (traceInstructionOption) printf("CURLOC \t\t\t\t\t=%d\t", current.location);
-                push(stack, current.location);
-                break;
-            case V_CURACT:
-                if (traceInstructionOption) printf("CURACT \t\t\t\t\t=%d\t", current.actor);
-                push(stack, current.actor);
-                break;
-            case V_CURVRB:
-                if (traceInstructionOption) printf("CURVRB \t\t\t\t\t=%d\t", current.verb);
-                push(stack, current.verb);
-                break;
-            case V_CURRENT_INSTANCE:
-                if (traceInstructionOption) printf("CURINS \t\t\t\t\t=%d\t", current.instance);
-                push(stack, current.instance);
-                break;
-            case V_SCORE:
-                if (traceInstructionOption) printf("CURSCORE \t\t\t\t\t=%d\t", current.score);
-                push(stack, current.score);
-                break;
-            case V_MAX_INSTANCE: {
-                int instanceMax = isPreBeta3(header->version)?header->instanceMax:header->instanceMax-1;
-                if (traceInstructionOption) printf("MAXINSTANCE \t\t\t\t=%d\t", instanceMax);
-                push(stack, instanceMax);
-                break;
-            }
-            default:
-                syserr("Unknown CURVAR instruction.");
-                break;
-            }
-            if (traceStackOption)
-                dumpStack(stack);
-            break;
-
-        case C_STMOP:
-            if (traceInstructionOption) printf("\n%4x: ", pc-1);
-            switch (I_OP(i)) {
-
-            case I_DUP:
-                if (traceInstructionOption)
-                    printf("DUP\t\t\t\t\t\t");
-                stackDup();
-                break;
-
-            case I_DUPSTR:
-                if (traceInstructionOption)
-                    printf("DUPSTR\t\t\t\t\t\t");
-                push(stack, toAptr(strdup((char*)fromAptr(top(stack)))));
-                break;
-
-            case I_POP: {
-                Aptr top = pop(stack);
-                if (traceInstructionOption)
-                    printf("POP\t%7ld", (long)top);
-                break;
-            }
-
-            case I_LINE: {
-                Aint line = pop(stack);
-                Aint file = pop(stack);
-                traceInstruction("LINE\t%7ld, %7ld\t\t\t", (long)file, (long)line);
-                if (traceStackOption)
-                    dumpStack(stack);
-                skipStackDump = TRUE;
-                if (line != 0) {
-                    bool atNext = stopAtNextLine && line != current.sourceLine;
-                    bool atBreakpoint =  breakpointIndex(file, line) != -1;
-                    if (traceSourceOption && stillOnSameLine(line, file)) {
-                        if (col != 1 || traceInstructionOption)
-                            printf("\n");
-                        showSourceLine(file, line);
-                        if (!traceInstructionOption)
-                            printf("\n");
-                    }
-                    current.sourceLine = line;
-                    current.sourceFile = file;
-                    if (atNext || atBreakpoint) {
-                        stopAtNextLine = FALSE;
-                        debug(TRUE, line, file);
-                    }
-                }
-                break;
-            }
-
-            case I_PRINT: {
-                Aint fpos = pop(stack);
-                Aint len = pop(stack);
-                if (traceInstructionOption) {
-	                printf("PRINT \t%7ld, %7ld\t\"", (long)fpos, (long)len);
-                    col = 41;		/* To break lines better! */
-                }
-                print(fpos, len);
-                if (traceInstructionOption) {
-                    printf("\"");
-                    if (traceStackOption)
-                        printf("\n\t\t\t\t\t\t\t");
-                }
-                break;
-            }
-
-            case I_STYLE: {
-                Aint style = pop(stack);
-                if (traceInstructionOption) {
-                    printf("STYLE \t%7ld\t\t\"", (long)style);
-                }
-                setStyle(style);
-                break;
-            }
-
-            case I_SYSTEM: {
-                Aint fpos = pop(stack);
-                Aint len = pop(stack);
-                if (traceInstructionOption) {
-                    printf("SYSTEM \t%7ld, %7ld\t\"", (long)fpos, (long)len);
-                    col = 34;		/* To format it better! */
-                }
-                sys(fpos, len);
-                if (traceInstructionOption)
-                    printf("\"\t\t\t\t\t\t");
-                break;
-            }
-
-            case I_GETSTR: {
-                Aint fpos = pop(stack);
-                Aint len = pop(stack);
-                if (traceInstructionOption)
-                    printf("GETSTR\t%7ld, %7ld", (long)fpos, (long)len);
-                push(stack, toAptr(getStringFromFile(fpos, len)));
-                traceStringTopValue();
-                break;
-            }
-
-            case I_QUIT: {
-                if (traceInstructionOption)
-                    printf("QUIT\t\t\t\t\t\t");
-                quitGame();
-                break;
-            }
-            case I_LOOK: {
-                if (traceInstructionOption)
-                    printf("LOOK\t\t\t\t\t\t");
-                look();
-                break;
-            }
-            case I_SAVE: {
-                if (traceInstructionOption)
-                    printf("SAVE\t\t\t\t\t\t");
-                save();
-                break;
-            }
-            case I_RESTORE: {
-                if (traceInstructionOption)
-                    printf("RESTORE\t\t\t\t\t\t");
-                restore();
-                break;
-            }
-            case I_RESTART: {
-                if (traceInstructionOption)
-                    printf("RESTART\t\t\t\t\t\t");
-                restartGame();
-                break;
-            }
-
-            case I_SCORE: {
-                Aint sc = pop(stack);
-                if (traceInstructionOption)
-                    printf("SCORE \t%7ld\t\t=%ld\t\t\t", (long)sc, (long)scores[sc-1]);
-                score(sc);
-                break;
-            }
-            case I_VISITS: {
-                Aint v = pop(stack);
-                if (traceInstructionOption)
-                    printf("VISITS \t%7ld\t\t\t\t\t", (long)v);
-                visits(v);
-                break;
-            }
-
-            case I_LIST: {
-                Aint cnt = pop(stack);
-                if (traceInstructionOption)
-                    printf("LIST \t%7ld\t\t\t\t\t", (long)cnt);
-                list(cnt);
-                break;
-            }
-            case I_EMPTY: {
-                Aint cnt = pop(stack);
-                Aint whr = pop(stack);
-                if (traceInstructionOption)
-                    printf("EMPTY \t%7ld, %7ld\t\t\t\t", (long)cnt, (long)whr);
-                empty(cnt, whr);
-                break;
-            }
-            case I_SCHEDULE: {
-                Aint event = pop(stack);
-                Aint where = pop(stack);
-                Aint after = pop(stack);
-                if (traceInstructionOption)
-                    printf("SCHEDULE \t%7ld, %7ld, %7ld\t\t\t\t", (long)event, (long)where, (long)after);
-                schedule(event, where, after);
-                break;
-            }
-            case I_CANCEL: {
-                Aint event = pop(stack);
-                if (traceInstructionOption)
-                    printf("CANCEL \t%7ld\t\t\t\t", (long)event);
-                cancelEvent(event);
-                break;
-            }
-            case I_MAKE: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                Abool val = pop(stack);
-                if (traceInstructionOption)
-                    printf("MAKE \t%7ld, %7ld, %s\t\t\t", (long)id, (long)atr, booleanValue(val));
-                setInstanceAttribute(id, atr, val);
-                break;
-            }
-            case I_SET: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                Aptr val = pop(stack);
-                if (traceInstructionOption) {
-                    printf("SET \t%7ld, %7ld, %7ld\t\t\t\t", (long)id, (long)atr, (long)val);
-                }
-                setInstanceAttribute(id, atr, val);
-                break;
-            }
-            case I_SETSTR: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                Aptr str = pop(stack);
-                if (traceInstructionOption) {
-                    printf("SETSTR\t%7ld, %7ld, %s\t\t\t\t", (long)id, (long)atr, stringValue(str));
-                }
-                setInstanceStringAttribute(id, atr, (char *)fromAptr(str));
-                break;
-            }
-            case I_SETSET: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                Aptr set = pop(stack);
-                if (traceInstructionOption) {
-                    printf("SETSET\t%7ld, %7ld, %7s\t\t", (long)id, (long)atr, pointerValue(set));
-                }
-                setInstanceSetAttribute(id, atr, set);
-                break;
-            }
-            case I_NEWSET: {
-                Set *set = newSet(0);
-                if (traceInstructionOption) {
-                    printf("NEWSET\t\t\t");
-                }
-                push(stack, toAptr(set));
-                tracePointerTopValue();
-                break;
-            }
-            case I_UNION: {
-                Aptr set2 = pop(stack);
-                Aptr set1 = pop(stack);
-                if (traceInstructionOption) {
-                    printf("UNION\t%7ld, %7ld\t\t\t\t", (long)set1, (long)set2);
-                }
-                push(stack, toAptr(setUnion((Set *)fromAptr(set1), (Set *)fromAptr(set2))));
-                tracePointerTopValue();
-                freeSet((Set *)fromAptr(set1));
-                freeSet((Set *)fromAptr(set2));
-                break;
-            }
-            case I_INCR: {
-                Aint step = pop(stack);
-                if (traceInstructionOption) {
-                    printf("INCR\t%7ld", (long)step);
-                }
-                push(stack, pop(stack) + step);
-                traceIntegerTopValue();
-                break;
-            }
-            case I_DECR: {
-                Aint step = pop(stack);
-                if (traceInstructionOption) {
-                    printf("DECR\t%7ld\t\t\t\t\t", (long)step);
-                }
-                push(stack, pop(stack) - step);
-                traceIntegerTopValue();
-                break;
-            }
-            case I_INCLUDE: {
-                Aint member = pop(stack);
-                if (traceInstructionOption) {
-                    printf("INCLUDE\t%7ld\t\t\t\t\t", (long)member);
-                }
-                addToSet((Set *)fromAptr(top(stack)), member);
-                break;
-            }
-            case I_EXCLUDE: {
-                Aint member = pop(stack);
-                if (traceInstructionOption) {
-                    printf("EXCLUDE\t%7ld", (long)member);
-                }
-                removeFromSet((Set *)fromAptr(top(stack)), member);
-                break;
-            }
-            case I_SETSIZE: {
-                Set *set = (Set *)fromAptr(pop(stack));
-                if (traceInstructionOption)
-                    printf("SETSIZE\t%7ld\t\t", (long)set);
-                push(stack, setSize(set));
-                if (traceInstructionOption)
-                    traceIntegerTopValue();
-                break;
-            }
-            case I_SETMEMB: {
-                Set *set = (Set *)fromAptr(pop(stack));
-                Aint index = pop(stack);
-                if (traceInstructionOption)
-                    printf("SETMEMB\t%7ld, %7ld", (long)set, (long)index);
-                push(stack, getSetMember(set, index));
-                if (traceInstructionOption)
-                    traceIntegerTopValue();
-                break;
-            }
-            case I_CONTSIZE: {
-                Abool transitivity = pop(stack);
-                Aint container = pop(stack);
-                if (traceInstructionOption)
-                    printf("CONTSIZE\t%7ld, %7s\t", (long)container, transitivityFlag((ATrans)transitivity));
-                push(stack, containerSize(container, (ATrans)transitivity));
-                if (traceInstructionOption)
-                    traceIntegerTopValue();
-                break;
-            }
-            case I_CONTMEMB: {
-                Abool transitivity = pop(stack);
-                Aint container = pop(stack);
-                Aint index = pop(stack);
-                if (traceInstructionOption)
-                    printf("CONTMEMB\t%7ld, %7ld, %7s", (long)container, (long)index, transitivityFlag((ATrans)transitivity));
-                push(stack, getContainerMember(container, index, transitivity));
-                if (traceInstructionOption)
-                    traceIntegerTopValue();
-                break;
-            }
-            case I_ATTRIBUTE: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("ATTRIBUTE %7ld, %7ld\t", (long)id, (long)atr);
-                push(stack, getInstanceAttribute(id, atr));
-                traceIntegerTopValue();
-                break;
-            }
-            case I_ATTRSTR: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("ATTRSTR \t%7ld, %7ld", (long)id, (long)atr);
-                push(stack, toAptr(getInstanceStringAttribute(id, atr)));
-                traceStringTopValue();
-                break;
-            }
-            case I_ATTRSET: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("ATTRSET \t%7ld, %7ld", (long)id, (long)atr);
-                push(stack, toAptr(getInstanceSetAttribute(id, atr)));
-                tracePointerTopValue();
-                break;
-            }
-            case I_SHOW: {
-                Aint image = pop(stack);
-                Aint align = pop(stack);
-                if (traceInstructionOption)
-                    printf("SHOW \t%7ld, %7ld\t\t\t\t", (long)image, (long)align);
-                showImage(image, align);
-                break;
-            }
-            case I_PLAY: {
-                Aint sound = pop(stack);
-                if (traceInstructionOption)
-                    printf("PLAY \t%7ld\t\t\t\t", (long)sound);
-                playSound(sound);
-                break;
-            }
-            case I_LOCATE: {
-                Aid id = pop(stack);
-                Aint whr = pop(stack);
-                if (traceInstructionOption)
-                    printf("LOCATE \t%7ld, %7ld\t\t\t", (long)id, (long)whr);
-                locate(id, whr);
-                break;
-            }
-            case I_WHERE: {
-                Abool transitivity = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("WHERE \t%7ld, %7s", (long)id, transitivityFlag((ATrans)transitivity));
-                push(stack, where(id, (ATrans)transitivity));
-                traceInstanceTopValue();
-                break;
-            }
-            case I_LOCATION: {
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("LOCATION \t%7ld\t\t", (long)id);
-                push(stack, locationOf(id));
-                traceInstanceTopValue();
-                break;
-            }
-            case I_HERE: {
-                Abool transitivity = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("HERE \t%7ld, %s\t\t\t", (long)id, transitivityFlag((ATrans)transitivity));
-                push(stack, isHere(id, (ATrans)transitivity));
-                tracebooleanTopValue();
-                break;
-            }
-            case I_NEARBY: {
-                Abool transitivity = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("NEARBY \t%7ld, %s\t\t\t", (long)id, transitivityFlag((ATrans)transitivity));
-                push(stack, isNearby(id, (ATrans)transitivity));
-                tracebooleanTopValue();
-                break;
-            }
-            case I_NEAR: {
-                Abool transitivity = pop(stack);
-                Aint other = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("NEAR \t%7ld, %7ld, %s\t\t\t", (long)id, (long)other, transitivityFlag((ATrans)transitivity));
-                push(stack, isNear(id, other, (ATrans)transitivity));
-                tracebooleanTopValue();
-                break;
-            }
-            case I_AT: {
-                Abool transitivity = pop(stack);
-                Aint other = pop(stack);
-                Aint instance = pop(stack);
-                if (traceInstructionOption)
-                    printf("AT \t%7ld, %7ld, %s", (long)instance, (long)other, transitivityFlag((ATrans)transitivity));
-                push(stack, isAt(instance, other, (ATrans)transitivity));
-                tracebooleanTopValue();
-                break;
-            }
-            case I_IN: {
-                Abool transitivity = pop(stack);
-                Aint cnt = pop(stack);
-                Aint obj = pop(stack);
-                if (traceInstructionOption)
-                    printf("IN \t%7ld, %7ld, %s", (long)obj, (long)cnt, transitivityFlag((ATrans)transitivity));
-                push(stack, isIn(obj, cnt, (ATrans)transitivity));
-                tracebooleanTopValue();
-                break;
-            }
-            case I_INSET: {
-                Aptr set = pop(stack);
-                Aword element = pop(stack);
-                if (traceInstructionOption)
-                    printf("INSET \t%7ld, %7ld", (long)element, (long)set);
-                push(stack, inSet((Set*)fromAptr(set), element));
-                freeSet((Set *)fromAptr(set));
-                tracebooleanTopValue();
-                break;
-            }
-            case I_USE: {
-                Aid act = pop(stack);
-                Aint scr = pop(stack);
-                if (traceInstructionOption)
-                    printf("USE \t%7ld, %7ld\t\t\t\t", (long)act, (long)scr);
-                use(act, scr);
-                break;
-            }
-            case I_STOP: {
-                Aid actor = pop(stack);
-                if (traceInstructionOption)
-                    printf("STOP \t%7ld\t\t\t\t\t", (long)actor);
-                stop(actor);
-                break;
-            }
-            case I_DESCRIBE: {
-                Aid id = pop(stack);
-                if (traceInstructionOption) {
-                    printf("DESCRIBE \t%7ld\t\t\t", (long)id);
-                    col = 41;		/* To format it better! */
-                }
-                describe(id);
-                if (traceInstructionOption)
-                    printf("\n\t\t\t\t\t\t");
-                break;
-            }
-            case I_SAY: {
-                Aint form = pop(stack);
-                Aid id = pop(stack);
-                if (traceInstructionOption)
-                    printf("SAY\t%7s, %7ld\t\t\t", printForm((SayForm)form), (long)id);
-                if (form == SAY_SIMPLE)
-                    say(id);
-                else
-                    sayForm(id, (SayForm)form);
-                if (traceInstructionOption)
-                    printf("\t\t\t\t\t\t\t");
-                break;
-            }
-            case I_SAYINT: {
-                Aword val = pop(stack);
-                if (traceInstructionOption)
-                    printf("SAYINT\t%7ld\t\t\t\"", (long)val);
-                sayInteger(val);
-                if (traceInstructionOption)
-                    printf("\"\n\t\t\t\t\t\t\t");
-                break;
-            }
-            case I_SAYSTR: {
-                Aptr sayAddr = pop(stack);
-                if (traceInstructionOption)
-                    printf("SAYSTR\t%7ld\t\ty\t", (long)sayAddr);
-                sayString((char *)fromAptr(sayAddr));
-                if (traceInstructionOption)
-                    printf("\n\t\t\t\t\t\t");
-                break;
-            }
-            case I_IF: {
-                Aword v = pop(stack);
-                if (traceInstructionOption)
-                    printf("IF \t%s\t\t\t\t\t", booleanValue(v));
-                interpretIf(v);
-                break;
-            }
-            case I_ELSE: {
-                if (traceInstructionOption)
-                    printf("ELSE\t\t\t\t\t\t");
-                interpretElse();
-                break;
-            }
-            case I_ENDIF: {
-                if (traceInstructionOption)
-                    printf("ENDIF\t\t\t\t\t\t");
-                break;
-            }
-            case I_AND: {
-                Aword rh = pop(stack);
-                Aword lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("AND \t%s, %s", booleanValue(lh), booleanValue(rh));
-                push(stack, lh && rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_OR: {
-                Aword rh = pop(stack);
-                Aword lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("OR \t%s, %s", booleanValue(lh), booleanValue(rh));
-                push(stack, lh || rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_NE: {
-                Aword rh = pop(stack);
-                Aword lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("NE \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh != rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_EQ: {
-                Aword rh = pop(stack);
-                Aword lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("EQ \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh == rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_STREQ: {
-                Aptr rh = pop(stack);
-                Aptr lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("STREQ \t0x%lx, 0x%lx", (long)lh, (long)rh);
-                push(stack, streq((char *)fromAptr(lh), (char *)fromAptr(rh)));
-                tracebooleanTopValue();
-                if (traceInstructionOption)
-	                printf("\t");
-                deallocate(fromAptr(lh));
-                deallocate(fromAptr(rh));
-                break;
-            }
-            case I_STREXACT: {
-                Aptr rh = pop(stack);
-                Aptr lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("STREXACT \t0x%lx, 0x%lx", (long)lh, (long)rh);
-                push(stack, strcmp((char *)fromAptr(lh), (char *)fromAptr(rh)) == 0);
-                tracebooleanTopValue();
-                deallocate(fromAptr(lh));
-                deallocate(fromAptr(rh));
-                break;
-            }
-            case I_LE: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("LE \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh <= rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_GE: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("GE \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh >= rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_LT: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("LT \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh < rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_GT: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("GT \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh > rh);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_PLUS: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("PLUS \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh + rh);
-                traceIntegerTopValue();
-                break;
-            }
-            case I_MINUS: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("MINUS \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh - rh);
-                traceIntegerTopValue();
-                break;
-            }
-            case I_MULT: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("MULT \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh * rh);
-                traceIntegerTopValue();
-                break;
-            }
-            case I_DIV: {
-                Aint rh = pop(stack);
-                Aint lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("DIV \t%7ld, %7ld", (long)lh, (long)rh);
-                push(stack, lh / rh);
-                traceIntegerTopValue();
-                break;
-            }
-            case I_NOT: {
-                Aword val = pop(stack);
-                if (traceInstructionOption)
-                    printf("NOT \t%s\t\t\t", booleanValue(val));
-                push(stack, !val);
-                tracebooleanTopValue();
-                break;
-            }
-            case I_RND: {
-                Aint from = pop(stack);
-                Aint to = pop(stack);
-                if (traceInstructionOption)
-                    printf("RANDOM \t%7ld, %7ld", (long)from, (long)to);
-                push(stack, randomInteger(from, to));
-                traceIntegerTopValue();
-                break;
-            }
-            case I_BTW: {
-                Aint high = pop(stack);
-                Aint low = pop(stack);
-                Aint val = pop(stack);
-                if (traceInstructionOption)
-                    printf("BETWEEN \t%7ld, %7ld, %7ld", (long)val, (long)low, (long)high);
-                push(stack, between(val, low, high));
-                traceIntegerTopValue();
-                break;
-            }
-
-                /*------------------------------------------------------------* \
-                  String functions
-                \*------------------------------------------------------------*/
-            case I_CONCAT: {
-                Aptr s2 = pop(stack);
-                Aptr s1 = pop(stack);
-                if (traceInstructionOption)
-                    printf("CONCAT \t%s, %s", pointerValue(s1), pointerValue(s2));
-                push(stack, concat(s1, s2));
-                traceStringTopValue();
-                deallocate(fromAptr(s1));
-                deallocate(fromAptr(s2));
-                break;
-            }
-
-            case I_CONTAINS: {
-                Aptr substring = pop(stack);
-                Aptr string = pop(stack);
-                if (traceInstructionOption)
-                    printf("CONTAINS \t%s, %s", pointerValue(string), pointerValue(substring));
-                push(stack, contains(string, substring));
-                traceIntegerTopValue();
-                deallocate(fromAptr(string));
-                deallocate(fromAptr(substring));
-                break;
-            }
-
-            case I_STRIP: {
-                Aint atr = pop(stack);
-                Aid id = pop(stack);
-                Aint words = pop(stack);
-                Aint count = pop(stack);
-                Aint first = pop(stack);
-                if (traceInstructionOption)
-                    printf("STRIP \t%7ld, %7ld, %7ld, %7ld, %7ld", (long)first, (long)count, (long)words, (long)id, (long)atr);
-                push(stack, strip(first, count, words, id, atr));
-                traceStringTopValue();
-                break;
-            }
-
-                /*------------------------------------------------------------
-                  Aggregation
-                  ------------------------------------------------------------*/
-            case I_MIN:
-            case I_SUM:
-            case I_MAX: {
-                Aint attribute = pop(stack);
-                Aint loopIndex = pop(stack);
-                Aint limit = pop(stack);
-                Aint aggregate = pop(stack);
-                switch (I_OP(i)) {
-                case I_MAX:
-                    if (traceInstructionOption)
-                        printf("MAX \t%7ld\t\t\t", (long)attribute);
-                    if (aggregate < attribute)
-                        push(stack, attribute);
-                    else
-                        push(stack, aggregate);
-                    break;
-                case I_MIN:
-                    if (traceInstructionOption)
-                        printf("MIN \t%7ld\t\t\t", (long)attribute);
-                    if (aggregate > attribute)
-                        push(stack, attribute);
-                    else
-                        push(stack, aggregate);
-                    break;
-                case I_SUM:
-                    if (traceInstructionOption)
-                        printf("SUM \t%7ld\t\t\t", (long)attribute);
-                    push(stack, aggregate + attribute);
-                    break;
-                }
-                traceIntegerTopValue();
-                push(stack, limit);
-                push(stack, loopIndex);
-                break;
-            }
-            case I_COUNT: {
-                Aint loopIndex = pop(stack);
-                Aint limit = pop(stack);
-                if (traceInstructionOption)
-                    printf("COUNT\t\t\t");
-                push(stack, pop(stack) + 1);
-                traceIntegerTopValue();
-                push(stack, limit);
-                push(stack, loopIndex);
-                break;
-            }
-            case I_TRANSCRIPT: {
-                Aint on_or_off = pop(stack);
-                if (traceInstructionOption)
-                    printf("TRANSCRIPT\t\t\t");
-                if (on_or_off)
-                    startTranscript();
-                else
-                    stopTranscript();
-                break;
-            }
-
-                /*------------------------------------------------------------
-                  Depending On
-                  ------------------------------------------------------------*/
-            case I_DEPEND:
-                if (traceInstructionOption)
-                    printf("DEPEND\t\t\t\t\t\t");
-                break;
-
-            case I_DEPCASE:
-                if (traceInstructionOption)
-                    printf("DEPCASE\t\t\t\t\t\t");
-                depcase();
-                break;
-
-            case I_DEPEXEC: {
-                Aword v = pop(stack);
-                if (traceInstructionOption) {
-                    printf("DEPEXEC \t\t\t");
-                    if (v) printf(" TRUE"); else printf("FALSE");
-                    printf("\t\t\t\t\t");
-                }
-                depexec(v);
-                break;
-            }
-
-            case I_DEPELSE:
-                if (traceInstructionOption)
-                    printf("DEPELSE\t\t\t\t\t\t");
-                depcase();
-                break;
-
-            case I_ENDDEP:
-                if (traceInstructionOption)
-                    printf("ENDDEP\t\t\t\t\t\t");
-                pop(stack);
-                break;
-
-            case I_ISA: {
-                Aid rh = pop(stack);
-                Aid lh = pop(stack);
-                if (traceInstructionOption)
-                    printf("ISA \t%7ld, %7ld\t", (long)lh, (long)rh);
-                push(stack, isA(lh, rh));
-                tracebooleanTopValue();
-                break;
-            }
-
-            case I_FRAME: {
-                Aint size = pop(stack);
-                if (traceInstructionOption)
-                    printf("FRAME \t%7ld\t\t\t\t\t", (long)size);
-                newFrame(stack, size);
-                break;
-            }
-
-            case I_GETLOCAL: {
-                Aint framesBelow = pop(stack);
-                Aint variableNumber = pop(stack);
-                if (traceInstructionOption)
-                    printf("GETLOCAL \t%7ld, %7ld\t", (long)framesBelow, (long)variableNumber);
-                push(stack, getLocal(stack, framesBelow, variableNumber));
-                traceIntegerTopValue();
-                break;
-            }
-
-            case I_SETLOCAL: {
-                Aint framesBelow = pop(stack);
-                Aint variableNumber = pop(stack);
-                Aint value = pop(stack);
-                if (traceInstructionOption)
-                    printf("SETLOCAL \t%7ld, %7ld, %7ld\t\t", (long)framesBelow, (long)variableNumber, (long)value);
-                setLocal(stack, framesBelow, variableNumber, value);
-                break;
-            }
-
-            case I_ENDFRAME: {
-                if (traceInstructionOption)
-                    printf("ENDFRAME\t\t\t\t\t\t");
-                endFrame(stack);
-                break;
-            }
-
-            case I_LOOP: {
-                Aint index = pop(stack);
-                Aint limit = pop(stack);
-                if (traceInstructionOption)
-                    printf("LOOP \t\t\t\t\t\t");
-                push(stack, limit);
-                push(stack, index);
-                if (index > limit)
-                    goToLOOPEND();
-                break;
-            }
-
-            case I_LOOPNEXT: {
-                if (traceInstructionOption)
-                    printf("LOOPNEXT\t\t\t\t\t\t");
-                nextLoop();
-                break;
-            }
-
-            case I_LOOPEND: {
-                Aint index = pop(stack);
-                Aint limit = pop(stack);
-                if (traceInstructionOption)
-                    printf("LOOPEND\t\t\t\t\t\t");
-                endLoop(index, limit);
-                break;
-            }
-
-            case I_RETURN:
-                if (traceInstructionOption)
-                    printf("RETURN\n--------------------------------------------------\n");
-                pc = oldpc;
-                goto exitInterpreter;
-
-            default:
-                syserr("Unknown STMOP instruction.");
-                break;
-            }
-            if (fail) {
-                pc = oldpc;
-                goto exitInterpreter;
-            }
-            if (traceStackOption) {
-                if (!skipStackDump)
-                    dumpStack(stack);
-                skipStackDump = FALSE;
-            }
-            break;
-
-        default:
-            syserr("Unknown instruction class.");
-            break;
-        }
-    }
- exitInterpreter:
-    recursionDepth--;
+void interpret(Aaddr adr) {
+	Aaddr oldpc;
+	Aword i;
+
+	/* Check for mock implementation */
+	if (interpreterMock != NULL) {
+		interpreterMock(adr);
+		return;
+	}
+
+	/* Sanity checks: */
+	if (adr == 0) syserr("Interpreting at address 0.");
+	checkForRecursion(adr);
+
+	if (traceInstructionOption)
+		printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++");
+
+	oldpc = pc;
+	pc = adr;
+	while (TRUE) {
+		if (pc > memTop)
+			syserr("Interpreting outside program.");
+
+		i = memory[pc++];
+
+		switch (I_CLASS(i)) {
+		case C_CONST:
+			if (tracePushOption) printf("\n%4x: PUSH  \t%7ld\t\t\t\t\t", pc - 1, (long)I_OP(i));
+			push(stack, I_OP(i));
+			if (tracePushOption && traceStackOption)
+				dumpStack(stack);
+			break;
+		case C_CURVAR:
+			if (traceInstructionOption) printf("\n%4x: ", pc - 1);
+			switch (I_OP(i)) {
+			case V_PARAM:
+				if (traceInstructionOption) printf("PARAM \t%7ld\t\t\t\t=%ld\t", (long)top(stack),
+					                                   (long)globalParameters[top(stack) - 1].instance);
+				push(stack, globalParameters[pop(stack) - 1].instance);
+				break;
+			case V_CURLOC:
+				if (traceInstructionOption) printf("CURLOC \t\t\t\t\t=%d\t", current.location);
+				push(stack, current.location);
+				break;
+			case V_CURACT:
+				if (traceInstructionOption) printf("CURACT \t\t\t\t\t=%d\t", current.actor);
+				push(stack, current.actor);
+				break;
+			case V_CURVRB:
+				if (traceInstructionOption) printf("CURVRB \t\t\t\t\t=%d\t", current.verb);
+				push(stack, current.verb);
+				break;
+			case V_CURRENT_INSTANCE:
+				if (traceInstructionOption) printf("CURINS \t\t\t\t\t=%d\t", current.instance);
+				push(stack, current.instance);
+				break;
+			case V_SCORE:
+				if (traceInstructionOption) printf("CURSCORE \t\t\t\t\t=%d\t", current.score);
+				push(stack, current.score);
+				break;
+			case V_MAX_INSTANCE: {
+				int instanceMax = isPreBeta3(header->version) ? header->instanceMax : header->instanceMax - 1;
+				if (traceInstructionOption) printf("MAXINSTANCE \t\t\t\t=%d\t", instanceMax);
+				push(stack, instanceMax);
+				break;
+			}
+			default:
+				syserr("Unknown CURVAR instruction.");
+				break;
+			}
+			if (traceStackOption)
+				dumpStack(stack);
+			break;
+
+		case C_STMOP:
+			if (traceInstructionOption) printf("\n%4x: ", pc - 1);
+			switch (I_OP(i)) {
+
+			case I_DUP:
+				if (traceInstructionOption)
+					printf("DUP\t\t\t\t\t\t");
+				stackDup();
+				break;
+
+			case I_DUPSTR:
+				if (traceInstructionOption)
+					printf("DUPSTR\t\t\t\t\t\t");
+				push(stack, toAptr(strdup((char *)fromAptr(top(stack)))));
+				break;
+
+			case I_POP: {
+				Aptr top = pop(stack);
+				if (traceInstructionOption)
+					printf("POP\t%7ld", (long)top);
+				break;
+			}
+
+			case I_LINE: {
+				Aint line = pop(stack);
+				Aint file = pop(stack);
+				traceInstruction("LINE\t%7ld, %7ld\t\t\t", (long)file, (long)line);
+				if (traceStackOption)
+					dumpStack(stack);
+				skipStackDump = TRUE;
+				if (line != 0) {
+					bool atNext = stopAtNextLine && line != current.sourceLine;
+					bool atBreakpoint =  breakpointIndex(file, line) != -1;
+					if (traceSourceOption && stillOnSameLine(line, file)) {
+						if (col != 1 || traceInstructionOption)
+							printf("\n");
+						showSourceLine(file, line);
+						if (!traceInstructionOption)
+							printf("\n");
+					}
+					current.sourceLine = line;
+					current.sourceFile = file;
+					if (atNext || atBreakpoint) {
+						stopAtNextLine = FALSE;
+						debug(TRUE, line, file);
+					}
+				}
+				break;
+			}
+
+			case I_PRINT: {
+				Aint fpos = pop(stack);
+				Aint len = pop(stack);
+				if (traceInstructionOption) {
+					printf("PRINT \t%7ld, %7ld\t\"", (long)fpos, (long)len);
+					col = 41;       /* To break lines better! */
+				}
+				print(fpos, len);
+				if (traceInstructionOption) {
+					printf("\"");
+					if (traceStackOption)
+						printf("\n\t\t\t\t\t\t\t");
+				}
+				break;
+			}
+
+			case I_STYLE: {
+				Aint style = pop(stack);
+				if (traceInstructionOption) {
+					printf("STYLE \t%7ld\t\t\"", (long)style);
+				}
+				setStyle(style);
+				break;
+			}
+
+			case I_SYSTEM: {
+				Aint fpos = pop(stack);
+				Aint len = pop(stack);
+				if (traceInstructionOption) {
+					printf("SYSTEM \t%7ld, %7ld\t\"", (long)fpos, (long)len);
+					col = 34;       /* To format it better! */
+				}
+				sys(fpos, len);
+				if (traceInstructionOption)
+					printf("\"\t\t\t\t\t\t");
+				break;
+			}
+
+			case I_GETSTR: {
+				Aint fpos = pop(stack);
+				Aint len = pop(stack);
+				if (traceInstructionOption)
+					printf("GETSTR\t%7ld, %7ld", (long)fpos, (long)len);
+				push(stack, toAptr(getStringFromFile(fpos, len)));
+				traceStringTopValue();
+				break;
+			}
+
+			case I_QUIT: {
+				if (traceInstructionOption)
+					printf("QUIT\t\t\t\t\t\t");
+				quitGame();
+				break;
+			}
+			case I_LOOK: {
+				if (traceInstructionOption)
+					printf("LOOK\t\t\t\t\t\t");
+				look();
+				break;
+			}
+			case I_SAVE: {
+				if (traceInstructionOption)
+					printf("SAVE\t\t\t\t\t\t");
+				save();
+				break;
+			}
+			case I_RESTORE: {
+				if (traceInstructionOption)
+					printf("RESTORE\t\t\t\t\t\t");
+				restore();
+				break;
+			}
+			case I_RESTART: {
+				if (traceInstructionOption)
+					printf("RESTART\t\t\t\t\t\t");
+				restartGame();
+				break;
+			}
+
+			case I_SCORE: {
+				Aint sc = pop(stack);
+				if (traceInstructionOption)
+					printf("SCORE \t%7ld\t\t=%ld\t\t\t", (long)sc, (long)scores[sc - 1]);
+				score(sc);
+				break;
+			}
+			case I_VISITS: {
+				Aint v = pop(stack);
+				if (traceInstructionOption)
+					printf("VISITS \t%7ld\t\t\t\t\t", (long)v);
+				visits(v);
+				break;
+			}
+
+			case I_LIST: {
+				Aint cnt = pop(stack);
+				if (traceInstructionOption)
+					printf("LIST \t%7ld\t\t\t\t\t", (long)cnt);
+				list(cnt);
+				break;
+			}
+			case I_EMPTY: {
+				Aint cnt = pop(stack);
+				Aint whr = pop(stack);
+				if (traceInstructionOption)
+					printf("EMPTY \t%7ld, %7ld\t\t\t\t", (long)cnt, (long)whr);
+				empty(cnt, whr);
+				break;
+			}
+			case I_SCHEDULE: {
+				Aint event = pop(stack);


Commit: 86f9985951203ed39e1a6c08e32730b478b10517
    https://github.com/scummvm/scummvm/commit/86f9985951203ed39e1a6c08e32730b478b10517
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Re-enable main game loop

Changed paths:
  A engines/glk/alan3/jumps.h
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/alan3.h
    engines/glk/alan3/main.cpp
    engines/glk/alan3/main.h


diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 4dd9191..3958bf2 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -41,12 +41,16 @@ namespace Alan3 {
 Alan3 *g_vm = nullptr;
 
 Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
-	vm_exited_cleanly(false), _restartFlag(false), _saveSlot(-1), _pendingLook(false) {
+	vm_exited_cleanly(false), _saveSlot(-1), _pendingLook(false) {
 	g_vm = this;
+
+	// main
+	codfil = nullptr;
 //	txtfil = nullptr;
 //	logfil = nullptr;
 	memory = nullptr;
 
+	// options
 	verboseOption = false;
 	ignoreErrorOption = false;
 	debugOption = false;
@@ -86,33 +90,31 @@ bool Alan3::initialize() {
 	glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
 	                                     winmethod_Fixed, 1, wintype_TextGrid, 0);
 	g_vm->glk_set_window(glkMainWin);
+
+	// Set up the code file to point to the already opened game file
+	codfil = &_gameFile;
 	/*
-	    // Set up the code file to point to the already opened game file
-	    codfil = &_gameFile;
-	    strncpy(codfnm, getFilename().c_str(), 255);
-	    codfnm[255] = '\0';
-
-	    if (_gameFile.size() < 8) {
-	        GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
-	        return false;
-	    }
-
-	    if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
-	        GUIErrorMessage(_("This is not a valid Alan3 file."));
-	        return false;
-	    }
-
-	    // Open up the text file
-	    txtfil = new Common::File();
-	    if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
-	        GUIErrorMessage("Could not open adventure text data file");
-	        delete txtfil;
-	        return false;
-	    }
-
-	    // Check for a save being loaded directly from the launcher
-	    _saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+	if (_gameFile.size() < 8) {
+	    GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
+	    return false;
+	}
+
+	if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
+	    GUIErrorMessage(_("This is not a valid Alan3 file."));
+	    return false;
+	}
+
+	// Open up the text file
+	txtfil = new Common::File();
+	if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
+	    GUIErrorMessage("Could not open adventure text data file");
+	    delete txtfil;
+	    return false;
+	}
 	*/
+	// Check for a save being loaded directly from the launcher
+	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+
 	return true;
 }
 
diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
index f4bb7a5..6693476 100644
--- a/engines/glk/alan3/alan3.h
+++ b/engines/glk/alan3/alan3.h
@@ -32,8 +32,6 @@ namespace Alan3 {
  * Alan3 game interpreter
  */
 class Alan3 : public GlkAPI {
-private:
-	bool _restartFlag;
 public:
 	bool vm_exited_cleanly;
 	Common::String _advName;
@@ -66,20 +64,6 @@ public:
 	void runGame();
 
 	/**
-	 * Flag for the game to restart
-	 */
-	void setRestart(bool flag) {
-		_restartFlag = flag;
-	}
-
-	/**
-	 * Returns whether the game should restart
-	 */
-	bool shouldRestart() const {
-		return _restartFlag;
-	}
-
-	/**
 	 * Returns the running interpreter type
 	 */
 	virtual InterpreterType getInterpreterType() const override {
diff --git a/engines/glk/alan3/jumps.h b/engines/glk/alan3/jumps.h
new file mode 100644
index 0000000..882ffbd
--- /dev/null
+++ b/engines/glk/alan3/jumps.h
@@ -0,0 +1,85 @@
+/* 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 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, P2); if (context._break) return; }
+#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return; }
+#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, 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, P2); if (context._break) return; }
+#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return; }
+#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, 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, P2); if (context._break) return 0; }
+#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return 0; }
+#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, 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, P2); if (context._break) return 0; }
+#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return 0; }
+#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, 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/main.cpp b/engines/glk/alan3/main.cpp
index c9612db..62ee3bf 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -36,6 +36,7 @@
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/instance.h"
 #include "glk/alan3/inter.h"
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/lists.h"
 #include "glk/alan3/literal.h"
 #include "glk/alan3/location.h"
@@ -731,80 +732,85 @@ static void moveActor(int theActor) {
 	current.instance = previousInstance;
 }
 
-#define RESTARTED (setjmp(restartLabel) != NO_JUMP_RETURN)
-#define ERROR_RETURNED (setjmp(returnLabel) != NO_JUMP_RETURN)
-
 /*======================================================================*/
 void run(void) {
-	static Stack theStack = NULL; /* Needs to survive longjmp() */
+	Stack theStack = NULL;
+	Context ctx;
 
-	openFiles();
-	load();         /* Load program */
-#ifdef TODO
-	if (RESTARTED) {
-		deleteStack(theStack);
-	}
+	do {
+		openFiles();
+		load();			// Load program
 
-	theStack = createStack(STACKSIZE);
-	setInterpreterStack(theStack);
+		if (theStack)
+			deleteStack(theStack);
 
-	initStateStack();
+		theStack = createStack(STACKSIZE);
+		setInterpreterStack(theStack);
 
-	if (!ERROR_RETURNED)      /* Can happen in start section too... */
-		init();               /* Initialise and start the adventure */
+		initStateStack();
 
-	while (TRUE) {
-		if (debugOption)
-			debug(FALSE, 0, 0);
+		// Initialise and start the adventure
+		init();
 
-		if (stackDepth(theStack) != 0)
-			syserr("Stack is not empty in main loop");
+		while (!g_vm->shouldQuit()) {
+			if (!ctx._break) {
+				if (debugOption)
+					debug(FALSE, 0, 0);
 
-		if (!current.meta)
-			runPendingEvents();
+				if (stackDepth(theStack) != 0)
+					syserr("Stack is not empty in main loop");
 
-		/* Return here if error during execution */
-		switch (setjmp(returnLabel)) {
-		case NO_JUMP_RETURN:
-			break;
-		case ERROR_RETURN:
-			forgetGameState();
-			forceNewPlayerInput();
-			break;
-		case UNDO_RETURN:
-			forceNewPlayerInput();
-			break;
-		default:
-			syserr("Unexpected longjmp() return value");
-		}
+				if (!current.meta)
+					runPendingEvents();
+			} else {
+				#ifdef TODO
+				// Return here if error during execution
+				switch (setjmp(returnLabel)) {
+				case NO_JUMP_RETURN:
+					break;
+				case ERROR_RETURN:
+					forgetGameState();
+					forceNewPlayerInput();
+					break;
+				case UNDO_RETURN:
+					forceNewPlayerInput();
+					break;
+				default:
+					syserr("Unexpected longjmp() return value");
+				}
+				#endif
+			}
 
-		recursionDepth = 0;
+			recursionDepth = 0;
 
-		/* Move all characters, hero first */
-		rememberGameState();
-		current.meta = FALSE;
-		moveActor(header->theHero);
+			// Move all characters, hero first
+			rememberGameState();
+			current.meta = FALSE;
+			moveActor(header->theHero);
 
-		if (gameStateChanged)
-			rememberCommands();
-		else
-			forgetGameState();
+			if (gameStateChanged)
+				rememberCommands();
+			else
+				forgetGameState();
 
-		if (!current.meta) {
-			current.tick++;
+			if (!current.meta) {
+				current.tick++;
 
-			/* Remove this call? Since Eval is done up there after each event... */
-			resetAndEvaluateRules(rules, header->version);
+				// Remove this call? Since Eval is done up there after each event...
+				resetAndEvaluateRules(rules, header->version);
 
-			/* Then all the other actors... */
-			for (uint i = 1; i <= header->instanceMax; i++)
-				if (i != header->theHero && isAActor(i)) {
-					moveActor(i);
-					resetAndEvaluateRules(rules, header->version);
-				}
+				/* Then all the other actors... */
+				for (uint i = 1; i <= header->instanceMax; i++)
+					if (i != header->theHero && isAActor(i)) {
+						moveActor(i);
+						resetAndEvaluateRules(rules, header->version);
+					}
+			}
+
+			if (ctx._break && ctx._label == "restart")
+				break;
 		}
-	}
-#endif
+	} while (!g_vm->shouldQuit() && ctx._label == "restart");
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/main.h b/engines/glk/alan3/main.h
index 60e3d05..6934f01 100644
--- a/engines/glk/alan3/main.h
+++ b/engines/glk/alan3/main.h
@@ -25,12 +25,15 @@
 
 /* Header file for main unit of ARUN Alan System interpreter */
 
+#include "common/stream.h"
 #include "glk/alan3/types.h"
 #include "glk/alan3/acode.h"
 
 namespace Glk {
 namespace Alan3 {
 
+extern Common::SeekableReadStream *codfil;
+
 extern VerbEntry *vrbs;     // Verb table pointer
 
 extern void run();


Commit: 9c197d71ab40143a40daa8b7599db18ed98a1215
    https://github.com/scummvm/scummvm/commit/9c197d71ab40143a40daa8b7599db18ed98a1215
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Add support for loading a3r Blorb files

Changed paths:
    engines/glk/blorb.cpp
    engines/glk/blorb.h
    engines/glk/glk.cpp


diff --git a/engines/glk/blorb.cpp b/engines/glk/blorb.cpp
index 03c3dd3..3c60fd3 100644
--- a/engines/glk/blorb.cpp
+++ b/engines/glk/blorb.cpp
@@ -215,7 +215,39 @@ bool Blorb::isBlorb(const Common::String &filename, uint32 type) {
 
 bool Blorb::hasBlorbExt(const Common::String &filename) {
 	return filename.hasSuffixIgnoreCase(".blorb") || filename.hasSuffixIgnoreCase(".zblorb")
-		|| filename.hasSuffixIgnoreCase(".gblorb") || filename.hasSuffixIgnoreCase(".blb");
+		|| filename.hasSuffixIgnoreCase(".gblorb") || filename.hasSuffixIgnoreCase(".blb")
+		|| filename.hasSuffixIgnoreCase(".a3r");
+}
+
+void Blorb::getBlorbFilenames(const Common::String &srcFilename, Common::StringArray &filenames,
+		InterpreterType interpType) {
+	// Strip off the source filename extension
+	Common::String filename = srcFilename;
+	if (!filename.contains('.')) {
+		filename += '.';
+	} else {
+		while (filename[filename.size() - 1] != '.')
+			filename.deleteLastChar();
+	}
+
+	// Add in the different possible filenames
+	filenames.clear();
+	filenames.push_back(filename + "blorb");
+	filenames.push_back(filename + "blb");
+
+	switch (interpType) {
+	case INTERPRETER_ALAN3:
+		filenames.push_back(filename + "a3r");
+		break;
+	case INTERPRETER_FROTZ:
+		filenames.push_back(filename + "zblorb");
+		break;
+	case INTERPRETER_GLULXE:
+		filenames.push_back(filename + "gblorb");
+		break;
+	default:
+		break;
+	}
 }
 
 } // End of namespace Glk
diff --git a/engines/glk/blorb.h b/engines/glk/blorb.h
index 92a5f3f..887690c 100644
--- a/engines/glk/blorb.h
+++ b/engines/glk/blorb.h
@@ -146,6 +146,12 @@ public:
 	 * Returns true if a given filename has a Blorb file extension
 	 */
 	static bool hasBlorbExt(const Common::String &filename);
+
+	/**
+	 * Return a list of possible filenames for blorb files
+	 */
+	static void getBlorbFilenames(const Common::String &srcFilename, Common::StringArray &filenames,
+		InterpreterType interpType);
 };
 
 } // End of namespace Glk
diff --git a/engines/glk/glk.cpp b/engines/glk/glk.cpp
index ffb5015..b17304d 100644
--- a/engines/glk/glk.cpp
+++ b/engines/glk/glk.cpp
@@ -126,16 +126,15 @@ Common::Error GlkEngine::run() {
 			return Common::kNoGameDataFoundError;
 	} else {
 		// Check for a secondary blorb file with the same filename
-		Common::String baseName = filename;
-		while (baseName.contains('.'))
-			baseName.deleteLastChar();
-
-		if (Common::File::exists(baseName + ".blorb")) {
-			_blorb = new Blorb(baseName + ".blorb", getInterpreterType());
-			SearchMan.add("blorb", _blorb, 99, false);
-		} else if (Common::File::exists(baseName + ".blb")) {
-			_blorb = new Blorb(baseName + ".blb", getInterpreterType());
-			SearchMan.add("blorb", _blorb, 99, false);
+		Common::StringArray blorbFilenames;
+		Blorb::getBlorbFilenames(filename, blorbFilenames, getInterpreterType());
+
+		for (uint idx = 0; idx < blorbFilenames.size(); ++idx) {
+			if (Common::File::exists(blorbFilenames[idx])) {
+				_blorb = new Blorb(blorbFilenames[idx], getInterpreterType());
+				SearchMan.add("blorb", _blorb, 99, false);
+				break;
+			}
 		}
 
 		// Open up the game file


Commit: 3527f9c48d3ab58c5e2480d7ce75c693453a6824
    https://github.com/scummvm/scummvm/commit/3527f9c48d3ab58c5e2480d7ce75c693453a6824
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Add detection logic

Changed paths:
  A engines/glk/alan3/detection.cpp
  A engines/glk/alan3/detection.h
  A engines/glk/alan3/detection_tables.h
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/save.cpp
    engines/glk/detection.cpp
    engines/glk/module.mk


diff --git a/engines/glk/alan3/detection.cpp b/engines/glk/alan3/detection.cpp
new file mode 100644
index 0000000..cafc426
--- /dev/null
+++ b/engines/glk/alan3/detection.cpp
@@ -0,0 +1,106 @@
+/* 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/alan3/detection.h"
+#include "glk/alan3/detection_tables.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/md5.h"
+#include "engines/game.h"
+
+namespace Glk {
+namespace Alan3 {
+
+void Alan3MetaEngine::getSupportedGames(PlainGameList &games) {
+	for (const PlainGameDescriptor *pd = ALAN3_GAME_LIST; pd->gameId; ++pd) {
+		games.push_back(*pd);
+	}
+}
+
+GameDescriptor Alan3MetaEngine::findGame(const char *gameId) {
+	for (const PlainGameDescriptor *pd = ALAN3_GAME_LIST; pd->gameId; ++pd) {
+		if (!strcmp(gameId, pd->gameId))
+			return *pd;
+	}
+
+	return GameDescriptor::empty();
+}
+
+bool Alan3MetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
+	// Loop through the files of the folder
+	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+		// Check for a recognised filename
+		if (file->isDirectory())
+			continue;
+		Common::String filename = file->getName();
+		bool hasExt = filename.hasSuffix(".a3c");
+		if (!hasExt)
+			continue;
+
+		// Open up the file and calculate the md5
+		Common::File gameFile;
+		if (!gameFile.open(*file) || gameFile.readUint32BE() != MKTAG('A', 'L', 'A', 'N'))
+			continue;
+
+		gameFile.seek(0);
+		Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
+		size_t filesize = gameFile.size();
+		gameFile.close();
+
+		// Check for known games
+		const Alan3GameDescription *p = ALAN3_GAMES;
+		while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
+			++p;
+
+		DetectedGame gd;
+		if (!p->_gameId) {
+			const PlainGameDescriptor &desc = ALAN3_GAME_LIST[0];
+			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
+			gd.canBeAdded = true;
+			gd.hasUnknownFiles = true;
+			FileProperties fp;
+			fp.md5 = md5;
+			fp.size = filesize;
+			gd.matchedFiles[filename] = fp;
+
+		} else {
+			PlainGameDescriptor gameDesc = findGame(p->_gameId);
+			gd = DetectedGame(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
+		}
+
+		gd.addExtraEntry("filename", filename);
+		gameList.push_back(gd);
+	}
+
+	return !gameList.empty();
+}
+
+void Alan3MetaEngine::detectClashes(Common::StringMap &map) {
+	for (const PlainGameDescriptor *pd = ALAN3_GAME_LIST; pd->gameId; ++pd) {
+		if (map.contains(pd->gameId))
+			error("Duplicate game Id found - %s", pd->gameId);
+		map[pd->gameId] = "";
+	}
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/detection.h b/engines/glk/alan3/detection.h
new file mode 100644
index 0000000..8fbed73
--- /dev/null
+++ b/engines/glk/alan3/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_ALAN3_DETECTION
+#define GLK_ALAN3_DETECTION
+
+#include "common/fs.h"
+#include "common/hash-str.h"
+#include "engines/game.h"
+#include "glk/detection.h"
+
+namespace Glk {
+namespace Alan3 {
+
+/**
+ * Meta engine for Alan3 interpreter
+ */
+class Alan3MetaEngine {
+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 Alan3
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/detection_tables.h b/engines/glk/alan3/detection_tables.h
new file mode 100644
index 0000000..8762983
--- /dev/null
+++ b/engines/glk/alan3/detection_tables.h
@@ -0,0 +1,69 @@
+/* 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 Alan3 {
+
+/**
+ * Game description
+ */
+struct Alan3GameDescription {
+	const char *const _gameId;
+	const char *const _extra;
+	const char *const _md5;
+	size_t _filesize;
+	Common::Language _language;
+};
+
+const PlainGameDescriptor ALAN3_GAME_LIST[] = {
+	{ "alan3", "Alan3 Game" },
+
+	{ "christmasparty", "The Christmas Party" },
+	{ "deadleaves", "City of Dead Leaves" },
+	{ "fishmess", "Fish Mess" },
+	{ "hwmurders", "Hollywood Murders" },
+	{ "misguided", "Mis/Guided" },
+	{ "room206", "Room 206" },
+
+	{ nullptr, nullptr }
+};
+
+#define ENTRY0(ID, MD5, FILESIZE) { ID, nullptr, MD5, FILESIZE, Common::EN_ANY }
+#define TABLE_END_MARKER { nullptr, nullptr, nullptr, 0, Common::EN_ANY }
+
+const Alan3GameDescription ALAN3_GAMES[] = {
+	ENTRY0("christmasparty", "86b87969d124c213632398980ec87c23", 94892),
+	ENTRY0("deadleaves", "7c228698507508043d1d3938695e28cd", 90139),
+	ENTRY0("fishmess", "e9952cfbe2adef5dcef82abd57661f60", 312561),
+	ENTRY0("hwmurders", "abadbb15faf7f0b7324222fdea6bd495", 213539),
+	ENTRY0("misguided", "cc2c6e724d599e731efa9b7a34ae4f51", 672613),
+	ENTRY0("room206", "eb5711ecfad102ee4d9fda7fcb3ddf78", 364156),
+
+	TABLE_END_MARKER
+};
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index b067156..4d0963b 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -26,6 +26,9 @@
 namespace Glk {
 namespace Alan3 {
 
+winid_t glkMainWin;
+winid_t glkStatusWin;
+
 void glkio_printf(const char *fmt, ...) {
 	// If there's a savegame being loaded from the launcher, ignore any text out
 	if (g_vm->_saveSlot != -1)
diff --git a/engines/glk/alan3/save.cpp b/engines/glk/alan3/save.cpp
index f1b7d0d..506cf9d 100644
--- a/engines/glk/alan3/save.cpp
+++ b/engines/glk/alan3/save.cpp
@@ -20,6 +20,9 @@
  *
  */
 
+namespace Glk {
+namespace Alan3 {
+
 #ifdef TODO
 
 /*----------------------------------------------------------------------*/
@@ -352,5 +355,10 @@ void restore(void) {
 
 	fclose(saveFile);
 }
-
+#else
+void save() {}
+void restore() {}
 #endif
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index beeb410..33a15757 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -27,6 +27,8 @@
 #include "glk/advsys/advsys.h"
 #include "glk/alan2/detection.h"
 #include "glk/alan2/alan2.h"
+#include "glk/alan3/detection.h"
+#include "glk/alan3/alan3.h"
 #include "glk/frotz/detection.h"
 #include "glk/frotz/frotz.h"
 #include "glk/glulxe/detection.h"
@@ -121,6 +123,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::Alan3::Alan3MetaEngine, Glk::Alan3::Alan3>(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)
@@ -167,6 +170,7 @@ PlainGameList GlkMetaEngine::getSupportedGames() const {
 	Glk::Hugo::HugoMetaEngine::getSupportedGames(list);
 	Glk::Scott::ScottMetaEngine::getSupportedGames(list);
 #ifndef RELEASE_BUILD
+	Glk::Alan3::Alan3MetaEngine::getSupportedGames(list);
 	Glk::Magnetic::MagneticMetaEngine::getSupportedGames(list);
 	Glk::TADS::TADSMetaEngine::getSupportedGames(list);
 #endif
@@ -194,6 +198,8 @@ PlainGameDescriptor GlkMetaEngine::findGame(const char *gameId) const {
 	if (gd._description) return gd;
 
 #ifndef RELEASE_BUILD
+	gd = Glk::Alan3::Alan3MetaEngine::findGame(gameId);
+	if (gd._description) return gd;
 
 	gd = Glk::Magnetic::MagneticMetaEngine::findGame(gameId);
 	if (gd._description) return gd;
@@ -217,6 +223,7 @@ DetectedGames GlkMetaEngine::detectGames(const Common::FSList &fslist) const {
 	Glk::Scott::ScottMetaEngine::detectGames(fslist, detectedGames);
 
 #ifndef RELEASE_BUILD
+	Glk::Alan3::Alan3MetaEngine::detectGames(fslist, detectedGames);
 	Glk::Magnetic::MagneticMetaEngine::detectGames(fslist, detectedGames);
 	Glk::TADS::TADSMetaEngine::detectGames(fslist, detectedGames);
 #endif
@@ -234,6 +241,7 @@ void GlkMetaEngine::detectClashes() const {
 	Glk::Scott::ScottMetaEngine::detectClashes(map);
 
 #ifndef RELEASE_BUILD
+	Glk::Alan3::Alan3MetaEngine::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 ec6e0f8..902b9fc 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -63,6 +63,7 @@ MODULE_OBJS := \
 	alan3/current.o \
 	alan3/debug.o \
 	alan3/decode.o \
+	alan3/detection.o \
 	alan3/dictionary.o \
 	alan3/event.o \
 	alan3/exe.o \


Commit: f2f46395ba8ba2653aefcbc07c90c71d76871386
    https://github.com/scummvm/scummvm/commit/f2f46395ba8ba2653aefcbc07c90c71d76871386
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Further gcc warning fixes

Changed paths:
    engines/glk/alan3/alt_info.cpp
    engines/glk/alan3/location.cpp
    engines/glk/alan3/rules.cpp


diff --git a/engines/glk/alan3/alt_info.cpp b/engines/glk/alan3/alt_info.cpp
index d9e8bd2..1b2b3fe 100644
--- a/engines/glk/alan3/alt_info.cpp
+++ b/engines/glk/alan3/alt_info.cpp
@@ -312,9 +312,9 @@ static AltEntry *findAlternative(Aaddr verbTableAddress, int verbCode, int param
 
 /*----------------------------------------------------------------------*/
 static AltEntry *alternativeFinder(int verb, int parameterNumber, int theInstance, int theClass) {
-	if (theClass != NO_CLASS)
+	if ((Aword)theClass != NO_CLASS)
 		return findAlternative(classes[theClass].verbs, verb, parameterNumber);
-	else if (theInstance != NO_INSTANCE)
+	else if ((Aword)theInstance != NO_INSTANCE)
 		return findAlternative(instances[theInstance].verbs, verb, parameterNumber);
 	else
 		return findAlternative(header->verbTableAddress, verb, parameterNumber);
diff --git a/engines/glk/alan3/location.cpp b/engines/glk/alan3/location.cpp
index 2199b7a..13076b4 100644
--- a/engines/glk/alan3/location.cpp
+++ b/engines/glk/alan3/location.cpp
@@ -39,7 +39,7 @@ namespace Glk {
 namespace Alan3 {
 
 /*----------------------------------------------------------------------*/
-static void traceExit(int location, int dir, char *what) {
+static void traceExit(int location, int dir, const char *what) {
 	printf("\n<EXIT %s[%d] from ",
 	       (char *)pointerTo(dictionary[playerWords[currentWordIndex - 1].code].string), dir);
 	traceSay(location);
diff --git a/engines/glk/alan3/rules.cpp b/engines/glk/alan3/rules.cpp
index 53b9220..de64a8d 100644
--- a/engines/glk/alan3/rules.cpp
+++ b/engines/glk/alan3/rules.cpp
@@ -87,7 +87,7 @@ void initRules(Aaddr ruleTableAddress) {
 
 
 /*----------------------------------------------------------------------*/
-static void traceRuleStart(int rule, char *what) {
+static void traceRuleStart(int rule, const char *what) {
 	printf("\n<RULE %d", rule);
 	if (current.location != 0) {
 		printf(" (at ");


Commit: 4d7cfeb2c7d860a86e57f27701a1c0465538b20f
    https://github.com/scummvm/scummvm/commit/4d7cfeb2c7d860a86e57f27701a1c0465538b20f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Context clearing in main loop, add packing to code structures

Changed paths:
    engines/glk/alan3/acode.h
    engines/glk/alan3/main.cpp


diff --git a/engines/glk/alan3/acode.h b/engines/glk/alan3/acode.h
index 079ea87..03391b1 100644
--- a/engines/glk/alan3/acode.h
+++ b/engines/glk/alan3/acode.h
@@ -319,10 +319,12 @@ enum ATrans {
 
 #define AwordSizeOf(x) (sizeof(x)/sizeof(Aword))
 
+#include "common/pack-start.h"  // START STRUCT PACKING
+
 struct ArticleEntry {
 	Aaddr address;      /* Address of article code */
 	Abool isForm;       /* Is the article a complete form? */
-};
+} PACKED_STRUCT;
 
 struct ClassEntry { /* CLASS TABLE */
 	Aword code;             /* Own code */
@@ -339,7 +341,7 @@ struct ClassEntry { /* CLASS TABLE */
 	Aaddr mentioned;        /* Address of code for Mentioned clause */
 	Aaddr verbs;            /* Address of verb table */
 	Aaddr entered;          /* Address of code for Entered clause */
-};
+} PACKED_STRUCT;
 
 struct InstanceEntry {  /* INSTANCE TABLE */
 	Aint code;                  /* Own code */
@@ -360,7 +362,7 @@ struct InstanceEntry {  /* INSTANCE TABLE */
 	Aaddr verbs;                /* Address of local verb list */
 	Aaddr entered;              /* Address of entered code (location only) */
 	Aaddr exits;                /* Address of exit list */
-};
+} PACKED_STRUCT;
 
 struct AttributeEntry {         /* ATTRIBUTE LIST */
 	Aint code;                  /* Its code */
@@ -368,7 +370,7 @@ struct AttributeEntry {         /* ATTRIBUTE LIST */
                                    string pointer, a set has a pointer
                                    to a dynamically allocated set */
 	Aaddr id;                   /* Address to the name */
-};
+} PACKED_STRUCT;
 
 struct AttributeHeaderEntry {   /* ATTRIBUTE LIST in header */
 	Aint code;                          /* Its code */
@@ -376,21 +378,21 @@ struct AttributeHeaderEntry {   /* ATTRIBUTE LIST in header */
                                    string pointer, a set has a pointer
                                    to a dynamically allocated set */
 	Aaddr id;                   /* Address to the name */
-};
+} PACKED_STRUCT;
 
 struct ExitEntry {  /* EXIT TABLE structure */
 	Aword code;             /* Direction code */
 	Aaddr checks;           /* Address of check table */
 	Aaddr action;           /* Address of action code */
 	Aword target;           /* Id for the target location */
-};
+} PACKED_STRUCT;
 
 
 struct RuleEntry {      /* RULE TABLE */
 	Abool alreadyRun;
 	Aaddr exp;                    /* Address to expression code */
 	Aaddr stms;                   /* Address to run */
-};
+} PACKED_STRUCT;
 
 
 #define RESTRICTIONCLASS_CONTAINER (-2)
@@ -401,7 +403,7 @@ struct RestrictionEntry {         /* PARAMETER RESTRICTION TABLE */
 	Aint parameterNumber;         /* Parameter number */
 	Aint _class;                  /* Parameter class code */
 	Aaddr stms;                   /* Exception statements */
-};
+} PACKED_STRUCT;
 
 struct ContainerEntry { /* CONTAINER TABLE */
 	Aword owner;                /* Owner instance index */
@@ -411,7 +413,7 @@ struct ContainerEntry { /* CONTAINER TABLE */
 	Aaddr empty;                /* Address to code for header when empty */
 	Aaddr extractChecks;        /* Address to check before extracting */
 	Aaddr extractStatements;    /* Address to execute when extracting */
-};
+} PACKED_STRUCT;
 
 
 struct ElementEntry {   /* SYNTAX ELEMENT TABLES */
@@ -419,73 +421,73 @@ struct ElementEntry {   /* SYNTAX ELEMENT TABLES */
 	Aword flags;                /* Flags for multiple/omni (if parameter), syntax number/verb of EOS */
 	Aaddr next;                 /* Address to next element table ... */
 	/* ... or restrictions if code == EOS */
-};
+} PACKED_STRUCT;
 
 struct SyntaxEntryPreBeta2 {    /* SYNTAX TABLE */
 	Aint code;                          /* Code for verb word */
 	Aaddr elms;                         /* Address to element tables */
-};
+} PACKED_STRUCT;
 
 struct SyntaxEntry {     /* SYNTAX TABLE */
 	Aint code;                   /* Code for verb word, or 0 if starting with parameter */
 	Aaddr elms;                  /* Address to element tables */
 	Aaddr parameterNameTable;    /* Address to a table of id-addresses giving the names of the parameters */
-};
+} PACKED_STRUCT;
 
 struct ParameterMapEntry {  /* PARAMETER MAPPING TABLE */
 	Aint syntaxNumber;
 	Aaddr parameterMapping;
 	Aint verbCode;
-};
+} PACKED_STRUCT;
 
 struct EventEntry { /* EVENT TABLE */
 	Aaddr id;                   /* Address to name string */
 	Aaddr code;
-};
+} PACKED_STRUCT;
 
 struct ScriptEntry {    /* SCRIPT TABLE */
 	Aaddr id;                   /* Address to name string */
 	Aint code;          /* Script number */
 	Aaddr description;      /* Optional description statements */
 	Aaddr steps;        /* Address to steps */
-};
+} PACKED_STRUCT;
 
 struct StepEntry {  /* STEP TABLE */
 	Aaddr after;        /* Expression to say after how many ticks? */
 	Aaddr exp;          /* Expression to condition saying when */
 	Aaddr stms;         /* Address to the actual code */
-};
+} PACKED_STRUCT;
 
 struct AltEntry {   /* VERB ALTERNATIVE TABLE */
 	Aword qual;         /* Verb execution qualifier */
 	Aint param;         /* Parameter number */
 	Aaddr checks;       /* Address of the check table */
 	Aaddr action;       /* Address of the action code */
-};
+} PACKED_STRUCT;
 
 struct SourceFileEntry { /* SOURCE FILE NAME TABLE */
 	Aint fpos;
 	Aint len;
-};
+} PACKED_STRUCT;
 
 struct SourceLineEntry { /* SOURCE LINE TABLE */
 	Aint file;
 	Aint line;
-};
+} PACKED_STRUCT;
 
 struct StringInitEntry { /* STRING INITIALISATION TABLE */
 	Aword fpos;                  /* File position */
 	Aword len;                   /* Length */
 	Aint instanceCode;           /* Where to store it */
 	Aint attributeCode;
-};
+} PACKED_STRUCT;
 
 struct SetInitEntry {   /* SET INITIALISATION TABLE */
 	Aint size;                  /* Size of the initial set */
 	Aword setAddress;           /* Address to the initial set */
 	Aint instanceCode;          /* Where to store it */
 	Aint attributeCode;
-};
+} PACKED_STRUCT;
 
 struct DictionaryEntry { /* Dictionary */
 	Aaddr string;                /* ACODE address to string */
@@ -494,7 +496,7 @@ struct DictionaryEntry { /* Dictionary */
 	Aaddr adjectiveRefs;        /* Address to reference list */
 	Aaddr nounRefs;             /* Address to reference list */
 	Aaddr pronounRefs;          /* Address to reference list */
-};
+} PACKED_STRUCT;
 
 
 
@@ -555,7 +557,7 @@ struct ACodeHeader {
 	Aword txtcrc;       /* Checksum for text data file */
 	Aaddr ifids;        /* Address to IFIDS */
 	Aaddr prompt;
-};
+} PACKED_STRUCT;
 
 struct Pre3_0beta2Header {
 	/* Important info */
@@ -611,7 +613,7 @@ struct Pre3_0beta2Header {
 	Aword acdcrc;       /* Checksum for acd code (excl. hdr) */
 	Aword txtcrc;       /* Checksum for text data file */
 	Aaddr ifids;        /* Address to IFIDS */
-};
+} PACKED_STRUCT;
 
 struct Pre3_0alpha5Header {
 	/* Important info */
@@ -666,7 +668,9 @@ struct Pre3_0alpha5Header {
 	Aaddr freq;         /* Address to Char freq's for coding */
 	Aword acdcrc;       /* Checksum for acd code (excl. hdr) */
 	Aword txtcrc;       /* Checksum for text data file */
-};
+} PACKED_STRUCT;
+
+#include "common/pack-end.h"    // END STRUCT PACKING
 
 /* Error message numbers */
 enum MsgKind {
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 62ee3bf..64f7019 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -738,6 +738,7 @@ void run(void) {
 	Context ctx;
 
 	do {
+		ctx.clear();
 		openFiles();
 		load();			// Load program
 
@@ -753,16 +754,7 @@ void run(void) {
 		init();
 
 		while (!g_vm->shouldQuit()) {
-			if (!ctx._break) {
-				if (debugOption)
-					debug(FALSE, 0, 0);
-
-				if (stackDepth(theStack) != 0)
-					syserr("Stack is not empty in main loop");
-
-				if (!current.meta)
-					runPendingEvents();
-			} else {
+			if (ctx._break) {
 				#ifdef TODO
 				// Return here if error during execution
 				switch (setjmp(returnLabel)) {
@@ -779,6 +771,16 @@ void run(void) {
 					syserr("Unexpected longjmp() return value");
 				}
 				#endif
+				ctx.clear();
+			} else {
+				if (debugOption)
+					debug(FALSE, 0, 0);
+
+				if (stackDepth(theStack) != 0)
+					syserr("Stack is not empty in main loop");
+
+				if (!current.meta)
+					runPendingEvents();
 			}
 
 			recursionDepth = 0;


Commit: f5ad5b00d0098f90416192a867f48dda4d607f51
    https://github.com/scummvm/scummvm/commit/f5ad5b00d0098f90416192a867f48dda4d607f51
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Fix endianness of loading temporary header

Changed paths:
    engines/glk/alan3/main.cpp
    engines/glk/alan3/reverse.cpp
    engines/glk/alan3/reverse.h


diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 64f7019..06e5895 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -135,8 +135,12 @@ static int crcStart(char version[4]) {
 /*----------------------------------------------------------------------*/
 static void readTemporaryHeader(ACodeHeader *tmphdr) {
 	codfil->seek(0);
-	codfil->read(tmphdr, sizeof(*tmphdr));
-	codfil->seek(0);
+	codfil->read(&tmphdr->tag[0], 4);
+
+	Aword *ptr = (Aword *)tmphdr + 1;
+	uint i;
+	for (i = 1; i < sizeof(ACodeHeader) / sizeof(Aword); ++i, ++ptr)
+		*ptr = codfil->readUint32BE();
 
 	if (strncmp((char *)tmphdr, "ALAN", 4) != 0)
 		playererr("Not an Alan game file, does not start with \"ALAN\"");
@@ -365,10 +369,6 @@ static void load(void) {
 	checkVersion(&tmphdr);
 
 	/* Allocate and load memory */
-
-	if (littleEndian())
-		reverseHdr(&tmphdr);
-
 	if (tmphdr.size <= sizeof(ACodeHeader) / sizeof(Aword))
 		syserr("Malformed game file. Too small.");
 
diff --git a/engines/glk/alan3/reverse.cpp b/engines/glk/alan3/reverse.cpp
index ca6db94..6fa7aa5 100644
--- a/engines/glk/alan3/reverse.cpp
+++ b/engines/glk/alan3/reverse.cpp
@@ -573,7 +573,7 @@ static void reversePreBeta2() {
 
 
 /*======================================================================*/
-void reverseHdr(ACodeHeader *hdr) {
+static void reverseHdr(ACodeHeader *hdr) {
 	uint i;
 
 	/* Reverse all words in the header except the tag and the version marking */
diff --git a/engines/glk/alan3/reverse.h b/engines/glk/alan3/reverse.h
index ebcc0f5..cca38c0 100644
--- a/engines/glk/alan3/reverse.h
+++ b/engines/glk/alan3/reverse.h
@@ -32,7 +32,6 @@ namespace Alan3 {
 
 /* Functions: */
 
-extern void reverseHdr(ACodeHeader *hdr);
 extern void reverseACD(void);
 extern void reverse(Aword *word);
 extern Aword reversed(Aword word);


Commit: 5c8c4b3b6e0ca5010420b31e3cd49549622104ec
    https://github.com/scummvm/scummvm/commit/5c8c4b3b6e0ca5010420b31e3cd49549622104ec
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Standardize on using syserr for errors

Changed paths:
    engines/glk/alan3/act.cpp
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/syserr.cpp
    engines/glk/alan3/syserr.h


diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
index 1b92234..4874cb9 100644
--- a/engines/glk/alan3/act.cpp
+++ b/engines/glk/alan3/act.cpp
@@ -22,11 +22,11 @@
 
 #include "glk/alan3/act.h"
 #include "glk/alan3/alt_info.h"
-#include "glk/alan3/output.h"
-#include "glk/alan3/msg.h"
 #include "glk/alan3/exe.h"
 #include "glk/alan3/lists.h"
-#include "common/textconsole.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/output.h"
+#include "glk/alan3/syserr.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -111,7 +111,7 @@ void action(int verb, Parameter parameters[], Parameter multipleMatches[]) {
 		memcpy(returnLabel, savedReturnLabel, sizeof(returnLabel));
 		parameters[multiplePosition].instance = 0;
 #else
-		::error("TODO: action");
+		syserr("TODO: action");
 #endif
 	} else {
 		setGlobalParameters(parameters);
diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 3958bf2..10850f8 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -84,7 +84,7 @@ bool Alan3::initialize() {
 	// first, open a window for error output
 	glkMainWin = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
 	if (glkMainWin == nullptr)
-		::error("FATAL ERROR: Cannot open initial window");
+		syserr("FATAL ERROR: Cannot open initial window");
 
 	g_vm->glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
 	glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index e3e0e0c..34c9c61 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -46,7 +46,6 @@
 #include "glk/alan3/utils.h"
 #include "glk/alan3/word.h"
 #include "common/stream.h"
-#include "common/textconsole.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -150,7 +149,7 @@ void print(Aword fpos, Aword len) {
 
 /*======================================================================*/
 void sys(Aword fpos, Aword len) {
-	::error("sys calls are unsupported");
+	syserr("sys calls are unsupported");
 }
 
 
@@ -226,7 +225,7 @@ void undo(void) {
 #ifdef TODO
 	longjmp(returnLabel, UNDO_RETURN);
 #else
-	::error("TODO: undo longjmp");
+	syserr("TODO: undo longjmp");
 #endif
 }
 
@@ -283,7 +282,7 @@ void restartGame(void) {
 	}
 	current.location = previousLocation;
 #else
-	::error("TODO: restartGame");
+	syserr("TODO: restartGame");
 #endif
 }
 
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 06e5895..6fc5e01 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -20,7 +20,6 @@
  *
  */
 
-#include "common/textconsole.h"
 #include "glk/alan3/main.h"
 #include "glk/alan3/alan_version.h"
 #include "glk/alan3/args.h"
@@ -674,7 +673,7 @@ static void moveActor(int theActor) {
 			fail = FALSE;           /* fail only aborts one actor */
 		}
 #else
-		::error("TODO: moveActor setjmp");
+		syserr("TODO: moveActor setjmp");
 #endif
 	} else if (admin[theActor].script != 0) {
 		for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++) {
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 8f823de..dcfcc6f 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -34,9 +34,9 @@
 #include "glk/alan3/output.h"
 #include "glk/alan3/params.h"
 #include "glk/alan3/readline.h"
+#include "glk/alan3/syserr.h"
 #include "glk/alan3/term.h"
 #include "glk/alan3/word.h"
-#include "common/textconsole.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -166,7 +166,7 @@ static void getLine(void) {
 			longjmp(forfeitLabel, 0);
 		}
 #else
-		::error("TODO: empty command");
+		syserr("TODO: empty command");
 #endif
 
 		strcpy(isobuf, buf);
diff --git a/engines/glk/alan3/syserr.cpp b/engines/glk/alan3/syserr.cpp
index 31aa981..559f104 100644
--- a/engines/glk/alan3/syserr.cpp
+++ b/engines/glk/alan3/syserr.cpp
@@ -62,6 +62,8 @@ void setSyserrHandler(void (*f)(const char *)) {
 /*======================================================================*/
 // TODO Make syserr() use ... as printf()
 void syserr(const char *description) {
+	::error("%s", description);
+#if 0
 	lin = 0;
 	if (handler == NULL) {
 		const char *blurb = "<If you are the creator of this piece of Interactive Fiction, \
@@ -71,6 +73,7 @@ it to support at alanif.se. Thank you!>";
 		runtimeError("SYSTEM ERROR: ", description, blurb);
 	} else
 		handler(description);
+#endif
 }
 
 
diff --git a/engines/glk/alan3/syserr.h b/engines/glk/alan3/syserr.h
index 3202600..6112e88 100644
--- a/engines/glk/alan3/syserr.h
+++ b/engines/glk/alan3/syserr.h
@@ -25,6 +25,8 @@
 
 /* Header file for syserr unit of ARUN Alan System interpreter */
 
+#include "common/textconsole.h"
+
 namespace Glk {
 namespace Alan3 {
 


Commit: 395174301b7a3b00a34e3c42176f64089990fed5
    https://github.com/scummvm/scummvm/commit/395174301b7a3b00a34e3c42176f64089990fed5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Change header version field from char[4] to byte[4]

Changed paths:
    engines/glk/alan3/acode.h
    engines/glk/alan3/compatibility.cpp
    engines/glk/alan3/compatibility.h
    engines/glk/alan3/main.cpp
    engines/glk/alan3/reverse.cpp
    engines/glk/alan3/rules.cpp
    engines/glk/alan3/rules.h


diff --git a/engines/glk/alan3/acode.h b/engines/glk/alan3/acode.h
index 03391b1..7aa1d8e 100644
--- a/engines/glk/alan3/acode.h
+++ b/engines/glk/alan3/acode.h
@@ -505,7 +505,7 @@ struct DictionaryEntry { /* Dictionary */
 struct ACodeHeader {
 	/* Important info */
 	char tag[4];              /* "ALAN" */
-	char version[4];          /* Version of compiler */
+	byte version[4];          /* Version of compiler */
 	Aword uid;                /* Unique id of the compiled game */
 	Aword size;               /* Size of ACD-file in Awords */
 	/* Options */
@@ -562,7 +562,7 @@ struct ACodeHeader {
 struct Pre3_0beta2Header {
 	/* Important info */
 	char tag[4];        /* "ALAN" */
-	char version[4];        /* Version of compiler */
+	byte version[4];    /* Version of compiler */
 	Aword uid;          /* Unique id of the compiled game */
 	Aword size;         /* Size of ACD-file in Awords */
 	/* Options */
@@ -618,7 +618,7 @@ struct Pre3_0beta2Header {
 struct Pre3_0alpha5Header {
 	/* Important info */
 	char tag[4];        /* "ALAN" */
-	char version[4];        /* Version of compiler */
+	byte version[4];    /* Version of compiler */
 	Aword uid;          /* Unique id of the compiled game */
 	Aword size;         /* Size of ACD-file in Awords */
 	/* Options */
diff --git a/engines/glk/alan3/compatibility.cpp b/engines/glk/alan3/compatibility.cpp
index 4668d6e..aedfae8 100644
--- a/engines/glk/alan3/compatibility.cpp
+++ b/engines/glk/alan3/compatibility.cpp
@@ -26,42 +26,42 @@ namespace Glk {
 namespace Alan3 {
 
 /*----------------------------------------------------------------------*/
-static bool is3_0Alpha(char version[]) {
+static bool is3_0Alpha(const byte version[]) {
 	return version[3] == 3 && version[2] == 0 && version[0] == 'a';
 }
 
 /*----------------------------------------------------------------------*/
-static bool is3_0Beta(char version[]) {
+static bool is3_0Beta(const byte version[]) {
 	return version[3] == 3 && version[2] == 0 && version[0] == 'b';
 }
 
 /*----------------------------------------------------------------------*/
-static int correction(char version[]) {
+static int correction(const byte version[]) {
 	return version[1];
 }
 
 /*======================================================================*/
-bool isPreAlpha5(char version[4]) {
+bool isPreAlpha5(const byte version[4]) {
 	return is3_0Alpha(version) && correction(version) < 5;
 }
 
 /*======================================================================*/
-bool isPreBeta2(char version[4]) {
+bool isPreBeta2(const byte version[4]) {
 	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) == 1);
 }
 
 /*======================================================================*/
-bool isPreBeta3(char version[4]) {
+bool isPreBeta3(const byte version[4]) {
 	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 2);
 }
 
 /*======================================================================*/
-bool isPreBeta4(char version[4]) {
+bool isPreBeta4(const byte version[4]) {
 	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 3);
 }
 
 /*======================================================================*/
-bool isPreBeta5(char version[4]) {
+bool isPreBeta5(const byte version[4]) {
 	return is3_0Alpha(version) || (is3_0Beta(version) && correction(version) <= 4);
 }
 
diff --git a/engines/glk/alan3/compatibility.h b/engines/glk/alan3/compatibility.h
index 0187c72..8b759c5 100644
--- a/engines/glk/alan3/compatibility.h
+++ b/engines/glk/alan3/compatibility.h
@@ -29,12 +29,12 @@ namespace Glk {
 namespace Alan3 {
 
 /* FUNCTIONS: */
-extern bool isPreAlpha5(char version[4]);
-extern bool isPreBeta2(char version[4]);
-extern bool isPreBeta3(char version[4]);
-extern bool isPreBeta4(char version[4]);
-extern bool isPreBeta5(char version[4]);
-extern char *decodedGameVersion(char version[]);
+extern bool isPreAlpha5(const byte version[4]);
+extern bool isPreBeta2(const byte version[4]);
+extern bool isPreBeta3(const byte version[4]);
+extern bool isPreBeta4(const byte version[4]);
+extern bool isPreBeta5(const byte version[4]);
+extern char *decodedGameVersion(const byte version[]);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 6fc5e01..f09a54c 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -120,7 +120,7 @@ Common::SeekableReadStream *codfil;
   be compatible.  If header size changes this should return beta2
   header size for later versions.
 */
-static int crcStart(char version[4]) {
+static int crcStart(const byte version[4]) {
 	/* Some earlier versions had a shorter header */
 	if (isPreAlpha5(version))
 		return sizeof(Pre3_0alpha5Header) / sizeof(Aword);
@@ -229,7 +229,7 @@ static const char *decodeState(int c) {
 }
 
 /*======================================================================*/
-char *decodedGameVersion(char version[]) {
+char *decodedGameVersion(const byte version[]) {
 	static char str[100];
 	sprintf(str, "%d.%d%s%d",
 	        (int)version[3],
@@ -278,7 +278,7 @@ static void alphaRunningLaterGame(char gameState) {
 }
 
 /*----------------------------------------------------------------------*/
-static void nonDevelopmentRunningDevelopmentStateGame(char version[]) {
+static void nonDevelopmentRunningDevelopmentStateGame(const byte version[]) {
 	char errorMessage[200];
 	char versionString[100];
 
diff --git a/engines/glk/alan3/reverse.cpp b/engines/glk/alan3/reverse.cpp
index 6fa7aa5..4dcba12 100644
--- a/engines/glk/alan3/reverse.cpp
+++ b/engines/glk/alan3/reverse.cpp
@@ -368,7 +368,7 @@ static void reverseSyntaxTablePreBeta2(Aword adr) {
 }
 
 
-static void reverseSyntaxTable(Aword adr, char version[]) {
+static void reverseSyntaxTable(Aword adr, byte version[]) {
 	if (!adr || alreadyDone(adr)) return;
 
 	if (isPreBeta2(version))
@@ -634,7 +634,7 @@ static void reverseNative() {
   */
 void reverseACD(void) {
 	ACodeHeader *hdr = (ACodeHeader *)memory;
-	char version[4];
+	byte version[4];
 	int i;
 
 	/* Make a copy of the version marking to reverse */
diff --git a/engines/glk/alan3/rules.cpp b/engines/glk/alan3/rules.cpp
index de64a8d..b589168 100644
--- a/engines/glk/alan3/rules.cpp
+++ b/engines/glk/alan3/rules.cpp
@@ -243,7 +243,7 @@ void evaluateRules(RuleEntry ruleList[]) {
 
 
 /*=======================================================================*/
-void resetAndEvaluateRules(RuleEntry ruleList[], char *version) {
+void resetAndEvaluateRules(RuleEntry ruleList[], const byte *version) {
 	if (isPreBeta2(version))
 		evaluateRulesPreBeta2();
 	else if (isPreBeta3(version))
diff --git a/engines/glk/alan3/rules.h b/engines/glk/alan3/rules.h
index 849fc50..65291a0 100644
--- a/engines/glk/alan3/rules.h
+++ b/engines/glk/alan3/rules.h
@@ -36,7 +36,7 @@ extern bool anyRuleRun;       /* Did any rule run? */
 
 /* FUNCTIONS */
 extern void initRules(Aaddr rulesTableAddress);
-extern void resetAndEvaluateRules(RuleEntry rules[], char *version);
+extern void resetAndEvaluateRules(RuleEntry rules[], const byte *version);
 extern void resetRules(void);
 extern void evaluateRules(RuleEntry rules[]);
 


Commit: b8a737a8a4d0ec723f04da39649548d4ded807ed
    https://github.com/scummvm/scummvm/commit/b8a737a8a4d0ec723f04da39649548d4ded807ed
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Further loading fixes

Changed paths:
    engines/glk/alan3/main.cpp
    engines/glk/alan3/reverse.cpp
    engines/glk/alan3/reverse.h
    engines/glk/alan3/sysdep.cpp
    engines/glk/alan3/sysdep.h


diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index f09a54c..52c1476 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -134,27 +134,19 @@ static int crcStart(const byte version[4]) {
 /*----------------------------------------------------------------------*/
 static void readTemporaryHeader(ACodeHeader *tmphdr) {
 	codfil->seek(0);
-	codfil->read(&tmphdr->tag[0], 4);
-
-	Aword *ptr = (Aword *)tmphdr + 1;
-	uint i;
-	for (i = 1; i < sizeof(ACodeHeader) / sizeof(Aword); ++i, ++ptr)
-		*ptr = codfil->readUint32BE();
-
-	if (strncmp((char *)tmphdr, "ALAN", 4) != 0)
+	if (codfil->read(&tmphdr->tag[0], sizeof(ACodeHeader)) != sizeof(ACodeHeader) ||
+			strncmp((char *)tmphdr, "ALAN", 4) != 0)
 		playererr("Not an Alan game file, does not start with \"ALAN\"");
 }
 
 
 /*----------------------------------------------------------------------*/
 static void reverseMemory() {
-	if (littleEndian()) {
-		if (debugOption || traceSectionOption || traceInstructionOption)
-			output("<Hmm, this is a little-endian machine, fixing byte ordering....");
-		reverseACD();           /* Reverse content of the ACD file */
-		if (debugOption || traceSectionOption || traceInstructionOption)
-			output("OK.>$n");
-	}
+	if (debugOption || traceSectionOption || traceInstructionOption)
+		output("<Hmm, this is a little-endian machine, fixing byte ordering....");
+	reverseACD();           /* Reverse content of the ACD file */
+	if (debugOption || traceSectionOption || traceInstructionOption)
+		output("OK.>$n");
 }
 
 
@@ -183,12 +175,10 @@ static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
 	}
 
 	memTop = tmphdr.size;
-	if ((int)(sizeof(Aword) * tmphdr.size) > codfil->size())
+	codfil->seek(0);
+	if (codfil->read(memory, sizeof(Aword) * memTop) != (sizeof(Aword) * memTop))
 		syserr("Could not read all ACD code.");
 
-	for (i = 0; i < (int)tmphdr.size; ++i)
-		memory[i] = codfil->readUint32LE();
-
 	/* Calculate checksum */
 	for (i = crcStart(tmphdr.version); i < memTop; i++) {
 		crc += memory[i] & 0xff;
@@ -368,14 +358,19 @@ static void load(void) {
 	checkVersion(&tmphdr);
 
 	/* Allocate and load memory */
+#ifdef SCUMM_LITTLE_ENDIAN
+	reverseHdr(&tmphdr);
+#endif
+
 	if (tmphdr.size <= sizeof(ACodeHeader) / sizeof(Aword))
 		syserr("Malformed game file. Too small.");
 
 	loadAndCheckMemory(tmphdr, crc, err);
 
+#ifdef SCUMM_LITTLE_ENDIAN
 	reverseMemory();
+#endif
 	setupHeader(tmphdr);
-
 }
 
 
diff --git a/engines/glk/alan3/reverse.cpp b/engines/glk/alan3/reverse.cpp
index 4dcba12..ead8725 100644
--- a/engines/glk/alan3/reverse.cpp
+++ b/engines/glk/alan3/reverse.cpp
@@ -573,7 +573,7 @@ static void reversePreBeta2() {
 
 
 /*======================================================================*/
-static void reverseHdr(ACodeHeader *hdr) {
+void reverseHdr(ACodeHeader *hdr) {
 	uint i;
 
 	/* Reverse all words in the header except the tag and the version marking */
diff --git a/engines/glk/alan3/reverse.h b/engines/glk/alan3/reverse.h
index cca38c0..ebcc0f5 100644
--- a/engines/glk/alan3/reverse.h
+++ b/engines/glk/alan3/reverse.h
@@ -32,6 +32,7 @@ namespace Alan3 {
 
 /* Functions: */
 
+extern void reverseHdr(ACodeHeader *hdr);
 extern void reverseACD(void);
 extern void reverse(Aword *word);
 extern Aword reversed(Aword word);
diff --git a/engines/glk/alan3/sysdep.cpp b/engines/glk/alan3/sysdep.cpp
index 58f0fa0..ae8625f 100644
--- a/engines/glk/alan3/sysdep.cpp
+++ b/engines/glk/alan3/sysdep.cpp
@@ -313,13 +313,6 @@ void toNative(char copy[], char original[], int charset) {
 
 
 /*======================================================================*/
-int littleEndian() {
-	int x = 1;
-	return (*(char *)&x == 1);
-}
-
-
-/*======================================================================*/
 char *baseNameStart(char *fullPathName) {
 	const char *delimiters = "\\>]/:";
 	int i;
diff --git a/engines/glk/alan3/sysdep.h b/engines/glk/alan3/sysdep.h
index 87b95fc..1889a3e 100644
--- a/engines/glk/alan3/sysdep.h
+++ b/engines/glk/alan3/sysdep.h
@@ -130,8 +130,6 @@ extern void toNative(char copy[], /* OUT - Mapped string */
                      char original[], /* IN - string to convert */
                      int charset); /* IN - current character set */
 
-extern int littleEndian(void);
-
 extern char *baseNameStart(char *fullPathName);
 
 } // End of namespace Alan3


Commit: ae6ae33bed6ce27603c9f4d952010fb63498ea66
    https://github.com/scummvm/scummvm/commit/ae6ae33bed6ce27603c9f4d952010fb63498ea66
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Fix setup and outputing of text data

Changed paths:
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/exe.h


diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 10850f8..950e9cd 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -46,10 +46,13 @@ Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, g
 
 	// main
 	codfil = nullptr;
-//	txtfil = nullptr;
+	textFile = nullptr;
 //	logfil = nullptr;
 	memory = nullptr;
 
+	// exe
+	printFlag = false;
+
 	// options
 	verboseOption = false;
 	ignoreErrorOption = false;
@@ -93,25 +96,21 @@ bool Alan3::initialize() {
 
 	// Set up the code file to point to the already opened game file
 	codfil = &_gameFile;
-	/*
+
 	if (_gameFile.size() < 8) {
 	    GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
 	    return false;
 	}
 
-	if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
-	    GUIErrorMessage(_("This is not a valid Alan3 file."));
+	// In Alan 3, the text data comes from the adventure file itself
+	Common::File *txt = new Common::File();
+	if (!txt->open(getFilename())) {
+	    GUIErrorMessage("Could not open adventure file for text data");
+	    delete txt;
 	    return false;
 	}
+	textFile = txt;
 
-	// Open up the text file
-	txtfil = new Common::File();
-	if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
-	    GUIErrorMessage("Could not open adventure text data file");
-	    delete txtfil;
-	    return false;
-	}
-	*/
 	// Check for a save being loaded directly from the launcher
 	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
 
@@ -120,10 +119,8 @@ bool Alan3::initialize() {
 
 void Alan3::deinitialize() {
 	free(memory);
-	/*
-	    delete txtfil;
-	    delete logfil;
-	*/
+	delete textFile;
+//  delete logfil;
 }
 
 Common::Error Alan3::readSaveData(Common::SeekableReadStream *rs) {
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index 34c9c61..5c6f09b 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -50,10 +50,12 @@
 namespace Glk {
 namespace Alan3 {
 
-/* PUBLIC DATA */
-
+// PUBLIC DATA
 Common::SeekableReadStream *textFile;
 
+// PUBLIC DATA - formerly method statics
+bool printFlag;				// Printing already?
+
 /* Long jump buffers */
 // TODO move to longjump.c? or error.c, and abstract them into functions?
 //jmp_buf restartLabel;       /* Restart long jump return point */
@@ -94,7 +96,6 @@ void print(Aword fpos, Aword len) {
 	int ch = 0;
 	int i;
 	long savfp = 0;     /* Temporary saved text file position */
-	static bool printFlag = FALSE; /* Printing already? */
 	bool savedPrintFlag = printFlag;
 	void *info = NULL;      /* Saved decoding info */
 
@@ -126,9 +127,10 @@ void print(Aword fpos, Aword len) {
 				else
 					ch = textFile->readByte();
 
+				if (ch == EOFChar)
+					break;				// Or end of text?
+
 				str[i] = ch;
-				if (textFile->pos() >= textFile->size())      /* Or end of text? */
-					break;
 			}
 			str[i] = '\0';
 
diff --git a/engines/glk/alan3/exe.h b/engines/glk/alan3/exe.h
index 77fb70a..428f112 100644
--- a/engines/glk/alan3/exe.h
+++ b/engines/glk/alan3/exe.h
@@ -43,8 +43,8 @@ namespace Alan3 {
 
 /* DATA */
 
-/* The text and message file */
-extern Common::SeekableReadStream *textFile;
+extern Common::SeekableReadStream *textFile;		// The text and message file
+extern bool printFlag;
 
 /* Long jump buffer for restart, errors and undo */
 //extern jmp_buf restartLabel;


Commit: f0d5304a4c160abc8a16cac637a48ebe751b602c
    https://github.com/scummvm/scummvm/commit/f0d5304a4c160abc8a16cac637a48ebe751b602c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Fix jumps.h macros

Changed paths:
    engines/glk/alan2/jumps.h
    engines/glk/alan3/jumps.h


diff --git a/engines/glk/alan2/jumps.h b/engines/glk/alan2/jumps.h
index b477354..2aa4561 100644
--- a/engines/glk/alan2/jumps.h
+++ b/engines/glk/alan2/jumps.h
@@ -40,25 +40,25 @@ struct Context {
 
 #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, P2); if (context._break) return; }
-#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return; }
-#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); 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, P2); if (context._break) return; }
-#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return; }
-#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); 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, P2); if (context._break) return 0; }
-#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return 0; }
-#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); 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, P2); if (context._break) return 0; }
-#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return 0; }
-#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); 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; }
diff --git a/engines/glk/alan3/jumps.h b/engines/glk/alan3/jumps.h
index 882ffbd..10c33fa 100644
--- a/engines/glk/alan3/jumps.h
+++ b/engines/glk/alan3/jumps.h
@@ -27,6 +27,8 @@
  * breakouts to the main game loop from subroutinese rather than using unportable setjmps
  */
 
+#include "common/str.h"
+
 namespace Glk {
 namespace Alan3 {
 
@@ -53,25 +55,25 @@ struct Context {
 
 #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, P2); if (context._break) return; }
-#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return; }
-#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); 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, P2); if (context._break) return; }
-#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return; }
-#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); 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, P2); if (context._break) return 0; }
-#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return 0; }
-#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); 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, P2); if (context._break) return 0; }
-#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return 0; }
-#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); 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; }


Commit: c833d39ccf8ec2493929afaa7066113802fb90b0
    https://github.com/scummvm/scummvm/commit/c833d39ccf8ec2493929afaa7066113802fb90b0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Outer game loop to handle forfeit setjmp replacement

Changed paths:
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/output.cpp
    engines/glk/alan3/output.h


diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 950e9cd..bbcd6da 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -25,6 +25,7 @@
 #include "glk/alan3/main.h"
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/options.h"
+#include "glk/alan3/output.h"
 #include "glk/alan3/syserr.h"
 #include "common/system.h"
 #include "common/config-manager.h"
@@ -67,6 +68,12 @@ Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, g
 	statusLineOption = true;
 	regressionTestOption = false;
 
+	// output
+	anyOutput = false;
+	capitalize = false;
+	needSpace = false;
+	skipSpace = false;
+
 	// syserr
 	setSyserrHandler(nullptr);
 }
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 52c1476..4fd8cf6 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -651,7 +651,7 @@ static char *scriptName(int theActor, int theScript) {
 
 
 /*----------------------------------------------------------------------*/
-static void moveActor(int theActor) {
+static void moveActor(CONTEXT, int theActor) {
 	ScriptEntry *scr;
 	StepEntry *step;
 	Aint previousInstance = current.instance;
@@ -659,17 +659,18 @@ static void moveActor(int theActor) {
 	current.actor = theActor;
 	current.instance = theActor;
 	current.location = where(theActor, TRANSITIVE);
-	if (theActor == (int)HERO) {
-#ifdef TODO
-		/* Ask him! */
-		if (setjmp(forfeitLabel) == 0) {
+	if (context._break || theActor == (int)HERO) {
+		if (context._break) {
+			// Forfeit jump destination
+			assert(context._label == "forfeit");
+			context.clear();
+		} else {
+			// Ask him!
 			parse();
 			capitalize = TRUE;
-			fail = FALSE;           /* fail only aborts one actor */
+			fail = FALSE;           // fail only aborts one actor
 		}
-#else
-		syserr("TODO: moveActor setjmp");
-#endif
+
 	} else if (admin[theActor].script != 0) {
 		for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++) {
 			if (scr->code == admin[theActor].script) {
@@ -748,63 +749,73 @@ void run(void) {
 		init();
 
 		while (!g_vm->shouldQuit()) {
-			if (ctx._break) {
-				#ifdef TODO
-				// Return here if error during execution
-				switch (setjmp(returnLabel)) {
-				case NO_JUMP_RETURN:
-					break;
-				case ERROR_RETURN:
-					forgetGameState();
-					forceNewPlayerInput();
-					break;
-				case UNDO_RETURN:
-					forceNewPlayerInput();
-					break;
-				default:
-					syserr("Unexpected longjmp() return value");
+			if (!(ctx._break && ctx._label == "forfeit")) {
+				if (ctx._break) {
+					assert(ctx._label == "return");
+#ifdef TODO
+					// Return here if error during execution
+					switch (setjmp(returnLabel)) {
+					case NO_JUMP_RETURN:
+						break;
+					case ERROR_RETURN:
+						forgetGameState();
+						forceNewPlayerInput();
+						break;
+					case UNDO_RETURN:
+						forceNewPlayerInput();
+						break;
+					default:
+						syserr("Unexpected longjmp() return value");
+					}
+#endif
+					ctx.clear();
+				} else {
+					if (debugOption)
+						debug(FALSE, 0, 0);
+
+					if (stackDepth(theStack) != 0)
+						syserr("Stack is not empty in main loop");
+
+					if (!current.meta)
+						runPendingEvents();
 				}
-				#endif
-				ctx.clear();
-			} else {
-				if (debugOption)
-					debug(FALSE, 0, 0);
 
-				if (stackDepth(theStack) != 0)
-					syserr("Stack is not empty in main loop");
+				recursionDepth = 0;
 
-				if (!current.meta)
-					runPendingEvents();
+				// Move all characters, hero first
+				rememberGameState();
+				current.meta = FALSE;
 			}
 
-			recursionDepth = 0;
+			moveActor(ctx, header->theHero);
 
-			// Move all characters, hero first
-			rememberGameState();
-			current.meta = FALSE;
-			moveActor(header->theHero);
+			if (!ctx._break) {
+				if (gameStateChanged)
+					rememberCommands();
+				else
+					forgetGameState();
 
-			if (gameStateChanged)
-				rememberCommands();
-			else
-				forgetGameState();
+				if (!current.meta) {
+					current.tick++;
 
-			if (!current.meta) {
-				current.tick++;
+					// Remove this call? Since Eval is done up there after each event...
+					resetAndEvaluateRules(rules, header->version);
 
-				// Remove this call? Since Eval is done up there after each event...
-				resetAndEvaluateRules(rules, header->version);
+					/* Then all the other actors... */
+					for (uint i = 1; i <= header->instanceMax; i++) {
+						if (i != header->theHero && isAActor(i)) {
+							moveActor(ctx, i);
+							if (ctx._break)
+								break;
 
-				/* Then all the other actors... */
-				for (uint i = 1; i <= header->instanceMax; i++)
-					if (i != header->theHero && isAActor(i)) {
-						moveActor(i);
-						resetAndEvaluateRules(rules, header->version);
+							resetAndEvaluateRules(rules, header->version);
+						}
 					}
-			}
+				}
 
-			if (ctx._break && ctx._label == "restart")
-				break;
+				if (ctx._break && ctx._label == "restart")
+					break;
+			}
 		}
 	} while (!g_vm->shouldQuit() && ctx._label == "restart");
 }
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index 97a3a35..5f64692 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -40,10 +40,10 @@ namespace Glk {
 namespace Alan3 {
 
 /* PUBLIC DATA */
-bool anyOutput = FALSE;
-bool capitalize = FALSE;
-bool needSpace = FALSE;
-bool skipSpace = FALSE;
+bool anyOutput;
+bool capitalize;
+bool needSpace;
+bool skipSpace;
 
 /* Screen formatting info */
 int col, lin;
diff --git a/engines/glk/alan3/output.h b/engines/glk/alan3/output.h
index e889b76..6f52cfc 100644
--- a/engines/glk/alan3/output.h
+++ b/engines/glk/alan3/output.h
@@ -36,6 +36,7 @@ extern int pageLength, pageWidth;
 extern bool anyOutput;
 extern bool needSpace;
 extern bool capitalize;
+extern bool skipSpace;
 
 /* Log file */
 extern strid_t logFile;


Commit: 55b93f5a20bb352b0388c8cc1802437a2fcc6ce9
    https://github.com/scummvm/scummvm/commit/55b93f5a20bb352b0388c8cc1802437a2fcc6ce9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Hook up empty lines to forfeit longjmp replacement

Changed paths:
    engines/glk/alan3/main.cpp
    engines/glk/alan3/parse.cpp
    engines/glk/alan3/parse.h
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/scan.h


diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 4fd8cf6..ad690c6 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -656,20 +656,23 @@ static void moveActor(CONTEXT, int theActor) {
 	StepEntry *step;
 	Aint previousInstance = current.instance;
 
+	if (context._break) {
+		// forfeit setjmp replacement destination
+		assert(context._label == "forfeit");
+		context.clear();
+		current.instance = previousInstance;
+		return;
+	}
+
 	current.actor = theActor;
 	current.instance = theActor;
 	current.location = where(theActor, TRANSITIVE);
-	if (context._break || theActor == (int)HERO) {
-		if (context._break) {
-			// Forfeit jump destination
-			assert(context._label == "forfeit");
-			context.clear();
-		} else {
-			// Ask him!
-			parse();
-			capitalize = TRUE;
-			fail = FALSE;           // fail only aborts one actor
-		}
+
+	if (theActor == (int)HERO) {
+		// Ask him!
+		CALL0(parse)
+		capitalize = TRUE;
+		fail = FALSE;           // fail only aborts one actor
 
 	} else if (admin[theActor].script != 0) {
 		for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++) {
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp
index f04b910..da9d759 100644
--- a/engines/glk/alan3/parse.cpp
+++ b/engines/glk/alan3/parse.cpp
@@ -1437,7 +1437,7 @@ static void parseInstanceCommand(Parameter parameters[], Parameter multipleParam
 
 
 /*======================================================================*/
-void parse(void) {
+void parse(CONTEXT) {
 	/* longjmp's ahead so these need to survive to not leak memory */
 	static Parameter *parameters = NULL;
 	static Parameter *multipleParameters = NULL;
@@ -1446,9 +1446,10 @@ void parse(void) {
 
 	if (endOfWords(currentWordIndex)) {
 		currentWordIndex = 0;
-		scan();
-	} else if (anyOutput)
+		CALL0(scan)
+	} else if (anyOutput) {
 		para();
+	}
 
 	capitalize = TRUE;
 
diff --git a/engines/glk/alan3/parse.h b/engines/glk/alan3/parse.h
index 7425301..2737183 100644
--- a/engines/glk/alan3/parse.h
+++ b/engines/glk/alan3/parse.h
@@ -27,13 +27,14 @@
 
 #include "glk/alan3/types.h"
 #include "glk/alan3/params.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
 
 /* FUNCTIONS */
 
-extern void parse(void);
+extern void parse(CONTEXT);
 extern void initParsing(void);
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index dcfcc6f..284f28f 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -134,7 +134,7 @@ static char *gettoken(char *txtBuf) {
 
 /*----------------------------------------------------------------------*/
 // TODO replace dependency to exe.c with injection of quitGame() and undo()
-static void getLine(void) {
+static void getLine(CONTEXT) {
 	para();
 	do {
 		statusline();
@@ -160,14 +160,10 @@ static void getLine(void) {
 			g_vm->glk_put_char_stream(logFile, '\n');
 		}
 		/* If the player input an empty command he forfeited his command */
-#ifdef TODO
 		if (strlen(buf) == 0) {
 			clearWordList(playerWords);
-			longjmp(forfeitLabel, 0);
+			LONG_JUMP_LABEL("forfeit")
 		}
-#else
-		syserr("TODO: empty command");
-#endif
 
 		strcpy(isobuf, buf);
 		token = gettoken(isobuf);
@@ -190,7 +186,7 @@ static void getLine(void) {
 
 
 /*======================================================================*/
-void scan(void) {
+void scan(CONTEXT) {
 	int i;
 	int w;
 
@@ -198,11 +194,13 @@ void scan(void) {
 		/* Player used '.' to separate commands. Read next */
 		para();
 		token = gettoken(NULL); /* Or did he just finish the command with a full stop? */
-		if (token == NULL)
-			getLine();
+		if (token == NULL) {
+			CALL0(getLine)
+		}
 		continued = FALSE;
-	} else
-		getLine();
+	} else {
+		CALL0(getLine)
+	}
 
 	freeLiterals();
 	playerWords[0].code = 0; // TODO This means what?
diff --git a/engines/glk/alan3/scan.h b/engines/glk/alan3/scan.h
index 04d8937..6f565c05 100644
--- a/engines/glk/alan3/scan.h
+++ b/engines/glk/alan3/scan.h
@@ -26,6 +26,7 @@
 /* Player input scanner for ALAN interpreter module. */
 
 #include "glk/alan3/types.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -37,7 +38,7 @@ extern bool continued;
 /* FUNCTIONS */
 
 extern void forceNewPlayerInput();
-extern void scan();
+extern void scan(CONTEXT);
 
 } // End of namespace Alan3
 } // End of namespace Glk


Commit: ec979b8555cfc10cca3858df2cca635c04f240d2
    https://github.com/scummvm/scummvm/commit/ec979b8555cfc10cca3858df2cca635c04f240d2
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Fix quitting game from input line when window closed

Changed paths:
    engines/glk/alan3/readline.cpp
    engines/glk/alan3/scan.cpp


diff --git a/engines/glk/alan3/readline.cpp b/engines/glk/alan3/readline.cpp
index 2bd408f..34e9e64 100644
--- a/engines/glk/alan3/readline.cpp
+++ b/engines/glk/alan3/readline.cpp
@@ -70,6 +70,9 @@ bool readline(char buffer[]) {
 		*/
 		do {
 			g_vm->glk_select(&event);
+			if (g_vm->shouldQuit())
+				return FALSE;
+
 			switch (event.type) {
 			case evtype_Arrange:
 				statusline();
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 284f28f..6785b2a 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -148,6 +148,11 @@ static void getLine(CONTEXT) {
 			printAndLog("> ");
 
 		if (!readline(buf)) {
+			if (g_vm->shouldQuit()) {
+				context._break = true;
+				return;
+			}
+
 			newline();
 			quitGame();
 		}


Commit: 18566feefcb9f4fa4d7395ffa6e6f2a6f0247d0e
    https://github.com/scummvm/scummvm/commit/18566feefcb9f4fa4d7395ffa6e6f2a6f0247d0e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:08-07:00

Commit Message:
GLK: ALAN3: Implement savegame code

Changed paths:
  A engines/glk/alan3/acode.cpp
    engines/glk/alan3/acode.h
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/alan3.h
    engines/glk/alan3/current.cpp
    engines/glk/alan3/current.h
    engines/glk/alan3/event.cpp
    engines/glk/alan3/event.h
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/instance.h
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/save.cpp
    engines/glk/alan3/save.h
    engines/glk/module.mk


diff --git a/engines/glk/alan3/acode.cpp b/engines/glk/alan3/acode.cpp
new file mode 100644
index 0000000..3dbfaa5
--- /dev/null
+++ b/engines/glk/alan3/acode.cpp
@@ -0,0 +1,35 @@
+/* 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/alan3/acode.h"
+
+namespace Glk {
+namespace Alan3 {
+
+void AttributeEntry::synchronize(Common::Serializer &s) {
+	s.syncAsSint32LE(code);
+	s.syncAsSint32LE(value);
+	s.syncAsSint32LE(id);
+}
+
+} // End of namespace Alan3
+} // End of namespace Glk
diff --git a/engines/glk/alan3/acode.h b/engines/glk/alan3/acode.h
index 7aa1d8e..6e663fa 100644
--- a/engines/glk/alan3/acode.h
+++ b/engines/glk/alan3/acode.h
@@ -24,6 +24,7 @@
 #define GLK_ACODE
 
 #include "common/scummsys.h"
+#include "common/serializer.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -370,6 +371,11 @@ struct AttributeEntry {         /* ATTRIBUTE LIST */
                                    string pointer, a set has a pointer
                                    to a dynamically allocated set */
 	Aaddr id;                   /* Address to the name */
+
+	/**
+	 * Save/resotre data from save file
+	 */
+	void synchronize(Common::Serializer &s);
 } PACKED_STRUCT;
 
 struct AttributeHeaderEntry {   /* ATTRIBUTE LIST in header */
diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index bbcd6da..7fc7e84 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -26,6 +26,7 @@
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/options.h"
 #include "glk/alan3/output.h"
+#include "glk/alan3/save.h"
 #include "glk/alan3/syserr.h"
 #include "common/system.h"
 #include "common/config-manager.h"
@@ -131,29 +132,14 @@ void Alan3::deinitialize() {
 }
 
 Common::Error Alan3::readSaveData(Common::SeekableReadStream *rs) {
-	Common::Serializer s(rs, nullptr);
-	synchronizeSave(s);
-
+	Glk::Alan3::restoreGame(rs);
 	return Common::kNoError;
 }
 
 Common::Error Alan3::writeGameData(Common::WriteStream *ws) {
-	Common::Serializer s(nullptr, ws);
-	synchronizeSave(s);
-
-	ws->flush();
+	Glk::Alan3::saveGame(ws);
 	return Common::kNoError;
 }
 
-// This works around gcc errors for passing packed structure fields
-void syncVal(Common::Serializer &s, uint32 *fld) {
-	uint32 &v = *fld;
-	s.syncAsUint32LE(v);
-}
-
-void Alan3::synchronizeSave(Common::Serializer &s) {
-	// TODO
-}
-
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
index 6693476..73a9a03 100644
--- a/engines/glk/alan3/alan3.h
+++ b/engines/glk/alan3/alan3.h
@@ -47,11 +47,6 @@ private:
 	 * Deinitialization
 	 */
 	void deinitialize();
-
-	/**
-	 * Synchronize data to or from a save file
-	 */
-	void synchronizeSave(Common::Serializer &s);
 public:
 	/**
 	 * Constructor
diff --git a/engines/glk/alan3/current.cpp b/engines/glk/alan3/current.cpp
index 7c2dfe2..37b5682 100644
--- a/engines/glk/alan3/current.cpp
+++ b/engines/glk/alan3/current.cpp
@@ -29,5 +29,19 @@ namespace Alan3 {
 CurVars current;
 bool gameStateChanged = FALSE;
 
+void CurVars::synchronize(Common::Serializer &s) {
+	s.syncAsSint32LE(syntax);
+	s.syncAsSint32LE(verb);
+	s.syncAsSint32LE(location);
+	s.syncAsSint32LE(actor);
+	s.syncAsSint32LE(instance);
+	s.syncAsSint32LE(tick);
+	s.syncAsSint32LE(score);
+	s.syncAsSint32LE(visits);
+	s.syncAsSint32LE(sourceLine);
+	s.syncAsSint32LE(sourceFile);
+	s.syncAsUint32LE(meta);
+}
+
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/current.h b/engines/glk/alan3/current.h
index 8c98653..91a217b 100644
--- a/engines/glk/alan3/current.h
+++ b/engines/glk/alan3/current.h
@@ -41,6 +41,11 @@ struct CurVars {
 	    sourceLine,
 	    sourceFile;
 	bool meta;
+
+	/**
+	 * Save/load data from save file
+	 */
+	void synchronize(Common::Serializer &s);
 };
 
 /* DATA */
diff --git a/engines/glk/alan3/event.cpp b/engines/glk/alan3/event.cpp
index ce866be..73d7d9d 100644
--- a/engines/glk/alan3/event.cpp
+++ b/engines/glk/alan3/event.cpp
@@ -31,5 +31,11 @@ EventQueueEntry *eventQueue = NULL;
 int eventQueueTop = 0;
 EventEntry *events;
 
+void EventQueueEntry::synchronize(Common::Serializer &s) {
+	s.syncAsSint32LE(after);
+	s.syncAsSint32LE(event);
+	s.syncAsSint32LE(where);
+}
+
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/event.h b/engines/glk/alan3/event.h
index 0a76d3c..e0199f0 100644
--- a/engines/glk/alan3/event.h
+++ b/engines/glk/alan3/event.h
@@ -23,18 +23,26 @@
 #ifndef GLK_ALAN3_EVENT
 #define GLK_ALAN3_EVENT
 
+#include "common/serializer.h"
 #include "glk/alan3/acode.h"
 #include "glk/alan3/types.h"
 
 namespace Glk {
 namespace Alan3 {
 
-/* TYPES */
-typedef struct EventQueueEntry { /* EVENT QUEUE ENTRIES */
+/**
+ * Event queue entries
+ */
+struct EventQueueEntry {
 	int after;
 	int event;
 	int where;
-} EventQueueEntry;
+
+	/**
+	 * Save/load from a save file
+	 */
+	void synchronize(Common::Serializer &s);
+};
 
 
 /* DATA */
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index 89e3659..05ccd69 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -52,6 +52,21 @@ AttributeEntry *attributes; /* Dynamic attribute values */
 
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 
+void AdminEntry::synchronize(Common::Serializer &s) {
+	s.syncAsUint32LE(location);
+
+	Aword attr = 0;
+	s.syncAsUint32LE(attr);
+
+	s.syncAsUint32LE(alreadyDescribed);
+	s.syncAsUint32LE(visitsCount);
+	s.syncAsUint32LE(script);
+	s.syncAsUint32LE(step);
+	s.syncAsUint32LE(waitCount);
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
 /* Instance query methods */
 
 /*======================================================================*/
diff --git a/engines/glk/alan3/instance.h b/engines/glk/alan3/instance.h
index 6c62bb5..bd43195 100644
--- a/engines/glk/alan3/instance.h
+++ b/engines/glk/alan3/instance.h
@@ -23,6 +23,7 @@
 #ifndef GLK_ALAN3_INSTANCE
 #define GLK_ALAN3_INSTANCE
 
+#include "common/serializer.h"
 #include "glk/alan3/acode.h"
 #include "glk/alan3/types.h"
 #include "glk/alan3/set.h"
@@ -39,6 +40,11 @@ struct AdminEntry { /* Administrative data about instances */
 	Aint script;
 	Aint step;
 	Aint waitCount;
+
+	/**
+	 * Save/Restore data
+	 */
+	void synchronize(Common::Serializer &s);
 };
 
 
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index 0421442..2219854 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -601,13 +601,13 @@ void interpret(Aaddr adr) {
 			case I_SAVE: {
 				if (traceInstructionOption)
 					printf("SAVE\t\t\t\t\t\t");
-				save();
+				g_vm->saveGame();
 				break;
 			}
 			case I_RESTORE: {
 				if (traceInstructionOption)
 					printf("RESTORE\t\t\t\t\t\t");
-				restore();
+				g_vm->loadGame();
 				break;
 			}
 			case I_RESTART: {
diff --git a/engines/glk/alan3/save.cpp b/engines/glk/alan3/save.cpp
index 506cf9d..0d33ea6 100644
--- a/engines/glk/alan3/save.cpp
+++ b/engines/glk/alan3/save.cpp
@@ -20,14 +20,24 @@
  *
  */
 
+#include "glk/alan3/save.h"
+#include "glk/alan3/acode.h"
+#include "glk/alan3/args.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/event.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/lists.h"
+#include "glk/alan3/memory.h"
+#include "glk/alan3/msg.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/score.h"
+#include "glk/alan3/types.h"
+
 namespace Glk {
 namespace Alan3 {
 
-#ifdef TODO
-
 /*----------------------------------------------------------------------*/
-static void saveStrings(AFILE saveFile) {
-
+static void saveStrings(Common::WriteStream *saveFile) {
 	StringInitEntry *initEntry;
 
 	if (header->stringInitTable != 0)
@@ -35,68 +45,77 @@ static void saveStrings(AFILE saveFile) {
 		        !isEndOfArray(initEntry); initEntry++) {
 			char *attr = (char *)getInstanceStringAttribute(initEntry->instanceCode, initEntry->attributeCode);
 			Aint length = strlen(attr) + 1;
-			fwrite((void *)&length, sizeof(length), 1, saveFile);
-			fwrite((void *)attr, 1, length, saveFile);
+			saveFile->writeUint32LE(length);
+			saveFile->write(attr, length);
 		}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveSets(AFILE saveFile) {
+static void saveSets(Common::WriteStream *saveFile) {
 	SetInitEntry *initEntry;
 
 	if (header->setInitTable != 0)
 		for (initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
 		        !isEndOfArray(initEntry); initEntry++) {
 			Set *attr = (Set *)getInstanceSetAttribute(initEntry->instanceCode, initEntry->attributeCode);
-			fwrite((void *)&attr->size, sizeof(attr->size), 1, saveFile);
-			fwrite((void *)attr->members, sizeof(attr->members[0]), attr->size, saveFile);
+			saveFile->writeUint32LE(attr->size);
+			saveFile->write(attr->members, attr->size);
 		}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveGameInfo(AFILE saveFile) {
-	fwrite((void *)"ASAV", 1, 4, saveFile);
-	fwrite((void *)&header->version, 1, sizeof(Aword), saveFile);
-	fwrite((void *)adventureName, 1, strlen(adventureName) + 1, saveFile);
-	fwrite((void *)&header->uid, 1, sizeof(Aword), saveFile);
+static void saveGameInfo(Common::WriteStream *saveFile) {
+	saveFile->writeUint32BE(MKTAG('A', 'S', 'A', 'V'));
+	saveFile->write(header->version, 4);
+	saveFile->write(adventureName, strlen(adventureName) + 1);
+	saveFile->writeUint32LE(header->uid);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveAdmin(AFILE saveFile) {
-	fwrite((void *)&admin[1], sizeof(AdminEntry), header->instanceMax, saveFile);
+static void saveAdmin(Common::WriteStream *saveFile) {
+	Common::Serializer s(nullptr, saveFile);
+	for (uint i = 1; i <= header->instanceMax; i++)
+		admin[i].synchronize(s);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveAttributeArea(AFILE saveFile) {
-	fwrite((void *)attributes, header->attributesAreaSize, sizeof(Aword), saveFile);
+static void saveAttributeArea(Common::WriteStream *saveFile) {
+	Common::Serializer s(nullptr, saveFile);
+	for (Aint i = 0; i < header->attributesAreaSize; ++i)
+		attributes[i].synchronize(s);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveEventQueue(AFILE saveFile) {
-	fwrite((void *)&eventQueueTop, sizeof(eventQueueTop), 1, saveFile);
-	fwrite((void *)&eventQueue[0], sizeof(eventQueue[0]), eventQueueTop, saveFile);
+static void saveEventQueue(Common::WriteStream *saveFile) {
+	Common::Serializer s(nullptr, saveFile);
+
+	s.syncAsSint32LE(eventQueueTop);
+	for (int i = 0; i < eventQueueTop; ++i)
+		eventQueue[i].synchronize(s);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveCurrentValues(AFILE saveFile) {
-	fwrite((void *)&current, sizeof(current), 1, saveFile);
+static void saveCurrentValues(Common::WriteStream *saveFile) {
+	Common::Serializer s(nullptr, saveFile);
+	current.synchronize(s);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveScores(AFILE saveFile) {
-	fwrite((void *)scores, sizeof(Aword), header->scoreCount, saveFile);
+static void saveScores(Common::WriteStream *saveFile) {
+	for (Aint i = 0; i < header->scoreCount; ++i)
+		saveFile->writeUint32LE(scores[i]);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void saveGame(AFILE saveFile) {
+void saveGame(Common::WriteStream *saveFile) {
 	/* Save tag, version of interpreter, name and uid of game */
 	saveGameInfo(saveFile);
 
@@ -115,88 +134,34 @@ static void saveGame(AFILE saveFile) {
 }
 
 
-/*======================================================================*/
-void save(void) {
-#ifdef HAVE_GLK
-	frefid_t saveFileRef;
-	strid_t saveFile;
-	saveFileRef = glk_fileref_create_by_prompt(fileusage_SavedGame, filemode_Write, 0);
-	if (saveFileRef == NULL)
-		error(M_SAVEFAILED);
-	saveFile = glk_stream_open_file(saveFileRef, filemode_Write, 0);
-
-#else
-	FILE *saveFile;
-	char str[256];
-
-	current.location = where(HERO, DIRECT);
-	/* First save ? */
-	if (saveFileName[0] == '\0') {
-		strcpy(saveFileName, adventureName);
-		strcat(saveFileName, ".sav");
-	}
-	printMessage(M_SAVEWHERE);
-	sprintf(str, "(%s) : ", saveFileName);
-	output(str);
-#ifdef USE_READLINE
-	readline(str);
-#else
-	gets(str);
-#endif
-	if (str[0] == '\0')
-		strcpy(str, saveFileName);
-	col = 1;
-	if ((saveFile = fopen(str, READ_MODE)) != NULL)
-		/* It already existed */
-		if (!regressionTestOption) {
-			/* Ask for overwrite confirmation */
-			if (!confirm(M_SAVEOVERWRITE))
-				abortPlayerCommand();            /* Return to player without saying anything */
-		}
-	strcpy(saveFileName, str);
-	if ((saveFile = fopen(saveFileName, WRITE_MODE)) == NULL)
-		error(M_SAVEFAILED);
-#endif
-
-	saveGame(saveFile);
-
-	fclose(saveFile);
-}
-
-
 /*----------------------------------------------------------------------*/
-static void restoreStrings(AFILE saveFile) {
+static void restoreStrings(Common::SeekableReadStream *saveFile) {
 	StringInitEntry *initEntry;
 
 	if (header->stringInitTable != 0)
 		for (initEntry = (StringInitEntry *)pointerTo(header->stringInitTable);
 		        !isEndOfArray(initEntry); initEntry++) {
-			Aint length;
-			char *string;
-			fread((void *)&length, sizeof(Aint), 1, saveFile);
-			string = allocate(length + 1);
-			fread((void *)string, 1, length, saveFile);
+			Aint length = saveFile->readUint32LE();
+			char *string = (char *)allocate(length + 1);
+
+			saveFile->read(string, length);
 			setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(string));
 		}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void restoreSets(AFILE saveFile) {
+static void restoreSets(Common::SeekableReadStream *saveFile) {
 	SetInitEntry *initEntry;
 
 	if (header->setInitTable != 0)
 		for (initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
 		        !isEndOfArray(initEntry); initEntry++) {
-			Aint setSize;
-			Set *set;
-			int i;
-
-			fread((void *)&setSize, sizeof(setSize), 1, saveFile);
-			set = newSet(setSize);
-			for (i = 0; i < setSize; i++) {
-				Aword member;
-				fread((void *)&member, sizeof(member), 1, saveFile);
+			Aint setSize = saveFile->readUint32LE();
+			Set *set = newSet(setSize);
+
+			for (int i = 0; i < setSize; i++) {
+				Aword member = saveFile->readUint32LE();
 				addToSet(set, member);
 			}
 			setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(set));
@@ -205,92 +170,91 @@ static void restoreSets(AFILE saveFile) {
 
 
 /*----------------------------------------------------------------------*/
-static void restoreScores(AFILE saveFile) {
-	fread((void *)scores, sizeof(Aword), header->scoreCount, saveFile);
+static void restoreScores(Common::SeekableReadStream *saveFile) {
+	for (Aint i = 0; i < header->scoreCount; ++i)
+		scores[i] = saveFile->readUint32LE();
 }
 
 
 /*----------------------------------------------------------------------*/
-static void restoreEventQueue(AFILE saveFile) {
-	fread((void *)&eventQueueTop, sizeof(eventQueueTop), 1, saveFile);
-	if (eventQueueTop > eventQueueSize) {
-		deallocate(eventQueue);
-		eventQueue = allocate(eventQueueTop * sizeof(eventQueue[0]));
-	}
-	fread((void *)&eventQueue[0], sizeof(eventQueue[0]), eventQueueTop, saveFile);
+static void restoreEventQueue(Common::SeekableReadStream *saveFile) {
+	Common::Serializer s(saveFile, nullptr);
+
+	s.syncAsSint32LE(eventQueueTop);
+	for (int i = 0; i < eventQueueTop; ++i)
+		eventQueue[i].synchronize(s);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void restoreAdmin(AFILE saveFile) {
-	/* Restore admin for instances, remember to reset attribute area pointer */
-	int i;
-	for (i = 1; i <= header->instanceMax; i++) {
+static void restoreAdmin(Common::SeekableReadStream *saveFile) {
+	// Restore admin for instances, remember to reset attribute area pointer
+	Common::Serializer s(saveFile, nullptr);
+	for (uint i = 1; i <= header->instanceMax; i++) {
 		AttributeEntry *currentAttributesArea = admin[i].attributes;
-		fread((void *)&admin[i], sizeof(AdminEntry), 1, saveFile);
+		admin[i].synchronize(s);
 		admin[i].attributes = currentAttributesArea;
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void restoreAttributeArea(AFILE saveFile) {
-	fread((void *)attributes, header->attributesAreaSize, sizeof(Aword), saveFile);
+static void restoreAttributeArea(Common::SeekableReadStream *saveFile) {
+	Common::Serializer s(saveFile, nullptr);
+	for (Aint i = 0; i < header->attributesAreaSize; ++i)
+		attributes[i].synchronize(s);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void restoreCurrentValues(AFILE saveFile) {
-	fread((void *)&current, sizeof(current), 1, saveFile);
+static void restoreCurrentValues(Common::SeekableReadStream *saveFile) {
+	Common::Serializer s(saveFile, nullptr);
+	current.synchronize(s);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void verifyGameId(AFILE saveFile) {
-	Aword savedUid;
-
-	fread((void *)&savedUid, sizeof(Aword), 1, saveFile);
+static void verifyGameId(Common::SeekableReadStream *saveFile) {
+	Aword savedUid = saveFile->readUint32LE();
 	if (!ignoreErrorOption && savedUid != header->uid)
 		error(M_SAVEVERS);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void verifyGameName(AFILE saveFile) {
+static void verifyGameName(Common::SeekableReadStream *saveFile) {
 	char savedName[256];
 	int i = 0;
 
-	while ((savedName[i++] = fgetc(saveFile)) != '\0');
+	while ((savedName[i++] = saveFile->readByte()) != '\0');
 	if (strcmp(savedName, adventureName) != 0)
 		error(M_SAVENAME);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void verifyCompilerVersion(AFILE saveFile) {
+static void verifyCompilerVersion(Common::SeekableReadStream *saveFile) {
 	char savedVersion[4];
 
-	fread((void *)&savedVersion, sizeof(Aword), 1, saveFile);
-	if (!ignoreErrorOption && strncmp(savedVersion, header->version, 4))
+	saveFile->read(&savedVersion, 4);
+	if (!ignoreErrorOption && memcmp(savedVersion, header->version, 4))
 		error(M_SAVEVERS);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void verifySaveFile(AFILE saveFile) {
-	char string[256];
-
-	fread((void *)&string, 1, 4, saveFile);
+static void verifySaveFile(Common::SeekableReadStream *saveFile) {
+	char string[5];
+	saveFile->read(string, 4);
 	string[4] = '\0';
+
 	if (strcmp(string, "ASAV") != 0)
 		error(M_NOTASAVEFILE);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void restoreGame(AFILE saveFile) {
-	if (saveFile == NULL) syserr("'restoreGame()' from a null fileref");
-
+void restoreGame(Common::SeekableReadStream *saveFile) {
 	verifySaveFile(saveFile);
 
 	/* Verify version of compiler/interpreter of saved game with us */
@@ -311,54 +275,5 @@ static void restoreGame(AFILE saveFile) {
 	restoreSets(saveFile);
 }
 
-
-/*======================================================================*/
-void restore(void) {
-#ifdef HAVE_GLK
-	frefid_t saveFileRef;
-	strid_t saveFile;
-	saveFileRef = glk_fileref_create_by_prompt(fileusage_SavedGame, filemode_Read, 0);
-	if (saveFileRef == NULL) return;
-	saveFile = glk_stream_open_file(saveFileRef, filemode_Read, 0);
-	if (saveFile == NULL) return;
-
-#else
-	char str[1000];
-	FILE *saveFile;
-
-	current.location = where(HERO, DIRECT);
-	/* First save ? */
-	if (saveFileName[0] == '\0') {
-		strcpy(saveFileName, adventureName);
-		strcat(saveFileName, ".sav");
-	}
-	printMessage(M_RESTOREFROM);
-	sprintf(str, "(%s) : ", saveFileName);
-	output(str);
-#ifdef USE_READLINE
-	readline(str);
-#else
-	gets(str);
-#endif
-
-	col = 1;
-	if (str[0] == '\0') {
-		strcpy(str, saveFileName);
-	}
-	if ((saveFile = fopen(str, READ_MODE)) == NULL)
-		error(M_SAVEMISSING);
-	strcpy(saveFileName, str);          /* Save it for future use */
-
-#endif
-
-	restoreGame(saveFile);
-
-	fclose(saveFile);
-}
-#else
-void save() {}
-void restore() {}
-#endif
-
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/save.h b/engines/glk/alan3/save.h
index 3f12f05..e4b00f6 100644
--- a/engines/glk/alan3/save.h
+++ b/engines/glk/alan3/save.h
@@ -23,14 +23,13 @@
 #ifndef GLK_ALAN3_SAVE
 #define GLK_ALAN3_SAVE
 
-/* Header file for save and restore unit in Alan interpreter */
+#include "common/stream.h"
 
 namespace Glk {
 namespace Alan3 {
 
-/* Functions: */
-extern void save();
-extern void restore();
+extern void saveGame(Common::WriteStream *saveFile);
+extern void restoreGame(Common::SeekableReadStream *saveFile);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 902b9fc..65ddd80 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -49,6 +49,7 @@ MODULE_OBJS := \
 	alan2/sysdep.o \
 	alan2/term.o \
 	alan2/types.o \
+	alan3/acode.o \
 	alan3/act.o \
 	alan3/actor.o \
 	alan3/alan3.o \


Commit: 5dea66231397c52afc7d2cdeae5989fd5edd0604
    https://github.com/scummvm/scummvm/commit/5dea66231397c52afc7d2cdeae5989fd5edd0604
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Wrapping method calls in longjmp replacement macros

Changed paths:
    engines/glk/alan3/act.cpp
    engines/glk/alan3/act.h
    engines/glk/alan3/actor.cpp
    engines/glk/alan3/actor.h
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/alt_info.cpp
    engines/glk/alan3/alt_info.h
    engines/glk/alan3/checkentry.cpp
    engines/glk/alan3/checkentry.h
    engines/glk/alan3/container.cpp
    engines/glk/alan3/container.h
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/debug.h
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/exe.h
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/instance.h
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/inter.h
    engines/glk/alan3/location.cpp
    engines/glk/alan3/location.h
    engines/glk/alan3/main.cpp
    engines/glk/alan3/msg.cpp
    engines/glk/alan3/msg.h
    engines/glk/alan3/output.cpp
    engines/glk/alan3/parse.cpp
    engines/glk/alan3/readline.cpp
    engines/glk/alan3/readline.h
    engines/glk/alan3/rules.cpp
    engines/glk/alan3/rules.h
    engines/glk/alan3/save.cpp
    engines/glk/alan3/save.h
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/syntax.cpp
    engines/glk/alan3/syntax.h
    engines/glk/alan3/term.cpp
    engines/glk/alan3/term.h


diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
index 4874cb9..cdc95f9 100644
--- a/engines/glk/alan3/act.cpp
+++ b/engines/glk/alan3/act.cpp
@@ -32,9 +32,10 @@ namespace Glk {
 namespace Alan3 {
 
 /*----------------------------------------------------------------------*/
-static void executeCommand(int verb, Parameter parameters[]) {
+static void executeCommand(CONTEXT, int verb, Parameter parameters[]) {
 	static AltInfo *altInfos = NULL; /* Need to survive lots of different exits...*/
 	int altIndex;
+	bool flag;
 
 	/* Did we leave anything behind last time... */
 	if (altInfos != NULL)
@@ -42,20 +43,22 @@ static void executeCommand(int verb, Parameter parameters[]) {
 
 	altInfos = findAllAlternatives(verb, parameters);
 
-	if (anyCheckFailed(altInfos, EXECUTE_CHECK_BODY_ON_FAIL))
+	FUNC2(anyCheckFailed, flag, altInfos, EXECUTE_CHECK_BODY_ON_FAIL)
+	if (flag)
 		return;
 
 	/* Check for anything to execute... */
 	if (!anythingToExecute(altInfos))
-		error(M_CANT0);
+		CALL1(error, M_CANT0)
 
 	/* Now perform actions! First try any BEFORE or ONLY from inside out */
 	for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
 		if (altInfos[altIndex].alt != 0) // TODO Can this ever be NULL? Why?
 			if (altInfos[altIndex].alt->qual == (Aword)Q_BEFORE
 			        || altInfos[altIndex].alt->qual == (Aword)Q_ONLY) {
-				if (!executedOk(&altInfos[altIndex]))
-					abortPlayerCommand();
+				FUNC1(executedOk, flag, &altInfos[altIndex])
+				if (!flag)
+					CALL0(abortPlayerCommand)
 				if (altInfos[altIndex].alt->qual == (Aword)Q_ONLY)
 					return;
 			}
@@ -63,17 +66,22 @@ static void executeCommand(int verb, Parameter parameters[]) {
 
 	/* Then execute any not declared as AFTER, i.e. the default */
 	for (altIndex = 0; !altInfos[altIndex].end; altIndex++) {
-		if (altInfos[altIndex].alt != 0)
-			if (altInfos[altIndex].alt->qual != (Aword)Q_AFTER)
-				if (!executedOk(&altInfos[altIndex]))
-					abortPlayerCommand();
+		if (altInfos[altIndex].alt != 0) {
+			if (altInfos[altIndex].alt->qual != (Aword)Q_AFTER) {
+				FUNC1(executedOk, flag, &altInfos[altIndex])
+				if (!flag)
+					CALL0(abortPlayerCommand)
+			}
+		}
 	}
 
 	/* Finally, the ones declared as AFTER */
 	for (altIndex = lastAltInfoIndex(altInfos); altIndex >= 0; altIndex--) {
-		if (altInfos[altIndex].alt != 0)
-			if (!executedOk(&altInfos[altIndex]))
-				abortPlayerCommand();
+		if (altInfos[altIndex].alt != 0) {
+			FUNC1(executedOk, flag, &altInfos[altIndex])
+			if (!flag)
+				CALL0(abortPlayerCommand)
+		}
 	}
 }
 
@@ -86,7 +94,7 @@ static void executeCommand(int verb, Parameter parameters[]) {
   such as ALL, THEM or lists of objects.
 
 */
-void action(int verb, Parameter parameters[], Parameter multipleMatches[]) {
+void action(CONTEXT, int verb, Parameter parameters[], Parameter multipleMatches[]) {
 	int multiplePosition;
 #ifdef TODO
 	char marker[10];
@@ -115,7 +123,7 @@ void action(int verb, Parameter parameters[], Parameter multipleMatches[]) {
 #endif
 	} else {
 		setGlobalParameters(parameters);
-		executeCommand(verb, parameters);
+		CALL2(executeCommand, verb, parameters)
 	}
 
 }
diff --git a/engines/glk/alan3/act.h b/engines/glk/alan3/act.h
index 09f8676..b2daa25 100644
--- a/engines/glk/alan3/act.h
+++ b/engines/glk/alan3/act.h
@@ -25,12 +25,13 @@
 
 /* Header file for action unit of ARUN Alan System interpreter */
 
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/params.h"
 
 namespace Glk {
 namespace Alan3 {
 
-extern void action(int verb, Parameter *parameters, Parameter *multipleMatches);
+extern void action(CONTEXT, int verb, Parameter *parameters, Parameter *multipleMatches);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/actor.cpp b/engines/glk/alan3/actor.cpp
index ff4d89f..337034f 100644
--- a/engines/glk/alan3/actor.cpp
+++ b/engines/glk/alan3/actor.cpp
@@ -61,18 +61,19 @@ StepEntry *stepOf(int actor) {
 
 
 /*======================================================================*/
-void describeActor(int actor) {
+void describeActor(CONTEXT, int actor) {
 	ScriptEntry *script = scriptOf(actor);
 
-	if (script != NULL && script->description != 0)
-		interpret(script->description);
-	else if (hasDescription(actor))
-		describeAnything(actor);
-	else {
+	if (script != NULL && script->description != 0) {
+		CALL1(interpret, script->description)
+	} else if (hasDescription(actor)) {
+		CALL1(describeAnything, actor)
+	} else {
 		printMessageWithInstanceParameter(M_SEE_START, actor);
 		printMessage(M_SEE_END);
+
 		if (instances[actor].container != 0)
-			describeContainer(actor);
+			CALL1(describeContainer, actor)
 	}
 	admin[actor].alreadyDescribed = TRUE;
 }
diff --git a/engines/glk/alan3/actor.h b/engines/glk/alan3/actor.h
index 8b2c1ad..6ac20b2 100644
--- a/engines/glk/alan3/actor.h
+++ b/engines/glk/alan3/actor.h
@@ -24,6 +24,7 @@
 #define GLK_ALAN3_ACTOR
 
 #include "glk/alan3/acode.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -31,7 +32,7 @@ namespace Alan3 {
 /* FUNCTIONS */
 extern ScriptEntry *scriptOf(int actor);
 extern StepEntry *stepOf(int actor);
-extern void describeActor(int actor);
+extern void describeActor(CONTEXT, int actor);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 7fc7e84..52a6e25 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -132,8 +132,7 @@ void Alan3::deinitialize() {
 }
 
 Common::Error Alan3::readSaveData(Common::SeekableReadStream *rs) {
-	Glk::Alan3::restoreGame(rs);
-	return Common::kNoError;
+	return Glk::Alan3::restoreGame(rs) ? Common::kNoError : Common::kReadingFailed;
 }
 
 Common::Error Alan3::writeGameData(Common::WriteStream *ws) {
diff --git a/engines/glk/alan3/alt_info.cpp b/engines/glk/alan3/alt_info.cpp
index 1b2b3fe..1e5a05c 100644
--- a/engines/glk/alan3/alt_info.cpp
+++ b/engines/glk/alan3/alt_info.cpp
@@ -55,8 +55,8 @@ void primeAltInfo(AltInfo *altInfo, int level, int parameter, int instance, int
 
 
 /*----------------------------------------------------------------------*/
-static void traceInstanceAndItsClass(Aid instance, Aid cls) {
-	traceSay(instance);
+static void traceInstanceAndItsClass(CONTEXT, Aid instance, Aid cls) {
+	CALL1(traceSay, instance)
 	printf("[%d]", instance);
 	if (cls != NO_CLASS)
 		printf(", inherited from %s[%d]", idOfClass(cls), cls);
@@ -64,14 +64,14 @@ static void traceInstanceAndItsClass(Aid instance, Aid cls) {
 
 
 /*----------------------------------------------------------------------*/
-static void traceAltInfo(AltInfo *alt) {
+static void traceAltInfo(CONTEXT, AltInfo *alt) {
 	switch (alt->level) {
 	case GLOBAL_LEVEL:
 		printf("GLOBAL");
 		break;
 	case LOCATION_LEVEL:
 		printf("in (location) ");
-		traceInstanceAndItsClass(current.location, alt->_class);
+		CALL2(traceInstanceAndItsClass, current.location, alt->_class)
 		break;
 	case PARAMETER_LEVEL: {
 		char *parameterName = parameterNameInSyntax(current.verb, alt->parameter);
@@ -79,7 +79,7 @@ static void traceAltInfo(AltInfo *alt) {
 			printf("in parameter %s(#%d)=", parameterName, alt->parameter);
 		else
 			printf("in parameter #%d=", alt->parameter);
-		traceInstanceAndItsClass(globalParameters[alt->parameter - 1].instance, alt->_class);
+		CALL2(traceInstanceAndItsClass, globalParameters[alt->parameter - 1].instance, alt->_class)
 		break;
 	}
 	}
@@ -87,35 +87,36 @@ static void traceAltInfo(AltInfo *alt) {
 
 
 /*----------------------------------------------------------------------*/
-static void traceVerbCheck(AltInfo *alt, bool execute) {
+static void traceVerbCheck(CONTEXT, AltInfo *alt, bool execute) {
 	if (traceSectionOption && execute) {
 		printf("\n<VERB %d, ", current.verb);
-		traceAltInfo(alt);
+		CALL1(traceAltInfo, alt)
 		printf(", CHECK:>\n");
 	}
 }
 
 
 /*======================================================================*/
-bool checkFailed(AltInfo *altInfo, bool execute) {
+bool checkFailed(CONTEXT, AltInfo *altInfo, bool execute) {
 	if (altInfo->alt != NULL && altInfo->alt->checks != 0) {
-		traceVerbCheck(altInfo, execute);
+		R0CALL2(traceVerbCheck, altInfo, execute)
+
 		// TODO Why does this not generate a regression error with !
 		// Need a new regression case?
-		fail = FALSE;
-		if (checksFailed(altInfo->alt->checks, execute)) return TRUE;
-		if (fail) return TRUE;
+		R0FUNC2(checksFailed, fail, altInfo->alt->checks, execute)
+		return fail;
 	}
 	return FALSE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void traceVerbExecution(AltInfo *alt) {
+static void traceVerbExecution(CONTEXT, AltInfo *alt) {
 	if (traceSectionOption) {
 		printf("\n<VERB %d, ", current.verb);
-		traceAltInfo(alt);
+		CALL1(traceAltInfo, alt)
 		printf(", DOES");
+
 		switch (alt->alt->qual) {
 		case Q_BEFORE:
 			printf(" (BEFORE)");
@@ -135,12 +136,12 @@ static void traceVerbExecution(AltInfo *alt) {
 
 
 /*======================================================================*/
-bool executedOk(AltInfo *altInfo) {
+bool executedOk(CONTEXT, AltInfo *altInfo) {
 	fail = FALSE;
 	if (!altInfo->done && altInfo->alt->action != 0) {
-		traceVerbExecution(altInfo);
+		R0CALL1(traceVerbExecution, altInfo)
 		current.instance = altInfo->instance;
-		interpret(altInfo->alt->action);
+		R0CALL1(interpret, altInfo->alt->action)
 	}
 	altInfo->done = TRUE;
 	return !fail;
@@ -248,14 +249,16 @@ static void addAlternativesFromParameter(AltInfoArray altInfos, int verb, Parame
 
 
 /*======================================================================*/
-bool anyCheckFailed(AltInfoArray altInfo, bool execute) {
+bool anyCheckFailed(CONTEXT, AltInfoArray altInfo, bool execute) {
 	int altIndex;
+	bool flag;
 
 	if (altInfo != NULL)
 		for (altIndex = 0; !altInfo[altIndex].end; altIndex++) {
 			current.instance = altInfo[altIndex].instance;
-			if (checkFailed(&altInfo[altIndex], execute))
-				return TRUE;
+
+			R0FUNC2(checkFailed, flag, &altInfo[altIndex], execute)
+			return flag;
 		}
 	return FALSE;
 }
@@ -339,15 +342,17 @@ AltInfo *findAllAlternatives(int verb, Parameter parameters[]) {
 
 
 /*----------------------------------------------------------------------*/
-static bool possibleWithFinder(int verb, Parameter parameters[], AltInfoFinder *finder) {
+static bool possibleWithFinder(CONTEXT, int verb, Parameter parameters[], AltInfoFinder *finder) {
 	bool anything;
 	AltInfo *allAlternatives;
+	bool flag;
 
 	allAlternatives = finder(verb, parameters);
 
 	// TODO Need to do this since anyCheckFailed() call execute() which assumes the global parameters
 	setGlobalParameters(parameters);
-	if (anyCheckFailed(allAlternatives, DONT_EXECUTE_CHECK_BODY_ON_FAIL))
+	R0FUNC2(anyCheckFailed, flag, allAlternatives, DONT_EXECUTE_CHECK_BODY_ON_FAIL)
+	if (flag)
 		anything = FALSE;
 	else
 		anything = anythingToExecute(allAlternatives);
@@ -361,11 +366,11 @@ static bool possibleWithFinder(int verb, Parameter parameters[], AltInfoFinder *
 
 
 /*======================================================================*/
-bool possible(int verb, Parameter inParameters[], ParameterPosition parameterPositions[]) {
+bool possible(CONTEXT, int verb, Parameter inParameters[], ParameterPosition parameterPositions[]) {
 	// This is a wrapper for possibleWithFinder() which is used in unit tests
 	// possible() should be used "for real".
 
-	return possibleWithFinder(verb, inParameters, findAllAlternatives);
+	return possibleWithFinder(context, verb, inParameters, findAllAlternatives);
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/alt_info.h b/engines/glk/alan3/alt_info.h
index 2a7dd0c..a46d16b 100644
--- a/engines/glk/alan3/alt_info.h
+++ b/engines/glk/alan3/alt_info.h
@@ -27,6 +27,7 @@
 
 #include "glk/alan3/types.h"
 #include "glk/alan3/acode.h"
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/params.h"
 #include "glk/alan3/parameter_position.h"
 
@@ -72,14 +73,14 @@ typedef AltInfo AltInfoArray[];
 
 /* Functions */
 extern void primeAltInfo(AltInfo *altInfo, int level, int parameter, int instance, int cls);
-extern bool executedOk(AltInfo *altInfo);
-extern bool checkFailed(AltInfo *altInfo, bool execute);
+extern bool executedOk(CONTEXT, AltInfo *altInfo);
+extern bool checkFailed(CONTEXT, AltInfo *altInfo, bool execute);
 extern bool canBeExecuted(AltInfo *altInfo);
 extern AltInfo *duplicateAltInfoArray(AltInfoArray altInfos);
 extern int lastAltInfoIndex(AltInfoArray altInfos);
-extern bool anyCheckFailed(AltInfoArray altInfos, bool execute);
+extern bool anyCheckFailed(CONTEXT, AltInfoArray altInfos, bool execute);
 extern bool anythingToExecute(AltInfoArray altInfos);
-extern bool possible(int verb, Parameter parameters[], ParameterPosition parameterPositions[]);
+extern bool possible(CONTEXT, int verb, Parameter parameters[], ParameterPosition parameterPositions[]);
 extern AltInfo *findAllAlternatives(int verb, Parameter parameters[]);
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/checkentry.cpp b/engines/glk/alan3/checkentry.cpp
index 6a49128..3977d9e 100644
--- a/engines/glk/alan3/checkentry.cpp
+++ b/engines/glk/alan3/checkentry.cpp
@@ -29,17 +29,20 @@ namespace Glk {
 namespace Alan3 {
 
 /*======================================================================*/
-bool checksFailed(Aaddr adr, bool execute) {
+bool checksFailed(CONTEXT, Aaddr adr, bool execute) {
 	CheckEntry *chk = (CheckEntry *) pointerTo(adr);
+	bool flag;
+
 	if (chk->exp == 0) {
 		if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
-			interpret(chk->stms);
+			R0CALL1(interpret, chk->stms)
 		return TRUE;
 	} else {
 		while (!isEndOfArray(chk)) {
-			if (!evaluate(chk->exp)) {
+			R0FUNC1(evaluate, flag, chk->exp)
+			if (!flag) {
 				if (execute == EXECUTE_CHECK_BODY_ON_FAIL)
-					interpret(chk->stms);
+					R0CALL1(interpret, chk->stms)
 				return TRUE;
 			}
 			chk++;
diff --git a/engines/glk/alan3/checkentry.h b/engines/glk/alan3/checkentry.h
index f5bcff1..a0c3d25 100644
--- a/engines/glk/alan3/checkentry.h
+++ b/engines/glk/alan3/checkentry.h
@@ -25,6 +25,7 @@
 
 #include "glk/alan3/types.h"
 #include "glk/alan3/acode.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -48,7 +49,7 @@ typedef CheckEntry CheckEntryArray[];
 
 
 /* FUNCTIONS */
-extern bool checksFailed(Aaddr adr, bool execute);
+extern bool checksFailed(CONTEXT, Aaddr adr, bool execute);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/container.cpp b/engines/glk/alan3/container.cpp
index 36469a3..0ce44b0 100644
--- a/engines/glk/alan3/container.cpp
+++ b/engines/glk/alan3/container.cpp
@@ -79,14 +79,14 @@ static bool containerIsEmpty(int container) {
 
 
 /*======================================================================*/
-void describeContainer(int container) {
+void describeContainer(CONTEXT, int container) {
 	if (!containerIsEmpty(container) && !isOpaque(container))
-		list(container);
+		CALL1(list, container)
 }
 
 
 /*======================================================================*/
-bool passesContainerLimits(Aint theContainer, Aint theAddedInstance) {
+bool passesContainerLimits(CONTEXT, Aint theContainer, Aint theAddedInstance) {
 	LimitEntry *limit;
 	Aword props;
 
@@ -100,12 +100,12 @@ bool passesContainerLimits(Aint theContainer, Aint theAddedInstance) {
 		for (limit = (LimitEntry *) pointerTo(containers[props].limits); !isEndOfArray(limit); limit++)
 			if ((int)limit->atr == 1 - I_COUNT) { /* TODO This is actually some encoding of the attribute number, right? */
 				if (countInContainer(theContainer) >= (int)limit->val) {
-					interpret(limit->stms);
+					R0CALL1(interpret, limit->stms)
 					return (FALSE);
 				}
 			} else {
 				if (sumAttributeInContainer(theContainer, limit->atr) + getInstanceAttribute(theAddedInstance, limit->atr) > limit->val) {
-					interpret(limit->stms);
+					R0CALL1(interpret, limit->stms)
 					return (FALSE);
 				}
 			}
@@ -127,7 +127,7 @@ int containerSize(int container, ATrans trans) {
 }
 
 /*======================================================================*/
-void list(int container) {
+void list(CONTEXT, int container) {
 	uint i;
 	Aword props;
 	Aword foundInstance[2] = {0, 0};
@@ -145,9 +145,9 @@ void list(int container) {
 			/* We can only see objects and actors directly in this container... */
 			if (admin[i].location == container) { /* Yes, it's in this container */
 				if (found == 0) {
-					if (containers[props].header != 0)
-						interpret(containers[props].header);
-					else {
+					if (containers[props].header != 0) {
+						CALL1(interpret, containers[props].header)
+					} else {
 						if (isAActor(containers[props].owner))
 							printMessageWithInstanceParameter(M_CARRIES, containers[props].owner);
 						else
@@ -169,9 +169,9 @@ void list(int container) {
 			printMessageWithInstanceParameter(M_CONTAINS_AND, foundInstance[1]);
 		printMessageWithInstanceParameter(M_CONTAINS_END, foundInstance[0]);
 	} else {
-		if (containers[props].empty != 0)
-			interpret(containers[props].empty);
-		else {
+		if (containers[props].empty != 0) {
+			CALL1(interpret, containers[props].empty)
+		} else {
 			if (isAActor(containers[props].owner))
 				printMessageWithInstanceParameter(M_EMPTYHANDED, containers[props].owner);
 			else
diff --git a/engines/glk/alan3/container.h b/engines/glk/alan3/container.h
index 88aac47..86d84c6 100644
--- a/engines/glk/alan3/container.h
+++ b/engines/glk/alan3/container.h
@@ -25,6 +25,7 @@
 
 #include "glk/alan3/types.h"
 #include "glk/alan3/acode.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -35,9 +36,9 @@ extern ContainerEntry *containers; /* Container table pointer */
 
 /* FUNCTIONS */
 extern int containerSize(int container, ATrans trans);
-extern bool passesContainerLimits(Aint container, Aint addedInstance);
-extern void describeContainer(int container);
-extern void list(int cnt);
+extern bool passesContainerLimits(CONTEXT, Aint container, Aint addedInstance);
+extern void describeContainer(CONTEXT, int container);
+extern void list(CONTEXT, int cnt);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index d090021..84f9e07 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -73,7 +73,7 @@ static void showAttributes(AttributeEntry *attrib) {
 
 
 /*----------------------------------------------------------------------*/
-static void showContents(int cnt) {
+static void showContents(CONTEXT, int cnt) {
 	uint i;
 	char str[80];
 	Abool found = FALSE;
@@ -84,7 +84,7 @@ static void showContents(int cnt) {
 			if (!found)
 				found = TRUE;
 			output("$i$t");
-			say(i);
+			say(context, i);
 			sprintf(str, "[%d] ", i);
 			output(str);
 		}
@@ -95,7 +95,7 @@ static void showContents(int cnt) {
 
 
 /*----------------------------------------------------------------------*/
-static char *idOfInstance(int instance) {
+static char *idOfInstance(CONTEXT, int instance) {
 	int base = header->instanceTableAddress +
 	           header->instanceMax * sizeof(InstanceEntry) / sizeof(Aword) + 1;
 	return (char *)&memory[memory[base + instance - 1]];
@@ -103,60 +103,61 @@ static char *idOfInstance(int instance) {
 
 
 /*----------------------------------------------------------------------*/
-static void sayInstanceNumberAndName(int ins) {
+static void sayInstanceNumberAndName(CONTEXT, int ins) {
 	char buf[1000];
 
-	sprintf(buf, "[%d] %s (\"$$", ins, idOfInstance(ins));
+	sprintf(buf, "[%d] %s (\"$$", ins, idOfInstance(context, ins));
 	output(buf);
-	say(ins);
+	say(context, ins);
 	output("$$\")");
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayLocationOfInstance(int ins, const char *prefix) {
+static void sayLocationOfInstance(CONTEXT, int ins, const char *prefix) {
 	if (admin[ins].location == 0)
 		return;
 	else {
 		output(prefix);
 		if (isALocation(admin[ins].location)) {
 			output("at");
-			sayInstanceNumberAndName(admin[ins].location);
-			sayLocationOfInstance(admin[ins].location, prefix);
+			CALL1(sayInstanceNumberAndName, admin[ins].location)
+			CALL2(sayLocationOfInstance, admin[ins].location, prefix)
 		} else if (isAContainer(admin[ins].location)) {
 			if (isAObject(admin[ins].location))
 				output("in");
 			else if (isAActor(admin[ins].location))
 				output("carried by");
-			sayInstanceNumberAndName(admin[ins].location);
-			sayLocationOfInstance(admin[ins].location, prefix);
-		} else
+			CALL1(sayInstanceNumberAndName, admin[ins].location)
+			CALL2(sayLocationOfInstance, admin[ins].location, prefix)
+		} else {
 			output("Illegal location!");
+		}
 	}
 }
 
 /*----------------------------------------------------------------------*/
-static void listInstance(int ins) {
+static void listInstance(CONTEXT, int ins) {
 	output("$i");
-	sayInstanceNumberAndName(ins);
+	CALL1(sayInstanceNumberAndName, ins)
 	if (instances[ins].container)
 		output("(container)");
-	sayLocationOfInstance(ins, ", ");
+	CALL2(sayLocationOfInstance, ins, ", ")
 }
 
 
 /*----------------------------------------------------------------------*/
-static void listInstances(char *pattern) {
+static void listInstances(CONTEXT, char *pattern) {
 	uint ins;
 	bool found = FALSE;
 
 	for (ins = 1; ins <= header->instanceMax; ins++) {
-		if (pattern == NULL || (pattern != NULL && match(pattern, idOfInstance(ins)))) {
+		if (pattern == NULL || (pattern != NULL && match(pattern, idOfInstance(context, ins)))) {
 			if (!found) {
 				output("Instances:");
 				found = TRUE;
 			}
-			listInstance(ins);
+			CALL1(listInstance, ins)
 		}
 	}
 	if (pattern != NULL && !found)
@@ -164,7 +165,7 @@ static void listInstances(char *pattern) {
 }
 
 /*----------------------------------------------------------------------*/
-static void showInstance(int ins) {
+static void showInstance(CONTEXT, int ins) {
 	char str[80];
 
 	if (ins > (int)header->instanceMax || ins < 1) {
@@ -174,7 +175,7 @@ static void showInstance(int ins) {
 	}
 
 	output("The");
-	sayInstanceNumberAndName(ins);
+	CALL1(sayInstanceNumberAndName, ins)
 	if (instances[ins].parent) {
 		sprintf(str, "Isa %s[%d]", idOfClass(instances[ins].parent), instances[ins].parent);
 		output(str);
@@ -184,14 +185,14 @@ static void showInstance(int ins) {
 		sprintf(str, "$iLocation:");
 		output(str);
 		needSpace = TRUE;
-		sayLocationOfInstance(ins, "");
+		CALL2(sayLocationOfInstance, ins, "")
 	}
 
 	output("$iAttributes:");
 	showAttributes(admin[ins].attributes);
 
 	if (instances[ins].container)
-		showContents(ins);
+		CALL1(showContents, ins)
 
 	if (isA(ins, header->actorClassId)) {
 		if (admin[ins].script == 0)
@@ -205,18 +206,18 @@ static void showInstance(int ins) {
 
 
 /*----------------------------------------------------------------------*/
-static void listObjects(void) {
+static void listObjects(CONTEXT) {
 	uint obj;
 
 	output("Objects:");
 	for (obj = 1; obj <= header->instanceMax; obj++)
 		if (isAObject(obj))
-			listInstance(obj);
+			CALL1(listInstance, obj)
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showObject(int obj) {
+static void showObject(CONTEXT, int obj) {
 	char str[80];
 
 
@@ -226,8 +227,7 @@ static void showObject(int obj) {
 		return;
 	}
 
-	showInstance(obj);
-
+	CALL1(showInstance, obj)
 }
 
 /*----------------------------------------------------------------------*/
@@ -314,18 +314,18 @@ static void showClassHierarchy(int thisItem, int depth) {
 
 
 /*----------------------------------------------------------------------*/
-static void listLocations(void) {
+static void listLocations(CONTEXT) {
 	uint loc;
 
 	output("Locations:");
 	for (loc = 1; loc <= header->instanceMax; loc++)
 		if (isALocation(loc))
-			listInstance(loc);
+			listInstance(context, loc);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showLocation(int loc) {
+static void showLocation(CONTEXT, int loc) {
 	char str[80];
 
 
@@ -336,7 +336,7 @@ static void showLocation(int loc) {
 	}
 
 	output("The ");
-	say(loc);
+	CALL1(say, loc)
 	sprintf(str, "(%d) Isa location :", loc);
 	output(str);
 
@@ -346,18 +346,18 @@ static void showLocation(int loc) {
 
 
 /*----------------------------------------------------------------------*/
-static void listActors(void) {
+static void listActors(CONTEXT) {
 	uint act;
 
 	output("Actors:");
 	for (act = 1; act <= header->instanceMax; act++)
 		if (isAActor(act))
-			listInstance(act);
+			CALL1(listInstance, act)
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showActor(int act) {
+static void showActor(CONTEXT, int act) {
 	char str[80];
 
 	if (!isAActor(act)) {
@@ -366,12 +366,12 @@ static void showActor(int act) {
 		return;
 	}
 
-	showInstance(act);
+	CALL1(showInstance, act)
 }
 
 
 /*----------------------------------------------------------------------*/
-static void showEvents(void) {
+static void showEvents(CONTEXT) {
 	uint event;
 	int i;
 	char str[80];
@@ -389,7 +389,7 @@ static void showEvents(void) {
 		if (scheduled) {
 			sprintf(str, "Scheduled for +%d, at ", eventQueue[i].after);
 			output(str);
-			say(eventQueue[i].where);
+			CALL1(say, eventQueue[i].where)
 		} else
 			output("Not scheduled.");
 	}
@@ -734,15 +734,17 @@ static char parseDebugCommand(char *command) {
 
 
 /*----------------------------------------------------------------------*/
-static void readCommand(char buf[]) {
+static void readCommand(CONTEXT, char buf[], size_t maxLen) {
 	char c;
+	bool flag;
 
 	capitalize = FALSE;
 	if (anyOutput) newline();
 	do {
 		output("adbg> ");
 
-		if (!readline(buf)) {
+		FUNC2(readline, flag, buf, maxLen)
+		if (!flag) {
 			newline();
 			quitGame();
 		}
@@ -919,32 +921,32 @@ static void handleNextCommand(bool calledFromBreakpoint) {
 
 
 /*----------------------------------------------------------------------*/
-static void handleLocationsCommand() {
+static void handleLocationsCommand(CONTEXT) {
 	char *parameter = strtok(NULL, "");
 	if (parameter == 0)
-		listLocations();
+		listLocations(context);
 	else
-		showLocation(atoi(parameter));
+		showLocation(context, atoi(parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
-static void handleActorsCommand() {
+static void handleActorsCommand(CONTEXT) {
 	char *parameter = strtok(NULL, "");
 	if (parameter == NULL)
-		listActors();
+		listActors(context);
 	else
-		showActor(atoi(parameter));
+		showActor(context, atoi(parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
-static void handleClassesCommand() {
+static void handleClassesCommand(CONTEXT) {
 	char *parameter = strtok(NULL, "");
 	if (parameter == NULL || strchr(parameter, '*') != 0) {
 		output("Classes:");
 		showClassHierarchy(1, 0);
-		listInstances(parameter);
+		listInstances(context, parameter);
 	} else if (isdigit((int)parameter[0]))
 		showClass(atoi(parameter));
 	else {
@@ -954,28 +956,28 @@ static void handleClassesCommand() {
 
 
 /*----------------------------------------------------------------------*/
-static void handleObjectsCommand() {
+static void handleObjectsCommand(CONTEXT) {
 	char *parameter = strtok(NULL, "");
 	if (parameter == NULL)
-		listObjects();
+		listObjects(context);
 	else
-		showObject(atoi(parameter));
+		showObject(context, atoi(parameter));
 }
 
 
 /*----------------------------------------------------------------------*/
-static void handleInstancesCommand() {
+static void handleInstancesCommand(CONTEXT) {
 	char *parameter = strtok(NULL, "");
 	uint i;
 
 	if (parameter == NULL || strchr(parameter, '*') != 0)
-		listInstances(parameter);
+		listInstances(context, parameter);
 	else if (isdigit((int)parameter[0]))
-		showInstance(atoi(parameter));
+		showInstance(context, atoi(parameter));
 	else {
 		for (i = 1; i < header->instanceMax; i++)
-			if (strcmp(parameter, idOfInstance(i)) == 0) {
-				showInstance(i);
+			if (strcmp(parameter, idOfInstance(context, i)) == 0) {
+				showInstance(context, i);
 				return;
 			}
 		printf("No instance named '%s'.", parameter);
@@ -992,7 +994,7 @@ static bool exactSameVersion() {
 
 
 /*======================================================================*/
-void debug(bool calledFromBreakpoint, int line, int fileNumber) {
+void debug(CONTEXT, bool calledFromBreakpoint, int line, int fileNumber) {
 	static bool warned = FALSE;
 
 	saveInfo();
@@ -1011,9 +1013,9 @@ void debug(bool calledFromBreakpoint, int line, int fileNumber) {
 	}
 
 	while (TRUE) {
-
 		char commandLine[200];
-		readCommand(commandLine);
+		CALL2(readCommand, commandLine, 200)
+
 		char *command = strtok(commandLine, " ");
 		char commandCode = parseDebugCommand(command);
 
@@ -1022,19 +1024,19 @@ void debug(bool calledFromBreakpoint, int line, int fileNumber) {
 			output("Ambiguous ADBG command abbreviation. ? for help.");
 			break;
 		case ACTORS_COMMAND:
-			handleActorsCommand();
+			handleActorsCommand(context);
 			break;
 		case BREAK_COMMAND:
 			handleBreakCommand(fileNumber);
 			break;
 		case CLASSES_COMMAND:
-			handleClassesCommand();
+			handleClassesCommand(context);
 			break;
 		case DELETE_COMMAND:
 			handleDeleteCommand(calledFromBreakpoint, line, fileNumber);
 			break;
 		case EVENTS_COMMAND:
-			showEvents();
+			showEvents(context);
 			break;
 		case EXIT_COMMAND:
 			debugOption = FALSE;
@@ -1050,7 +1052,7 @@ void debug(bool calledFromBreakpoint, int line, int fileNumber) {
 			handleHelpCommand();
 			break;
 		case INSTANCES_COMMAND:
-			handleInstancesCommand();
+			handleInstancesCommand(context);
 			break;
 		case TRACE_COMMAND:
 			handleTraceCommand();
@@ -1059,13 +1061,13 @@ void debug(bool calledFromBreakpoint, int line, int fileNumber) {
 			toggleInstructionTrace();
 			break;
 		case LOCATIONS_COMMAND:
-			handleLocationsCommand();
+			handleLocationsCommand(context);
 			break;
 		case NEXT_COMMAND:
 			handleNextCommand(calledFromBreakpoint);
 			goto exit_debug;
 		case OBJECTS_COMMAND:
-			handleObjectsCommand();
+			handleObjectsCommand(context);
 			break;
 		case QUIT_COMMAND:
 			terminate(0);
@@ -1085,7 +1087,7 @@ exit_debug:
 
 
 /*======================================================================*/
-void traceSay(int item) {
+void traceSay(CONTEXT, int item) {
 	/*
 	  Say something, but make sure we don't disturb anything and that it is
 	  shown to the player. Needed for tracing. During debugging things are
@@ -1095,10 +1097,12 @@ void traceSay(int item) {
 	saveInfo();
 	needSpace = FALSE;
 	col = 1;
-	if (item == 0)
+	if (item == 0) {
 		printf("$null$");
-	else
-		say(item);
+	} else {
+		CALL1(say, item)
+	}
+
 	needSpace = FALSE;
 	col = 1;
 	restoreInfo();
diff --git a/engines/glk/alan3/debug.h b/engines/glk/alan3/debug.h
index 3bfa32e..1f5e2c1 100644
--- a/engines/glk/alan3/debug.h
+++ b/engines/glk/alan3/debug.h
@@ -26,6 +26,7 @@
 /* Header file for debug handler in Alan interpreter */
 
 #include "glk/alan3/types.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -49,8 +50,8 @@ extern int breakpointIndex(int file, int line);
 extern char *sourceFileName(int file);
 extern char *readSourceLine(int file, int line);
 extern void showSourceLine(int fileNumber, int line);
-extern void debug(bool calledFromBreakpoint, int line, int fileNumber);
-extern void traceSay(int item);
+extern void debug(CONTEXT, bool calledFromBreakpoint, int line, int fileNumber);
+extern void traceSay(CONTEXT, int item);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index 5c6f09b..39cec13 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -577,18 +577,18 @@ void playSound(int sound) {
 
 
 /*======================================================================*/
-void empty(int cnt, int whr) {
+void empty(CONTEXT, int cnt, int whr) {
 	uint i;
 
 	for (i = 1; i <= header->instanceMax; i++)
 		if (isIn(i, cnt, DIRECT))
-			locate(i, whr);
+			CALL2(locate, i, whr)
 }
 
 
 
 /*======================================================================*/
-void use(int actor, int script) {
+void use(CONTEXT, int actor, int script) {
 	char str[80];
 	StepEntry *step;
 
@@ -601,7 +601,7 @@ void use(int actor, int script) {
 	admin[actor].step = 0;
 	step = stepOf(actor);
 	if (step != NULL && step->after != 0) {
-		admin[actor].waitCount = evaluate(step->after);
+		FUNC1(evaluate, admin[actor].waitCount, step->after)
 	}
 
 	gameStateChanged = TRUE;
diff --git a/engines/glk/alan3/exe.h b/engines/glk/alan3/exe.h
index 428f112..a039d6f 100644
--- a/engines/glk/alan3/exe.h
+++ b/engines/glk/alan3/exe.h
@@ -27,6 +27,7 @@
 
 /* IMPORTS */
 #include "glk/alan3/sysdep.h"
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/acode.h"
 #include "glk/alan3/types.h"
 #include "glk/alan3/set.h"
@@ -47,9 +48,7 @@ extern Common::SeekableReadStream *textFile;		// The text and message file
 extern bool printFlag;
 
 /* Long jump buffer for restart, errors and undo */
-//extern jmp_buf restartLabel;
 //extern jmp_buf returnLabel;
-//extern jmp_buf forfeitLabel;
 
 
 /* FUNCTIONS */
@@ -69,10 +68,10 @@ extern void undo(void);
 extern void quitGame(void);
 extern void restartGame(void);
 
-extern void use(int act, int scr);
+extern void use(CONTEXT, int act, int scr);
 extern void stop(int act);
 
-extern void empty(int cnt, int whr);
+extern void empty(CONTEXT, int cnt, int whr);
 extern int getContainerMember(int container, int index, bool directly);
 extern int randomInContainer(int cont);
 
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index 05ccd69..b522057 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -425,29 +425,35 @@ int where(int instance, ATrans trans) {
 
 
 /*----------------------------------------------------------------------*/
-static bool executeInheritedMentioned(int cls) {
+static bool executeInheritedMentioned(CONTEXT, int cls) {
 	if (cls == 0) return FALSE;
 
 	if (classes[cls].mentioned) {
-		interpret(classes[cls].mentioned);
+		R0CALL1(interpret, classes[cls].mentioned)
 		return TRUE;
-	} else
-		return executeInheritedMentioned(classes[cls].parent);
+	} else {
+		bool flag;
+		R0FUNC1(executeInheritedMentioned, flag, classes[cls].parent)
+		return flag;
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool mention(int instance) {
+static bool mention(CONTEXT, int instance) {
 	if (instances[instance].mentioned) {
-		interpret(instances[instance].mentioned);
+		R0CALL1(interpret, instances[instance].mentioned)
 		return TRUE;
-	} else
-		return executeInheritedMentioned(instances[instance].parent);
+	} else {
+		bool flag;
+		R0FUNC1(executeInheritedMentioned, flag, instances[instance].parent)
+		return flag;
+	}
 }
 
 
 /*======================================================================*/
-void sayInstance(int instance) {
+void sayInstance(CONTEXT, int instance) {
 #ifdef SAY_INSTANCE_WITH_PLAYER_WORDS_IF_PARAMETER
 	int p, i;
 
@@ -475,8 +481,11 @@ void sayInstance(int instance) {
 				return;
 			}
 #endif
-	if (!mention(instance))
-		interpret(instances[instance].name);
+	
+	bool flag;
+	FUNC1(mention, flag, instance)
+	if (!flag)
+		CALL1(interpret, instances[instance].name)
 }
 
 
@@ -527,134 +536,157 @@ static char *wordWithCode(int classBit, int code) {
 
 
 /*----------------------------------------------------------------------*/
-static bool sayInheritedDefiniteForm(int cls) {
+static bool sayInheritedDefiniteForm(CONTEXT, int cls) {
 	if (cls == 0) {
 		syserr("No default definite article");
 		return FALSE;
 	} else {
 		if (classes[cls].definite.address) {
-			interpret(classes[cls].definite.address);
+			R0CALL1(interpret, classes[cls].definite.address)
 			return classes[cls].definite.isForm;
-		} else
-			return sayInheritedDefiniteForm(classes[cls].parent);
+		} else {
+			bool flag;
+			R0FUNC1(sayInheritedDefiniteForm, flag, classes[cls].parent)
+			return flag;
+		}
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayDefinite(int instance) {
+static void sayDefinite(CONTEXT, int instance) {
 	if (instances[instance].definite.address) {
-		interpret(instances[instance].definite.address);
+		CALL1(interpret, instances[instance].definite.address)
+
 		if (!instances[instance].definite.isForm)
-			sayInstance(instance);
-	} else if (!sayInheritedDefiniteForm(instances[instance].parent))
-		sayInstance(instance);
+			CALL1(sayInstance, instance)
+	} else {
+		bool flag;
+		FUNC1(sayInheritedDefiniteForm, flag, instances[instance].parent)
+		if (!flag)
+			CALL1(sayInstance, instance)
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool sayInheritedIndefiniteForm(int cls) {
+static bool sayInheritedIndefiniteForm(CONTEXT, int cls) {
 	if (cls == 0) {
 		syserr("No default indefinite article");
 		return FALSE;
 	} else {
 		if (classes[cls].indefinite.address) {
-			interpret(classes[cls].indefinite.address);
+			R0CALL1(interpret, classes[cls].indefinite.address)
 			return classes[cls].indefinite.isForm;
-		} else
-			return sayInheritedIndefiniteForm(classes[cls].parent);
+		} else {
+			bool flag;
+			R0FUNC1(sayInheritedIndefiniteForm, flag, classes[cls].parent)
+			return flag;
+		}
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayIndefinite(int instance) {
+static void sayIndefinite(CONTEXT, int instance) {
 	if (instances[instance].indefinite.address) {
-		interpret(instances[instance].indefinite.address);
+		CALL1(interpret, instances[instance].indefinite.address)
+
 		if (!instances[instance].indefinite.isForm)
-			sayInstance(instance);
-	} else if (!sayInheritedIndefiniteForm(instances[instance].parent))
-		sayInstance(instance);
+			CALL1(sayInstance, instance)
+	} else {
+		bool flag;
+		FUNC1(sayInheritedIndefiniteForm, flag, instances[instance].parent)
+		if (!flag)
+			CALL1(sayInstance, instance)
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool sayInheritedNegativeForm(int cls) {
+static bool sayInheritedNegativeForm(CONTEXT, int cls) {
 	if (cls == 0) {
 		syserr("No default negative form");
 		return FALSE;
 	} else {
 		if (classes[cls].negative.address) {
-			interpret(classes[cls].negative.address);
+			R0CALL1(interpret, classes[cls].negative.address)
 			return classes[cls].negative.isForm;
-		} else
-			return sayInheritedNegativeForm(classes[cls].parent);
+		} else {
+			bool flag;
+			R0FUNC1(sayInheritedNegativeForm, flag, classes[cls].parent)
+			return flag;
+		}
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayNegative(int instance) {
+static void sayNegative(CONTEXT, int instance) {
 	if (instances[instance].negative.address) {
-		interpret(instances[instance].negative.address);
+		CALL1(interpret, instances[instance].negative.address)
 		if (!instances[instance].negative.isForm)
-			sayInstance(instance);
-	} else if (!sayInheritedNegativeForm(instances[instance].parent))
-		sayInstance(instance);
+			CALL1(sayInstance, instance)
+	} else {
+		bool flag;
+		FUNC1(sayInheritedNegativeForm, flag, instances[instance].parent)
+		CALL1(sayInstance, instance)
+	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayInheritedPronoun(int instance) {
+static void sayInheritedPronoun(CONTEXT, int instance) {
 	if (instance == 0)
 		syserr("No default pronoun");
 	else {
 		if (classes[instance].pronoun != 0)
 			output(wordWithCode(PRONOUN_BIT, classes[instance].pronoun));
 		else
-			sayInheritedPronoun(classes[instance].parent);
+			CALL1(sayInheritedPronoun, classes[instance].parent)
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayPronoun(int instance) {
+static void sayPronoun(CONTEXT, int instance) {
 	if (instances[instance].pronoun != 0)
 		output(wordWithCode(PRONOUN_BIT, instances[instance].pronoun));
 	else
-		sayInheritedPronoun(instances[instance].parent);
+		CALL1(sayInheritedPronoun, instances[instance].parent)
 }
 
 
 /*----------------------------------------------------------------------*/
-static void sayArticleOrForm(int id, SayForm form) {
-	if (!isLiteral(id))
+static void sayArticleOrForm(CONTEXT, int id, SayForm form) {
+	if (!isLiteral(id)) {
 		switch (form) {
 		case SAY_DEFINITE:
-			sayDefinite(id);
+			CALL1(sayDefinite, id)
 			break;
 		case SAY_INDEFINITE:
-			sayIndefinite(id);
+			CALL1(sayIndefinite, id)
 			break;
 		case SAY_NEGATIVE:
-			sayNegative(id);
+			CALL1(sayNegative, id)
 			break;
 		case SAY_PRONOUN:
-			sayPronoun(id);
+			CALL1(sayPronoun, id)
 			break;
 		case SAY_SIMPLE:
-			say(id);
+			CALL1(say, id)
 			break;
 		default:
 			syserr("Unexpected form in 'sayArticleOrForm()'");
 		}
-	else
-		say(id);
+	} else {
+		CALL1(say, id)
+	}
 }
 
 
 /*======================================================================*/
-void say(int instance) {
+void say(CONTEXT, int instance) {
 	Aword previousInstance = current.instance;
 	current.instance = instance;
 
@@ -663,7 +695,7 @@ void say(int instance) {
 			sayLiteral(instance);
 		else {
 			verifyInstance(instance, "SAY");
-			sayInstance(instance);
+			sayInstance(context, instance);
 		}
 	}
 	current.instance = previousInstance;
@@ -671,11 +703,11 @@ void say(int instance) {
 
 
 /*======================================================================*/
-void sayForm(int instance, SayForm form) {
+void sayForm(CONTEXT, int instance, SayForm form) {
 	Aword previousInstance = current.instance;
 	current.instance = instance;
 
-	sayArticleOrForm(instance, form);
+	sayArticleOrForm(context, instance, form);
 
 	current.instance = previousInstance;
 }
@@ -710,66 +742,72 @@ bool hasDescription(int instance) {
 
 
 /*----------------------------------------------------------------------*/
-static void describeClass(int instance) {
+static void describeClass(CONTEXT, int instance) {
 	if (classes[instance].description != 0) {
 		/* This class has a description, run it */
-		interpret(classes[instance].description);
+		CALL1(interpret, classes[instance].description)
 	} else {
 		/* Search up the inheritance tree, if any, to find a description */
 		if (classes[instance].parent != 0)
-			describeClass(classes[instance].parent);
+			CALL1(describeClass, classes[instance].parent)
 	}
 }
 
 
 /*======================================================================*/
-void describeAnything(int instance) {
+void describeAnything(CONTEXT, int instance) {
 	if (instances[instance].description != 0) {
 		/* This instance has its own description, run it */
-		interpret(instances[instance].description);
+		CALL1(interpret, instances[instance].description)
 	} else {
 		/* Search up the inheritance tree to find a description */
 		if (instances[instance].parent != 0)
-			describeClass(instances[instance].parent);
+			CALL1(describeClass, instances[instance].parent)
 	}
 	admin[instance].alreadyDescribed = TRUE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void describeObject(int object) {
-	if (hasDescription(object))
-		describeAnything(object);
-	else {
+static void describeObject(CONTEXT, int object) {
+	if (hasDescription(object)) {
+		CALL1(describeAnything, object)
+	} else {
 		printMessageWithInstanceParameter(M_SEE_START, object);
 		printMessage(M_SEE_END);
 		if (instances[object].container != 0)
-			describeContainer(object);
+			CALL1(describeContainer, object)
 	}
 	admin[object].alreadyDescribed = TRUE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool inheritedDescriptionCheck(int cls) {
+static bool inheritedDescriptionCheck(CONTEXT, int cls) {
 	if (cls == 0) return TRUE;
-	if (!inheritedDescriptionCheck(classes[cls].parent)) return FALSE;
+
+	bool flag;
+	R0FUNC1(inheritedDescriptionCheck, flag, classes[cls].parent)
+	if (!flag) return FALSE;
+
 	if (classes[cls].descriptionChecks == 0) return TRUE;
-	return !checksFailed(classes[cls].descriptionChecks, TRUE);
+	R0FUNC2(checksFailed, flag, classes[cls].descriptionChecks, TRUE)
+	return !flag;
 }
 
 /*----------------------------------------------------------------------*/
-static bool descriptionCheck(int instance) {
+static bool descriptionCheck(CONTEXT, int instance) {
 	int previousInstance = current.instance;
 	bool r;
 
 	current.instance = instance;
-	if (inheritedDescriptionCheck(instances[instance].parent)) {
+	if (inheritedDescriptionCheck(context, instances[instance].parent)) {
 		if (instances[instance].checks == 0)
 			r = TRUE;
 		else
-			r = !checksFailed(instances[instance].checks, TRUE);
-	} else
+			r = !checksFailed(context, instances[instance].checks, TRUE);
+	}
+	else
 		r = FALSE;
 	current.instance = previousInstance;
 	return r;
@@ -777,7 +815,7 @@ static bool descriptionCheck(int instance) {
 
 
 /*======================================================================*/
-void describeInstances(void) {
+void describeInstances(CONTEXT) {
 	uint i;
 	int lastInstanceFound = 0;
 	int found = 0;
@@ -786,14 +824,14 @@ void describeInstances(void) {
 	for (i = 1; i <= header->instanceMax; i++)
 		if (admin[i].location == current.location && isAObject(i) &&
 		        !admin[i].alreadyDescribed && hasDescription(i))
-			describe(i);
+			CALL1(describe, i)
 
 	/* Then list all things without a description */
 	for (i = 1; i <= header->instanceMax; i++)
 		if (admin[i].location == current.location
 		        && !admin[i].alreadyDescribed
 		        && isAObject(i)
-		        && descriptionCheck(i)) {
+		        && descriptionCheck(context, i)) {
 			if (found == 0)
 				printMessageWithInstanceParameter(M_SEE_START, i);
 			else if (found > 1)
@@ -805,7 +843,7 @@ void describeInstances(void) {
 				if (found > 0)
 					printMessageWithInstanceParameter(M_SEE_AND, i);
 				printMessage(M_SEE_END);
-				describeContainer(i);
+				CALL1(describeContainer, i)
 				found = 0;
 				continue;       /* Actually start another list. */
 			}
@@ -824,7 +862,7 @@ void describeInstances(void) {
 	for (i = 1; i <= header->instanceMax; i++)
 		if (admin[i].location == current.location && i != HERO && isAActor(i)
 		        && !admin[i].alreadyDescribed)
-			describe(i);
+			CALL1(describe, i)
 
 	/* Clear the describe flag for all instances */
 	for (i = 1; i <= header->instanceMax; i++)
@@ -833,35 +871,37 @@ void describeInstances(void) {
 
 
 /*======================================================================*/
-bool describe(int instance) {
+bool describe(CONTEXT, int instance) {
 	bool descriptionOk;
 	int previousInstance = current.instance;
 
 	current.instance = instance;
 	verifyInstance(instance, "DESCRIBE");
-	if (descriptionCheck(instance)) {
+
+	if (descriptionCheck(context, instance)) {
 		descriptionOk = TRUE;
 		if (isAObject(instance)) {
-			describeObject(instance);
+			describeObject(context, instance);
 		} else if (isAActor(instance)) {
-			describeActor(instance);
+			describeActor(context, instance);
 		} else
-			describeAnything(instance);
+			describeAnything(context, instance);
 	} else
 		descriptionOk = FALSE;
+
 	current.instance = previousInstance;
 	return descriptionOk;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void locateIntoContainer(Aword theInstance, Aword theContainer) {
+static void locateIntoContainer(CONTEXT, Aword theInstance, Aword theContainer) {
 	if (!isA(theInstance, containers[instances[theContainer].container]._class))
 		printMessageUsing2InstanceParameters(M_CANNOTCONTAIN, theContainer, theInstance);
-	else if (passesContainerLimits(theContainer, theInstance))
+	else if (passesContainerLimits(context, theContainer, theInstance))
 		admin[theInstance].location = theContainer;
 	else
-		abortPlayerCommand();
+		abortPlayerCommand(context);
 }
 
 
@@ -881,9 +921,9 @@ static void locateLocation(Aword loc, Aword whr) {
 
 
 /*----------------------------------------------------------------------*/
-static void locateObject(Aword obj, Aword whr) {
+static void locateObject(CONTEXT, Aword obj, Aword whr) {
 	if (isAContainer(whr)) { /* Into a container */
-		locateIntoContainer(obj, whr);
+		locateIntoContainer(context, obj, whr);
 	} else {
 		admin[obj].location = whr;
 		/* Make sure the location is described since it's changed */
@@ -901,36 +941,38 @@ static void traceEnteredClass(Aint theClass, bool empty) {
 
 
 /*----------------------------------------------------------------------*/
-static void traceEnteredInstance(Aint instance, bool empty) {
+static void traceEnteredInstance(CONTEXT, Aint instance, bool empty) {
 	printf("\n<ENTERED in instance ");
-	traceSay(instance);
+	traceSay(context, instance);
 	printf("[%d]%s>\n", instance, empty ? " is empty" : "");
 }
 
 
 /*----------------------------------------------------------------------*/
-static void executeInheritedEntered(Aint theClass) {
+static void executeInheritedEntered(CONTEXT, Aint theClass) {
 	if (theClass == 0) return;
-	executeInheritedEntered(classes[theClass].parent);
+	CALL1(executeInheritedEntered, classes[theClass].parent)
+
 	if (traceSectionOption)
 		traceEnteredClass(theClass, classes[theClass].entered == 0);
 	if (classes[theClass].entered) {
-		interpret(classes[theClass].entered);
+		CALL1(interpret, classes[theClass].entered)
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void executeEntered(Aint instance) {
+static void executeEntered(CONTEXT, Aint instance) {
 	int currentInstance = current.instance;
 	current.instance = instance;
 	if (admin[instance].location != 0)
-		executeEntered(admin[instance].location);
-	executeInheritedEntered(instances[instance].parent);
+		CALL1(executeEntered, admin[instance].location)
+	CALL1(executeInheritedEntered, instances[instance].parent)
+
 	if (traceSectionOption)
-		traceEnteredInstance(instance, instances[instance].entered == 0);
+		CALL2(traceEnteredInstance, instance, instances[instance].entered == 0)
 	if (instances[instance].entered != 0) {
-		interpret(instances[instance].entered);
+		CALL1(interpret, instances[instance].entered)
 	}
 	current.instance = currentInstance;
 }
@@ -952,13 +994,13 @@ static void incrementVisits(int location) {
 
 
 /*----------------------------------------------------------------------*/
-static void revisited(void) {
+static void revisited(CONTEXT) {
 	if (anyOutput)
 		para();
-	say(where(HERO, DIRECT));
+	CALL1(say, where(HERO, DIRECT))
 	printMessage(M_AGAIN);
 	newline();
-	describeInstances();
+	CALL0(describeInstances)
 }
 
 
@@ -973,7 +1015,7 @@ static bool shouldBeDescribed(void) {
 
 
 /*----------------------------------------------------------------------*/
-static void locateActor(Aint movingActor, Aint whr) {
+static void locateActor(CONTEXT, Aint movingActor, Aint whr) {
 	Aint previousCurrentLocation = current.location;
 	Aint previousActorLocation = admin[movingActor].location;
 	Aint previousActor = current.actor;
@@ -988,7 +1030,7 @@ static void locateActor(Aint movingActor, Aint whr) {
 	   is now it allows the hero to be located into a container. And what
 	   happens with current location if so... */
 	if (isAContainer(whr))
-		locateIntoContainer(movingActor, whr);
+		CALL2(locateIntoContainer, movingActor, whr)
 	else {
 		current.location = whr;
 		admin[movingActor].location = whr;
@@ -1000,16 +1042,17 @@ static void locateActor(Aint movingActor, Aint whr) {
 	/* Execute possible entered */
 	current.actor = movingActor;
 	if (previousActorLocation != current.location) {
-		executeEntered(current.location);
+		CALL1(executeEntered, current.location)
 	}
 	current.instance = previousInstance;
 	current.actor = previousActor;
 
 	if (movingActor == (int)HERO) {
-		if (shouldBeDescribed())
-			look();
-		else
-			revisited();
+		if (shouldBeDescribed()) {
+			CALL0(look)
+		} else {
+			CALL0(revisited)
+		}
 		admin[where(HERO, DIRECT)].visitsCount++;
 	} else
 		/* Ensure that the location will be described to the hero next time */
@@ -1023,17 +1066,17 @@ static void locateActor(Aint movingActor, Aint whr) {
 
 
 /*----------------------------------------------------------------------*/
-static void traceExtract(int instance, int containerId, const char *what) {
+static void traceExtract(CONTEXT, int instance, int containerId, const char *what) {
 	if (traceSectionOption) {
 		printf("\n<EXTRACT from ");
-		traceSay(instance);
+		traceSay(context, instance);
 		printf("[%d, container %d], %s:>\n", instance, containerId, what);
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void containmentLoopError(int instance, int whr) {
+static void containmentLoopError(CONTEXT, int instance, int whr) {
 	ParameterArray parameters = newParameterArray();
 	if (isPreBeta4(header->version))
 		output("That would be to put something inside itself.");
@@ -1046,28 +1089,28 @@ static void containmentLoopError(int instance, int whr) {
 		printMessageWithParameters(M_CONTAINMENT_LOOP2, parameters);
 	}
 	free(parameters);
-	error(NO_MSG);
+	CALL1(error, NO_MSG)
 }
 
 
 /*----------------------------------------------------------------------*/
-static void runExtractStatements(int instance, int containerId) {
+static void runExtractStatements(CONTEXT, int instance, int containerId) {
 	ContainerEntry *theContainer = &containers[containerId];
 
 	if (theContainer->extractStatements != 0) {
-		traceExtract(instance, containerId, "Executing");
-		interpret(theContainer->extractStatements);
+		CALL3(traceExtract, instance, containerId, "Executing")
+		CALL1(interpret, theContainer->extractStatements)
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static bool runExtractChecks(int instance, int containerId) {
+static bool runExtractChecks(CONTEXT, int instance, int containerId) {
 	ContainerEntry *theContainer = &containers[containerId];
 
 	if (theContainer->extractChecks != 0) {
-		traceExtract(instance, containerId, "Checking");
-		if (checksFailed(theContainer->extractChecks, EXECUTE_CHECK_BODY_ON_FAIL)) {
+		R0CALL3(traceExtract, instance, containerId, "Checking")
+		if (checksFailed(context, theContainer->extractChecks, EXECUTE_CHECK_BODY_ON_FAIL)) {
 			fail = TRUE;
 			return FALSE;       /* Failed! */
 		}
@@ -1077,7 +1120,7 @@ static bool runExtractChecks(int instance, int containerId) {
 
 
 /*======================================================================*/
-void locate(int instance, int whr) {
+void locate(CONTEXT, int instance, int whr) {
 	int containerId;
 	int previousInstance = current.instance;
 
@@ -1086,7 +1129,7 @@ void locate(int instance, int whr) {
 
 	/* Will this create a containment loop? */
 	if (whr == instance || (isAContainer(instance) && isIn(whr, instance, TRANSITIVE)))
-		containmentLoopError(instance, whr);
+		CALL2(containmentLoopError, instance, whr)
 
 	/* First check if the instance is in a container, if so run extract checks */
 	if (isAContainer(admin[instance].location)) {    /* In something? */
@@ -1097,23 +1140,23 @@ void locate(int instance, int whr) {
 			current.instance = loc;
 			containerId = instances[loc].container;
 
-			if (!runExtractChecks(instance, containerId)) {
+			if (!runExtractChecks(context, instance, containerId)) {
 				current.instance = previousInstance;
 				return;
 			}
-			runExtractStatements(instance, containerId);
+			runExtractStatements(context, instance, containerId);
 			loc = admin[loc].location;
 		}
 		current.instance = previousInstance;
 	}
 
-	if (isAActor(instance))
-		locateActor(instance, whr);
-	else if (isALocation(instance))
+	if (isAActor(instance)) {
+		CALL2(locateActor, instance, whr)
+	} else if (isALocation(instance)) {
 		locateLocation(instance, whr);
-	else
-		locateObject(instance, whr);
-
+	} else {
+		CALL2(locateObject, instance, whr)
+	}
 	gameStateChanged = TRUE;
 }
 
diff --git a/engines/glk/alan3/instance.h b/engines/glk/alan3/instance.h
index bd43195..7c2b9cf 100644
--- a/engines/glk/alan3/instance.h
+++ b/engines/glk/alan3/instance.h
@@ -25,6 +25,7 @@
 
 #include "common/serializer.h"
 #include "glk/alan3/acode.h"
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/types.h"
 #include "glk/alan3/set.h"
 
@@ -73,15 +74,15 @@ extern void setInstanceAttribute(int instance, int atr, Aptr value);
 extern void setInstanceStringAttribute(int instance, int attribute, char *string);
 extern void setInstanceSetAttribute(int instance, int atr, Aptr set);
 
-extern void say(int instance);
-extern void sayForm(int instance, SayForm form);
-extern void sayInstance(int instance);
+extern void say(CONTEXT, int instance);
+extern void sayForm(CONTEXT, int instance, SayForm form);
+extern void sayInstance(CONTEXT, int instance);
 
 extern bool hasDescription(int instance);
 extern bool isDescribable(int instance);
-extern void describeAnything(int instance);
-extern void describeInstances(void);
-extern bool describe(int instance);
+extern void describeAnything(CONTEXT, int instance);
+extern void describeInstances(CONTEXT);
+extern bool describe(CONTEXT, int instance);
 
 extern int where(int instance, ATrans trans);
 extern int positionOf(int instance);
@@ -95,7 +96,7 @@ extern bool isNear(int instance, int other, ATrans trans);
 
 extern bool isOpaque(int container);
 
-extern void locate(int instance, int whr);
+extern void locate(CONTEXT, int instance, int whr);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index 2219854..002a580 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -346,10 +346,10 @@ static void tracePointerTopValue() {
 }
 
 /*----------------------------------------------------------------------*/
-static void traceInstanceTopValue() {
+static void traceInstanceTopValue(CONTEXT) {
 	if (traceInstructionOption) {
 		printf("\t=%ld ('", (long)top(stack));
-		traceSay(top(stack));
+		CALL1(traceSay, top(stack))
 		printf("')");
 		if (traceStackOption)
 			printf("\n\t\t\t\t\t\t\t");
@@ -414,7 +414,7 @@ static bool stillOnSameLine(Aint line, Aint file) {
 
 
 /*======================================================================*/
-void interpret(Aaddr adr) {
+void interpret(CONTEXT, Aaddr adr) {
 	Aaddr oldpc;
 	Aword i;
 
@@ -532,7 +532,7 @@ void interpret(Aaddr adr) {
 					current.sourceFile = file;
 					if (atNext || atBreakpoint) {
 						stopAtNextLine = FALSE;
-						debug(TRUE, line, file);
+						CALL3(debug, TRUE, line, file)
 					}
 				}
 				break;
@@ -595,7 +595,7 @@ void interpret(Aaddr adr) {
 			case I_LOOK: {
 				if (traceInstructionOption)
 					printf("LOOK\t\t\t\t\t\t");
-				look();
+				CALL0(look)
 				break;
 			}
 			case I_SAVE: {
@@ -636,7 +636,7 @@ void interpret(Aaddr adr) {
 				Aint cnt = pop(stack);
 				if (traceInstructionOption)
 					printf("LIST \t%7ld\t\t\t\t\t", (long)cnt);
-				list(cnt);
+				CALL1(list, cnt)
 				break;
 			}
 			case I_EMPTY: {
@@ -644,7 +644,7 @@ void interpret(Aaddr adr) {
 				Aint whr = pop(stack);
 				if (traceInstructionOption)
 					printf("EMPTY \t%7ld, %7ld\t\t\t\t", (long)cnt, (long)whr);
-				empty(cnt, whr);
+				CALL2(empty, cnt, whr)
 				break;
 			}
 			case I_SCHEDULE: {
@@ -844,7 +844,7 @@ void interpret(Aaddr adr) {
 				Aint whr = pop(stack);
 				if (traceInstructionOption)
 					printf("LOCATE \t%7ld, %7ld\t\t\t", (long)id, (long)whr);
-				locate(id, whr);
+				CALL2(locate, id, whr)
 				break;
 			}
 			case I_WHERE: {
@@ -853,7 +853,7 @@ void interpret(Aaddr adr) {
 				if (traceInstructionOption)
 					printf("WHERE \t%7ld, %7s", (long)id, transitivityFlag((ATrans)transitivity));
 				push(stack, where(id, (ATrans)transitivity));
-				traceInstanceTopValue();
+				CALL0(traceInstanceTopValue);
 				break;
 			}
 			case I_LOCATION: {
@@ -861,7 +861,7 @@ void interpret(Aaddr adr) {
 				if (traceInstructionOption)
 					printf("LOCATION \t%7ld\t\t", (long)id);
 				push(stack, locationOf(id));
-				traceInstanceTopValue();
+				CALL0(traceInstanceTopValue)
 				break;
 			}
 			case I_HERE: {
@@ -927,7 +927,7 @@ void interpret(Aaddr adr) {
 				Aint scr = pop(stack);
 				if (traceInstructionOption)
 					printf("USE \t%7ld, %7ld\t\t\t\t", (long)act, (long)scr);
-				use(act, scr);
+				CALL2(use, act, scr)
 				break;
 			}
 			case I_STOP: {
@@ -943,7 +943,7 @@ void interpret(Aaddr adr) {
 					printf("DESCRIBE \t%7ld\t\t\t", (long)id);
 					col = 41;       /* To format it better! */
 				}
-				describe(id);
+				CALL1(describe, id)
 				if (traceInstructionOption)
 					printf("\n\t\t\t\t\t\t");
 				break;
@@ -953,10 +953,12 @@ void interpret(Aaddr adr) {
 				Aid id = pop(stack);
 				if (traceInstructionOption)
 					printf("SAY\t%7s, %7ld\t\t\t", printForm((SayForm)form), (long)id);
-				if (form == SAY_SIMPLE)
-					say(id);
-				else
-					sayForm(id, (SayForm)form);
+				if (form == SAY_SIMPLE) {
+					CALL1(say, id)
+				} else {
+					CALL2(sayForm, id, (SayForm)form)
+				}
+
 				if (traceInstructionOption)
 					printf("\t\t\t\t\t\t\t");
 				break;
@@ -1400,8 +1402,8 @@ exitInterpreter:
 }
 
 /*======================================================================*/
-Aword evaluate(Aaddr adr) {
-	interpret(adr);
+Aword evaluate(CONTEXT, Aaddr adr) {
+	R0CALL1(interpret, adr)
 	return pop(stack);
 }
 
diff --git a/engines/glk/alan3/inter.h b/engines/glk/alan3/inter.h
index f451a06..887a06a 100644
--- a/engines/glk/alan3/inter.h
+++ b/engines/glk/alan3/inter.h
@@ -27,6 +27,7 @@
 
 #include "glk/alan3/types.h"
 #include "glk/alan3/stack.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -45,8 +46,8 @@ extern bool fail;
 
 extern void setInterpreterMock(void (*mock)(Aaddr adr));
 extern void setInterpreterStack(Stack stack);
-extern void interpret(Aaddr adr);
-extern Aword evaluate(Aaddr adr);
+extern void interpret(CONTEXT, Aaddr adr);
+extern Aword evaluate(CONTEXT, Aaddr adr);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/location.cpp b/engines/glk/alan3/location.cpp
index 13076b4..51c34f9 100644
--- a/engines/glk/alan3/location.cpp
+++ b/engines/glk/alan3/location.cpp
@@ -39,51 +39,56 @@ namespace Glk {
 namespace Alan3 {
 
 /*----------------------------------------------------------------------*/
-static void traceExit(int location, int dir, const char *what) {
+static void traceExit(CONTEXT, int location, int dir, const char *what) {
 	printf("\n<EXIT %s[%d] from ",
 	       (char *)pointerTo(dictionary[playerWords[currentWordIndex - 1].code].string), dir);
-	traceSay(location);
+	CALL1(traceSay, location)
 	printf("[%d], %s:>\n", location, what);
 }
 
 
 
 /*======================================================================*/
-void go(int location, int dir) {
+void go(CONTEXT, int location, int dir) {
 	ExitEntry *theExit;
 	bool ok;
 	Aword oldloc;
 
 	theExit = (ExitEntry *) pointerTo(instances[location].exits);
-	if (instances[location].exits != 0)
+	if (instances[location].exits != 0) {
 		while (!isEndOfArray(theExit)) {
 			if (theExit->code == (uint)dir) {
 				ok = TRUE;
 				if (theExit->checks != 0) {
 					if (traceSectionOption)
-						traceExit(location, dir, "Checking");
-					ok = !checksFailed(theExit->checks, EXECUTE_CHECK_BODY_ON_FAIL);
+						CALL3(traceExit, location, dir, "Checking")
+
+					FUNC2(checksFailed, ok, theExit->checks, EXECUTE_CHECK_BODY_ON_FAIL)
+					ok = !ok;
 				}
 				if (ok) {
 					oldloc = location;
 					if (theExit->action != 0) {
 						if (traceSectionOption)
-							traceExit(location, dir, "Executing");
-						interpret(theExit->action);
+							CALL3(traceExit, location, dir, "Executing")
+						CALL1(interpret, theExit->action)
 					}
 					/* Still at the same place? */
 					if (where(HERO, TRANSITIVE) == (int)oldloc) {
 						if (traceSectionOption)
-							traceExit(location, dir, "Moving");
-						locate(HERO, theExit->target);
+							CALL3(traceExit, location, dir, "Moving")
+						CALL2(locate, HERO, theExit->target)
 					}
 					return;
-				} else
-					error(NO_MSG);
+				} else {
+					CALL1(error, NO_MSG)
+				}
 			}
 			theExit++;
 		}
-	error(M_NO_WAY);
+	}
+
+	CALL1(error, M_NO_WAY)
 }
 
 
@@ -103,7 +108,7 @@ bool exitto(int to, int from) {
 
 
 /*======================================================================*/
-void look(void) {
+void look(CONTEXT) {
 	uint i;
 
 	/* Set describe flag for all objects and actors */
@@ -114,13 +119,13 @@ void look(void) {
 		para();
 
 	setSubHeaderStyle();
-	sayInstance(current.location);
+	CALL1(sayInstance, current.location)
 	setNormalStyle();
 
 	newline();
 	capitalize = TRUE;
-	if (describe(current.location))
-		describeInstances();
+	if (describe(context, current.location) && !context._break)
+		describeInstances(context);
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/location.h b/engines/glk/alan3/location.h
index 14cada9..005f8bc 100644
--- a/engines/glk/alan3/location.h
+++ b/engines/glk/alan3/location.h
@@ -24,13 +24,14 @@
 #define GLK_ALAN3_LOCATION
 
 #include "glk/alan3/types.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
 
 extern bool exitto(int to, int from);
-extern void go(int location, int dir);
-extern void look(void);
+extern void go(CONTEXT, int location, int dir);
+extern void look(CONTEXT);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index ad690c6..9abba88 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -79,7 +79,7 @@ static char *eventName(int event) {
 
 
 /*----------------------------------------------------------------------*/
-static void runPendingEvents(void) {
+static void runPendingEvents(CONTEXT) {
 	int i;
 
 	resetRules();
@@ -92,11 +92,11 @@ static void runPendingEvents(void) {
 		if (traceSectionOption) {
 			printf("\n<EVENT %s[%d] (at ", eventName(eventQueue[eventQueueTop].event),
 			       eventQueue[eventQueueTop].event);
-			traceSay(current.location);
+			CALL1(traceSay, current.location)
 			printf(" [%d]):>\n", current.location);
 		}
-		interpret(events[eventQueue[eventQueueTop].event].code);
-		evaluateRules(rules);
+		CALL1(interpret, events[eventQueue[eventQueueTop].event].code)
+		CALL1(evaluateRules, rules)
 	}
 
 	for (i = 0; i < eventQueueTop; i++)
@@ -104,8 +104,6 @@ static void runPendingEvents(void) {
 }
 
 
-
-
 /*----------------------------------------------------------------------*\
 
   Main program and initialisation
@@ -528,36 +526,38 @@ static void initDynamicData(void) {
 
 
 /*----------------------------------------------------------------------*/
-static void runInheritedInitialize(Aint theClass) {
+static void runInheritedInitialize(CONTEXT, Aint theClass) {
 	if (theClass == 0) return;
-	runInheritedInitialize(classes[theClass].parent);
+	CALL1(runInheritedInitialize, classes[theClass].parent)
+
 	if (classes[theClass].initialize)
-		interpret(classes[theClass].initialize);
+		interpret(context, classes[theClass].initialize);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void runInitialize(Aint theInstance) {
-	runInheritedInitialize(instances[theInstance].parent);
+static void runInitialize(CONTEXT, Aint theInstance) {
+	CALL1(runInheritedInitialize, instances[theInstance].parent)
+
 	if (instances[theInstance].initialize != 0)
-		interpret(instances[theInstance].initialize);
+		interpret(context, instances[theInstance].initialize);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void initializeInstances() {
+static void initializeInstances(CONTEXT) {
 	uint instanceId;
 
 	/* Set initial locations */
 	for (instanceId = 1; instanceId <= header->instanceMax; instanceId++) {
 		current.instance = instanceId;
-		runInitialize(instanceId);
+		CALL1(runInitialize, instanceId)
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void start(void) {
+static void start(CONTEXT) {
 	int startloc;
 
 	current.tick = 0;
@@ -565,19 +565,20 @@ static void start(void) {
 	current.actor = HERO;
 	current.score = 0;
 
-	initializeInstances();
+	CALL0(initializeInstances)
 
 	if (traceSectionOption)
 		printf("\n<START:>\n");
-	interpret(header->start);
+	CALL1(interpret, header->start)
 	para();
 
 	if (where(HERO, TRANSITIVE) == startloc) {
 		if (traceSectionOption)
 			printf("<CURRENT LOCATION:>");
-		look();
+		CALL0(look)
 	}
-	resetAndEvaluateRules(rules, header->version);
+
+	resetAndEvaluateRules(context, rules, header->version);
 }
 
 
@@ -591,7 +592,7 @@ static void openFiles(void) {
 
 
 /*----------------------------------------------------------------------*/
-static void init(void) {
+static void init(CONTEXT) {
 	int i;
 
 	/* Initialise some status */
@@ -611,25 +612,26 @@ static void init(void) {
 		}
 
 	/* Start the adventure */
-	if (debugOption)
-		debug(FALSE, 0, 0);
-	else
+	if (debugOption) {
+		CALL3(debug, FALSE, 0, 0)
+	} else {
 		clear();
+	}
 
-	start();
+	start(context);
 }
 
 
 
 /*----------------------------------------------------------------------*/
-static bool traceActor(int theActor) {
+static bool traceActor(CONTEXT, int theActor) {
 	if (traceSectionOption) {
 		printf("\n<ACTOR ");
-		traceSay(theActor);
+		R0CALL1(traceSay, theActor)
 		printf("[%d]", theActor);
 		if (current.location != 0) {
 			printf(" (at ");
-			traceSay(current.location);
+			R0CALL1(traceSay, current.location)
 		} else
 			printf(" (nowhere");
 		printf("[%d])", current.location);
@@ -655,6 +657,7 @@ static void moveActor(CONTEXT, int theActor) {
 	ScriptEntry *scr;
 	StepEntry *step;
 	Aint previousInstance = current.instance;
+	bool flag;
 
 	if (context._break) {
 		// forfeit setjmp replacement destination
@@ -682,34 +685,40 @@ static void moveActor(CONTEXT, int theActor) {
 				step = (StepEntry *) &step[admin[theActor].step];
 				/* Now execute it, maybe. First check wait count */
 				if (admin[theActor].waitCount > 0) { /* Wait some more ? */
-					if (traceActor(theActor))
+					FUNC1(traceActor, flag, theActor)
+					if (flag)
 						printf(", SCRIPT %s[%ld], STEP %ld, Waiting another %ld turns>\n",
 						       scriptName(theActor, admin[theActor].script),
 						       (long)admin[theActor].script, (long)admin[theActor].step + 1,
 						       (long)admin[theActor].waitCount);
+
 					admin[theActor].waitCount--;
 					break;
 				}
 				/* Then check possible expression to wait for */
 				if (step->exp != 0) {
-					if (traceActor(theActor))
-						printf(", SCRIPT %s[%ld], STEP %ld, Evaluating:>\n",
+					FUNC1(traceActor, flag, theActor)
+					if (flag)
+							printf(", SCRIPT %s[%ld], STEP %ld, Evaluating:>\n",
 						       scriptName(theActor, admin[theActor].script),
 						       (long)admin[theActor].script, (long)admin[theActor].step + 1);
-					if (!evaluate(step->exp))
+					FUNC1(evaluate, flag, step->exp)
+					if (!flag)
 						break;      /* Break loop, don't execute step*/
 				}
 				/* OK, so finally let him do his thing */
 				admin[theActor].step++;     /* Increment step number before executing... */
 				if (!isEndOfArray(step + 1) && (step + 1)->after != 0) {
-					admin[theActor].waitCount = evaluate((step + 1)->after);
+					FUNC1(evaluate, admin[theActor].waitCount, (step + 1)->after)
 				}
-				if (traceActor(theActor))
+
+				FUNC1(traceActor, flag, theActor)
+				if (flag)
 					printf(", SCRIPT %s[%ld], STEP %ld, Executing:>\n",
 					       scriptName(theActor, admin[theActor].script),
 					       (long)admin[theActor].script,
 					       (long)admin[theActor].step);
-				interpret(step->stms);
+				CALL1(interpret, step->stms)
 				step++;
 				/* ... so that we can see if he failed or is USEing another script now */
 				if (fail || (admin[theActor].step != 0 && isEndOfArray(step)))
@@ -722,7 +731,8 @@ static void moveActor(CONTEXT, int theActor) {
 		if (isEndOfArray(scr))
 			syserr("Unknown actor script.");
 	} else {
-		if (traceActor(theActor)) {
+		FUNC1(traceActor, flag, theActor)
+		if (flag) {
 			printf(", Idle>\n");
 		}
 	}
@@ -749,7 +759,7 @@ void run(void) {
 		initStateStack();
 
 		// Initialise and start the adventure
-		init();
+		init(ctx);
 
 		while (!g_vm->shouldQuit()) {
 			if (!(ctx._break && ctx._label == "forfeit")) {
@@ -774,13 +784,15 @@ void run(void) {
 					ctx.clear();
 				} else {
 					if (debugOption)
-						debug(FALSE, 0, 0);
+						debug(ctx, FALSE, 0, 0);
 
-					if (stackDepth(theStack) != 0)
-						syserr("Stack is not empty in main loop");
+					if (!ctx._break) {
+						if (stackDepth(theStack) != 0)
+							syserr("Stack is not empty in main loop");
 
-					if (!current.meta)
-						runPendingEvents();
+						if (!current.meta)
+							runPendingEvents(ctx);
+					}
 				}
 
 				recursionDepth = 0;
@@ -802,16 +814,20 @@ void run(void) {
 					current.tick++;
 
 					// Remove this call? Since Eval is done up there after each event...
-					resetAndEvaluateRules(rules, header->version);
-
-					/* Then all the other actors... */
-					for (uint i = 1; i <= header->instanceMax; i++) {
-						if (i != header->theHero && isAActor(i)) {
-							moveActor(ctx, i);
-							if (ctx._break)
-								break;
-
-							resetAndEvaluateRules(rules, header->version);
+					resetAndEvaluateRules(ctx, rules, header->version);
+
+					if (!ctx._break) {
+						// Then all the other actors...
+						for (uint i = 1; i <= header->instanceMax; i++) {
+							if (i != header->theHero && isAActor(i)) {
+								moveActor(ctx, i);
+								if (ctx._break)
+									break;
+
+								resetAndEvaluateRules(ctx, rules, header->version);
+								if (ctx._break)
+									break;
+							}
 						}
 					}
 				}
diff --git a/engines/glk/alan3/msg.cpp b/engines/glk/alan3/msg.cpp
index f748f26..b26e78a 100644
--- a/engines/glk/alan3/msg.cpp
+++ b/engines/glk/alan3/msg.cpp
@@ -34,7 +34,8 @@ MessageEntry *msgs;         /* Message table pointer */
 
 /*======================================================================*/
 void printMessage(MsgKind msg) {    /* IN - message number */
-	interpret(msgs[msg].stms);
+	Context ctx;
+	interpret(ctx, msgs[msg].stms);
 }
 
 
@@ -48,21 +49,21 @@ void setErrorHandler(void (*handler)(MsgKind msg)) { /* IN - The error message n
 
 
 /*======================================================================*/
-void error(MsgKind msgno) { /* IN - The error message number */
+void error(CONTEXT, MsgKind msgno) { /* IN - The error message number */
 	if (errorHandler != NULL)
 		errorHandler(msgno);
 	else {
 		/* Print an error message and longjmp to main loop. */
 		if (msgno != NO_MSG)
 			printMessage(msgno);
-		//longjmp(returnLabel, ERROR_RETURN);
+		LONG_JUMP_LABEL("return");
 	}
 }
 
 
 /*======================================================================*/
-void abortPlayerCommand(void) {
-	error(NO_MSG);
+void abortPlayerCommand(CONTEXT) {
+	error(context, NO_MSG);
 }
 
 
@@ -88,11 +89,12 @@ void printMessageUsing2InstanceParameters(MsgKind message, int instance1, int in
 /*======================================================================*/
 void printMessageWithParameters(MsgKind msg, Parameter *messageParameters) {
 	Parameter *savedParameters = newParameterArray();
+	Context ctx;
 
 	copyParameterArray(savedParameters, globalParameters);
 	copyParameterArray(globalParameters, messageParameters);
 
-	interpret(msgs[msg].stms);
+	interpret(ctx, msgs[msg].stms);
 
 	copyParameterArray(globalParameters, savedParameters);
 	freeParameterArray(savedParameters);
diff --git a/engines/glk/alan3/msg.h b/engines/glk/alan3/msg.h
index 5b2f8d6..6275c72 100644
--- a/engines/glk/alan3/msg.h
+++ b/engines/glk/alan3/msg.h
@@ -24,6 +24,7 @@
 #define GLK_ALAN3_MSG
 
 #include "glk/alan3/acode.h"
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/types.h"
 #include "glk/alan3/params.h"
 
@@ -42,9 +43,9 @@ extern MessageEntry *msgs;  /* Message table pointer */
 
 /* FUNCTIONS */
 extern void setErrorHandler(void (*handler)(MsgKind));
-extern void abortPlayerCommand(void);
-extern void error(MsgKind msg);
-extern bool confirm(MsgKind msgno);
+extern void abortPlayerCommand(CONTEXT);
+extern void error(CONTEXT, MsgKind msg);
+extern bool confirm(CONTEXT, MsgKind msgno);
 extern void printMessage(MsgKind msg);
 extern void printMessageWithParameters(MsgKind msg, Parameter *messageParameters);
 extern void printMessageWithInstanceParameter(MsgKind message, int i);
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index 5f64692..aa699c9 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -189,7 +189,7 @@ static void sayPlayerWordsForParameter(int p) {
 
 
 /*----------------------------------------------------------------------*/
-static void sayParameter(int p, int form) {
+static void sayParameter(CONTEXT, int p, int form) {
 	int i;
 
 	for (i = 0; i <= p; i++)
@@ -201,13 +201,14 @@ static void sayParameter(int p, int form) {
 		/* Yes, so use them... */
 		sayPlayerWordsForParameter(p);
 	else
-		sayForm(params[p].code, form);
+		CALL2(sayForm(params[p].code, form)
 #else
 	if (globalParameters[p].useWords) {
 		/* Ambiguous instance referenced, so use the words he used */
 		sayPlayerWordsForParameter(p);
-	} else
-		sayForm(globalParameters[p].instance, (SayForm)form);
+	} else {
+		CALL2(sayForm, globalParameters[p].instance, (SayForm)form)
+	}
 #endif
 }
 
@@ -230,8 +231,10 @@ static void sayParameter(int p, int form) {
   T = tabulation
   $ = no space needed after this, and don't capitalize
   _ = interpret this as a single dollar, if in doubt or conflict with other symbols
-*/
-static char *printSymbol(char str[]) { /* IN - The string starting with '$' */
+
+  str - The string starting with '$'
+  */
+static char *printSymbol(CONTEXT, char str[]) { 
 	int advance = 2;
 
 	if (*str == '\0') printAndLog("$");
@@ -248,7 +251,7 @@ static char *printSymbol(char str[]) { /* IN - The string starting with '$' */
 			break;
 		case 'o':
 			space();
-			sayParameter(0, 0);
+			R0CALL2(sayParameter, 0, 0)
 			needSpace = TRUE;       /* We did print something non-white */
 			break;
 		case '+':
@@ -275,7 +278,7 @@ static char *printSymbol(char str[]) { /* IN - The string starting with '$' */
 					form = SAY_SIMPLE;
 					break;
 				}
-				sayParameter(str[2] - '1', form);
+				R0CALL2(sayParameter, str[2] - '1', form)
 				needSpace = TRUE;
 			}
 			advance = 3;
@@ -290,17 +293,17 @@ static char *printSymbol(char str[]) { /* IN - The string starting with '$' */
 		case '8':
 		case '9':
 			space();
-			sayParameter(str[1] - '1', SAY_SIMPLE);
+			R0CALL2(sayParameter, str[1] - '1', SAY_SIMPLE)
 			needSpace = TRUE;       /* We did print something non-white */
 			break;
 		case 'l':
 			space();
-			say(current.location);
+			R0CALL1(say, current.location)
 			needSpace = TRUE;       /* We did print something non-white */
 			break;
 		case 'a':
 			space();
-			say(current.actor);
+			R0CALL1(say, current.actor)
 			needSpace = TRUE;       /* We did print something non-white */
 			break;
 		case 'v':
@@ -377,6 +380,7 @@ void output(const char *original) {
 	char ch;
 	char *str, *copy;
 	char *symptr;
+	Context ctx;
 
 	copy = strdup(original);
 	str = copy;
@@ -403,7 +407,7 @@ void output(const char *original) {
 			}
 		}
 		*symptr = ch;       /* restore '$' */
-		str = printSymbol(symptr);  /* Print the symbolic reference and advance */
+		str = printSymbol(ctx, symptr);  /* Print the symbolic reference and advance */
 	}
 
 	if (str[0] != 0) {
@@ -420,14 +424,16 @@ void output(const char *original) {
 
 
 /*======================================================================*/
-bool confirm(MsgKind msgno) {
+bool confirm(CONTEXT, MsgKind msgno) {
 	char buf[80];
+	bool flag;
 
 	/* This is a bit of a hack since we really want to compare the input,
 	   it could be affirmative, but for now any input is NOT! */
 	printMessage(msgno);
 
-	if (!readline(buf))
+	R0FUNC2(readline, flag, buf, 80)
+	if (!flag)
 		return TRUE;
 	col = 1;
 
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp
index da9d759..6618e9d 100644
--- a/engines/glk/alan3/parse.cpp
+++ b/engines/glk/alan3/parse.cpp
@@ -31,6 +31,7 @@
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/instance.h"
 #include "glk/alan3/inter.h"
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/lists.h"
 #include "glk/alan3/literal.h"
 #include "glk/alan3/location.h"
@@ -63,7 +64,7 @@ static void clearPronounList(Pronoun list[]) {
 
 
 typedef Aint *(*ReferencesFinder)(int wordIndex);
-typedef void (*ParameterParser)(Parameter parameters[]);
+typedef void (*ParameterParser)(CONTEXT, Parameter parameters[]);
 
 
 
@@ -108,19 +109,21 @@ static bool endOfWords(int wordIndex) {
 
 
 /*----------------------------------------------------------------------*/
-static void handleDirectionalCommand() {
+static void handleDirectionalCommand(CONTEXT) {
 	currentWordIndex++;
-	if (!endOfWords(currentWordIndex) && !isConjunctionWord(currentWordIndex))
-		error(M_WHAT);
-	else
-		go(current.location, dictionary[playerWords[currentWordIndex - 1].code].code);
+	if (!endOfWords(currentWordIndex) && !isConjunctionWord(currentWordIndex)) {
+		CALL1(error, M_WHAT)
+	} else {
+		CALL2(go, current.location, dictionary[playerWords[currentWordIndex - 1].code].code)
+	}
+
 	if (!endOfWords(currentWordIndex))
 		currentWordIndex++;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void errorWhichOne(Parameter alternative[]) {
+static void errorWhichOne(CONTEXT, Parameter alternative[]) {
 	int p; /* Index into the list of alternatives */
 	ParameterArray parameters = newParameterArray();
 
@@ -136,11 +139,11 @@ static void errorWhichOne(Parameter alternative[]) {
 	addParameterToParameterArray(parameters, &alternative[p]);
 	printMessageWithParameters(M_WHICH_ONE_OR, parameters);
 	freeParameterArray(parameters);
-	abortPlayerCommand(); /* Return with empty error message */
+	CALL0(abortPlayerCommand) /* Return with empty error message */
 }
 
 /*----------------------------------------------------------------------*/
-static void errorWhichPronoun(int pronounWordIndex, Parameter alternatives[]) {
+static void errorWhichPronoun(CONTEXT, int pronounWordIndex, Parameter alternatives[]) {
 	int p; /* Index into the list of alternatives */
 	Parameter *messageParameters = newParameterArray();
 
@@ -161,26 +164,26 @@ static void errorWhichPronoun(int pronounWordIndex, Parameter alternatives[]) {
 	addParameterToParameterArray(messageParameters, &alternatives[p]);
 	printMessageWithParameters(M_WHICH_ONE_OR, messageParameters);
 	freeParameterArray(messageParameters);
-	abortPlayerCommand();
+	CALL0(abortPlayerCommand)
 }
 
 /*----------------------------------------------------------------------*/
-static void errorWhat(int playerWordIndex) {
+static void errorWhat(CONTEXT, int playerWordIndex) {
 	Parameter *messageParameters = newParameterArray();
 
 	addParameterForWord(messageParameters, playerWordIndex);
 	printMessageWithParameters(M_WHAT_WORD, messageParameters);
 	freeParameterArray(messageParameters);
-	abortPlayerCommand();
+	CALL0(abortPlayerCommand)
 }
 
 /*----------------------------------------------------------------------*/
-static void errorAfterExcept(int butWordIndex) {
+static void errorAfterExcept(CONTEXT, int butWordIndex) {
 	Parameter *messageParameters = newParameterArray();
 	addParameterForWord(messageParameters, butWordIndex);
 	printMessageWithParameters(M_AFTER_BUT, messageParameters);
 	freeParameterArray(messageParameters);
-	abortPlayerCommand();
+	CALL0(abortPlayerCommand)
 }
 
 /*----------------------------------------------------------------------*/
@@ -202,13 +205,13 @@ static int fakePlayerWordForAll() {
 }
 
 /*----------------------------------------------------------------------*/
-static void errorButAfterAll(int butWordIndex) {
+static void errorButAfterAll(CONTEXT, int butWordIndex) {
 	Parameter *messageParameters = newParameterArray();
 	addParameterForWord(messageParameters, butWordIndex);
 	addParameterForWord(messageParameters, fakePlayerWordForAll());
 	printMessageWithParameters(M_BUT_ALL, messageParameters);
 	freeParameterArray(messageParameters);
-	abortPlayerCommand();
+	CALL0(abortPlayerCommand)
 }
 
 /*----------------------------------------------------------------------*/
@@ -220,7 +223,7 @@ static Aint findInstanceForNoun(int wordIndex) {
 }
 
 /*----------------------------------------------------------------------*/
-static void errorNoSuch(Parameter parameter) {
+static void errorNoSuch(CONTEXT, Parameter parameter) {
 
 	/* If there was no instance, assume the last word used is the noun,
 	 * then find any instance with the noun he used */
@@ -232,11 +235,11 @@ static void errorNoSuch(Parameter parameter) {
 
 	clearParameterArray(globalParameters);
 	addParameterToParameterArray(globalParameters, &parameter);
-	error(M_NO_SUCH);
+	CALL1(error, M_NO_SUCH)
 }
 
 /*----------------------------------------------------------------------*/
-static void buildAllHere(Parameter list[]) {
+static void buildAllHere(CONTEXT, Parameter list[]) {
 	uint instance;
 	bool found = FALSE;
 	int word = list[0].firstWord;
@@ -249,7 +252,7 @@ static void buildAllHere(Parameter list[]) {
 			found = TRUE;
 		}
 	if (!found)
-		errorWhat(word);
+		errorWhat(context, word);
 }
 
 
@@ -375,7 +378,8 @@ static void filterOutNonReachable(Parameter filteredCandidates[], bool (*reachab
  */
 
 /*----------------------------------------------------------------------*/
-static void disambiguateCandidatesForPosition(ParameterPosition parameterPositions[], int position, Parameter candidates[]) {
+static void disambiguateCandidatesForPosition(CONTEXT, ParameterPosition parameterPositions[],
+		int position, Parameter candidates[]) {
 	int i;
 	Parameter *parameters = newParameterArray();
 
@@ -384,8 +388,15 @@ static void disambiguateCandidatesForPosition(ParameterPosition parameterPositio
 		if (candidates[i].instance != 0) { /* Already empty? */
 			copyParameter(&parameters[position], &candidates[i]);
 			// DISAMBIGUATION!!
-			if (!reachable(candidates[i].instance) || !possible(current.verb, parameters, parameterPositions))
-				candidates[i].instance = 0; /* Then remove this candidate from list */
+			if (!reachable(candidates[i].instance)) {
+				// Then remove this candidate from list
+				candidates[i].instance = 0;
+			} else {
+				bool flag;
+				FUNC3(possible, flag, current.verb, parameters, parameterPositions)
+				if (!flag)
+					candidates[i].instance = 0;
+			}
 		}
 	}
 	compressParameterArray(candidates);
@@ -409,7 +420,7 @@ static bool parseAnyAdjectives(Parameter parameters[]) {
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 /* Parse the input and note the word indices in the parameters,
    matching will be done by the match* functions */
-static void parseAdjectivesAndNoun(Parameter parameters[]) {
+static void parseAdjectivesAndNoun(CONTEXT, Parameter parameters[]) {
 	int wordFirst, wordLast;
 	bool adjectiveOrNounFound = FALSE;
 
@@ -422,14 +433,14 @@ static void parseAdjectivesAndNoun(Parameter parameters[]) {
 			adjectiveOrNounFound = TRUE;
 			currentWordIndex++;
 		} else
-			error(M_NOUN);
+			CALL1(error, M_NOUN)
 	} else if (adjectiveOrNounFound) {
 		/* Perhaps the last word could also be interpreted as a noun? */
 		if (isNounWord(currentWordIndex - 1)) {
 			// TODO When does this get executed? Maybe if conjunctions can be nouns? Or nouns be adjectives?
 			printf("DEBUG: When does this get executed? Found adjective or Noun and the previous word could also be a noun...\n");
 		} else
-			error(M_NOUN);
+			CALL1(error, M_NOUN)
 	}
 
 	if (adjectiveOrNounFound) {
@@ -445,7 +456,7 @@ static void parseAdjectivesAndNoun(Parameter parameters[]) {
 
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void parseReference(Parameter parameters[]) {
+static void parseReference(CONTEXT, Parameter parameters[]) {
 	clearParameterArray(parameters);
 
 	if (isLiteralWord(currentWordIndex)) {
@@ -453,7 +464,7 @@ static void parseReference(Parameter parameters[]) {
 	} else if (isPronounWord(currentWordIndex)) {
 		parsePronoun(parameters);
 	} else {
-		parseAdjectivesAndNoun(parameters);
+		CALL1(parseAdjectivesAndNoun, parameters)
 	}
 }
 
@@ -484,7 +495,7 @@ static void parseReferenceToPreviousMultipleParameters(Parameter parameters[]) {
 
 
 /*----------------------------------------------------------------------*/
-static bool parseOneParameter(Parameter parameters[], int parameterIndex) {
+static bool parseOneParameter(CONTEXT, Parameter parameters[], int parameterIndex) {
 	Parameter *parameter = newParameterArray();
 
 	// TODO Maybe this should go in the complex()?
@@ -494,7 +505,7 @@ static bool parseOneParameter(Parameter parameters[], int parameterIndex) {
 		// are previous multiple parameters we give precedence to those
 		parseReferenceToPreviousMultipleParameters(parameter);
 	} else {
-		parseReference(parameter);
+		R0CALL1(parseReference, parameter)
 		if (lengthOfParameterArray(parameter) == 0) { /* Failed to find any exceptions! */
 			freeParameterArray(parameter);
 			return FALSE;
@@ -528,13 +539,14 @@ static bool parseOneParameter(Parameter parameters[], int parameterIndex) {
  */
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void simpleParameterParser(Parameter parameters[]) {
+static void simpleParameterParser(CONTEXT, Parameter parameters[]) {
+	bool flag;
 
 	/* This will loop until all references are collected (typically "a and b and c") */
 	int parameterIndex;
 	for (parameterIndex = 0;; parameterIndex++) {
-
-		if (!parseOneParameter(parameters, parameterIndex))
+		FUNC2(parseOneParameter, flag, parameters, parameterIndex)
+		if (!flag)
 			return;
 
 		if (!endOfWords(currentWordIndex)
@@ -551,13 +563,14 @@ static void simpleParameterParser(Parameter parameters[]) {
 
 
 /*----------------------------------------------------------------------*/
-static void parseExceptions(ParameterPosition *parameterPosition, ParameterParser simpleParameterParser) {
+static void parseExceptions(CONTEXT, ParameterPosition *parameterPosition, ParameterParser simpleParameterParser) {
 	int exceptWordIndex = currentWordIndex;
 	currentWordIndex++;
 	parameterPosition->exceptions = ensureParameterArrayAllocated(parameterPosition->exceptions);
-	simpleParameterParser(parameterPosition->exceptions);
+	CALL1(simpleParameterParser, parameterPosition->exceptions)
+	
 	if (lengthOfParameterArray(parameterPosition->exceptions) == 0)
-		errorAfterExcept(exceptWordIndex);
+		errorAfterExcept(context, exceptWordIndex);
 }
 
 
@@ -572,7 +585,8 @@ static void parseExceptions(ParameterPosition *parameterPosition, ParameterParse
  */
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void complexParameterParserDelegate(ParameterPosition *parameterPosition, ParameterParser simpleParameterParser) {
+static void complexParameterParserDelegate(CONTEXT, ParameterPosition *parameterPosition,
+		ParameterParser simpleParameterParser) {
 	parameterPosition->parameters = ensureParameterArrayAllocated(parameterPosition->parameters);
 
 	parameterPosition->all = FALSE;
@@ -588,9 +602,9 @@ static void complexParameterParserDelegate(ParameterPosition *parameterPosition,
 		parameterPosition->parameters[0].instance = 0;
 		setEndOfArray(&parameterPosition->parameters[1]);
 		if (!endOfWords(currentWordIndex) && isExceptWord(currentWordIndex))
-			parseExceptions(parameterPosition, simpleParameterParser);
+			CALL2(parseExceptions, parameterPosition, simpleParameterParser)
 	} else {
-		simpleParameterParser(parameterPosition->parameters);
+		CALL1(simpleParameterParser, parameterPosition->parameters)
 		if (lengthOfParameterArray(parameterPosition->parameters) > 1)
 			parameterPosition->explicitMultiple = TRUE;
 	}
@@ -598,8 +612,8 @@ static void complexParameterParserDelegate(ParameterPosition *parameterPosition,
 }
 
 /*----------------------------------------------------------------------*/
-static void complexReferencesParser(ParameterPosition *parameterPosition) {
-	complexParameterParserDelegate(parameterPosition, simpleParameterParser);
+static void complexReferencesParser(CONTEXT, ParameterPosition *parameterPosition) {
+	complexParameterParserDelegate(context, parameterPosition, simpleParameterParser);
 }
 
 
@@ -653,12 +667,13 @@ static bool restrictionCheck(RestrictionEntry *restriction, int instance) {
 
 
 /*----------------------------------------------------------------------*/
-static void runRestriction(RestrictionEntry *restriction, Parameter parameters[]) {
+static void runRestriction(CONTEXT, RestrictionEntry *restriction, Parameter parameters[]) {
 	if (restriction->stms) {
 		setGlobalParameters(parameters);
-		interpret(restriction->stms);
-	} else
-		error(M_CANT0);
+		interpret(context, restriction->stms);
+	} else {
+		error(context, M_CANT0);
+	}
 }
 
 
@@ -722,15 +737,16 @@ static bool multipleAllowed(Aword flags) {
  */
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void parseParameterPosition(ParameterPosition *parameterPosition, Aword flags, void (*complexReferencesParser)(ParameterPosition *parameterPosition)) {
+static void parseParameterPosition(CONTEXT, ParameterPosition *parameterPosition,
+		Aword flags, void (*complexReferencesParser)(CONTEXT, ParameterPosition *parameterPosition)) {
 	parameterPosition->parameters = ensureParameterArrayAllocated(parameterPosition->parameters);
 
-	complexReferencesParser(parameterPosition);
+	CALL1(complexReferencesParser, parameterPosition)
 	if (lengthOfParameterArray(parameterPosition->parameters) == 0) /* No object!? */
-		error(M_WHAT);
+		CALL1(error, M_WHAT)
 
 	if (parameterPosition->explicitMultiple && !multipleAllowed(flags))
-		error(M_MULTIPLE);
+		CALL1(error, M_MULTIPLE)
 }
 
 /*----------------------------------------------------------------------*/
@@ -776,7 +792,7 @@ static bool endOfPlayerCommand(int wordIndex) {
 
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static ElementEntry *parseInputAccordingToSyntax(SyntaxEntry *syntax, ParameterPosition parameterPositions[]) {
+static ElementEntry *parseInputAccordingToSyntax(CONTEXT, SyntaxEntry *syntax, ParameterPosition parameterPositions[]) {
 	ElementEntry *currentElement = elementTreeOf(syntax);
 	ElementEntry *nextElement = currentElement;
 
@@ -798,7 +814,8 @@ static ElementEntry *parseInputAccordingToSyntax(SyntaxEntry *syntax, ParameterP
 				// Create parameter structure for the parameter position based on player words
 				// but without resolving them
 				ParameterPosition *parameterPosition = &parameterPositions[parameterCount];
-				parseParameterPosition(parameterPosition, nextElement->flags, complexReferencesParser);
+				R0CALL3(parseParameterPosition, parameterPosition, nextElement->flags, complexReferencesParser)
+
 				parameterPosition->flags = nextElement->flags;
 				parameterPosition->endOfList = FALSE;
 
@@ -821,7 +838,7 @@ static ElementEntry *parseInputAccordingToSyntax(SyntaxEntry *syntax, ParameterP
 
 		/* Anything else is an error, but we'll handle 'but' specially here */
 		if (isExceptWord(currentWordIndex))
-			errorButAfterAll(currentWordIndex);
+			R0CALL1(errorButAfterAll, currentWordIndex)
 
 		/* If we get here we couldn't match anything... */
 		nextElement = NULL;
@@ -853,7 +870,7 @@ static bool anyAll(ParameterPosition parameterPositions[]) {
 
 
 /*----------------------------------------------------------------------*/
-static void checkRestrictedParameters(ParameterPosition parameterPositions[], ElementEntry elms[]) {
+static void checkRestrictedParameters(CONTEXT, ParameterPosition parameterPositions[], ElementEntry elms[]) {
 	RestrictionEntry *restriction;
 	static Parameter *localParameters = NULL;
 	int i;
@@ -880,7 +897,7 @@ static void checkRestrictedParameters(ParameterPosition parameterPositions[], El
 						sprintf(marker, "($%ld)", (unsigned long) restriction->parameterNumber);
 						setGlobalParameters(localParameters);
 						output(marker);
-						runRestriction(restriction, localParameters);
+						CALL2(runRestriction, restriction, localParameters)
 						para();
 					}
 					parameterPosition->parameters[i].instance = 0; /* In any case remove it from the list */
@@ -888,8 +905,8 @@ static void checkRestrictedParameters(ParameterPosition parameterPositions[], El
 			}
 		} else {
 			if (!restrictionCheck(restriction, parameterPosition->parameters[0].instance)) {
-				runRestriction(restriction, localParameters);
-				abortPlayerCommand();
+				CALL2(runRestriction, restriction, localParameters)
+				CALL0(abortPlayerCommand)
 			}
 		}
 		parameterPositions[restriction->parameterNumber - 1].checked = TRUE;
@@ -900,19 +917,19 @@ static void checkRestrictedParameters(ParameterPosition parameterPositions[], El
 
 
 /*----------------------------------------------------------------------*/
-static void impossibleWith(ParameterPosition parameterPositions[], int positionIndex) {
+static void impossibleWith(CONTEXT, ParameterPosition parameterPositions[], int positionIndex) {
 	if (isPreBeta2(header->version)) {
-		error(M_CANT0);
+		error(context, M_CANT0);
 	} else {
 		printMessageWithInstanceParameter(M_IMPOSSIBLE_WITH, parameterPositions[positionIndex].parameters[0].instance);
-		error(NO_MSG);
+		error(context, NO_MSG);
 	}
 }
 
 
 
 /*----------------------------------------------------------------------*/
-static void checkNonRestrictedParameters(ParameterPosition parameterPositions[]) {
+static void checkNonRestrictedParameters(CONTEXT, ParameterPosition parameterPositions[]) {
 	int positionIndex;
 	for (positionIndex = 0; !parameterPositions[positionIndex].endOfList; positionIndex++)
 		if (!parameterPositions[positionIndex].checked) {
@@ -924,16 +941,17 @@ static void checkNonRestrictedParameters(ParameterPosition parameterPositions[])
 						if (!isAObject(parameterPositions[positionIndex].parameters[i].instance))
 							parameterPositions[positionIndex].parameters[i].instance = 0;
 			} else if (!isAObject(parameterPositions[positionIndex].parameters[0].instance))
-				impossibleWith(parameterPositions, positionIndex);
+				impossibleWith(context, parameterPositions, positionIndex);
 		}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void restrictParametersAccordingToSyntax(ParameterPosition parameterPositions[], ElementEntry *elms) {
+static void restrictParametersAccordingToSyntax(CONTEXT, ParameterPosition parameterPositions[], ElementEntry *elms) {
 	uncheckAllParameterPositions(parameterPositions);
-	checkRestrictedParameters(parameterPositions, elms);
-	checkNonRestrictedParameters(parameterPositions);
+	CALL2(checkRestrictedParameters, parameterPositions, elms)
+	CALL1(checkNonRestrictedParameters, parameterPositions)
+
 	int positionIndex;
 	for (positionIndex = 0; !parameterPositions[positionIndex].endOfList; positionIndex++)
 		compressParameterArray(parameterPositions[positionIndex].parameters);
@@ -941,16 +959,16 @@ static void restrictParametersAccordingToSyntax(ParameterPosition parameterPosit
 
 
 /*----------------------------------------------------------------------*/
-static void matchPronoun(Parameter *parameter) {
+static void matchPronoun(CONTEXT, Parameter *parameter) {
 	static Parameter *pronounInstances = NULL;
 	pronounInstances = ensureParameterArrayAllocated(pronounInstances);
 
 	int pronounCandidateCount = getPronounInstances(playerWords[parameter->firstWord].code, pronounInstances);
-	if (pronounCandidateCount == 0)
-		errorWhat(parameter->firstWord);
-	else if (pronounCandidateCount > 1)
-		errorWhichPronoun(parameter->firstWord, pronounInstances);
-	else {
+	if (pronounCandidateCount == 0) {
+		CALL1(errorWhat, parameter->firstWord)
+	} else if (pronounCandidateCount > 1) {
+		CALL2(errorWhichPronoun, parameter->firstWord, pronounInstances)
+	} else {
 		parameter->candidates[0] = pronounInstances[0];
 		setEndOfArray(&parameter->candidates[1]);
 	}
@@ -968,7 +986,7 @@ static void matchNounPhrase(Parameter *parameter, ReferencesFinder adjectiveRefe
 
 
 /*----------------------------------------------------------------------*/
-static void instanceMatcher(Parameter *parameter) {
+static void instanceMatcher(CONTEXT, Parameter *parameter) {
 	Parameter *candidates = parameter->candidates;
 	int i;
 
@@ -976,7 +994,7 @@ static void instanceMatcher(Parameter *parameter) {
 		candidates[0].instance = instanceFromLiteral(playerWords[parameter->firstWord].code - dictionarySize);
 		setEndOfArray(&candidates[1]);
 	} else if (parameter->isPronoun) {
-		matchPronoun(parameter);
+		CALL1(matchPronoun, parameter)
 	} else
 		matchNounPhrase(parameter, adjectiveReferencesForWord, nounReferencesForWord);
 
@@ -991,24 +1009,25 @@ static void instanceMatcher(Parameter *parameter) {
 
 
 /*----------------------------------------------------------------------*/
-static void findCandidates(Parameter parameters[], void (*instanceMatcher)(Parameter *parameter)) {
+static void findCandidates(CONTEXT, Parameter parameters[], void (*instanceMatcher)(CONTEXT, Parameter *parameter)) {
 	int i;
 
 	for (i = 0; i < lengthOfParameterArray(parameters); i++) {
 		parameters[i].candidates = ensureParameterArrayAllocated(parameters[i].candidates);
-		instanceMatcher(&parameters[i]);
+		CALL1(instanceMatcher, &parameters[i])
+
 		parameters[i].candidates[0].isPronoun = parameters[i].isPronoun;
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void handleFailedParse(ElementEntry *elms) {
+static void handleFailedParse(CONTEXT, ElementEntry *elms) {
 	if (elms == NULL)
-		error(M_WHAT);
-	if (elms->next == 0) { /* No verb code, verb not declared! */
+		error(context, M_WHAT);
+	else if (elms->next == 0) { /* No verb code, verb not declared! */
 		/* TODO Does this ever happen? */
-		error(M_CANT0);
+		error(context, M_CANT0);
 	}
 }
 
@@ -1025,13 +1044,14 @@ static void convertMultipleCandidatesToMultipleParameters(ParameterPosition para
 
 
 /*----------------------------------------------------------------------*/
-static ElementEntry *parseInput(ParameterPosition *parameterPositions) {
+static ElementEntry *parseInput(CONTEXT, ParameterPosition *parameterPositions) {
 	ElementEntry *element;
 	SyntaxEntry *stx;
 
-	stx = findSyntaxTreeForVerb(verbWordCode);
-	element = parseInputAccordingToSyntax(stx, parameterPositions);
-	handleFailedParse(element);
+	R0FUNC1(findSyntaxTreeForVerb, stx, verbWordCode)
+	R0FUNC2(parseInputAccordingToSyntax, element, stx, parameterPositions)
+	R0CALL1(handleFailedParse, element)
+
 	current.syntax = element->flags;
 	current.verb = remapParameterOrder(current.syntax, parameterPositions);
 	return element;
@@ -1039,7 +1059,7 @@ static ElementEntry *parseInput(ParameterPosition *parameterPositions) {
 
 
 /*----------------------------------------------------------------------*/
-static void findCandidatesForPlayerWords(ParameterPosition *parameterPosition) {
+static void findCandidatesForPlayerWords(CONTEXT, ParameterPosition *parameterPosition) {
 	ParameterArray parameters = parameterPosition->parameters;
 
 	if (!parameterArrayIsEmpty(parameters)) {
@@ -1047,36 +1067,39 @@ static void findCandidatesForPlayerWords(ParameterPosition *parameterPosition) {
 			parameterPosition->them = TRUE;
 			getPreviousMultipleParameters(parameters);
 			if (lengthOfParameterArray(parameters) == 0)
-				errorWhat(parameters[0].firstWord);
+				CALL1(errorWhat, parameters[0].firstWord)
 			if (lengthOfParameterArray(parameters) > 1)
 				parameterPosition->explicitMultiple = TRUE;
 		} else if (parameterPosition->all) {
-			buildAllHere(parameters);
+			CALL1(buildAllHere, parameters)
 			if (!parameterArrayIsEmpty(parameterPosition->exceptions))
-				findCandidates(parameterPosition->exceptions, instanceMatcher);
+				CALL2(findCandidates, parameterPosition->exceptions, instanceMatcher)
 		} else
-			findCandidates(parameters, instanceMatcher);
+			CALL2(findCandidates, parameters, instanceMatcher)
 	}
 }
 
 
 /*----------------------------------------------------------------------*/
-static void handleMultiplePosition(ParameterPosition parameterPositions[]) {
+static void handleMultiplePosition(CONTEXT, ParameterPosition parameterPositions[]) {
 	int multiplePosition = findMultipleParameterPosition(parameterPositions);
 	if (anyAll(parameterPositions)) {
 		/* If the player used ALL, try to find out what was applicable */
-		disambiguateCandidatesForPosition(parameterPositions, multiplePosition, parameterPositions[multiplePosition].parameters);
+		CALL3(disambiguateCandidatesForPosition, parameterPositions, multiplePosition,
+			parameterPositions[multiplePosition].parameters)
+		
 		if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0)
-			errorWhat(parameterPositions[multiplePosition].parameters[0].firstWord);
+			CALL1(errorWhat, parameterPositions[multiplePosition].parameters[0].firstWord)
+
 		subtractParameterArrays(parameterPositions[multiplePosition].parameters, parameterPositions[multiplePosition].exceptions);
 		if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0)
-			error(M_NOT_MUCH);
+			CALL1(error, M_NOT_MUCH)
 	} else if (anyExplicitMultiple(parameterPositions)) {
 		compressParameterArray(parameterPositions[multiplePosition].parameters);
 		if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0) {
 			/* If there where multiple parameters but non left, exit without a */
 			/* word, assuming we have already said enough */
-			abortPlayerCommand();
+			CALL0(abortPlayerCommand)
 		}
 	}
 }
@@ -1115,81 +1138,89 @@ static void handleMultiplePosition(ParameterPosition parameterPositions[]) {
  */
 
 
-typedef Parameter *DisambiguationHandler(Parameter allCandidates[], Parameter presentCandidates[]);
+typedef Parameter *DisambiguationHandler(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]);
 typedef DisambiguationHandler *DisambiguationHandlerTable[3][3][2];
 
-static Parameter *disambiguate00N(Parameter allCandidates[], Parameter presentCandidates[]) {
+static Parameter *disambiguate00N(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	if (allCandidates[0].isPronoun)
-		errorWhat(allCandidates[0].firstWord);
+		R0CALL1(errorWhat, allCandidates[0].firstWord)
 	else
-		errorNoSuch(allCandidates[0]);
+		R0CALL1(errorNoSuch, allCandidates[0]);
 	return NULL;
 }
-static Parameter *disambiguate01N(Parameter allCandidates[], Parameter presentCandidates[]) {
+
+static Parameter *disambiguate01N(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	if (allCandidates[0].isPronoun)
-		errorWhat(allCandidates[0].firstWord);
+		R0CALL1(errorWhat, allCandidates[0].firstWord)
 	else
-		errorNoSuch(allCandidates[0]);
+		R0CALL1(errorNoSuch, allCandidates[0])
 	return NULL;
 }
-static Parameter *disambiguate0MN(Parameter allCandidates[], Parameter presentCandidates[]) {
+
+static Parameter *disambiguate0MN(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	if (allCandidates[0].isPronoun)
-		errorWhat(allCandidates[0].firstWord);
+		R0CALL1(errorWhat, allCandidates[0].firstWord)
 	else
-		errorNoSuch(allCandidates[0]);
+		R0CALL1(errorNoSuch, allCandidates[0])
 	return NULL;
 }
-static Parameter *disambiguate10N(Parameter allCandidates[], Parameter presentCandidates[]) {
+
+static Parameter *disambiguate10N(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	return presentCandidates;
 }
-static Parameter *disambiguate11N(Parameter allCandidates[], Parameter presentCandidates[]) {
+
+static Parameter *disambiguate11N(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	return presentCandidates;
 }
-static Parameter *disambiguate1MN(Parameter allCandidates[], Parameter presentCandidates[]) {
+
+static Parameter *disambiguate1MN(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	return presentCandidates;
 }
-static Parameter *disambiguateM0N(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorWhichOne(presentCandidates);
+static Parameter *disambiguateM0N(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	R0CALL1(errorWhichOne, presentCandidates)
 	return NULL;
 }
-static Parameter *disambiguateM1N(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorWhichOne(presentCandidates);
+
+static Parameter *disambiguateM1N(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	R0CALL1(errorWhichOne, presentCandidates)
 	return NULL;
 }
-static Parameter *disambiguateMMN(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorWhichOne(presentCandidates);
+
+static Parameter *disambiguateMMN(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	R0CALL1(errorWhichOne, presentCandidates)
 	return NULL;
 }
-static Parameter *disambiguate00Y(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorNoSuch(allCandidates[0]);
+
+static Parameter *disambiguate00Y(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	errorNoSuch(context, allCandidates[0]);
 	return NULL;
 }
-static Parameter *disambiguate01Y(Parameter allCandidates[], Parameter presentCandidates[]) {
+static Parameter *disambiguate01Y(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	return allCandidates;
 }
-static Parameter *disambiguate0MY(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorWhichOne(allCandidates);
+static Parameter *disambiguate0MY(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	R0CALL1(errorWhichOne, allCandidates)
 	return NULL;
 }
-static Parameter *disambiguate10Y(Parameter allCandidates[], Parameter presentCandidates[]) {
+static Parameter *disambiguate10Y(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	return presentCandidates;
 }
-static Parameter *disambiguate11Y(Parameter allCandidates[], Parameter presentCandidates[]) {
+static Parameter *disambiguate11Y(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	return presentCandidates;
 }
-static Parameter *disambiguate1MY(Parameter allCandidates[], Parameter presentCandidates[]) {
+static Parameter *disambiguate1MY(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
 	return presentCandidates;
 }
-static Parameter *disambiguateM0Y(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorWhichOne(presentCandidates);
+static Parameter *disambiguateM0Y(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	R0CALL1(errorWhichOne, presentCandidates)
 	return NULL;
 }
-static Parameter *disambiguateM1Y(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorWhichOne(presentCandidates);
+static Parameter *disambiguateM1Y(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	R0CALL1(errorWhichOne, presentCandidates)
 	return NULL;
 }
-static Parameter *disambiguateMMY(Parameter allCandidates[], Parameter presentCandidates[]) {
-	errorWhichOne(presentCandidates);
+static Parameter *disambiguateMMY(CONTEXT, Parameter allCandidates[], Parameter presentCandidates[]) {
+	R0CALL1(errorWhichOne, presentCandidates)
 	return NULL;
 }
 
@@ -1242,7 +1273,7 @@ static DisambiguationHandlerTable disambiguationHandlerTable = {
 };
 
 /*----------------------------------------------------------------------*/
-static void disambiguateCandidates(Parameter *allCandidates, bool omnipotent, bool (*reachable)(int), DisambiguationHandlerTable handler) {
+static void disambiguateCandidates(CONTEXT, Parameter *allCandidates, bool omnipotent, bool (*reachable)(int), DisambiguationHandlerTable handler) {
 	static Parameter *presentCandidates = NULL;
 	int present;
 	int distant;
@@ -1259,7 +1290,7 @@ static void disambiguateCandidates(Parameter *allCandidates, bool omnipotent, bo
 	distant = lengthOfParameterArray(allCandidates) - present;
 	if (distant > 1) distant = 2; /* 2 = M */
 
-	result = handler[present][distant][omnipotent](allCandidates, presentCandidates);
+	FUNC2(handler[present][distant][omnipotent], result, allCandidates, presentCandidates)
 
 	// If we returned then it's ok, use the single candidate found
 	allCandidates[0] = result[0];
@@ -1268,13 +1299,13 @@ static void disambiguateCandidates(Parameter *allCandidates, bool omnipotent, bo
 
 
 /*----------------------------------------------------------------------*/
-static void disambiguate(ParameterPosition parameterPositions[], ElementEntry *element) {
+static void disambiguate(CONTEXT, ParameterPosition parameterPositions[], ElementEntry *element) {
 	/* The New Strategy! Parsing has only collected word indications,
 	   not built anything, so we need to match parameters to instances here */
 
 	int position;
 	for (position = 0; !parameterPositions[position].endOfList; position++) {
-		findCandidatesForPlayerWords(&parameterPositions[position]);
+		CALL1(findCandidatesForPlayerWords, &parameterPositions[position])
 	}
 
 	/* Now we have candidates for everything the player said, except
@@ -1291,7 +1322,8 @@ static void disambiguate(ParameterPosition parameterPositions[], ElementEntry *e
 			for (p = 0; p < lengthOfParameterArray(parameters); p++) {
 				Parameter *parameter = &parameters[p];
 				Parameter *candidates = parameter->candidates;
-				disambiguateCandidates(candidates, omni, reachable, disambiguationHandlerTable);
+				CALL4(disambiguateCandidates, candidates, omni, reachable, disambiguationHandlerTable)
+				
 				parameter->instance = candidates[0].instance;
 			}
 		}
@@ -1301,21 +1333,22 @@ static void disambiguate(ParameterPosition parameterPositions[], ElementEntry *e
 			for (p = 0; p < lengthOfParameterArray(exceptions); p++) {
 				Parameter *parameter = &exceptions[p];
 				Parameter *candidates = parameter->candidates;
-				disambiguateCandidates(candidates, omni, reachable, disambiguationHandlerTable);
+				CALL4(disambiguateCandidates, candidates, omni, reachable, disambiguationHandlerTable)
+
 				parameter->instance = candidates[0].instance;
 			}
 		}
 	}
 
-	handleMultiplePosition(parameterPositions);
+	CALL1(handleMultiplePosition, parameterPositions)
 
 	/* Now perform restriction checks */
-	restrictParametersAccordingToSyntax(parameterPositions, element);
+	CALL2(restrictParametersAccordingToSyntax, parameterPositions, element)
 }
 
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void tryParam(Parameter parameters[], Parameter multipleParameters[]) {
+static void tryParam(CONTEXT, Parameter parameters[], Parameter multipleParameters[]) {
 	ElementEntry *element;      /* Pointer to element list */
 	static ParameterPosition *parameterPositions = NULL;
 	if (parameterPositions != NULL)
@@ -1325,9 +1358,8 @@ static void tryParam(Parameter parameters[], Parameter multipleParameters[]) {
 	parameterPositions = (ParameterPosition *)allocate(sizeof(ParameterPosition) * (MAXPARAMS + 1));
 	parameterPositions[0].endOfList = TRUE;
 
-	element = parseInput(parameterPositions);
-
-	disambiguate(parameterPositions, element);
+	FUNC1(parseInput, element, parameterPositions)
+	CALL2(disambiguate, parameterPositions, element)
 
 	// TODO: Now we need to convert back to legacy parameter and multipleParameter format
 	convertPositionsToParameters(parameterPositions, parameters);
@@ -1340,15 +1372,16 @@ static void tryParam(Parameter parameters[], Parameter multipleParameters[]) {
 
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void parseOneCommand(Parameter parameters[], Parameter multipleParameters[]) {
-	tryParam(parameters, multipleParameters); /* ... to understand what he said */
+static void parseOneCommand(CONTEXT, Parameter parameters[], Parameter multipleParameters[]) {
+	// ... to understand what he said
+	CALL2(tryParam, parameters, multipleParameters)
 
 	/* More on this line? */
 	if (!endOfWords(currentWordIndex)) {
 		if (isConjunctionWord(currentWordIndex))
 			currentWordIndex++; /* If so skip the conjunction */
 		else
-			error(M_WHAT);
+			error(context, M_WHAT);
 	}
 }
 
@@ -1410,27 +1443,27 @@ static void notePronounsForParameters(Parameter parameters[]) {
 
 
 /*----------------------------------------------------------------------*/
-static void parseVerbCommand(Parameter parameters[], Parameter multipleParameters[]) {
+static void parseVerbCommand(CONTEXT, Parameter parameters[], Parameter multipleParameters[]) {
 	verbWord = playerWords[currentWordIndex].code;
 	verbWordCode = dictionary[verbWord].code;
 	if (isPreBeta2(header->version))
 		/* Pre-beta2 didn't generate syntax elements for verb words,
 		   need to skip first word which should be the verb */
 		currentWordIndex++;
-	parseOneCommand(parameters, multipleParameters);
+	CALL2(parseOneCommand, parameters, multipleParameters)
 	notePronounsForParameters(parameters);
 	fail = FALSE;
 }
 
 
 /*----------------------------------------------------------------------*/
-static void parseInstanceCommand(Parameter parameters[], Parameter multipleParameters[]) {
+static void parseInstanceCommand(CONTEXT, Parameter parameters[], Parameter multipleParameters[]) {
 	/* Pick up the parse tree for the syntaxes that start with an
 	   instance reference and parse according to that. The
 	   verbWord code is set to 0 to indicate that it is not a verb
 	   but an instance that starts the command. */
 	verbWordCode = 0;
-	parseOneCommand(parameters, multipleParameters);
+	CALL2(parseOneCommand, parameters, multipleParameters)
 	notePronounsForParameters(parameters);
 	fail = FALSE;
 }
@@ -1455,19 +1488,20 @@ void parse(CONTEXT) {
 
 	firstWord = currentWordIndex;
 	if (isVerbWord(currentWordIndex)) {
-		parseVerbCommand(parameters, multipleParameters);
-		action(current.verb, parameters, multipleParameters);
+		CALL2(parseVerbCommand, parameters, multipleParameters);
+		CALL3(action, current.verb, parameters, multipleParameters)
 	} else if (isDirectionWord(currentWordIndex)) {
 		clearParameterArray(previousMultipleParameters);
 		clearPronounList(pronouns);
-		handleDirectionalCommand();
+		CALL0(handleDirectionalCommand)
 	} else if (isInstanceReferenceWord(currentWordIndex)) {
-		parseInstanceCommand(parameters, multipleParameters);
-		action(current.verb, parameters, multipleParameters);
+		CALL2(parseInstanceCommand, parameters, multipleParameters)
+		CALL3(action, current.verb, parameters, multipleParameters)
 	} else
-		error(M_WHAT);
+		CALL1(error, M_WHAT)
 
-	if (fail) error(NO_MSG);
+	if (fail)
+		CALL1(error, NO_MSG)
 
 	lastWord = currentWordIndex - 1;
 	if (isConjunctionWord(lastWord))
diff --git a/engines/glk/alan3/readline.cpp b/engines/glk/alan3/readline.cpp
index 34e9e64..832f00d 100644
--- a/engines/glk/alan3/readline.cpp
+++ b/engines/glk/alan3/readline.cpp
@@ -48,14 +48,14 @@ namespace Alan3 {
 */
 
 /* TODO - length of user buffer should be used */
-bool readline(char buffer[]) {
+bool readline(CONTEXT, char *buffer, size_t maxLen) {
 	event_t event;
 	static bool readingCommands = FALSE;
 	static frefid_t commandFileRef;
 	static strid_t commandFile;
 
 	if (readingCommands) {
-		if (g_vm->glk_get_line_stream(commandFile, buffer, 255) == 0) {
+		if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) == 0) {
 			g_vm->glk_stream_close(commandFile, NULL);
 			readingCommands = FALSE;
 		} else {
@@ -64,18 +64,16 @@ bool readline(char buffer[]) {
 			g_vm->glk_set_style(style_Normal);
 		}
 	} else {
-		g_vm->glk_request_line_event(glkMainWin, buffer, 255, 0);
-		/* FIXME: buffer size should be infallible: all existing calls use 256 or
-		   80 character buffers, except parse which uses LISTLEN (currently 100)
-		*/
+		g_vm->glk_request_line_event(glkMainWin, buffer, maxLen, 0);
+
 		do {
 			g_vm->glk_select(&event);
 			if (g_vm->shouldQuit())
-				return FALSE;
+				LONG_JUMP0
 
 			switch (event.type) {
 			case evtype_Arrange:
-				statusline();
+				R0CALL0(statusline)
 				break;
 
 			default:
@@ -87,7 +85,7 @@ bool readline(char buffer[]) {
 			commandFileRef = g_vm->glk_fileref_create_by_name(fileusage_InputRecord + fileusage_TextMode, &buffer[1], 0);
 			commandFile = g_vm->glk_stream_open_file(commandFileRef, filemode_Read, 0);
 			if (commandFile != NULL)
-				if (g_vm->glk_get_line_stream(commandFile, buffer, 255) != 0) {
+				if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) != 0) {
 					readingCommands = TRUE;
 					g_vm->glk_set_style(style_Input);
 					printf(buffer);
diff --git a/engines/glk/alan3/readline.h b/engines/glk/alan3/readline.h
index 3ab217c..624bf4a 100644
--- a/engines/glk/alan3/readline.h
+++ b/engines/glk/alan3/readline.h
@@ -26,13 +26,14 @@
 /* Header file for user input, history and editing support */
 
 #include "glk/alan3/types.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
 
 #define HISTORYLENGTH 20
 
-extern bool readline(char usrbuf[]);
+extern bool readline(CONTEXT, char *usrBuf, size_t maxLen);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/rules.cpp b/engines/glk/alan3/rules.cpp
index b589168..2adc819 100644
--- a/engines/glk/alan3/rules.cpp
+++ b/engines/glk/alan3/rules.cpp
@@ -87,11 +87,11 @@ void initRules(Aaddr ruleTableAddress) {
 
 
 /*----------------------------------------------------------------------*/
-static void traceRuleStart(int rule, const char *what) {
+static void traceRuleStart(CONTEXT, int rule, const char *what) {
 	printf("\n<RULE %d", rule);
 	if (current.location != 0) {
 		printf(" (at ");
-		traceSay(current.location);
+		CALL1(traceSay, current.location)
 	} else
 		printf(" (nowhere");
 	printf("[%d]), %s", current.location, what);
@@ -103,14 +103,14 @@ static bool detailedTraceOn() {
 
 
 /*----------------------------------------------------------------------*/
-static void traceRuleEvaluation(int rule) {
+static void traceRuleEvaluation(CONTEXT, int rule) {
 	if (traceSectionOption) {
 		if (detailedTraceOn()) {
-			traceRuleStart(rule, "Evaluating:>");
+			CALL2(traceRuleStart, rule, "Evaluating:>")
 			if (!traceInstructionOption)
 				printf("\n");
 		} else {
-			traceRuleStart(rule, "Evaluating to ");
+			CALL2(traceRuleStart, rule, "Evaluating to ")
 		}
 	}
 }
@@ -126,12 +126,12 @@ static void traceRuleResult(int rule, bool result) {
 }
 
 /*----------------------------------------------------------------------*/
-static void traceRuleExecution(int rule) {
+static void traceRuleExecution(CONTEXT, int rule) {
 	if (traceSectionOption) {
 		if (!traceInstructionOption && !traceSourceOption)
 			printf(", Executing:>\n");
 		else {
-			traceRuleStart(rule, "Executing:>");
+			CALL2(traceRuleStart, rule, "Executing:>")
 			if (!traceInstructionOption)
 				printf("\n");
 		}
@@ -141,8 +141,9 @@ static void traceRuleExecution(int rule) {
 
 
 /*----------------------------------------------------------------------*/
-static void evaluateRulesPreBeta2(void) {
+static void evaluateRulesPreBeta2(CONTEXT) {
 	bool change = TRUE;
+	bool flag;
 	int i;
 
 	for (i = 1; !isEndOfArray(&rules[i - 1]); i++)
@@ -152,12 +153,13 @@ static void evaluateRulesPreBeta2(void) {
 		change = FALSE;
 		for (i = 1; !isEndOfArray(&rules[i - 1]); i++)
 			if (!rules[i - 1].alreadyRun) {
-				traceRuleEvaluation(i);
-				if (evaluate(rules[i - 1].exp)) {
+				CALL1(traceRuleEvaluation, i)
+				FUNC1(evaluate, flag, rules[i - 1].exp)
+				if (flag) {
 					change = TRUE;
 					rules[i - 1].alreadyRun = TRUE;
-					traceRuleExecution(i);
-					interpret(rules[i - 1].stms);
+					CALL1(traceRuleExecution, i)
+					CALL1(interpret, rules[i - 1].stms)
 				} else if (traceSectionOption && !traceInstructionOption)
 					printf(":>\n");
 			}
@@ -168,8 +170,9 @@ static void evaluateRulesPreBeta2(void) {
 /*----------------------------------------------------------------------*/
 /* This is how beta2 thought rules should be evaluated:
  */
-static void evaluateRulesBeta2(void) {
+static void evaluateRulesBeta2(CONTEXT) {
 	bool change = TRUE;
+	bool triggered;
 	int i;
 
 	for (i = 1; !isEndOfArray(&rules[i - 1]); i++)
@@ -182,14 +185,15 @@ static void evaluateRulesBeta2(void) {
 		change = FALSE;
 		for (i = 1; !isEndOfArray(&rules[i - 1]); i++)
 			if (!rules[i - 1].alreadyRun) {
-				traceRuleEvaluation(i);
-				bool triggered = evaluate(rules[i - 1].exp);
+				CALL1(traceRuleEvaluation, i)
+				FUNC1(evaluate, triggered, rules[i - 1].exp)
+
 				if (triggered) {
 					if (rulesAdmin[i - 1].lastEval == false) {
 						change = TRUE;
 						rules[i - 1].alreadyRun = TRUE;
-						traceRuleExecution(i);
-						interpret(rules[i - 1].stms);
+						CALL1(traceRuleExecution, i)
+						CALL1(interpret, rules[i - 1].stms)
 					}
 					rulesAdmin[i - 1].lastEval = triggered;
 				} else {
@@ -212,8 +216,9 @@ void resetRules() {
 
 
 /*======================================================================*/
-void evaluateRules(RuleEntry ruleList[]) {
+void evaluateRules(CONTEXT, RuleEntry ruleList[]) {
 	bool change = TRUE;
+	bool evaluated_value;
 	int rule;
 
 	current.location = NOWHERE;
@@ -222,14 +227,15 @@ void evaluateRules(RuleEntry ruleList[]) {
 	while (change) {
 		change = FALSE;
 		for (rule = 1; !isEndOfArray(&ruleList[rule - 1]); rule++) {
-			traceRuleEvaluation(rule);
-			bool evaluated_value = evaluate(ruleList[rule - 1].exp);
+			CALL1(traceRuleEvaluation, rule)
+			FUNC1(evaluate, evaluated_value, ruleList[rule - 1].exp)
 			traceRuleResult(rule, evaluated_value);
+
 			if (evaluated_value == true && rulesAdmin[rule - 1].lastEval == false
 			        && !rulesAdmin[rule - 1].alreadyRun) {
 				change = TRUE;
-				traceRuleExecution(rule);
-				interpret(ruleList[rule - 1].stms);
+				CALL1(traceRuleExecution, rule)
+				CALL1(interpret, ruleList[rule - 1].stms)
 				rulesAdmin[rule - 1].alreadyRun = TRUE;
 				anyRuleRun = TRUE;
 			} else {
@@ -243,14 +249,14 @@ void evaluateRules(RuleEntry ruleList[]) {
 
 
 /*=======================================================================*/
-void resetAndEvaluateRules(RuleEntry ruleList[], const byte *version) {
+void resetAndEvaluateRules(CONTEXT, RuleEntry ruleList[], const byte *version) {
 	if (isPreBeta2(version))
-		evaluateRulesPreBeta2();
+		evaluateRulesPreBeta2(context);
 	else if (isPreBeta3(version))
-		evaluateRulesBeta2();
+		evaluateRulesBeta2(context);
 	else {
 		resetRules();
-		evaluateRules(ruleList);
+		evaluateRules(context, ruleList);
 	}
 }
 
diff --git a/engines/glk/alan3/rules.h b/engines/glk/alan3/rules.h
index 65291a0..abb5a2b 100644
--- a/engines/glk/alan3/rules.h
+++ b/engines/glk/alan3/rules.h
@@ -25,6 +25,7 @@
 
 /* Header file for rules handler in Alan interpreter */
 
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/acode.h"
 
 namespace Glk {
@@ -36,9 +37,9 @@ extern bool anyRuleRun;       /* Did any rule run? */
 
 /* FUNCTIONS */
 extern void initRules(Aaddr rulesTableAddress);
-extern void resetAndEvaluateRules(RuleEntry rules[], const byte *version);
+extern void resetAndEvaluateRules(CONTEXT, RuleEntry rules[], const byte *version);
 extern void resetRules(void);
-extern void evaluateRules(RuleEntry rules[]);
+extern void evaluateRules(CONTEXT, RuleEntry rules[]);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/save.cpp b/engines/glk/alan3/save.cpp
index 0d33ea6..935d08f 100644
--- a/engines/glk/alan3/save.cpp
+++ b/engines/glk/alan3/save.cpp
@@ -214,57 +214,62 @@ static void restoreCurrentValues(Common::SeekableReadStream *saveFile) {
 
 
 /*----------------------------------------------------------------------*/
-static void verifyGameId(Common::SeekableReadStream *saveFile) {
+static void verifyGameId(CONTEXT, Common::SeekableReadStream *saveFile) {
 	Aword savedUid = saveFile->readUint32LE();
 	if (!ignoreErrorOption && savedUid != header->uid)
-		error(M_SAVEVERS);
+		error(context, M_SAVEVERS);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void verifyGameName(Common::SeekableReadStream *saveFile) {
+static void verifyGameName(CONTEXT, Common::SeekableReadStream *saveFile) {
 	char savedName[256];
 	int i = 0;
 
 	while ((savedName[i++] = saveFile->readByte()) != '\0');
 	if (strcmp(savedName, adventureName) != 0)
-		error(M_SAVENAME);
+		error(context, M_SAVENAME);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void verifyCompilerVersion(Common::SeekableReadStream *saveFile) {
+static void verifyCompilerVersion(CONTEXT, Common::SeekableReadStream *saveFile) {
 	char savedVersion[4];
 
 	saveFile->read(&savedVersion, 4);
 	if (!ignoreErrorOption && memcmp(savedVersion, header->version, 4))
-		error(M_SAVEVERS);
+		error(context, M_SAVEVERS);
 }
 
 
 /*----------------------------------------------------------------------*/
-static void verifySaveFile(Common::SeekableReadStream *saveFile) {
+static void verifySaveFile(CONTEXT, Common::SeekableReadStream *saveFile) {
 	char string[5];
 	saveFile->read(string, 4);
 	string[4] = '\0';
 
 	if (strcmp(string, "ASAV") != 0)
-		error(M_NOTASAVEFILE);
+		error(context, M_NOTASAVEFILE);
 }
 
 
 /*----------------------------------------------------------------------*/
-void restoreGame(Common::SeekableReadStream *saveFile) {
-	verifySaveFile(saveFile);
+bool restoreGame(Common::SeekableReadStream *saveFile) {
+	Context ctx;
+	verifySaveFile(ctx, saveFile);
+	if (ctx._break) return false;
 
-	/* Verify version of compiler/interpreter of saved game with us */
-	verifyCompilerVersion(saveFile);
+	// Verify version of compiler/interpreter of saved game with us
+	verifyCompilerVersion(ctx, saveFile);
+	if (ctx._break) return false;
 
-	/* Verify name of game */
-	verifyGameName(saveFile);
+	// Verify name of game 
+	verifyGameName(ctx, saveFile);
+	if (ctx._break) return false;
 
-	/* Verify unique id of game */
-	verifyGameId(saveFile);
+	// Verify unique id of game
+	verifyGameId(ctx, saveFile);
+	if (ctx._break) return false;
 
 	restoreCurrentValues(saveFile);
 	restoreAttributeArea(saveFile);
@@ -273,6 +278,8 @@ void restoreGame(Common::SeekableReadStream *saveFile) {
 	restoreScores(saveFile);
 	restoreStrings(saveFile);
 	restoreSets(saveFile);
+
+	return true;
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/save.h b/engines/glk/alan3/save.h
index e4b00f6..dbcf290 100644
--- a/engines/glk/alan3/save.h
+++ b/engines/glk/alan3/save.h
@@ -29,7 +29,7 @@ namespace Glk {
 namespace Alan3 {
 
 extern void saveGame(Common::WriteStream *saveFile);
-extern void restoreGame(Common::SeekableReadStream *saveFile);
+extern bool restoreGame(Common::SeekableReadStream *saveFile);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 6785b2a..6d1e7d4 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -59,7 +59,7 @@ void forceNewPlayerInput() {
 
 
 /*----------------------------------------------------------------------*/
-static void unknown(char tok[]) {
+static void unknown(CONTEXT, char tok[]) {
 	char *str = strdup(tok);
 	Parameter *messageParameters = newParameterArray();
 
@@ -67,7 +67,7 @@ static void unknown(char tok[]) {
 	printMessageWithParameters(M_UNKNOWN_WORD, messageParameters);
 	deallocate(messageParameters);
 	free(str);
-	abortPlayerCommand();
+	CALL0(abortPlayerCommand)
 }
 
 
@@ -81,7 +81,7 @@ static int number(char tok[]) {
 
 
 /*----------------------------------------------------------------------*/
-static int lookup(char wrd[]) {
+static int lookup(CONTEXT, char wrd[]) {
 	int i;
 
 	for (i = 0; !isEndOfArray(&dictionary[i]); i++) {
@@ -89,7 +89,7 @@ static int lookup(char wrd[]) {
 			return (i);
 		}
 	}
-	unknown(wrd);
+	R0CALL1(unknown, wrd)
 	return (int)EOD;
 }
 
@@ -137,22 +137,21 @@ static char *gettoken(char *txtBuf) {
 static void getLine(CONTEXT) {
 	para();
 	do {
-		statusline();
+		CALL0(statusline)
+
 		if (header->prompt) {
 			anyOutput = FALSE;
-			interpret(header->prompt);
+			CALL1(interpret, header->prompt)
+
 			if (anyOutput)
 				printAndLog(" ");
 			needSpace = FALSE;
 		} else
 			printAndLog("> ");
 
-		if (!readline(buf)) {
-			if (g_vm->shouldQuit()) {
-				context._break = true;
-				return;
-			}
-
+		bool flag;
+		FUNC2(readline, flag, buf, 255);
+		if (!flag) {
 			newline();
 			quitGame();
 		}
@@ -175,12 +174,13 @@ static void getLine(CONTEXT) {
 		if (token != NULL) {
 			if (strcmp("debug", token) == 0 && header->debug) {
 				debugOption = TRUE;
-				debug(FALSE, 0, 0);
+				CALL3(debug, FALSE, 0, 0)
+
 				token = NULL;
 			} else if (strcmp("undo", token) == 0) {
 				token = gettoken(NULL);
 				if (token != NULL) /* More tokens? */
-					error(M_WHAT);
+					CALL1(error, M_WHAT)
 				undo();
 			}
 		}
@@ -215,7 +215,7 @@ void scan(CONTEXT) {
 		playerWords[i].start = token;
 		playerWords[i].end = strchr(token, '\0');
 		if (isISOLetter(token[0])) {
-			w = lookup(token);
+			FUNC1(lookup, w, token);
 			if (!isNoise(w))
 				playerWords[i++].code = w;
 		} else if (isdigit((int)token[0]) || token[0] == '\"') {
@@ -236,7 +236,7 @@ void scan(CONTEXT) {
 			eol = TRUE;
 			break;
 		} else
-			unknown(token);
+			CALL1(unknown, token)
 		setEndOfArray(&playerWords[i]);
 		eol = (token = gettoken(NULL)) == NULL;
 	} while (!eol);
diff --git a/engines/glk/alan3/syntax.cpp b/engines/glk/alan3/syntax.cpp
index 940c1ff..a3c44c6 100644
--- a/engines/glk/alan3/syntax.cpp
+++ b/engines/glk/alan3/syntax.cpp
@@ -69,7 +69,7 @@ static SyntaxEntry *findSyntaxEntry(int verbCode) {
 
 
 /*======================================================================*/
-SyntaxEntry *findSyntaxTreeForVerb(int verbCode) {
+SyntaxEntry *findSyntaxTreeForVerb(CONTEXT, int verbCode) {
 	SyntaxEntry *foundStx = NULL;
 	if (isPreBeta2(header->version)) {
 		foundStx = findSyntaxEntryForPreBeta2(verbCode, foundStx);
@@ -77,8 +77,8 @@ SyntaxEntry *findSyntaxTreeForVerb(int verbCode) {
 		foundStx = findSyntaxEntry(verbCode);
 	}
 	if (foundStx == NULL)
-		/* No matching syntax */
-		error(M_WHAT);
+		// No matching syntax
+		R0CALL1(error, M_WHAT)
 	return foundStx;
 }
 
diff --git a/engines/glk/alan3/syntax.h b/engines/glk/alan3/syntax.h
index de7e484..8aebc23 100644
--- a/engines/glk/alan3/syntax.h
+++ b/engines/glk/alan3/syntax.h
@@ -24,6 +24,7 @@
 #define GLK_ALAN3_SYNTAX
 
 #include "glk/alan3/types.h"
+#include "glk/alan3/jumps.h"
 #include "glk/alan3/memory.h"
 
 namespace Glk {
@@ -36,7 +37,7 @@ extern SyntaxEntry *stxs;   /* Syntax table pointer */
 /* FUNCTIONS */
 extern ElementEntry *elementTreeOf(SyntaxEntry *stx);
 extern char *parameterNameInSyntax(int syntaxNumber, int parameterNumber);
-extern SyntaxEntry *findSyntaxTreeForVerb(int verbCode);
+extern SyntaxEntry *findSyntaxTreeForVerb(CONTEXT, int verbCode);
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/term.cpp b/engines/glk/alan3/term.cpp
index 86c6036..37f709e 100644
--- a/engines/glk/alan3/term.cpp
+++ b/engines/glk/alan3/term.cpp
@@ -48,7 +48,7 @@ void getPageSize(void) {
 }
 
 /*======================================================================*/
-void statusline(void) {
+void statusline(CONTEXT) {
 	uint32 glkWidth;
 	char line[100];
 	int pcol = col;
@@ -64,7 +64,7 @@ void statusline(void) {
 	onStatusLine = TRUE;
 	col = 1;
 	g_vm->glk_window_move_cursor(glkStatusWin, 1, 0);
-	sayInstance(where(HERO, /*TRUE*/ TRANSITIVE));
+	CALL1(sayInstance, where(HERO, /*TRUE*/ TRANSITIVE))
 
 	// TODO Add status message1  & 2 as author customizable messages
 	if (header->maximumScore > 0)
diff --git a/engines/glk/alan3/term.h b/engines/glk/alan3/term.h
index df19a63..1f6dadc 100644
--- a/engines/glk/alan3/term.h
+++ b/engines/glk/alan3/term.h
@@ -25,6 +25,8 @@
 
 /* Header file for terminal functions in ARUN, the Alan interpreter */
 
+#include "glk/alan3/jumps.h"
+
 namespace Glk {
 namespace Alan3 {
 
@@ -33,7 +35,7 @@ extern bool onStatusLine;
 
 /* FUNCTIONS */
 extern void getPageSize();
-extern void statusline();
+extern void statusline(CONTEXT);
 
 } // End of namespace Alan3
 } // End of namespace Glk


Commit: 6a4931106dfa426b8fc59f3ef871bd8b5e25b2db
    https://github.com/scummvm/scummvm/commit/6a4931106dfa426b8fc59f3ef871bd8b5e25b2db
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Wrap playererr and terminate methods in context

Changed paths:
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/glkstart.cpp
    engines/glk/alan3/glkstart.h
    engines/glk/alan3/main.cpp
    engines/glk/alan3/syserr.cpp
    engines/glk/alan3/syserr.h
    engines/glk/alan3/utils.cpp
    engines/glk/alan3/utils.h


diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index 84f9e07..ec28d30 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -1070,7 +1070,7 @@ void debug(CONTEXT, bool calledFromBreakpoint, int line, int fileNumber) {
 			handleObjectsCommand(context);
 			break;
 		case QUIT_COMMAND:
-			terminate(0);
+			CALL1(terminate, 0)
 			break;
 		case SECTION_TRACE_COMMAND:
 			toggleSectionTrace();
diff --git a/engines/glk/alan3/glkstart.cpp b/engines/glk/alan3/glkstart.cpp
index f5f91a5..84a891c 100644
--- a/engines/glk/alan3/glkstart.cpp
+++ b/engines/glk/alan3/glkstart.cpp
@@ -45,71 +45,5 @@ const glkunix_argumentlist_t glkunix_arguments[] = {
 	{ NULL, glkunix_arg_End, NULL }
 };
 
-/* Resources */
-static strid_t resourceFile;
-
-/*----------------------------------------------------------------------*/
-static void openGlkWindows() {
-	glkMainWin = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
-	if (glkMainWin == NULL) {
-		printf("FATAL ERROR: Cannot open initial window");
-		g_vm->glk_exit();
-	}
-
-	glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
-	                                     winmethod_Fixed, 1, wintype_TextGrid, 0);
-	g_vm->glk_set_window(glkStatusWin);
-	g_vm->glk_set_style(style_Preformatted);
-	g_vm->glk_set_window(glkMainWin);
-}
-
-/*----------------------------------------------------------------------*/
-static void openResourceFile() {
-#ifdef TODO
-	char *originalFileName = strdup(adventureFileName);
-	char *resourceFileName = originalFileName;
-	char *extension = strrchr(resourceFileName, '.');
-	frefid_t resourceFileRef;
-//    giblorb_err_t ecode;
-
-	strcpy(extension, ".a3r");
-
-	resourceFileRef = winglk_fileref_create_by_name(fileusage_BinaryMode,
-	                  resourceFileName, 0, FALSE);
-
-	if (glk_fileref_does_file_exist(resourceFileRef)) {
-		resourceFile = glk_stream_open_file(resourceFileRef, filemode_Read, 0);
-		ecode = giblorb_set_resource_map(resourceFile);
-		(void)ecode;
-	}
-	free(originalFileName);
-#endif
-}
-
-
-/*======================================================================*/
-int glkunix_startup_code(glkunix_startup_t *data) {
-	g_vm->glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Weight, 0);
-	g_vm->glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Oblique, 1);
-	g_vm->glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Indentation, 10);
-
-	/* first, open a window for error output */
-	openGlkWindows();
-
-	/* now process the command line arguments */
-	//args(data->argc, data->argv);
-
-	if (adventureFileName == NULL || strcmp(adventureFileName, "") == 0) {
-		printf("You should supply a game file to play.\n");
-		usage("arun"); // TODO Find real programname from arguments
-		terminate(1);
-	}
-
-	/* Open any possible blorb resource file */
-	openResourceFile();
-
-	return TRUE;
-}
-
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/glkstart.h b/engines/glk/alan3/glkstart.h
index 0d91732..004bf9c 100644
--- a/engines/glk/alan3/glkstart.h
+++ b/engines/glk/alan3/glkstart.h
@@ -73,9 +73,6 @@ struct glkunix_startup_t {
 /* The list of command-line arguments; this should be defined in your code. */
 extern const glkunix_argumentlist_t glkunix_arguments[];
 
-/* The external function; this should be defined in your code. */
-extern int glkunix_startup_code(glkunix_startup_t *data);
-
 } // End of namespace Alan3
 } // End of namespace Glk
 
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 9abba88..c32693e 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -130,11 +130,11 @@ static int crcStart(const byte version[4]) {
 
 
 /*----------------------------------------------------------------------*/
-static void readTemporaryHeader(ACodeHeader *tmphdr) {
+static void readTemporaryHeader(CONTEXT, ACodeHeader *tmphdr) {
 	codfil->seek(0);
 	if (codfil->read(&tmphdr->tag[0], sizeof(ACodeHeader)) != sizeof(ACodeHeader) ||
 			strncmp((char *)tmphdr, "ALAN", 4) != 0)
-		playererr("Not an Alan game file, does not start with \"ALAN\"");
+		playererr(context, "Not an Alan game file, does not start with \"ALAN\"");
 }
 
 
@@ -347,12 +347,12 @@ void checkVersion(ACodeHeader *hdr) {
 }
 
 /*----------------------------------------------------------------------*/
-static void load(void) {
+static void load(CONTEXT) {
 	ACodeHeader tmphdr;
 	Aword crc = 0;
 	char err[100];
 
-	readTemporaryHeader(&tmphdr);
+	CALL1(readTemporaryHeader, &tmphdr)
 	checkVersion(&tmphdr);
 
 	/* Allocate and load memory */
@@ -373,12 +373,12 @@ static void load(void) {
 
 
 /*----------------------------------------------------------------------*/
-static void checkDebug(void) {
+static void checkDebug(CONTEXT) {
 	/* Make sure he can't debug if not allowed! */
 	if (!header->debug) {
 		if (debugOption | traceSectionOption | traceInstructionOption) {
 			printf("<Sorry, '%s' is not compiled for debug! Exiting.>\n", adventureFileName);
-			terminate(0);
+			CALL1(terminate, 0)
 		}
 		para();
 		debugOption = FALSE;
@@ -600,7 +600,7 @@ static void init(CONTEXT) {
 	initStaticData();
 	initDynamicData();
 	initParsing();
-	checkDebug();
+	CALL0(checkDebug)
 
 	getPageSize();
 
@@ -748,7 +748,9 @@ void run(void) {
 	do {
 		ctx.clear();
 		openFiles();
-		load();			// Load program
+		load(ctx);			// Load program
+		if (ctx._break)
+			break;
 
 		if (theStack)
 			deleteStack(theStack);
diff --git a/engines/glk/alan3/syserr.cpp b/engines/glk/alan3/syserr.cpp
index 559f104..8a0dad5 100644
--- a/engines/glk/alan3/syserr.cpp
+++ b/engines/glk/alan3/syserr.cpp
@@ -26,6 +26,7 @@
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/output.h"
 #include "glk/alan3/utils.h"
+#include "common/textconsole.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -33,7 +34,7 @@ namespace Alan3 {
 static void (*handler)(const char *);
 
 /*----------------------------------------------------------------------*/
-static void runtimeError(const char *errorClassification, const char *errorDescription, const char *blurb) {
+static void runtimeError(CONTEXT, const char *errorClassification, const char *errorDescription, const char *blurb) {
 	output("$n$nAs you enter the twilight zone of Adventures, you stumble \
 and fall to your knees. In front of you, you can vaguely see the outlines \
 of an Adventure that never was.$n$n");
@@ -49,7 +50,11 @@ of an Adventure that never was.$n$n");
 	newline();
 	output(blurb);
 
-	terminate(2);
+	terminate(context, 2);
+}
+
+static void runtimeError(const char *errorClassification, const char *errorDescription, const char *blurb) {
+	::error("%s %s %s", errorClassification, errorDescription, blurb);
 }
 
 
@@ -90,10 +95,10 @@ If you *are* the author, then you have to figure this out before releasing the g
 }
 
 /*======================================================================*/
-void playererr(const char *description) {
+void playererr(CONTEXT, const char *description) {
 	if (handler == NULL) {
 		const char *blurb = "<You have probably done something that is not exactly right.>";
-		runtimeError("PLAYER ERROR: ", description, blurb);
+		runtimeError(context, "PLAYER ERROR: ", description, blurb);
 	} else
 		handler(description);
 }
diff --git a/engines/glk/alan3/syserr.h b/engines/glk/alan3/syserr.h
index 6112e88..fc80e72 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 "common/textconsole.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -33,7 +33,7 @@ namespace Alan3 {
 /* Functions: */
 extern void syserr(const char *msg);
 extern void apperr(const char *msg);
-extern void playererr(const char *msg);
+extern void playererr(CONTEXT, const char *msg);
 extern void setSyserrHandler(void (*handler)(const char *));
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/utils.cpp b/engines/glk/alan3/utils.cpp
index 402cbe6..38176e1 100644
--- a/engines/glk/alan3/utils.cpp
+++ b/engines/glk/alan3/utils.cpp
@@ -42,7 +42,7 @@ namespace Alan3 {
   return buffers...
 
  */
-void terminate(int code) {
+void terminate(CONTEXT, int code) {
 	newline();
 
 	terminateStateStack();
@@ -53,6 +53,7 @@ void terminate(int code) {
 		deallocate(memory);
 
 	g_vm->glk_exit();
+	LONG_JUMP
 }
 
 /*======================================================================*/
diff --git a/engines/glk/alan3/utils.h b/engines/glk/alan3/utils.h
index f103436..0c56e0a 100644
--- a/engines/glk/alan3/utils.h
+++ b/engines/glk/alan3/utils.h
@@ -26,12 +26,13 @@
 /* Utility functions for the Alan interpreter */
 
 #include "glk/alan3/types.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
 
 /* FUNCTIONS: */
-extern void terminate(int code);
+extern void terminate(CONTEXT, int code);
 extern void usage(const char *programName);
 extern void printVersion(int buildNumber);
 extern bool match(const char *pattern, char *input);


Commit: 1183dc65bb4cc50e6e1fa79cbf461c6763d46265
    https://github.com/scummvm/scummvm/commit/1183dc65bb4cc50e6e1fa79cbf461c6763d46265
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Remove deprecated glkstart.cpp

Changed paths:
  R engines/glk/alan3/glkstart.cpp
  R engines/glk/alan3/glkstart.h
    engines/glk/module.mk


diff --git a/engines/glk/alan3/glkstart.cpp b/engines/glk/alan3/glkstart.cpp
deleted file mode 100644
index 84a891c..0000000
--- a/engines/glk/alan3/glkstart.cpp
+++ /dev/null
@@ -1,49 +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/alan3/glkstart.h"
-#include "glk/alan3/alan_version.h"
-#include "glk/alan3/alan3.h"
-#include "glk/alan3/args.h"
-#include "glk/alan3/main.h"
-#include "glk/alan3/glkio.h"
-#include "glk/alan3/resources.h"
-#include "glk/alan3/utils.h"
-#include "glk/streams.h"
-
-namespace Glk {
-namespace Alan3 {
-
-const glkunix_argumentlist_t glkunix_arguments[] = {
-	{ "-l", glkunix_arg_NoValue, "-l: log player command and game output" },
-	{ "-c", glkunix_arg_NoValue, "-c: log player commands to a file" },
-	{ "-n", glkunix_arg_NoValue, "-n: no status line" },
-	{ "-i", glkunix_arg_NoValue, "-i: ignore version and checksum errors" },
-	{ "-d", glkunix_arg_NoValue, "-d: enter debug mode" },
-	{ "-t", glkunix_arg_NoValue, "-t [<n>]: trace game execution, higher <n> gives more trace" },
-	{ "-r", glkunix_arg_NoValue, "-r: refrain from printing timestamps and paging (making regression testing easier)" },
-	{ "", glkunix_arg_ValueFollows, "filename: The game file to load." },
-	{ NULL, glkunix_arg_End, NULL }
-};
-
-} // End of namespace Alan3
-} // End of namespace Glk
diff --git a/engines/glk/alan3/glkstart.h b/engines/glk/alan3/glkstart.h
deleted file mode 100644
index 004bf9c..0000000
--- a/engines/glk/alan3/glkstart.h
+++ /dev/null
@@ -1,79 +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_ALAN3_GLKSTART
-#define GLK_ALAN3_GLKSTART
-
-/* glkstart.h: Unix-specific header file for GlkTerm, CheapGlk, and XGlk
-        (Unix implementations of the Glk API).
-    Designed by Andrew Plotkin <erkyrath at netcom.com>
-    http://www.eblong.com/zarf/glk/index.html
-*/
-
-/* This header defines an interface that must be used by program linked
-    with the various Unix Glk libraries -- at least, the three I wrote.
-    (I encourage anyone writing a Unix Glk library to use this interface,
-    but it's not part of the Glk spec.)
-
-    Because Glk is *almost* perfectly portable, this interface *almost*
-    doesn't have to exist. In practice, it's small.
-*/
-
-namespace Glk {
-namespace Alan3 {
-
-/* We define our own TRUE and FALSE and NULL, because ANSI
-    is a strange world. */
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define glkunix_arg_End (0)
-#define glkunix_arg_ValueFollows (1)
-#define glkunix_arg_NoValue (2)
-#define glkunix_arg_ValueCanFollow (3)
-#define glkunix_arg_NumberValue (4)
-
-struct glkunix_argumentlist_t {
-	const char *name;
-	int argtype;
-	const char *desc;
-};
-
-struct glkunix_startup_t {
-	int argc;
-	char **argv;
-};
-
-/* The list of command-line arguments; this should be defined in your code. */
-extern const glkunix_argumentlist_t glkunix_arguments[];
-
-} // End of namespace Alan3
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 65ddd80..11b44fe 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -70,7 +70,6 @@ MODULE_OBJS := \
 	alan3/exe.o \
 	alan3/fnmatch.o \
 	alan3/glkio.o \
-	alan3/glkstart.o \
 	alan3/instance.o \
 	alan3/inter.o \
 	alan3/lists.o \


Commit: 3e9d215dd821c0f337cc6f527c2d16fdb10cbd8c
    https://github.com/scummvm/scummvm/commit/3e9d215dd821c0f337cc6f527c2d16fdb10cbd8c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Minor errors cleanup

Changed paths:
    engines/glk/alan3/syserr.cpp


diff --git a/engines/glk/alan3/syserr.cpp b/engines/glk/alan3/syserr.cpp
index 8a0dad5..6ed6d0b 100644
--- a/engines/glk/alan3/syserr.cpp
+++ b/engines/glk/alan3/syserr.cpp
@@ -54,7 +54,7 @@ of an Adventure that never was.$n$n");
 }
 
 static void runtimeError(const char *errorClassification, const char *errorDescription, const char *blurb) {
-	::error("%s %s %s", errorClassification, errorDescription, blurb);
+	::error("%s%s %s", errorClassification, errorDescription, blurb);
 }
 
 
@@ -67,8 +67,6 @@ void setSyserrHandler(void (*f)(const char *)) {
 /*======================================================================*/
 // TODO Make syserr() use ... as printf()
 void syserr(const char *description) {
-	::error("%s", description);
-#if 0
 	lin = 0;
 	if (handler == NULL) {
 		const char *blurb = "<If you are the creator of this piece of Interactive Fiction, \
@@ -78,7 +76,6 @@ it to support at alanif.se. Thank you!>";
 		runtimeError("SYSTEM ERROR: ", description, blurb);
 	} else
 		handler(description);
-#endif
 }
 
 


Commit: d185cc58946922939e41aca7c6440804c83b2fae
    https://github.com/scummvm/scummvm/commit/d185cc58946922939e41aca7c6440804c83b2fae
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Remove adventureName variable

Changed paths:
    engines/glk/alan3/args.cpp
    engines/glk/alan3/args.h
    engines/glk/alan3/save.cpp


diff --git a/engines/glk/alan3/args.cpp b/engines/glk/alan3/args.cpp
index 5ccf0fc..5a59068 100644
--- a/engines/glk/alan3/args.cpp
+++ b/engines/glk/alan3/args.cpp
@@ -32,8 +32,6 @@ namespace Glk {
 namespace Alan3 {
 
 /* PUBLIC DATA */
-/* The files and filenames */
-char *adventureName;        /* The name of the game */
 char *adventureFileName;
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
diff --git a/engines/glk/alan3/args.h b/engines/glk/alan3/args.h
index 690f675..a80c8a4 100644
--- a/engines/glk/alan3/args.h
+++ b/engines/glk/alan3/args.h
@@ -35,7 +35,6 @@ namespace Alan3 {
 #endif
 
 /* DATA */
-extern char *adventureName; /* The name of the game */
 extern char *adventureFileName;
 
 /* FUNCTIONS */
diff --git a/engines/glk/alan3/save.cpp b/engines/glk/alan3/save.cpp
index 935d08f..6e645d0 100644
--- a/engines/glk/alan3/save.cpp
+++ b/engines/glk/alan3/save.cpp
@@ -69,7 +69,6 @@ static void saveSets(Common::WriteStream *saveFile) {
 static void saveGameInfo(Common::WriteStream *saveFile) {
 	saveFile->writeUint32BE(MKTAG('A', 'S', 'A', 'V'));
 	saveFile->write(header->version, 4);
-	saveFile->write(adventureName, strlen(adventureName) + 1);
 	saveFile->writeUint32LE(header->uid);
 }
 
@@ -222,17 +221,6 @@ static void verifyGameId(CONTEXT, Common::SeekableReadStream *saveFile) {
 
 
 /*----------------------------------------------------------------------*/
-static void verifyGameName(CONTEXT, Common::SeekableReadStream *saveFile) {
-	char savedName[256];
-	int i = 0;
-
-	while ((savedName[i++] = saveFile->readByte()) != '\0');
-	if (strcmp(savedName, adventureName) != 0)
-		error(context, M_SAVENAME);
-}
-
-
-/*----------------------------------------------------------------------*/
 static void verifyCompilerVersion(CONTEXT, Common::SeekableReadStream *saveFile) {
 	char savedVersion[4];
 
@@ -263,10 +251,6 @@ bool restoreGame(Common::SeekableReadStream *saveFile) {
 	verifyCompilerVersion(ctx, saveFile);
 	if (ctx._break) return false;
 
-	// Verify name of game 
-	verifyGameName(ctx, saveFile);
-	if (ctx._break) return false;
-
 	// Verify unique id of game
 	verifyGameId(ctx, saveFile);
 	if (ctx._break) return false;


Commit: 0f0c2c97e13d01cd77ba9fb489aec77398ce6945
    https://github.com/scummvm/scummvm/commit/0f0c2c97e13d01cd77ba9fb489aec77398ce6945
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Move some Glk interface methods to glkio.cpp

Changed paths:
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/exe.h
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/glkio.h


diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index 39cec13..f30ebc2 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -67,28 +67,6 @@ bool printFlag;				// Printing already?
 
 #define WIDTH 80
 
-
-/*======================================================================*/
-void setStyle(int style) {
-	switch (style) {
-	case NORMAL_STYLE:
-		g_vm->glk_set_style(style_Normal);
-		break;
-	case EMPHASIZED_STYLE:
-		g_vm->glk_set_style(style_Emphasized);
-		break;
-	case PREFORMATTED_STYLE:
-		g_vm->glk_set_style(style_Preformatted);
-		break;
-	case ALERT_STYLE:
-		g_vm->glk_set_style(style_Alert);
-		break;
-	case QUOTE_STYLE:
-		g_vm->glk_set_style(style_BlockQuote);
-		break;
-	}
-}
-
 /*======================================================================*/
 void print(Aword fpos, Aword len) {
 	char str[2 * WIDTH];          /* String buffer */
@@ -546,37 +524,6 @@ int getContainerMember(int container, int index, bool directly) {
 
 
 /*======================================================================*/
-void showImage(int image, int align) {
-	uint ecode;
-
-	if ((g_vm->glk_gestalt(gestalt_Graphics, 0) == 1) &&
-	        (g_vm->glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
-		g_vm->glk_window_flow_break(glkMainWin);
-		printf("\n");
-		ecode = g_vm->glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
-		(void)ecode;
-	}
-}
-
-
-/*======================================================================*/
-void playSound(int sound) {
-#ifdef GLK_MODULE_SOUND
-	static schanid_t soundChannel = NULL;
-
-	if (g_vm->glk_gestalt(gestalt_Sound, 0) == 1) {
-		if (soundChannel == NULL)
-			soundChannel = g_vm->glk_schannel_create(0);
-		if (soundChannel != NULL) {
-			g_vm->glk_schannel_stop(soundChannel);
-			(void)g_vm->glk_schannel_play(soundChannel, sound);
-		}
-	}
-#endif
-}
-
-
-/*======================================================================*/
 void empty(CONTEXT, int cnt, int whr) {
 	uint i;
 
diff --git a/engines/glk/alan3/exe.h b/engines/glk/alan3/exe.h
index a039d6f..79e7720 100644
--- a/engines/glk/alan3/exe.h
+++ b/engines/glk/alan3/exe.h
@@ -59,9 +59,6 @@ extern Aptr strip(bool stripFromBeginningNotEnd, int count, bool stripWordsNotCh
 extern Aptr concat(Aptr s1, Aptr s2);
 extern char *getStringFromFile(Aword fpos, Aword len);
 extern void print(Aword fpos, Aword len);
-extern void setStyle(int style);
-extern void showImage(int image, int align);
-extern void playSound(int sound);
 extern void score(Aword sc);
 extern void visits(Aword v);
 extern void undo(void);
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index 4d0963b..6cc264f 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -22,6 +22,7 @@
 
 #include "glk/alan3/alan3.h"
 #include "glk/alan3/glkio.h"
+#include "glk/alan3/acode.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -49,5 +50,52 @@ void glkio_printf(const char *fmt, ...) {
 	va_end(argp);
 }
 
+void showImage(int image, int align) {
+	uint ecode;
+
+	if ((g_vm->glk_gestalt(gestalt_Graphics, 0) == 1) &&
+		(g_vm->glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
+		g_vm->glk_window_flow_break(glkMainWin);
+		printf("\n");
+		ecode = g_vm->glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
+		(void)ecode;
+	}
+}
+
+void playSound(int sound) {
+#ifdef GLK_MODULE_SOUND
+	static schanid_t soundChannel = NULL;
+
+	if (g_vm->glk_gestalt(gestalt_Sound, 0) == 1) {
+		if (soundChannel == NULL)
+			soundChannel = g_vm->glk_schannel_create(0);
+		if (soundChannel != NULL) {
+			g_vm->glk_schannel_stop(soundChannel);
+			(void)g_vm->glk_schannel_play(soundChannel, sound);
+		}
+	}
+#endif
+}
+
+void setStyle(int style) {
+	switch (style) {
+	case NORMAL_STYLE:
+		g_vm->glk_set_style(style_Normal);
+		break;
+	case EMPHASIZED_STYLE:
+		g_vm->glk_set_style(style_Emphasized);
+		break;
+	case PREFORMATTED_STYLE:
+		g_vm->glk_set_style(style_Preformatted);
+		break;
+	case ALERT_STYLE:
+		g_vm->glk_set_style(style_Alert);
+		break;
+	case QUOTE_STYLE:
+		g_vm->glk_set_style(style_BlockQuote);
+		break;
+	}
+}
+
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index b77e659..32ce758 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -23,8 +23,6 @@
 #ifndef GLK_ALAN3_GLKIO
 #define GLK_ALAN3_GLKIO
 
-/* Header file for Glk output for Alan interpreter */
-
 #include "glk/alan3/alan3.h"
 #include "glk/windows.h"
 
@@ -34,12 +32,16 @@ namespace Alan3 {
 extern winid_t glkMainWin;
 extern winid_t glkStatusWin;
 
-/* NB: this header must be included in any file which calls printf() */
-
 #undef printf
 #define printf glkio_printf
 extern void glkio_printf(const char *, ...);
 
+extern void showImage(int image, int align);
+
+extern void playSound(int sound);
+
+extern void setStyle(int style);
+
 } // End of namespace Alan3
 } // End of namespace Glk
 


Commit: efdf25b3d28113b01e18ef0c69221194a1100e9e
    https://github.com/scummvm/scummvm/commit/efdf25b3d28113b01e18ef0c69221194a1100e9e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Move term.cpp code into glkio.cpp

Changed paths:
  R engines/glk/alan3/term.cpp
  R engines/glk/alan3/term.h
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/glkio.h
    engines/glk/alan3/main.cpp
    engines/glk/alan3/output.cpp
    engines/glk/alan3/output.h
    engines/glk/alan3/parse.cpp
    engines/glk/alan3/readline.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/module.mk


diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index f30ebc2..e2555f5 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -41,7 +41,6 @@
 #include "glk/alan3/state.h"
 #include "glk/alan3/syserr.h"
 #include "glk/alan3/sysdep.h"
-#include "glk/alan3/term.h"
 #include "glk/alan3/types.h"
 #include "glk/alan3/utils.h"
 #include "glk/alan3/word.h"
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index 6cc264f..f36c396 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -20,15 +20,19 @@
  *
  */
 
-#include "glk/alan3/alan3.h"
 #include "glk/alan3/glkio.h"
 #include "glk/alan3/acode.h"
+#include "glk/alan3/current.h"
+#include "glk/alan3/instance.h"
+#include "glk/alan3/options.h"
+#include "glk/alan3/output.h"
 
 namespace Glk {
 namespace Alan3 {
 
 winid_t glkMainWin;
 winid_t glkStatusWin;
+bool onStatusLine;
 
 void glkio_printf(const char *fmt, ...) {
 	// If there's a savegame being loaded from the launcher, ignore any text out
@@ -97,5 +101,38 @@ void setStyle(int style) {
 	}
 }
 
+void statusline(CONTEXT) {
+	uint32 glkWidth;
+	char line[100];
+	int pcol = col;
+
+	if (!statusLineOption) return;
+	if (glkStatusWin == NULL)
+		return;
+
+	g_vm->glk_set_window(glkStatusWin);
+	g_vm->glk_window_clear(glkStatusWin);
+	g_vm->glk_window_get_size(glkStatusWin, &glkWidth, NULL);
+
+	onStatusLine = TRUE;
+	col = 1;
+	g_vm->glk_window_move_cursor(glkStatusWin, 1, 0);
+	CALL1(sayInstance, where(HERO, /*TRUE*/ TRANSITIVE))
+
+		// TODO Add status message1  & 2 as author customizable messages
+		if (header->maximumScore > 0)
+			sprintf(line, "Score %d(%d)/%d moves", current.score, (int)header->maximumScore, current.tick);
+		else
+			sprintf(line, "%d moves", current.tick);
+	g_vm->glk_window_move_cursor(glkStatusWin, glkWidth - strlen(line) - 1, 0);
+	g_vm->glk_put_string(line);
+	needSpace = FALSE;
+
+	col = pcol;
+	onStatusLine = FALSE;
+
+	g_vm->glk_set_window(glkMainWin);
+}
+
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index 32ce758..b0629ce 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -24,6 +24,7 @@
 #define GLK_ALAN3_GLKIO
 
 #include "glk/alan3/alan3.h"
+#include "glk/alan3/jumps.h"
 #include "glk/windows.h"
 
 namespace Glk {
@@ -31,6 +32,7 @@ namespace Alan3 {
 
 extern winid_t glkMainWin;
 extern winid_t glkStatusWin;
+extern bool onStatusLine;
 
 #undef printf
 #define printf glkio_printf
@@ -42,6 +44,8 @@ extern void playSound(int sound);
 
 extern void setStyle(int style);
 
+extern void statusline(CONTEXT);
+
 } // End of namespace Alan3
 } // End of namespace Glk
 
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index c32693e..de65b09 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -51,7 +51,6 @@
 #include "glk/alan3/state.h"
 #include "glk/alan3/syserr.h"
 #include "glk/alan3/syntax.h"
-#include "glk/alan3/term.h"
 #include "glk/alan3/utils.h"
 
 namespace Glk {
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index aa699c9..15d4ff4 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -27,7 +27,6 @@
 #include "glk/alan3/memory.h"
 #include "glk/alan3/word.h"
 #include "glk/alan3/lists.h"
-#include "glk/alan3/term.h"
 #include "glk/alan3/syserr.h"
 #include "glk/alan3/dictionary.h"
 #include "glk/alan3/current.h"
@@ -55,6 +54,18 @@ strid_t logFile;
 
 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 
+/*
+  getPageSize()
+
+  Try to get the current page size from the system, else use the ones
+  from the header.
+
+ */
+void getPageSize(void) {
+	pageLength = 0;
+	pageWidth = 0;
+}
+
 
 /*----------------------------------------------------------------------*/
 static int updateColumn(int currentColumn, const char *string) {
diff --git a/engines/glk/alan3/output.h b/engines/glk/alan3/output.h
index 6f52cfc..fc34490 100644
--- a/engines/glk/alan3/output.h
+++ b/engines/glk/alan3/output.h
@@ -42,6 +42,7 @@ extern bool skipSpace;
 extern strid_t logFile;
 
 /* FUNCTIONS */
+extern void getPageSize();
 extern void setSubHeaderStyle(void);
 extern void setNormalStyle(void);
 extern void newline(void);
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp
index 6618e9d..efa5464 100644
--- a/engines/glk/alan3/parse.cpp
+++ b/engines/glk/alan3/parse.cpp
@@ -43,7 +43,6 @@
 #include "glk/alan3/syntax.h"
 #include "glk/alan3/scan.h"
 #include "glk/alan3/syserr.h"
-#include "glk/alan3/term.h"
 #include "glk/alan3/utils.h"
 #include "glk/alan3/word.h"
 
diff --git a/engines/glk/alan3/readline.cpp b/engines/glk/alan3/readline.cpp
index 832f00d..7be20c7 100644
--- a/engines/glk/alan3/readline.cpp
+++ b/engines/glk/alan3/readline.cpp
@@ -24,7 +24,6 @@
 
 #include "glk/alan3/sysdep.h"
 #include "glk/alan3/output.h"
-#include "glk/alan3/term.h"
 #include "glk/alan3/exe.h"
 #include "glk/alan3/save.h"
 #include "glk/alan3/location.h"
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 6d1e7d4..6cc1ef9 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -35,7 +35,6 @@
 #include "glk/alan3/params.h"
 #include "glk/alan3/readline.h"
 #include "glk/alan3/syserr.h"
-#include "glk/alan3/term.h"
 #include "glk/alan3/word.h"
 
 namespace Glk {
diff --git a/engines/glk/alan3/term.cpp b/engines/glk/alan3/term.cpp
deleted file mode 100644
index 37f709e..0000000
--- a/engines/glk/alan3/term.cpp
+++ /dev/null
@@ -1,85 +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/alan3/current.h"
-#include "glk/alan3/glkio.h"
-#include "glk/alan3/instance.h"
-#include "glk/alan3/memory.h"
-#include "glk/alan3/output.h"
-#include "glk/alan3/options.h"
-#include "glk/alan3/sysdep.h"
-
-namespace Glk {
-namespace Alan3 {
-
-/* PUBLIC DATA */
-bool onStatusLine = FALSE; /* To know if where printing the status line or not */
-
-/*======================================================================
-
-  getPageSize()
-
-  Try to get the current page size from the system, else use the ones
-  from the header.
-
- */
-void getPageSize(void) {
-	pageLength = 0;
-	pageWidth = 0;
-}
-
-/*======================================================================*/
-void statusline(CONTEXT) {
-	uint32 glkWidth;
-	char line[100];
-	int pcol = col;
-
-	if (!statusLineOption) return;
-	if (glkStatusWin == NULL)
-		return;
-
-	g_vm->glk_set_window(glkStatusWin);
-	g_vm->glk_window_clear(glkStatusWin);
-	g_vm->glk_window_get_size(glkStatusWin, &glkWidth, NULL);
-
-	onStatusLine = TRUE;
-	col = 1;
-	g_vm->glk_window_move_cursor(glkStatusWin, 1, 0);
-	CALL1(sayInstance, where(HERO, /*TRUE*/ TRANSITIVE))
-
-	// TODO Add status message1  & 2 as author customizable messages
-	if (header->maximumScore > 0)
-		sprintf(line, "Score %d(%d)/%d moves", current.score, (int)header->maximumScore, current.tick);
-	else
-		sprintf(line, "%d moves", current.tick);
-	g_vm->glk_window_move_cursor(glkStatusWin, glkWidth - strlen(line) - 1, 0);
-	g_vm->glk_put_string(line);
-	needSpace = FALSE;
-
-	col = pcol;
-	onStatusLine = FALSE;
-
-	g_vm->glk_set_window(glkMainWin);
-}
-
-} // End of namespace Alan3
-} // End of namespace Glk
diff --git a/engines/glk/alan3/term.h b/engines/glk/alan3/term.h
deleted file mode 100644
index 1f6dadc..0000000
--- a/engines/glk/alan3/term.h
+++ /dev/null
@@ -1,43 +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_ALAN3_TERM
-#define GLK_ALAN3_TERM
-
-/* Header file for terminal functions in ARUN, the Alan interpreter */
-
-#include "glk/alan3/jumps.h"
-
-namespace Glk {
-namespace Alan3 {
-
-/* DATA */
-extern bool onStatusLine;
-
-/* FUNCTIONS */
-extern void getPageSize();
-extern void statusline(CONTEXT);
-
-} // End of namespace Alan3
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 11b44fe..3d3c62b 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -96,7 +96,6 @@ MODULE_OBJS := \
 	alan3/syntax.o \
 	alan3/sysdep.o \
 	alan3/syserr.o \
-	alan3/term.o \
 	alan3/types.o \
 	alan3/utils.o \
 	alan3/word.o \


Commit: b634a97f41877b233a654dc204a2c9760f9ad2f6
    https://github.com/scummvm/scummvm/commit/b634a97f41877b233a654dc204a2c9760f9ad2f6
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Move readline.cpp into glkio.cpp

Changed paths:
  R engines/glk/alan3/readline.cpp
  R engines/glk/alan3/readline.h
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/glkio.h
    engines/glk/alan3/output.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/module.mk


diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index ec28d30..94f5bb4 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -36,7 +36,6 @@
 #include "glk/alan3/memory.h"
 #include "glk/alan3/options.h"
 #include "glk/alan3/output.h"
-#include "glk/alan3/readline.h"
 #include "glk/alan3/sysdep.h"
 #include "glk/alan3/utils.h"
 #include "glk/streams.h"
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index e2555f5..499eaee 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -35,7 +35,6 @@
 #include "glk/alan3/msg.h"
 #include "glk/alan3/output.h"
 #include "glk/alan3/options.h"
-#include "glk/alan3/readline.h"
 #include "glk/alan3/save.h"
 #include "glk/alan3/score.h"
 #include "glk/alan3/state.h"
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index f36c396..ccf2a67 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -134,5 +134,64 @@ void statusline(CONTEXT) {
 	g_vm->glk_set_window(glkMainWin);
 }
 
+
+/*======================================================================
+
+  readline()
+
+  Read a line from the user, with history and editing
+
+*/
+
+/* TODO - length of user buffer should be used */
+bool readline(CONTEXT, char *buffer, size_t maxLen) {
+	event_t event;
+	static bool readingCommands = FALSE;
+	static frefid_t commandFileRef;
+	static strid_t commandFile;
+
+	if (readingCommands) {
+		if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) == 0) {
+			g_vm->glk_stream_close(commandFile, NULL);
+			readingCommands = FALSE;
+		} else {
+			g_vm->glk_set_style(style_Input);
+			printf(buffer);
+			g_vm->glk_set_style(style_Normal);
+		}
+	} else {
+		g_vm->glk_request_line_event(glkMainWin, buffer, maxLen, 0);
+
+		do {
+			g_vm->glk_select(&event);
+			if (g_vm->shouldQuit())
+				LONG_JUMP0
+
+			switch (event.type) {
+			case evtype_Arrange:
+				R0CALL0(statusline)
+				break;
+
+			default:
+				break;
+			}
+		} while (event.type != evtype_LineInput);
+		if (buffer[0] == '@') {
+			buffer[event.val1] = 0;
+			commandFileRef = g_vm->glk_fileref_create_by_name(fileusage_InputRecord + fileusage_TextMode, &buffer[1], 0);
+			commandFile = g_vm->glk_stream_open_file(commandFileRef, filemode_Read, 0);
+			if (commandFile != NULL)
+				if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) != 0) {
+					readingCommands = TRUE;
+					g_vm->glk_set_style(style_Input);
+					printf(buffer);
+					g_vm->glk_set_style(style_Normal);
+				}
+		} else
+			buffer[event.val1] = 0;
+	}
+	return TRUE;
+}
+
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index b0629ce..8876aec 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -46,6 +46,8 @@ extern void setStyle(int style);
 
 extern void statusline(CONTEXT);
 
+extern bool readline(CONTEXT, char *usrBuf, size_t maxLen);
+
 } // End of namespace Alan3
 } // End of namespace Glk
 
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index 15d4ff4..405ca2e 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -31,7 +31,6 @@
 #include "glk/alan3/dictionary.h"
 #include "glk/alan3/current.h"
 #include "glk/alan3/msg.h"
-#include "glk/alan3/readline.h"
 #include "glk/alan3/sysdep.h"
 #include "glk/alan3/instance.h"
 
diff --git a/engines/glk/alan3/readline.cpp b/engines/glk/alan3/readline.cpp
deleted file mode 100644
index 7be20c7..0000000
--- a/engines/glk/alan3/readline.cpp
+++ /dev/null
@@ -1,100 +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/alan3/readline.h"
-
-#include "glk/alan3/sysdep.h"
-#include "glk/alan3/output.h"
-#include "glk/alan3/exe.h"
-#include "glk/alan3/save.h"
-#include "glk/alan3/location.h"
-
-#include "glk/alan3/options.h"
-#include "glk/alan3/alan3.h"
-#include "glk/alan3/glkio.h"
-#include "glk/alan3/resources.h"
-
-namespace Glk {
-namespace Alan3 {
-
-#define LINELENGTH 1000
-
-/*======================================================================
-
-  readline()
-
-  Read a line from the user, with history and editing
-
-*/
-
-/* TODO - length of user buffer should be used */
-bool readline(CONTEXT, char *buffer, size_t maxLen) {
-	event_t event;
-	static bool readingCommands = FALSE;
-	static frefid_t commandFileRef;
-	static strid_t commandFile;
-
-	if (readingCommands) {
-		if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) == 0) {
-			g_vm->glk_stream_close(commandFile, NULL);
-			readingCommands = FALSE;
-		} else {
-			g_vm->glk_set_style(style_Input);
-			printf(buffer);
-			g_vm->glk_set_style(style_Normal);
-		}
-	} else {
-		g_vm->glk_request_line_event(glkMainWin, buffer, maxLen, 0);
-
-		do {
-			g_vm->glk_select(&event);
-			if (g_vm->shouldQuit())
-				LONG_JUMP0
-
-			switch (event.type) {
-			case evtype_Arrange:
-				R0CALL0(statusline)
-				break;
-
-			default:
-				break;
-			}
-		} while (event.type != evtype_LineInput);
-		if (buffer[0] == '@') {
-			buffer[event.val1] = 0;
-			commandFileRef = g_vm->glk_fileref_create_by_name(fileusage_InputRecord + fileusage_TextMode, &buffer[1], 0);
-			commandFile = g_vm->glk_stream_open_file(commandFileRef, filemode_Read, 0);
-			if (commandFile != NULL)
-				if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) != 0) {
-					readingCommands = TRUE;
-					g_vm->glk_set_style(style_Input);
-					printf(buffer);
-					g_vm->glk_set_style(style_Normal);
-				}
-		} else
-			buffer[event.val1] = 0;
-	}
-	return TRUE;
-}
-
-} // End of namespace Alan3
-} // End of namespace Glk
diff --git a/engines/glk/alan3/readline.h b/engines/glk/alan3/readline.h
deleted file mode 100644
index 624bf4a..0000000
--- a/engines/glk/alan3/readline.h
+++ /dev/null
@@ -1,41 +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_ALAN3_READLINE
-#define GLK_ALAN3_READLINE
-
-/* Header file for user input, history and editing support */
-
-#include "glk/alan3/types.h"
-#include "glk/alan3/jumps.h"
-
-namespace Glk {
-namespace Alan3 {
-
-#define HISTORYLENGTH 20
-
-extern bool readline(CONTEXT, char *usrBuf, size_t maxLen);
-
-} // End of namespace Alan3
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 6cc1ef9..0875acb 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -33,7 +33,6 @@
 #include "glk/alan3/options.h"
 #include "glk/alan3/output.h"
 #include "glk/alan3/params.h"
-#include "glk/alan3/readline.h"
 #include "glk/alan3/syserr.h"
 #include "glk/alan3/word.h"
 
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 3d3c62b..ad5e665 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -83,7 +83,6 @@ MODULE_OBJS := \
 	alan3/parameter_position.o \
 	alan3/params.o \
 	alan3/parse.o \
-	alan3/readline.o \
 	alan3/reverse.o \
 	alan3/rules.o \
 	alan3/save.o \


Commit: c5214f6d349df9bc4ec088bbbca3543e47b22744
    https://github.com/scummvm/scummvm/commit/c5214f6d349df9bc4ec088bbbca3543e47b22744
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Making GlkIO base class

Changed paths:
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/alan3.h
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/glkio.h
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/output.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/utils.cpp


diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 52a6e25..990874e 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -29,7 +29,6 @@
 #include "glk/alan3/save.h"
 #include "glk/alan3/syserr.h"
 #include "common/system.h"
-#include "common/config-manager.h"
 #include "common/translation.h"
 #include "common/error.h"
 #include "common/scummsys.h"
@@ -42,8 +41,8 @@ namespace Alan3 {
 
 Alan3 *g_vm = nullptr;
 
-Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
-	vm_exited_cleanly(false), _saveSlot(-1), _pendingLook(false) {
+Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkIO(syst, gameDesc),
+	vm_exited_cleanly(false), _pendingLook(false) {
 	g_vm = this;
 
 	// main
@@ -87,29 +86,14 @@ void Alan3::runGame() {
 }
 
 bool Alan3::initialize() {
+	if (!GlkIO::initialize())
+		syserr("FATAL ERROR: Cannot open initial window");
+
 	// Set up adventure name
 	_advName = getFilename();
 	if (_advName.size() > 4 && _advName[_advName.size() - 4] == '.')
 		_advName = Common::String(_advName.c_str(), _advName.size() - 4);
 
-	// first, open a window for error output
-	glkMainWin = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
-	if (glkMainWin == nullptr)
-		syserr("FATAL ERROR: Cannot open initial window");
-
-	g_vm->glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
-	glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
-	                                     winmethod_Fixed, 1, wintype_TextGrid, 0);
-	g_vm->glk_set_window(glkMainWin);
-
-	// Set up the code file to point to the already opened game file
-	codfil = &_gameFile;
-
-	if (_gameFile.size() < 8) {
-	    GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
-	    return false;
-	}
-
 	// In Alan 3, the text data comes from the adventure file itself
 	Common::File *txt = new Common::File();
 	if (!txt->open(getFilename())) {
@@ -119,8 +103,8 @@ bool Alan3::initialize() {
 	}
 	textFile = txt;
 
-	// Check for a save being loaded directly from the launcher
-	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+	// Set up the code file to point to the already opened game file
+	codfil = &_gameFile;
 
 	return true;
 }
diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
index 73a9a03..ffb6282 100644
--- a/engines/glk/alan3/alan3.h
+++ b/engines/glk/alan3/alan3.h
@@ -23,7 +23,7 @@
 #ifndef GLK_ALAN3
 #define GLK_ALAN3
 
-#include "glk/glk_api.h"
+#include "glk/alan3/glkio.h"
 
 namespace Glk {
 namespace Alan3 {
@@ -31,11 +31,10 @@ namespace Alan3 {
 /**
  * Alan3 game interpreter
  */
-class Alan3 : public GlkAPI {
+class Alan3 : public GlkIO {
 public:
 	bool vm_exited_cleanly;
 	Common::String _advName;
-	int _saveSlot;
 	bool _pendingLook;
 private:
 	/**
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index 94f5bb4..4705010 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -742,7 +742,7 @@ static void readCommand(CONTEXT, char buf[], size_t maxLen) {
 	do {
 		output("adbg> ");
 
-		FUNC2(readline, flag, buf, maxLen)
+		FUNC2(g_io->readLine, flag, buf, maxLen)
 		if (!flag) {
 			newline();
 			quitGame();
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index ccf2a67..15c3278 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -26,17 +26,38 @@
 #include "glk/alan3/instance.h"
 #include "glk/alan3/options.h"
 #include "glk/alan3/output.h"
+#include "common/config-manager.h"
 
 namespace Glk {
 namespace Alan3 {
 
-winid_t glkMainWin;
-winid_t glkStatusWin;
-bool onStatusLine;
+GlkIO *g_io;
 
-void glkio_printf(const char *fmt, ...) {
+GlkIO::GlkIO(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
+		glkMainWin(nullptr), glkStatusWin(nullptr), onStatusLine(false), _saveSlot(-1) {
+	g_io = this;
+}
+
+bool GlkIO::initialize() {
+	// first, open a window for error output
+	glkMainWin = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
+	if (glkMainWin == nullptr)
+		return false;
+
+	glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_ReverseColor, 1);
+	glkStatusWin = glk_window_open(glkMainWin, winmethod_Above |
+		winmethod_Fixed, 1, wintype_TextGrid, 0);
+	glk_set_window(glkMainWin);
+
+	// Check for a save being loaded directly from the launcher
+	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+
+	return true;
+}
+
+void GlkIO::print(const char *fmt, ...) {
 	// If there's a savegame being loaded from the launcher, ignore any text out
-	if (g_vm->_saveSlot != -1)
+	if (_saveSlot != -1)
 		return;
 
 	va_list argp;
@@ -44,7 +65,7 @@ void glkio_printf(const char *fmt, ...) {
 	if (glkMainWin) {
 		char buf[1024]; /* FIXME: buf size should be foolproof */
 		vsprintf(buf, fmt, argp);
-		g_vm->glk_put_string(buf);
+		glk_put_string(buf);
 	} else {
 		// assume stdio is available in this case only
 		Common::String str = Common::String::vformat(fmt, argp);
@@ -54,54 +75,54 @@ void glkio_printf(const char *fmt, ...) {
 	va_end(argp);
 }
 
-void showImage(int image, int align) {
+void GlkIO::showImage(int image, int align) {
 	uint ecode;
 
-	if ((g_vm->glk_gestalt(gestalt_Graphics, 0) == 1) &&
-		(g_vm->glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
-		g_vm->glk_window_flow_break(glkMainWin);
+	if ((glk_gestalt(gestalt_Graphics, 0) == 1) &&
+		(glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
+		glk_window_flow_break(glkMainWin);
 		printf("\n");
-		ecode = g_vm->glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
+		ecode = glk_image_draw(glkMainWin, image, imagealign_MarginLeft, 0);
 		(void)ecode;
 	}
 }
 
-void playSound(int sound) {
+void GlkIO::playSound(int sound) {
 #ifdef GLK_MODULE_SOUND
 	static schanid_t soundChannel = NULL;
 
-	if (g_vm->glk_gestalt(gestalt_Sound, 0) == 1) {
+	if (glk_gestalt(gestalt_Sound, 0) == 1) {
 		if (soundChannel == NULL)
-			soundChannel = g_vm->glk_schannel_create(0);
+			soundChannel = glk_schannel_create(0);
 		if (soundChannel != NULL) {
-			g_vm->glk_schannel_stop(soundChannel);
-			(void)g_vm->glk_schannel_play(soundChannel, sound);
+			glk_schannel_stop(soundChannel);
+			(void)glk_schannel_play(soundChannel, sound);
 		}
 	}
 #endif
 }
 
-void setStyle(int style) {
+void GlkIO::setStyle(int style) {
 	switch (style) {
 	case NORMAL_STYLE:
-		g_vm->glk_set_style(style_Normal);
+		glk_set_style(style_Normal);
 		break;
 	case EMPHASIZED_STYLE:
-		g_vm->glk_set_style(style_Emphasized);
+		glk_set_style(style_Emphasized);
 		break;
 	case PREFORMATTED_STYLE:
-		g_vm->glk_set_style(style_Preformatted);
+		glk_set_style(style_Preformatted);
 		break;
 	case ALERT_STYLE:
-		g_vm->glk_set_style(style_Alert);
+		glk_set_style(style_Alert);
 		break;
 	case QUOTE_STYLE:
-		g_vm->glk_set_style(style_BlockQuote);
+		glk_set_style(style_BlockQuote);
 		break;
 	}
 }
 
-void statusline(CONTEXT) {
+void GlkIO::statusLine(CONTEXT) {
 	uint32 glkWidth;
 	char line[100];
 	int pcol = col;
@@ -110,13 +131,13 @@ void statusline(CONTEXT) {
 	if (glkStatusWin == NULL)
 		return;
 
-	g_vm->glk_set_window(glkStatusWin);
-	g_vm->glk_window_clear(glkStatusWin);
-	g_vm->glk_window_get_size(glkStatusWin, &glkWidth, NULL);
+	glk_set_window(glkStatusWin);
+	glk_window_clear(glkStatusWin);
+	glk_window_get_size(glkStatusWin, &glkWidth, NULL);
 
 	onStatusLine = TRUE;
 	col = 1;
-	g_vm->glk_window_move_cursor(glkStatusWin, 1, 0);
+	glk_window_move_cursor(glkStatusWin, 1, 0);
 	CALL1(sayInstance, where(HERO, /*TRUE*/ TRANSITIVE))
 
 		// TODO Add status message1  & 2 as author customizable messages
@@ -124,14 +145,14 @@ void statusline(CONTEXT) {
 			sprintf(line, "Score %d(%d)/%d moves", current.score, (int)header->maximumScore, current.tick);
 		else
 			sprintf(line, "%d moves", current.tick);
-	g_vm->glk_window_move_cursor(glkStatusWin, glkWidth - strlen(line) - 1, 0);
-	g_vm->glk_put_string(line);
+	glk_window_move_cursor(glkStatusWin, glkWidth - strlen(line) - 1, 0);
+	glk_put_string(line);
 	needSpace = FALSE;
 
 	col = pcol;
 	onStatusLine = FALSE;
 
-	g_vm->glk_set_window(glkMainWin);
+	glk_set_window(glkMainWin);
 }
 
 
@@ -144,32 +165,32 @@ void statusline(CONTEXT) {
 */
 
 /* TODO - length of user buffer should be used */
-bool readline(CONTEXT, char *buffer, size_t maxLen) {
+bool GlkIO::readLine(CONTEXT, char *buffer, size_t maxLen) {
 	event_t event;
 	static bool readingCommands = FALSE;
 	static frefid_t commandFileRef;
 	static strid_t commandFile;
 
 	if (readingCommands) {
-		if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) == 0) {
-			g_vm->glk_stream_close(commandFile, NULL);
+		if (glk_get_line_stream(commandFile, buffer, maxLen) == 0) {
+			glk_stream_close(commandFile, NULL);
 			readingCommands = FALSE;
 		} else {
-			g_vm->glk_set_style(style_Input);
+			glk_set_style(style_Input);
 			printf(buffer);
-			g_vm->glk_set_style(style_Normal);
+			glk_set_style(style_Normal);
 		}
 	} else {
-		g_vm->glk_request_line_event(glkMainWin, buffer, maxLen, 0);
+		glk_request_line_event(glkMainWin, buffer, maxLen, 0);
 
 		do {
-			g_vm->glk_select(&event);
-			if (g_vm->shouldQuit())
+			glk_select(&event);
+			if (shouldQuit())
 				LONG_JUMP0
 
 			switch (event.type) {
 			case evtype_Arrange:
-				R0CALL0(statusline)
+				R0CALL0(g_io->statusLine)
 				break;
 
 			default:
@@ -178,14 +199,14 @@ bool readline(CONTEXT, char *buffer, size_t maxLen) {
 		} while (event.type != evtype_LineInput);
 		if (buffer[0] == '@') {
 			buffer[event.val1] = 0;
-			commandFileRef = g_vm->glk_fileref_create_by_name(fileusage_InputRecord + fileusage_TextMode, &buffer[1], 0);
-			commandFile = g_vm->glk_stream_open_file(commandFileRef, filemode_Read, 0);
+			commandFileRef = glk_fileref_create_by_name(fileusage_InputRecord + fileusage_TextMode, &buffer[1], 0);
+			commandFile = glk_stream_open_file(commandFileRef, filemode_Read, 0);
 			if (commandFile != NULL)
-				if (g_vm->glk_get_line_stream(commandFile, buffer, maxLen) != 0) {
+				if (glk_get_line_stream(commandFile, buffer, maxLen) != 0) {
 					readingCommands = TRUE;
-					g_vm->glk_set_style(style_Input);
+					glk_set_style(style_Input);
 					printf(buffer);
-					g_vm->glk_set_style(style_Normal);
+					glk_set_style(style_Normal);
 				}
 		} else
 			buffer[event.val1] = 0;
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index 8876aec..55c8ab6 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -23,30 +23,58 @@
 #ifndef GLK_ALAN3_GLKIO
 #define GLK_ALAN3_GLKIO
 
-#include "glk/alan3/alan3.h"
-#include "glk/alan3/jumps.h"
+#include "glk/glk_api.h"
 #include "glk/windows.h"
+#include "glk/alan3/jumps.h"
 
 namespace Glk {
 namespace Alan3 {
 
-extern winid_t glkMainWin;
-extern winid_t glkStatusWin;
-extern bool onStatusLine;
+class GlkIO : public GlkAPI {
+private:
+	winid_t glkMainWin;
+	winid_t glkStatusWin;
+	int _saveSlot;
+public:
+	bool onStatusLine;
+protected:
+	/**
+	 * Does initialization
+	 */
+	bool initialize();
+public:
+	/**
+	 * Constructor
+	 */
+	GlkIO(OSystem *syst, const GlkGameDescription &gameDesc);
 
-#undef printf
-#define printf glkio_printf
-extern void glkio_printf(const char *, ...);
+	void print(const char *, ...);
+
+	void showImage(int image, int align);
 
-extern void showImage(int image, int align);
+	void playSound(int sound);
 
-extern void playSound(int sound);
+	void setStyle(int style);
 
-extern void setStyle(int style);
+	void statusLine(CONTEXT);
 
-extern void statusline(CONTEXT);
+	bool readLine(CONTEXT, char *usrBuf, size_t maxLen);
 
-extern bool readline(CONTEXT, char *usrBuf, size_t maxLen);
+	void clear() {
+		glk_window_clear(glkMainWin);
+	}
+
+	void flowBreak() {
+		/* Make a new paragraph, i.e one empty line (one or two newlines). */
+		if (glk_gestalt(gestalt_Graphics, 0) == 1)
+			glk_window_flow_break(glkMainWin);
+	}
+};
+
+extern GlkIO *g_io;
+
+#undef printf
+#define printf g_io->print
 
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index 002a580..5ee5ea9 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -559,7 +559,7 @@ void interpret(CONTEXT, Aaddr adr) {
 				if (traceInstructionOption) {
 					printf("STYLE \t%7ld\t\t\"", (long)style);
 				}
-				setStyle(style);
+				g_io->setStyle(style);
 				break;
 			}
 
@@ -829,14 +829,14 @@ void interpret(CONTEXT, Aaddr adr) {
 				Aint align = pop(stack);
 				if (traceInstructionOption)
 					printf("SHOW \t%7ld, %7ld\t\t\t\t", (long)image, (long)align);
-				showImage(image, align);
+				g_io->showImage(image, align);
 				break;
 			}
 			case I_PLAY: {
 				Aint sound = pop(stack);
 				if (traceInstructionOption)
 					printf("PLAY \t%7ld\t\t\t\t", (long)sound);
-				playSound(sound);
+				g_io->playSound(sound);
 				break;
 			}
 			case I_LOCATE: {
diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index 405ca2e..0d94611 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -78,13 +78,13 @@ static int updateColumn(int currentColumn, const char *string) {
 
 /*======================================================================*/
 void setSubHeaderStyle(void) {
-	g_vm->glk_set_style(style_Subheader);
+	g_io->glk_set_style(style_Subheader);
 }
 
 
 /*======================================================================*/
 void setNormalStyle(void) {
-	g_vm->glk_set_style(style_Normal);
+	g_io->glk_set_style(style_Normal);
 }
 
 /*======================================================================*/
@@ -97,9 +97,7 @@ void newline(void) {
 
 /*======================================================================*/
 void para(void) {
-	/* Make a new paragraph, i.e one empty line (one or two newlines). */
-	if (g_vm->glk_gestalt(gestalt_Graphics, 0) == 1)
-		g_vm->glk_window_flow_break(glkMainWin);
+	g_io->flowBreak();
 
 	if (col != 1)
 		newline();
@@ -110,7 +108,7 @@ void para(void) {
 
 /*======================================================================*/
 void clear(void) {
-	g_vm->glk_window_clear(glkMainWin);
+	g_io->clear();
 }
 
 
@@ -135,7 +133,7 @@ void printAndLog(const char *string) {
 	char *stringPart;
 
 	printf("%s", string);
-	if (!onStatusLine && transcriptOption) {
+	if (!g_io->onStatusLine && transcriptOption) {
 		// TODO Is this assuming only 70-char wide windows for GLK?
 		if ((int)strlen(string) > 70 - column) {
 			stringCopy = strdup(string);  /* Make sure we can write NULLs */
@@ -144,16 +142,16 @@ void printAndLog(const char *string) {
 				int p;
 				for (p = 70 - column; p > 0 && !isspace((int)stringPart[p]); p--);
 				stringPart[p] = '\0';
-				g_vm->glk_put_string_stream(logFile, stringPart);
-				g_vm->glk_put_char_stream(logFile, '\n');
+				g_io->glk_put_string_stream(logFile, stringPart);
+				g_io->glk_put_char_stream(logFile, '\n');
 				column = 0;
 				stringPart = &stringPart[p + 1];
 			}
-			g_vm->glk_put_string_stream(logFile, stringPart);
+			g_io->glk_put_string_stream(logFile, stringPart);
 			column = updateColumn(column, stringPart);
 			free(stringCopy);
 		} else {
-			g_vm->glk_put_string_stream(logFile, string);
+			g_io->glk_put_string_stream(logFile, string);
 			column = updateColumn(column, string);
 		}
 	}
@@ -442,7 +440,7 @@ bool confirm(CONTEXT, MsgKind msgno) {
 	   it could be affirmative, but for now any input is NOT! */
 	printMessage(msgno);
 
-	R0FUNC2(readline, flag, buf, 80)
+	R0FUNC2(g_io->readLine, flag, buf, 80)
 	if (!flag)
 		return TRUE;
 	col = 1;
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 0875acb..8f3ab80 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -135,7 +135,7 @@ static char *gettoken(char *txtBuf) {
 static void getLine(CONTEXT) {
 	para();
 	do {
-		CALL0(statusline)
+		CALL0(g_io->statusLine)
 
 		if (header->prompt) {
 			anyOutput = FALSE;
@@ -148,7 +148,7 @@ static void getLine(CONTEXT) {
 			printAndLog("> ");
 
 		bool flag;
-		FUNC2(readline, flag, buf, 255);
+		FUNC2(g_io->readLine, flag, buf, 255);
 		if (!flag) {
 			newline();
 			quitGame();
@@ -158,8 +158,8 @@ static void getLine(CONTEXT) {
 		anyOutput = FALSE;
 		if (transcriptOption || logOption) {
 			// TODO: Refactor out the logging to log.c?
-			g_vm->glk_put_string_stream(logFile, buf);
-			g_vm->glk_put_char_stream(logFile, '\n');
+			g_io->glk_put_string_stream(logFile, buf);
+			g_io->glk_put_char_stream(logFile, '\n');
 		}
 		/* If the player input an empty command he forfeited his command */
 		if (strlen(buf) == 0) {
diff --git a/engines/glk/alan3/utils.cpp b/engines/glk/alan3/utils.cpp
index 38176e1..acbf8e4 100644
--- a/engines/glk/alan3/utils.cpp
+++ b/engines/glk/alan3/utils.cpp
@@ -52,7 +52,7 @@ void terminate(CONTEXT, int code) {
 	if (memory)
 		deallocate(memory);
 
-	g_vm->glk_exit();
+	g_io->glk_exit();
 	LONG_JUMP
 }
 
@@ -75,7 +75,7 @@ void usage(const char *programName) {
 	printf("    %s [<switches>] <adventure>\n\n", programName);
 	printf("where the possible optional switches are:\n");
 
-	g_vm->glk_set_style(style_Preformatted);
+	g_io->glk_set_style(style_Preformatted);
 	printf("    -v       verbose mode\n");
 	printf("    -l       log transcript to a file\n");
 	printf("    -c       log player commands to a file\n");
@@ -84,7 +84,7 @@ void usage(const char *programName) {
 	printf("    -t[<n>]  trace game execution, higher <n> gives more trace\n");
 	printf("    -i       ignore version and checksum errors\n");
 	printf("    -r       make regression test easier (don't timestamp, page break, randomize...)\n");
-	g_vm->glk_set_style(style_Normal);
+	g_io->glk_set_style(style_Normal);
 }
 
 


Commit: 87a86c0fb61add346a368c27407be990c2827c4c
    https://github.com/scummvm/scummvm/commit/87a86c0fb61add346a368c27407be990c2827c4c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Merge saving & loading code, loading fixes

Changed paths:
    engines/glk/alan3/acode.cpp
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/save.cpp


diff --git a/engines/glk/alan3/acode.cpp b/engines/glk/alan3/acode.cpp
index 3dbfaa5..4d41e0f 100644
--- a/engines/glk/alan3/acode.cpp
+++ b/engines/glk/alan3/acode.cpp
@@ -26,9 +26,20 @@ namespace Glk {
 namespace Alan3 {
 
 void AttributeEntry::synchronize(Common::Serializer &s) {
-	s.syncAsSint32LE(code);
-	s.syncAsSint32LE(value);
-	s.syncAsSint32LE(id);
+	// We have to do some annoying temporary copy of the fields to get around gcc
+	// errors about getting references to fields of packed structures
+	Aint c = code;
+	Aptr v = value;
+	Aaddr i = id;
+	s.syncAsSint32LE(c);
+	s.syncAsSint32LE(v);
+	s.syncAsSint32LE(i);
+
+	if (s.isLoading()) {
+		code = c;
+		value = v;
+		id = i;
+	}
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index b522057..b738fd6 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -630,7 +630,8 @@ static void sayNegative(CONTEXT, int instance) {
 	} else {
 		bool flag;
 		FUNC1(sayInheritedNegativeForm, flag, instances[instance].parent)
-		CALL1(sayInstance, instance)
+		if (!flag)
+			CALL1(sayInstance, instance)
 	}
 }
 
diff --git a/engines/glk/alan3/save.cpp b/engines/glk/alan3/save.cpp
index 6e645d0..da1d5b6 100644
--- a/engines/glk/alan3/save.cpp
+++ b/engines/glk/alan3/save.cpp
@@ -36,212 +36,106 @@
 namespace Glk {
 namespace Alan3 {
 
-/*----------------------------------------------------------------------*/
-static void saveStrings(Common::WriteStream *saveFile) {
-	StringInitEntry *initEntry;
-
-	if (header->stringInitTable != 0)
-		for (initEntry = (StringInitEntry *)pointerTo(header->stringInitTable);
-		        !isEndOfArray(initEntry); initEntry++) {
-			char *attr = (char *)getInstanceStringAttribute(initEntry->instanceCode, initEntry->attributeCode);
-			Aint length = strlen(attr) + 1;
-			saveFile->writeUint32LE(length);
-			saveFile->write(attr, length);
-		}
-}
-
-
-/*----------------------------------------------------------------------*/
-static void saveSets(Common::WriteStream *saveFile) {
-	SetInitEntry *initEntry;
-
-	if (header->setInitTable != 0)
-		for (initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
-		        !isEndOfArray(initEntry); initEntry++) {
-			Set *attr = (Set *)getInstanceSetAttribute(initEntry->instanceCode, initEntry->attributeCode);
-			saveFile->writeUint32LE(attr->size);
-			saveFile->write(attr->members, attr->size);
-		}
-}
-
-
-/*----------------------------------------------------------------------*/
 static void saveGameInfo(Common::WriteStream *saveFile) {
 	saveFile->writeUint32BE(MKTAG('A', 'S', 'A', 'V'));
 	saveFile->write(header->version, 4);
 	saveFile->writeUint32LE(header->uid);
 }
 
+static void verifySaveFile(CONTEXT, Common::SeekableReadStream *saveFile) {
+	if (saveFile->readUint32BE() != MKTAG('A', 'S', 'A', 'V'))
+		error(context, M_NOTASAVEFILE);
+}
+
+static void verifyCompilerVersion(CONTEXT, Common::SeekableReadStream *saveFile) {
+	char savedVersion[4];
 
-/*----------------------------------------------------------------------*/
-static void saveAdmin(Common::WriteStream *saveFile) {
-	Common::Serializer s(nullptr, saveFile);
-	for (uint i = 1; i <= header->instanceMax; i++)
-		admin[i].synchronize(s);
+	saveFile->read(&savedVersion, 4);
+	if (!ignoreErrorOption && memcmp(savedVersion, header->version, 4))
+		error(context, M_SAVEVERS);
+}
+
+static void verifyGameId(CONTEXT, Common::SeekableReadStream *saveFile) {
+	Aword savedUid = saveFile->readUint32LE();
+	if (!ignoreErrorOption && savedUid != header->uid)
+		error(context, M_SAVEVERS);
 }
 
+void syncGame(Common::Serializer &s) {
+	// Current values
+	current.synchronize(s);
 
-/*----------------------------------------------------------------------*/
-static void saveAttributeArea(Common::WriteStream *saveFile) {
-	Common::Serializer s(nullptr, saveFile);
+	// Attributes area
 	for (Aint i = 0; i < header->attributesAreaSize; ++i)
 		attributes[i].synchronize(s);
-}
 
+	// Admin data
+	for (uint i = 1; i <= header->instanceMax; i++)
+		admin[i].synchronize(s);
 
-/*----------------------------------------------------------------------*/
-static void saveEventQueue(Common::WriteStream *saveFile) {
-	Common::Serializer s(nullptr, saveFile);
-
+	// Event queue
 	s.syncAsSint32LE(eventQueueTop);
 	for (int i = 0; i < eventQueueTop; ++i)
 		eventQueue[i].synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void saveCurrentValues(Common::WriteStream *saveFile) {
-	Common::Serializer s(nullptr, saveFile);
-	current.synchronize(s);
-}
-
 
-/*----------------------------------------------------------------------*/
-static void saveScores(Common::WriteStream *saveFile) {
+	// Scores
 	for (Aint i = 0; i < header->scoreCount; ++i)
-		saveFile->writeUint32LE(scores[i]);
-}
-
-
-/*----------------------------------------------------------------------*/
-void saveGame(Common::WriteStream *saveFile) {
-	/* Save tag, version of interpreter, name and uid of game */
-	saveGameInfo(saveFile);
-
-	/* Save current values */
-	saveCurrentValues(saveFile);
-
-	saveAttributeArea(saveFile);
-	saveAdmin(saveFile);
-
-	saveEventQueue(saveFile);
-
-	saveScores(saveFile);
-
-	saveStrings(saveFile);
-	saveSets(saveFile);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreStrings(Common::SeekableReadStream *saveFile) {
-	StringInitEntry *initEntry;
+		s.syncAsUint32LE(scores[i]);
 
+	// Strings
 	if (header->stringInitTable != 0)
-		for (initEntry = (StringInitEntry *)pointerTo(header->stringInitTable);
-		        !isEndOfArray(initEntry); initEntry++) {
-			Aint length = saveFile->readUint32LE();
-			char *string = (char *)allocate(length + 1);
+		for (StringInitEntry *initEntry = (StringInitEntry *)pointerTo(header->stringInitTable);
+				!isEndOfArray(initEntry); initEntry++) {
 
-			saveFile->read(string, length);
+		if (s.isSaving()) {
+			char *attr = (char *)getInstanceStringAttribute(initEntry->instanceCode, initEntry->attributeCode);
+			Aint length = strlen(attr) + 1;
+			s.syncAsUint32LE(length);
+			s.syncBytes((byte *)attr, length);
+		} else {
+			Aint length = 0;
+			s.syncAsUint32LE(length);
+			char *string = (char *)allocate(length + 1);
+			s.syncBytes((byte *)string, length);
 			setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(string));
 		}
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreSets(Common::SeekableReadStream *saveFile) {
-	SetInitEntry *initEntry;
-
-	if (header->setInitTable != 0)
-		for (initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
-		        !isEndOfArray(initEntry); initEntry++) {
-			Aint setSize = saveFile->readUint32LE();
-			Set *set = newSet(setSize);
+	}
 
-			for (int i = 0; i < setSize; i++) {
-				Aword member = saveFile->readUint32LE();
-				addToSet(set, member);
+	// Sets
+	if (header->setInitTable != 0) {
+		for (SetInitEntry *initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
+				!isEndOfArray(initEntry); initEntry++) {
+
+			if (s.isSaving()) {
+				Set *attr = (Set *)getInstanceSetAttribute(initEntry->instanceCode, initEntry->attributeCode);
+				s.syncAsUint32LE(attr->size);
+				for (int i = 0; i < attr->size; ++i)
+					s.syncAsUint32LE(attr->members[i]);
+
+			} else {
+				Aword setSize = 0, member = 0;
+				s.syncAsUint32BE(setSize);
+				Set *set = newSet(setSize);
+				for (uint i = 0; i < setSize; ++i) {
+					s.syncAsUint32LE(member);
+					addToSet(set, member);
+				}
+
+				setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(set));
 			}
-			setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(set));
 		}
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreScores(Common::SeekableReadStream *saveFile) {
-	for (Aint i = 0; i < header->scoreCount; ++i)
-		scores[i] = saveFile->readUint32LE();
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreEventQueue(Common::SeekableReadStream *saveFile) {
-	Common::Serializer s(saveFile, nullptr);
-
-	s.syncAsSint32LE(eventQueueTop);
-	for (int i = 0; i < eventQueueTop; ++i)
-		eventQueue[i].synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreAdmin(Common::SeekableReadStream *saveFile) {
-	// Restore admin for instances, remember to reset attribute area pointer
-	Common::Serializer s(saveFile, nullptr);
-	for (uint i = 1; i <= header->instanceMax; i++) {
-		AttributeEntry *currentAttributesArea = admin[i].attributes;
-		admin[i].synchronize(s);
-		admin[i].attributes = currentAttributesArea;
 	}
 }
 
+void saveGame(Common::WriteStream *saveFile) {
+	// Save tag, version of interpreter, and unique id of game
+	saveGameInfo(saveFile);
 
-/*----------------------------------------------------------------------*/
-static void restoreAttributeArea(Common::SeekableReadStream *saveFile) {
-	Common::Serializer s(saveFile, nullptr);
-	for (Aint i = 0; i < header->attributesAreaSize; ++i)
-		attributes[i].synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreCurrentValues(Common::SeekableReadStream *saveFile) {
-	Common::Serializer s(saveFile, nullptr);
-	current.synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void verifyGameId(CONTEXT, Common::SeekableReadStream *saveFile) {
-	Aword savedUid = saveFile->readUint32LE();
-	if (!ignoreErrorOption && savedUid != header->uid)
-		error(context, M_SAVEVERS);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void verifyCompilerVersion(CONTEXT, Common::SeekableReadStream *saveFile) {
-	char savedVersion[4];
-
-	saveFile->read(&savedVersion, 4);
-	if (!ignoreErrorOption && memcmp(savedVersion, header->version, 4))
-		error(context, M_SAVEVERS);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void verifySaveFile(CONTEXT, Common::SeekableReadStream *saveFile) {
-	char string[5];
-	saveFile->read(string, 4);
-	string[4] = '\0';
-
-	if (strcmp(string, "ASAV") != 0)
-		error(context, M_NOTASAVEFILE);
+	// Save game data
+	Common::Serializer s(nullptr, saveFile);
+	syncGame(s);
 }
 
-
-/*----------------------------------------------------------------------*/
 bool restoreGame(Common::SeekableReadStream *saveFile) {
 	Context ctx;
 	verifySaveFile(ctx, saveFile);
@@ -255,13 +149,9 @@ bool restoreGame(Common::SeekableReadStream *saveFile) {
 	verifyGameId(ctx, saveFile);
 	if (ctx._break) return false;
 
-	restoreCurrentValues(saveFile);
-	restoreAttributeArea(saveFile);
-	restoreAdmin(saveFile);
-	restoreEventQueue(saveFile);
-	restoreScores(saveFile);
-	restoreStrings(saveFile);
-	restoreSets(saveFile);
+	// Restore game data
+	Common::Serializer s(saveFile, nullptr);
+	syncGame(s);
 
 	return true;
 }


Commit: 4de30c9e2f02d028660bbfa1011047747abba548
    https://github.com/scummvm/scummvm/commit/4de30c9e2f02d028660bbfa1011047747abba548
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Fix Valgrind identified memory issues

Changed paths:
    engines/glk/alan3/output.cpp
    engines/glk/alan3/save.cpp


diff --git a/engines/glk/alan3/output.cpp b/engines/glk/alan3/output.cpp
index 0d94611..1ac2cd6 100644
--- a/engines/glk/alan3/output.cpp
+++ b/engines/glk/alan3/output.cpp
@@ -424,10 +424,12 @@ void output(const char *original) {
 		if (lastCharOf(str) != ' ')
 			needSpace = TRUE;
 	}
+
 	if (needSpace)
 		capitalize = strchr("!?.", str[strlen(str) - 1]) != 0;
+
 	anyOutput = TRUE;
-	free(copy);
+	delete[] copy;
 }
 
 
diff --git a/engines/glk/alan3/save.cpp b/engines/glk/alan3/save.cpp
index da1d5b6..839ce2b 100644
--- a/engines/glk/alan3/save.cpp
+++ b/engines/glk/alan3/save.cpp
@@ -66,7 +66,7 @@ void syncGame(Common::Serializer &s) {
 	current.synchronize(s);
 
 	// Attributes area
-	for (Aint i = 0; i < header->attributesAreaSize; ++i)
+	for (Aint i = 0; i < header->attributesAreaSize / 3; ++i)
 		attributes[i].synchronize(s);
 
 	// Admin data


Commit: 3165fa628ab44022ee8370d0244137295f3c59f1
    https://github.com/scummvm/scummvm/commit/3165fa628ab44022ee8370d0244137295f3c59f1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Add loading savegame from launcher

Changed paths:
    engines/glk/alan3/alan3.cpp
    engines/glk/alan3/alan3.h
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/glkio.h
    engines/glk/alan3/inter.cpp


diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 990874e..33ccf75 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -41,8 +41,7 @@ namespace Alan3 {
 
 Alan3 *g_vm = nullptr;
 
-Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkIO(syst, gameDesc),
-	vm_exited_cleanly(false), _pendingLook(false) {
+Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkIO(syst, gameDesc) {
 	g_vm = this;
 
 	// main
diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
index ffb6282..f1d88f8 100644
--- a/engines/glk/alan3/alan3.h
+++ b/engines/glk/alan3/alan3.h
@@ -33,9 +33,7 @@ namespace Alan3 {
  */
 class Alan3 : public GlkIO {
 public:
-	bool vm_exited_cleanly;
 	Common::String _advName;
-	bool _pendingLook;
 private:
 	/**
 	 * Initialization
@@ -73,7 +71,7 @@ public:
 	 * 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;
+	virtual Common::Error writeGameData(Common::WriteStream *ws) override;;
 };
 
 extern Alan3 *g_vm;
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index 15c3278..61e9f18 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -62,21 +62,21 @@ void GlkIO::print(const char *fmt, ...) {
 
 	va_list argp;
 	va_start(argp, fmt);
+	Common::String str = Common::String::vformat(fmt, argp);
+	va_end(argp);
+
 	if (glkMainWin) {
-		char buf[1024]; /* FIXME: buf size should be foolproof */
-		vsprintf(buf, fmt, argp);
-		glk_put_string(buf);
+		glk_put_string(str.c_str());
 	} else {
 		// assume stdio is available in this case only
-		Common::String str = Common::String::vformat(fmt, argp);
-		warning(fmt, argp);
+		warning("%s", str.c_str());
 	}
-
-	va_end(argp);
 }
 
 void GlkIO::showImage(int image, int align) {
 	uint ecode;
+	if (_saveSlot != -1)
+		return;
 
 	if ((glk_gestalt(gestalt_Graphics, 0) == 1) &&
 		(glk_gestalt(gestalt_DrawImage, wintype_TextBuffer) == 1)) {
@@ -88,6 +88,9 @@ void GlkIO::showImage(int image, int align) {
 }
 
 void GlkIO::playSound(int sound) {
+	if (_saveSlot != -1)
+		return;
+
 #ifdef GLK_MODULE_SOUND
 	static schanid_t soundChannel = NULL;
 
@@ -127,8 +130,7 @@ void GlkIO::statusLine(CONTEXT) {
 	char line[100];
 	int pcol = col;
 
-	if (!statusLineOption) return;
-	if (glkStatusWin == NULL)
+	if (!statusLineOption || _saveSlot != -1 || glkStatusWin == nullptr)
 		return;
 
 	glk_set_window(glkStatusWin);
@@ -171,7 +173,13 @@ bool GlkIO::readLine(CONTEXT, char *buffer, size_t maxLen) {
 	static frefid_t commandFileRef;
 	static strid_t commandFile;
 
-	if (readingCommands) {
+	if (_saveSlot != -1) {
+		// Return a "restore" command
+		forcePrint("> ");
+		forcePrint("restore\n");
+		strcpy(buffer, "restore");
+
+	} else if (readingCommands) {
 		if (glk_get_line_stream(commandFile, buffer, maxLen) == 0) {
 			glk_stream_close(commandFile, NULL);
 			readingCommands = FALSE;
@@ -180,6 +188,7 @@ bool GlkIO::readLine(CONTEXT, char *buffer, size_t maxLen) {
 			printf(buffer);
 			glk_set_style(style_Normal);
 		}
+
 	} else {
 		glk_request_line_event(glkMainWin, buffer, maxLen, 0);
 
@@ -214,5 +223,15 @@ bool GlkIO::readLine(CONTEXT, char *buffer, size_t maxLen) {
 	return TRUE;
 }
 
+Common::Error GlkIO::loadGame() {
+	if (_saveSlot != -1) {
+		int saveSlot = _saveSlot;
+		_saveSlot = -1;
+		return loadGameState(saveSlot);
+	} else {
+		return GlkAPI::loadGame();
+	}
+}
+
 } // End of namespace Alan3
 } // End of namespace Glk
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index 55c8ab6..fb342d1 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -48,7 +48,17 @@ public:
 	 */
 	GlkIO(OSystem *syst, const GlkGameDescription &gameDesc);
 
-	void print(const char *, ...);
+	/**
+	 * Print a string to the window
+	 */
+	void print(const char *fmt, ...);
+
+	/**
+	 * Outputs a string to the window, even during startup
+	 */
+	void forcePrint(const char *str) {
+		glk_put_string(str);
+	}
 
 	void showImage(int image, int align);
 
@@ -66,9 +76,15 @@ public:
 
 	void flowBreak() {
 		/* Make a new paragraph, i.e one empty line (one or two newlines). */
-		if (glk_gestalt(gestalt_Graphics, 0) == 1)
+		if (_saveSlot == -1 && glk_gestalt(gestalt_Graphics, 0) == 1)
 			glk_window_flow_break(glkMainWin);
 	}
+
+	/**
+	 * If a savegame was selected to be loaded from the launcher, then load it.
+	 * Otherwise, prompt the user for a savegame to load, and then load it
+	 */
+	Common::Error loadGame();
 };
 
 extern GlkIO *g_io;
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index 5ee5ea9..3647548 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "glk/alan3/inter.h"
+#include "glk/alan3/alan3.h"
 #include "glk/alan3/current.h"
 #include "glk/alan3/exe.h"
 #include "glk/alan3/syserr.h"


Commit: f28d3b74969896d048ec57aa7e0200f258205423
    https://github.com/scummvm/scummvm/commit/f28d3b74969896d048ec57aa7e0200f258205423
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Further refactoring of setjmp calls

Changed paths:
    engines/glk/alan3/act.cpp
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/exe.h
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/scan.cpp


diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
index cdc95f9..13ca56a 100644
--- a/engines/glk/alan3/act.cpp
+++ b/engines/glk/alan3/act.cpp
@@ -96,36 +96,33 @@ static void executeCommand(CONTEXT, int verb, Parameter parameters[]) {
 */
 void action(CONTEXT, int verb, Parameter parameters[], Parameter multipleMatches[]) {
 	int multiplePosition;
-#ifdef TODO
 	char marker[10];
-#endif
 
 	multiplePosition = findMultiplePosition(parameters);
 	if (multiplePosition != -1) {
-#ifdef TODO
-		jmp_buf savedReturnLabel;
-		memcpy(savedReturnLabel, returnLabel, sizeof(returnLabel));
 		sprintf(marker, "($%d)", multiplePosition + 1); /* Prepare a printout with $1/2/3 */
 		for (int i = 0; !isEndOfArray(&multipleMatches[i]); i++) {
 			copyParameter(&parameters[multiplePosition], &multipleMatches[i]);
 			setGlobalParameters(parameters); /* Need to do this here since the marker use them */
 			output(marker);
-			// TODO: if execution for one parameter aborts we should return here, not to top level
-			if (setjmp(returnLabel) == NO_JUMP_RETURN)
-				executeCommand(verb, parameters);
+
+			// WARNING: The original did a temporary grabbing of the returnLabel setjmp point here.
+			// Which is why I manually check the context return instead of using the CALL macro
+			executeCommand(context, verb, parameters);
+			if (context._break && context._label.hasPrefix("return"))
+				context._break = false;
+			if (context._break)
+				return;
+			
 			if (multipleMatches[i + 1].instance != EOD)
 				para();
 		}
-		memcpy(returnLabel, savedReturnLabel, sizeof(returnLabel));
+
 		parameters[multiplePosition].instance = 0;
-#else
-		syserr("TODO: action");
-#endif
 	} else {
 		setGlobalParameters(parameters);
 		CALL2(executeCommand, verb, parameters)
 	}
-
 }
 
 } // End of namespace Alan3
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index 4705010..114019d 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -745,7 +745,7 @@ static void readCommand(CONTEXT, char buf[], size_t maxLen) {
 		FUNC2(g_io->readLine, flag, buf, maxLen)
 		if (!flag) {
 			newline();
-			quitGame();
+			CALL0(quitGame)
 		}
 		lin = 1;
 		c = buf[0];
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index 499eaee..8c22742 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -54,13 +54,6 @@ Common::SeekableReadStream *textFile;
 // PUBLIC DATA - formerly method statics
 bool printFlag;				// Printing already?
 
-/* Long jump buffers */
-// TODO move to longjump.c? or error.c, and abstract them into functions?
-//jmp_buf restartLabel;       /* Restart long jump return point */
-//jmp_buf returnLabel;        /* Error (or undo) long jump return point */
-//jmp_buf forfeitLabel;       /* Player forfeit by an empty command */
-
-
 /* PRIVATE CONSTANTS */
 
 #define WIDTH 80
@@ -192,7 +185,7 @@ static void sayUndoneCommand(char *words) {
 
 
 /*======================================================================*/
-void undo(void) {
+void undo(CONTEXT) {
 	forgetGameState();
 	if (anySavedState()) {
 		recallGameState();
@@ -200,68 +193,73 @@ void undo(void) {
 	} else {
 		printMessage(M_NO_UNDO);
 	}
-#ifdef TODO
-	longjmp(returnLabel, UNDO_RETURN);
-#else
-	syserr("TODO: undo longjmp");
-#endif
+
+	LONG_JUMP_LABEL("returnUndo")
 }
 
 
 /*======================================================================*/
-void quitGame(void) {
-#ifdef TODO
+void quitGame(CONTEXT) {
 	char buf[80];
+	bool flag;
 
 	current.location = where(HERO, DIRECT);
 	para();
 	while (TRUE) {
 		col = 1;
-		statusline();
+		CALL0(g_io->statusLine)
 		printMessage(M_QUITACTION);
 
-		if (!readline(buf)) terminate(0);
-		if (strcasecmp(buf, "restart") == 0)
-			longjmp(restartLabel, TRUE);
-		else if (strcasecmp(buf, "restore") == 0) {
-			restore();
+		FUNC2(g_io->readLine, flag, buf, 80)
+		if (!flag)
+			CALL1(terminate, 0)
+
+		if (strcasecmp(buf, "restart") == 0) {
+			LONG_JUMP_LABEL("restart")
+
+		} else if (strcasecmp(buf, "restore") == 0) {
+			g_vm->loadGame();
 			return;
+
 		} else if (strcasecmp(buf, "quit") == 0) {
-			terminate(0);
+			CALL1(terminate, 0)
+
 		} else if (strcasecmp(buf, "undo") == 0) {
 			if (gameStateChanged) {
 				rememberCommands();
 				rememberGameState();
-				undo();
+				CALL0(undo)
 			} else {
 				if (anySavedState()) {
 					recallGameState();
 					sayUndoneCommand(playerWordsAsCommandString());
-				} else
+				} else {
 					printMessage(M_NO_UNDO);
-				longjmp(returnLabel, UNDO_RETURN);
+				}
+
+				LONG_JUMP_LABEL("returnUndo")
 			}
 		}
 	}
-#endif
+
 	syserr("Fallthrough in QUIT");
 }
 
 
 
 /*======================================================================*/
-void restartGame(void) {
-#ifdef TODO
+void restartGame(CONTEXT) {
 	Aint previousLocation = current.location;
 	current.location = where(HERO, DIRECT);
 	para();
-	if (confirm(M_REALLY)) {
-		longjmp(restartLabel, TRUE);
+
+	bool flag;
+	FUNC1(confirm, flag, M_REALLY)
+	if (flag) {
+		LONG_JUMP_LABEL("restart")
 	}
+
 	current.location = previousLocation;
-#else
-	syserr("TODO: restartGame");
-#endif
 }
 
 
diff --git a/engines/glk/alan3/exe.h b/engines/glk/alan3/exe.h
index 79e7720..df5892c 100644
--- a/engines/glk/alan3/exe.h
+++ b/engines/glk/alan3/exe.h
@@ -47,10 +47,6 @@ namespace Alan3 {
 extern Common::SeekableReadStream *textFile;		// The text and message file
 extern bool printFlag;
 
-/* Long jump buffer for restart, errors and undo */
-//extern jmp_buf returnLabel;
-
-
 /* FUNCTIONS */
 extern void sys(Aword fpos, Aword len);
 extern void sayInteger(int val);
@@ -61,9 +57,9 @@ extern char *getStringFromFile(Aword fpos, Aword len);
 extern void print(Aword fpos, Aword len);
 extern void score(Aword sc);
 extern void visits(Aword v);
-extern void undo(void);
-extern void quitGame(void);
-extern void restartGame(void);
+extern void undo(CONTEXT);
+extern void quitGame(CONTEXT);
+extern void restartGame(CONTEXT);
 
 extern void use(CONTEXT, int act, int scr);
 extern void stop(int act);
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index 3647548..4708cf8 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -590,7 +590,7 @@ void interpret(CONTEXT, Aaddr adr) {
 			case I_QUIT: {
 				if (traceInstructionOption)
 					printf("QUIT\t\t\t\t\t\t");
-				quitGame();
+				CALL0(quitGame)
 				break;
 			}
 			case I_LOOK: {
@@ -602,19 +602,19 @@ void interpret(CONTEXT, Aaddr adr) {
 			case I_SAVE: {
 				if (traceInstructionOption)
 					printf("SAVE\t\t\t\t\t\t");
-				g_vm->saveGame();
+				(void)g_vm->saveGame();
 				break;
 			}
 			case I_RESTORE: {
 				if (traceInstructionOption)
 					printf("RESTORE\t\t\t\t\t\t");
-				g_vm->loadGame();
+				(void)g_vm->loadGame();
 				break;
 			}
 			case I_RESTART: {
 				if (traceInstructionOption)
 					printf("RESTART\t\t\t\t\t\t");
-				restartGame();
+				CALL0(restartGame)
 				break;
 			}
 
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index de65b09..e56ac87 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -744,10 +744,11 @@ void run(void) {
 	Stack theStack = NULL;
 	Context ctx;
 
+	openFiles();
+	load(ctx);			// Load program
+
 	do {
 		ctx.clear();
-		openFiles();
-		load(ctx);			// Load program
 		if (ctx._break)
 			break;
 
@@ -765,23 +766,15 @@ void run(void) {
 		while (!g_vm->shouldQuit()) {
 			if (!(ctx._break && ctx._label == "forfeit")) {
 				if (ctx._break) {
-					assert(ctx._label == "return");
-#ifdef TODO
-					// Return here if error during execution
-					switch (setjmp(returnLabel)) {
-					case NO_JUMP_RETURN:
-						break;
-					case ERROR_RETURN:
+					assert(ctx._label.hasPrefix("return"));
+
+					if (ctx._label == "returnError") {
 						forgetGameState();
 						forceNewPlayerInput();
-						break;
-					case UNDO_RETURN:
+					} else if (ctx._label == "returnUndo") {
 						forceNewPlayerInput();
-						break;
-					default:
-						syserr("Unexpected longjmp() return value");
 					}
-#endif
+
 					ctx.clear();
 				} else {
 					if (debugOption)
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 8f3ab80..788e5ca 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -151,7 +151,7 @@ static void getLine(CONTEXT) {
 		FUNC2(g_io->readLine, flag, buf, 255);
 		if (!flag) {
 			newline();
-			quitGame();
+			CALL0(quitGame)
 		}
 
 		getPageSize();
@@ -179,7 +179,7 @@ static void getLine(CONTEXT) {
 				token = gettoken(NULL);
 				if (token != NULL) /* More tokens? */
 					CALL1(error, M_WHAT)
-				undo();
+				CALL0(undo)
 			}
 		}
 	} while (token == NULL);


Commit: 17d0459566bf570c34ba6873370aff71fd016d1b
    https://github.com/scummvm/scummvm/commit/17d0459566bf570c34ba6873370aff71fd016d1b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Fix gcc warning

Changed paths:
    engines/glk/alan3/alan3.h


diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
index f1d88f8..9b830c9 100644
--- a/engines/glk/alan3/alan3.h
+++ b/engines/glk/alan3/alan3.h
@@ -71,7 +71,7 @@ public:
 	 * 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;;
+	virtual Common::Error writeGameData(Common::WriteStream *ws) override;
 };
 
 extern Alan3 *g_vm;


Commit: 69f87bebf125b1be5e6d6cfe3432b417d5ca505e
    https://github.com/scummvm/scummvm/commit/69f87bebf125b1be5e6d6cfe3432b417d5ca505e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Fix double-free of memory array

Changed paths:
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/utils.cpp


diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index 8c22742..fbb0db5 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -205,7 +205,7 @@ void quitGame(CONTEXT) {
 
 	current.location = where(HERO, DIRECT);
 	para();
-	while (TRUE) {
+	while (!g_vm->shouldQuit()) {
 		col = 1;
 		CALL0(g_io->statusLine)
 		printMessage(M_QUITACTION);
diff --git a/engines/glk/alan3/utils.cpp b/engines/glk/alan3/utils.cpp
index acbf8e4..06ce3af 100644
--- a/engines/glk/alan3/utils.cpp
+++ b/engines/glk/alan3/utils.cpp
@@ -49,8 +49,10 @@ void terminate(CONTEXT, int code) {
 
 	stopTranscript();
 
-	if (memory)
+	if (memory) {
 		deallocate(memory);
+		memory = nullptr;
+	}
 
 	g_io->glk_exit();
 	LONG_JUMP


Commit: 4c014a105cf170efa4a57ae8231e256a8eb32e90
    https://github.com/scummvm/scummvm/commit/4c014a105cf170efa4a57ae8231e256a8eb32e90
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: Properly free pair window children on exit

Changed paths:
    engines/glk/window_pair.cpp


diff --git a/engines/glk/window_pair.cpp b/engines/glk/window_pair.cpp
index 8de16a0..e564e54 100644
--- a/engines/glk/window_pair.cpp
+++ b/engines/glk/window_pair.cpp
@@ -39,8 +39,10 @@ PairWindow::PairWindow(Windows *windows, uint method, Window *key, uint size) :
 }
 
 PairWindow::~PairWindow() {
-	for (uint idx = 0; idx < _children.size(); ++idx)
+	for (uint idx = 0; idx < _children.size(); ++idx) {
+		_children[idx]->_parent = nullptr;
 		delete _children[idx];
+	}
 }
 
 void PairWindow::rearrange(const Rect &box) {


Commit: 2fbb8af0bcec84d6653b97edf1699e94660e62fc
    https://github.com/scummvm/scummvm/commit/2fbb8af0bcec84d6653b97edf1699e94660e62fc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Move soundChannel static to GlkIO field

Changed paths:
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/glkio.h


diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index 61e9f18..c88e9fa 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -34,7 +34,8 @@ namespace Alan3 {
 GlkIO *g_io;
 
 GlkIO::GlkIO(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
-		glkMainWin(nullptr), glkStatusWin(nullptr), onStatusLine(false), _saveSlot(-1) {
+		glkMainWin(nullptr), glkStatusWin(nullptr), onStatusLine(false), _saveSlot(-1),
+		_soundChannel(nullptr) {
 	g_io = this;
 }
 
@@ -92,14 +93,12 @@ void GlkIO::playSound(int sound) {
 		return;
 
 #ifdef GLK_MODULE_SOUND
-	static schanid_t soundChannel = NULL;
-
 	if (glk_gestalt(gestalt_Sound, 0) == 1) {
-		if (soundChannel == NULL)
-			soundChannel = glk_schannel_create(0);
-		if (soundChannel != NULL) {
-			glk_schannel_stop(soundChannel);
-			(void)glk_schannel_play(soundChannel, sound);
+		if (_soundChannel == nullptr)
+			_soundChannel = glk_schannel_create(0);
+		if (_soundChannel) {
+			glk_schannel_stop(_soundChannel);
+			(void)glk_schannel_play(_soundChannel, sound);
 		}
 	}
 #endif
diff --git a/engines/glk/alan3/glkio.h b/engines/glk/alan3/glkio.h
index fb342d1..333a24b 100644
--- a/engines/glk/alan3/glkio.h
+++ b/engines/glk/alan3/glkio.h
@@ -34,6 +34,7 @@ class GlkIO : public GlkAPI {
 private:
 	winid_t glkMainWin;
 	winid_t glkStatusWin;
+	schanid_t _soundChannel;
 	int _saveSlot;
 public:
 	bool onStatusLine;


Commit: 1d2dee43d25307451b6915a6475f3a063a4fdc4b
    https://github.com/scummvm/scummvm/commit/1d2dee43d25307451b6915a6475f3a063a4fdc4b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: Fix playback of Blorb AIFF chunks

Changed paths:
    engines/glk/blorb.cpp


diff --git a/engines/glk/blorb.cpp b/engines/glk/blorb.cpp
index 3c60fd3..88d6552 100644
--- a/engines/glk/blorb.cpp
+++ b/engines/glk/blorb.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "glk/blorb.h"
+#include "common/memstream.h"
 
 namespace Glk {
 
@@ -64,16 +65,31 @@ const Common::ArchiveMemberPtr Blorb::getMember(const Common::String &name) cons
 
 Common::SeekableReadStream *Blorb::createReadStreamForMember(const Common::String &name) const {
 	for (uint idx = 0; idx < _chunks.size(); ++idx) {
-		if (_chunks[idx]._filename.equalsIgnoreCase(name)) {
+		const ChunkEntry &ce = _chunks[idx];
+
+		if (ce._filename.equalsIgnoreCase(name)) {
 			Common::File f;
 			if ((!_filename.empty() && !f.open(_filename)) ||
 					(_filename.empty() && !f.open(_fileNode)))
 				error("Reading failed");
 
-			f.seek(_chunks[idx]._offset);
-			Common::SeekableReadStream *result = f.readStream(_chunks[idx]._size);
-			f.close();
+			f.seek(ce._offset);
+			Common::SeekableReadStream *result;
+			
+			if (ce._id == ID_FORM) {
+				// AIFF chunks need to be wrapped in a FORM chunk for ScummVM decoder
+				byte *sound = (byte *)malloc(ce._size + 8);
+				WRITE_BE_UINT32(sound, MKTAG('F', 'O', 'R', 'M'));
+				WRITE_BE_UINT32(sound + 4, 0);
+				f.read(sound + 8, ce._size);
+				assert(READ_BE_UINT32(sound + 8) == ID_AIFF);
+
+				result = new Common::MemoryReadStream(sound, ce._size + 8, DisposeAfterUse::YES);
+			} else {
+				result = f.readStream(ce._size);
+			}
 
+			f.close();
 			return result;
 		}
 	}


Commit: 0502ac4bb1b41b17664adf46a2c3600553023c84
    https://github.com/scummvm/scummvm/commit/0502ac4bb1b41b17664adf46a2c3600553023c84
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:09-07:00

Commit Message:
GLK: ALAN3: Create GlkDetectedGame base class for simplifying detections

Changed paths:
    engines/glk/alan3/detection.cpp
    engines/glk/detection.cpp
    engines/glk/detection.h


diff --git a/engines/glk/alan3/detection.cpp b/engines/glk/alan3/detection.cpp
index cafc426..08a489b 100644
--- a/engines/glk/alan3/detection.cpp
+++ b/engines/glk/alan3/detection.cpp
@@ -71,24 +71,13 @@ bool Alan3MetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
 			++p;
 
-		DetectedGame gd;
 		if (!p->_gameId) {
 			const PlainGameDescriptor &desc = ALAN3_GAME_LIST[0];
-			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
 		} else {
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
-			gd = DetectedGame(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
+			gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
 		}
-
-		gd.addExtraEntry("filename", filename);
-		gameList.push_back(gd);
 	}
 
 	return !gameList.empty();
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index 33a15757..43f1291 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -54,6 +54,37 @@
 #include "common/config-manager.h"
 #include "common/file.h"
 
+namespace Glk {
+
+GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename) :
+		DetectedGame(gameId, gameDesc, Common::EN_ANY, Common::kPlatformUnknown) {
+	setGUIOptions(GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI));
+	addExtraEntry("filename", filename);
+}
+
+GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
+		Common::Language lang) : DetectedGame(gameId, gameDesc, lang, Common::kPlatformUnknown) {
+	setGUIOptions(GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI));
+	addExtraEntry("filename", filename);
+}
+
+GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
+		const Common::String &md5, size_t filesize) :
+		DetectedGame(gameId, gameDesc, Common::UNK_LANG, Common::kPlatformUnknown) {
+	setGUIOptions(GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI));
+	addExtraEntry("filename", filename);
+
+	canBeAdded = true;
+	hasUnknownFiles = true;
+
+	FileProperties fp;
+	fp.md5 = md5;
+	fp.size = filesize;
+	matchedFiles[filename] = fp;
+}
+
+} // End of namespace Glk
+
 bool GlkMetaEngine::hasFeature(MetaEngineFeature f) const {
 	return
 	    (f == kSupportsListSaves) ||
diff --git a/engines/glk/detection.h b/engines/glk/detection.h
index 0b21985..2e2047e 100644
--- a/engines/glk/detection.h
+++ b/engines/glk/detection.h
@@ -102,6 +102,18 @@ struct GameDescriptor {
 	}
 };
 
+/**
+ * Derived game descriptor class to simplifying setting up needed properties
+ */
+class GlkDetectedGame : public DetectedGame {
+public:
+	GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename);
+	GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
+		Common::Language lang);
+	GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
+		const Common::String &md5, size_t filesize);
+};
+
 } // End of namespace Glk
 
 #endif


Commit: 5dda48c1c785b8a477785ee6040db82b904858bb
    https://github.com/scummvm/scummvm/commit/5dda48c1c785b8a477785ee6040db82b904858bb
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:10-07:00

Commit Message:
GLK: Change other sub-engines to use GlkDetectedGame

Changed paths:
    engines/glk/advsys/detection.cpp
    engines/glk/alan2/detection.cpp
    engines/glk/detection.cpp
    engines/glk/frotz/detection.cpp
    engines/glk/glulxe/detection.cpp
    engines/glk/hugo/detection.cpp
    engines/glk/magnetic/detection.cpp
    engines/glk/scott/detection.cpp
    engines/glk/tads/detection.cpp


diff --git a/engines/glk/advsys/detection.cpp b/engines/glk/advsys/detection.cpp
index d6641a6..f14fda2 100644
--- a/engines/glk/advsys/detection.cpp
+++ b/engines/glk/advsys/detection.cpp
@@ -78,24 +78,13 @@ bool AdvSysMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
 		while (p->_md5 && p->_filesize != filesize && md5 != p->_md5)
 			++p;
 
-		if (p->_filesize) {
+		if (!p->_gameId) {
+			const PlainGameDescriptor &desc = ADVSYS_GAME_LIST[0];
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
+		} else {
 			// Found a match
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
-			DetectedGame gd(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
-			gd.addExtraEntry("filename", file->getName());
-
-			gameList.push_back(gd);
-		} else {
-			const PlainGameDescriptor &desc = ADVSYS_GAME_LIST[0];
-			DetectedGame gd(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[file->getName()] = fp;
-
-			gameList.push_back(gd);
+			gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
 		}
 	}
 
diff --git a/engines/glk/alan2/detection.cpp b/engines/glk/alan2/detection.cpp
index 2338ebb..345e230 100644
--- a/engines/glk/alan2/detection.cpp
+++ b/engines/glk/alan2/detection.cpp
@@ -71,24 +71,13 @@ bool Alan2MetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
 			++p;
 
-		DetectedGame gd;
 		if (!p->_gameId) {
 			const PlainGameDescriptor &desc = ALAN2_GAME_LIST[0];
-			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
 		} else {
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
-			gd = DetectedGame(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
+			gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
 		}
-
-		gd.addExtraEntry("filename", filename);
-		gameList.push_back(gd);
 	}
 
 	return !gameList.empty();
diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index 43f1291..7c6de28 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -58,20 +58,20 @@ namespace Glk {
 
 GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename) :
 		DetectedGame(gameId, gameDesc, Common::EN_ANY, Common::kPlatformUnknown) {
-	setGUIOptions(GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI));
+	setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
 	addExtraEntry("filename", filename);
 }
 
 GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
 		Common::Language lang) : DetectedGame(gameId, gameDesc, lang, Common::kPlatformUnknown) {
-	setGUIOptions(GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI));
+	setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
 	addExtraEntry("filename", filename);
 }
 
 GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
 		const Common::String &md5, size_t filesize) :
 		DetectedGame(gameId, gameDesc, Common::UNK_LANG, Common::kPlatformUnknown) {
-	setGUIOptions(GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI));
+	setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
 	addExtraEntry("filename", filename);
 
 	canBeAdded = true;
diff --git a/engines/glk/frotz/detection.cpp b/engines/glk/frotz/detection.cpp
index 4502fc6..d4ffee3 100644
--- a/engines/glk/frotz/detection.cpp
+++ b/engines/glk/frotz/detection.cpp
@@ -114,29 +114,21 @@ bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 				(filesize != p->_filesize && isBlorb)))
 			++p;
 
-		DetectedGame gd;
 		if (!p->_gameId) {
 			// Generic .dat/.zip files don't get reported as matches unless they have a known md5
 			if (filename.hasSuffixIgnoreCase(".dat") || filename.hasSuffixIgnoreCase(".zip") || emptyBlorb)
 				continue;
 
 			const PlainGameDescriptor &desc = ZCODE_GAME_LIST[0];
-			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
 		} else {
 			GameDescriptor gameDesc = findGame(p->_gameId);
-			gd = DetectedGame(p->_gameId, gameDesc._description, p->_language, Common::kPlatformUnknown, p->_extra);
+			DetectedGame gd = DetectedGame(p->_gameId, gameDesc._description, p->_language, Common::kPlatformUnknown, p->_extra);
 			gd.setGUIOptions(p->_guiOptions);
-		}
 
-		gd.addExtraEntry("filename", filename);
-		gameList.push_back(gd);
+			gd.addExtraEntry("filename", filename);
+			gameList.push_back(gd);
+		}
 	}
 
 	return !gameList.empty();
diff --git a/engines/glk/glulxe/detection.cpp b/engines/glk/glulxe/detection.cpp
index 5ee6285..39233e4 100644
--- a/engines/glk/glulxe/detection.cpp
+++ b/engines/glk/glulxe/detection.cpp
@@ -79,25 +79,13 @@ bool GlulxeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
 		while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
 			++p;
 
-		DetectedGame gd;
 		if (!p->_gameId) {
 			const PlainGameDescriptor &desc = GLULXE_GAME_LIST[0];
-			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
 		} else {
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
-			gd = DetectedGame(p->_gameId, gameDesc.description, p->_language, Common::kPlatformUnknown, p->_extra);
-			gd.setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
+			gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
 		}
-
-		gd.addExtraEntry("filename", filename);
-		gameList.push_back(gd);
 	}
 
 	return !gameList.empty();
diff --git a/engines/glk/hugo/detection.cpp b/engines/glk/hugo/detection.cpp
index daff460..bd59717 100644
--- a/engines/glk/hugo/detection.cpp
+++ b/engines/glk/hugo/detection.cpp
@@ -74,25 +74,13 @@ bool HugoMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &ga
 		while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
 			++p;
 
-		DetectedGame gd;
 		if (!p->_gameId) {
 			const PlainGameDescriptor &desc = HUGO_GAME_LIST[0];
-			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
 		} else {
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
-			gd = DetectedGame(p->_gameId, gameDesc.description, p->_language, Common::kPlatformUnknown, p->_extra);
-			gd.setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
+			gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
 		}
-
-		gd.addExtraEntry("filename", filename);
-		gameList.push_back(gd);
 	}
 
 	return !gameList.empty();
diff --git a/engines/glk/magnetic/detection.cpp b/engines/glk/magnetic/detection.cpp
index 1552eec..cc1714e 100644
--- a/engines/glk/magnetic/detection.cpp
+++ b/engines/glk/magnetic/detection.cpp
@@ -79,25 +79,13 @@ bool MagneticMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames
 		while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
 			++p;
 
-		DetectedGame gd;
 		if (!p->_gameId) {
 			const PlainGameDescriptor &desc = MAGNETIC_GAME_LIST[0];
-			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
 		} else {
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
-			gd = DetectedGame(p->_gameId, gameDesc.description, p->_language, Common::kPlatformUnknown, p->_extra);
-			gd.setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
+			gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
 		}
-
-		gd.addExtraEntry("filename", filename);
-		gameList.push_back(gd);
 	}
 
 	return !gameList.empty();
diff --git a/engines/glk/scott/detection.cpp b/engines/glk/scott/detection.cpp
index 03445ea..f0a6e47 100644
--- a/engines/glk/scott/detection.cpp
+++ b/engines/glk/scott/detection.cpp
@@ -77,28 +77,17 @@ bool ScottMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		while (p->_md5 && p->_filesize != filesize && md5 != p->_md5)
 			++p;
 
-		DetectedGame gd;
 		if (!p->_gameId) {
 			if (!isBlorb && filename.hasSuffixIgnoreCase(".dat"))
 				continue;
 
 			const PlainGameDescriptor &desc = SCOTT_GAME_LIST[0];
-			gd = DetectedGame(desc.gameId, desc.description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
 		} else {
 			// Found a match
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
-			DetectedGame gd(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
-			gd.addExtraEntry("filename", file->getName());
+			gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, filename));
 		}
-
-		gameList.push_back(gd);
 	}
 
 	return !gameList.empty();
diff --git a/engines/glk/tads/detection.cpp b/engines/glk/tads/detection.cpp
index 8ea996b..4cb7e56 100644
--- a/engines/glk/tads/detection.cpp
+++ b/engines/glk/tads/detection.cpp
@@ -107,21 +107,13 @@ bool TADSMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &ga
 		DetectedGame gd;
 		if (!p->_gameId) {
 			const GameDescriptor &desc = tadsVersion == 2 ? TADS2_GAME_LIST[0] : TADS3_GAME_LIST[0];
-			gd = DetectedGame(desc._gameId, desc._description, Common::UNK_LANG, Common::kPlatformUnknown);
-			gd.canBeAdded = true;
-			gd.hasUnknownFiles = true;
-			FileProperties fp;
-			fp.md5 = md5;
-			fp.size = filesize;
-			gd.matchedFiles[filename] = fp;
-
+			gameList.push_back(GlkDetectedGame(desc._gameId, desc._description, filename, md5, filesize));
 		} else {
 			PlainGameDescriptor gameDesc = findGame(p->_gameId);
 			gd = DetectedGame(p->_gameId, gameDesc.description, p->_language, Common::kPlatformUnknown, p->_extra);
+			gd.addExtraEntry("filename", filename);
+			gameList.push_back(gd);
 		}
-
-		gd.addExtraEntry("filename", filename);
-		gameList.push_back(gd);
 	}
 
 	return !gameList.empty();


Commit: 2c39c903fcd759de50e23de06b3388989e6f92a9
    https://github.com/scummvm/scummvm/commit/2c39c903fcd759de50e23de06b3388989e6f92a9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:27:10-07:00

Commit Message:
GLK: GLULXE: Fix MSVC field alignment warnings

Changed paths:
    engines/glk/glulxe/glulxe.h


diff --git a/engines/glk/glulxe/glulxe.h b/engines/glk/glulxe/glulxe.h
index bf1bad9..02c8ab9 100644
--- a/engines/glk/glulxe/glulxe.h
+++ b/engines/glk/glulxe/glulxe.h
@@ -47,7 +47,6 @@ private:
 	bool vm_exited_cleanly;
 	uint gamefile_start, gamefile_len;
 	char *init_err, *init_err2;
-	UnicharHandler stream_unichar_handler, glkio_unichar_han_ptr;
 	CharHandler stream_char_handler;
 
 	byte *memmap;
@@ -144,6 +143,8 @@ private:
 
 	/**@}*/
 
+	UnicharHandler stream_unichar_handler, glkio_unichar_han_ptr;
+
 	/**
 	 * \defgroup serial fields
 	 * @{


Commit: 1c412d3da705dabd709614c409927ce8f6fbfe05
    https://github.com/scummvm/scummvm/commit/1c412d3da705dabd709614c409927ce8f6fbfe05
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-07-06T15:32:39-07:00

Commit Message:
GLK: Properly handle sound setup

Changed paths:
    engines/glk/detection.cpp
    engines/glk/glk.cpp
    engines/glk/glk.h


diff --git a/engines/glk/detection.cpp b/engines/glk/detection.cpp
index 7c6de28..b19ecde 100644
--- a/engines/glk/detection.cpp
+++ b/engines/glk/detection.cpp
@@ -58,20 +58,20 @@ namespace Glk {
 
 GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename) :
 		DetectedGame(gameId, gameDesc, Common::EN_ANY, Common::kPlatformUnknown) {
-	setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
+	setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
 	addExtraEntry("filename", filename);
 }
 
 GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
 		Common::Language lang) : DetectedGame(gameId, gameDesc, lang, Common::kPlatformUnknown) {
-	setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
+	setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
 	addExtraEntry("filename", filename);
 }
 
 GlkDetectedGame::GlkDetectedGame(const char *gameId, const char *gameDesc, const Common::String &filename,
 		const Common::String &md5, size_t filesize) :
 		DetectedGame(gameId, gameDesc, Common::UNK_LANG, Common::kPlatformUnknown) {
-	setGUIOptions(GUIO4(GUIO_NOSPEECH, GUIO_NOSFX, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
+	setGUIOptions(GUIO3(GUIO_NOSPEECH, GUIO_NOMUSIC, GUIO_NOSUBTITLES));
 	addExtraEntry("filename", filename);
 
 	canBeAdded = true;
diff --git a/engines/glk/glk.cpp b/engines/glk/glk.cpp
index b17304d..06ab742 100644
--- a/engines/glk/glk.cpp
+++ b/engines/glk/glk.cpp
@@ -89,6 +89,9 @@ void GlkEngine::initialize() {
 	_sounds = new Sounds();
 	_streams = new Streams();
 	_windows = new Windows(_screen);
+
+	// Setup mixer
+	syncSoundSettings();
 }
 
 Screen *GlkEngine::createScreen() {
@@ -248,6 +251,13 @@ Common::Error GlkEngine::saveGameState(int slot, const Common::String &desc) {
 	return errCode;
 }
 
+void GlkEngine::syncSoundSettings() {
+	Engine::syncSoundSettings();
+
+	int volume = ConfMan.getBool("sfx_mute") ? 0 : CLIP(ConfMan.getInt("sfx_volume"), 0, 255);
+	_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
+}
+
 void GlkEngine::beep() {
 	_pcSpeaker->speakerOn(50, 50);
 }
diff --git a/engines/glk/glk.h b/engines/glk/glk.h
index 739f177..cc3fc10 100644
--- a/engines/glk/glk.h
+++ b/engines/glk/glk.h
@@ -209,6 +209,11 @@ public:
 	virtual Common::Error writeGameData(Common::WriteStream *ws) = 0;
 
 	/**
+	 * Updates sound settings
+	 */
+	virtual void syncSoundSettings() override;
+
+	/**
 	 * Generate a beep
 	 */
 	void beep();





More information about the Scummvm-git-logs mailing list