Miscellaneous constant definitions, usually providing symbolic names for otherwise inscrutable numbers, which are used throughout the template layer.


§1. Identification.

Constant BASICINFORMKIT = 1;
Constant SERIAL_COMMA = BasicInformKit`SERIAL_COMMA_CFGF;

§2. Nothing. This is defined automatically by the Inform 6 compiler, but not by other final compilation platforms (such as C).

Constant nothing = 0;

§3. Powers of Two. I6 lacks support for logical shifts, and the Z-machine opcodes which bear on this are not always well supported, so the I6 library has traditionally used a lookup table for the values of \(2^{15-n}\) where \(0\leq n \leq 11\).

Array PowersOfTwo_TB
  --> $$100000000000
      $$010000000000
      $$001000000000
      $$000100000000
      $$000010000000
      $$000001000000
      $$000000100000
      $$000000010000
      $$000000001000
      $$000000000100
      $$000000000010
      $$000000000001;

Array IncreasingPowersOfTwo_TB
  --> $$0000000000000001
      $$0000000000000010
      $$0000000000000100
      $$0000000000001000
      $$0000000000010000
      $$0000000000100000
      $$0000000001000000
      $$0000000010000000
      $$0000000100000000
      $$0000001000000000
      $$0000010000000000
      $$0000100000000000
      $$0001000000000000
      $$0010000000000000
      $$0100000000000000
      $$1000000000000000;

§4. Text Styles. These are the styles of text distinguished by the template layer, though they are not required to look different from each other on any given VM. The codes are independent of the VM targetted, though in fact they are equal to Glulx style numbers as conventionally used. (The Z-machine renders some as roman, some as bold, but for instance makes HEADER_VMSTY and SUBHEADER_VMSTY indistinguishable to the eye.) Glulx's system of styles is one of its weakest points from an IF author's perspective, since it is all but impossible to achieve the text effects one might want — boldface, for instance, or red text — and text rendering is almost the only area in which it is clearly inferior to the Z-machine, which it was designed to replace. Still, using these styles when we can will get the most out of it, and for unornamental works Glulx is fine in practice.

Constant NORMAL_VMSTY     = 0;
Constant HEADER_VMSTY     = 3;
Constant SUBHEADER_VMSTY  = 4;
Constant ALERT_VMSTY      = 5;
Constant NOTE_VMSTY       = 6;
Constant BLOCKQUOTE_VMSTY = 7;
Constant INPUT_VMSTY      = 8;

§5. Colour Codes. While most colour numbers are defined through the basic colour kind in the Architecture16/32Kits, these two colour codes are defined here instead.

#Ifdef TARGET_GLULX;
    Constant BASIC_COLOUR_CURRENT = -2;
    Constant BASIC_COLOUR_DEFAULT = -1;
#Ifnot;
    Constant BASIC_COLOUR_CURRENT = 0;
    Constant BASIC_COLOUR_DEFAULT = 1;
#Endif;

§6. Window Numbers. Although Glulx can support elaborate tessellations of windows on screen (if the complexity of handling this can be mastered), the Z-machine has much more limited resources in general, so the template layer assumes a simple screen model: there are just two screen areas, the scrolling main window in which commands are typed and responses printed, and the fixed status line bar at the top of the screen.

Constant WIN_ALL     = 0; Both windows at once
Constant WIN_STATUS  = 1;
Constant WIN_MAIN    = 2;

§7. Function key codes. So that users of VM_KeyChar() don't need to be aware of platform differences, function key codes are mapped to these common codes.

Constant KEY_DELETE = $0008;
Constant KEY_DOWN = $2193;
Constant KEY_END = $21F2;
Constant KEY_ESCAPE = $001B;
Constant KEY_F1 = $EF01;
Constant KEY_F2 = $EF02;
Constant KEY_F3 = $EF03;
Constant KEY_F4 = $EF04;
Constant KEY_F5 = $EF05;
Constant KEY_F6 = $EF06;
Constant KEY_F7 = $EF07;
Constant KEY_F8 = $EF08;
Constant KEY_F9 = $EF09;
Constant KEY_F10 = $EF0A;
Constant KEY_F11 = $EF0B;
Constant KEY_F12 = $EF0C;
Constant KEY_HOME = $21F1;
Constant KEY_LEFT = $2190;
Constant KEY_PAGE_DOWN = $21DF;
Constant KEY_PAGE_UP = $21DE;
Constant KEY_RETURN = $000A;
Constant KEY_RIGHT = $2192;
Constant KEY_TAB = $0009;
Constant KEY_UNKNOWN = $FFFD;
Constant KEY_UP = $2191;

§8. Paragraphing Flags. I am not sure many dictionaries would countenance "to paragraph" as a verb, but never mind: the reference here is to the algorithm used to place paragraph breaks within text, which uses bitmaps composed of the following.

Constant PARA_COMPLETED          = 1;
Constant PARA_PROMPTSKIP         = 2;
Constant PARA_SUPPRESSPROMPTSKIP = 4;
Constant PARA_NORULEBOOKBREAKS   = 8;
Constant PARA_CONTENTEXPECTED    = 16;

§9. Descriptors in the Language of Play. The following constants are used in the LanguageDescriptors table found in the definition of the language of play.

Constant POSSESS_PK   = $100;
Constant DEFART_PK    = $101;
Constant INDEFART_PK  = $102;
Constant LIGHTED_PK   = $103;
Constant UNLIGHTED_PK = $104;

§10. Auxiliary file structure. The I7 kind of value "auxiliary-file" is an --> array, holding a memory structure containing information about external files. The following constants specify memory offsets and values. Note the safety value stored as the first word of the structure: this helps protect the routines below from accidents.

Constant AUXF_MAGIC = 0; First word holds a safety constant
Constant AUXF_MAGIC_VALUE = 16339; Should be first word of any valid file structure
Constant AUXF_STATUS = 1; One of the following:
    Constant AUXF_STATUS_IS_CLOSED = 1; Currently closed, or perhaps doesn't exist
    Constant AUXF_STATUS_IS_OPEN_FOR_READ = 2;
    Constant AUXF_STATUS_IS_OPEN_FOR_WRITE = 3;
    Constant AUXF_STATUS_IS_OPEN_FOR_APPEND = 4;
    Constant AUXF_STATUS_IS_ERRONEOUS = 5;
Constant AUXF_BINARY = 2; False for text files (I7 default), true for binary
Constant AUXF_STREAM = 3; Stream for an open file (meaningless otherwise)
Constant AUXF_FILENAME = 4; Packed address of constant string
Constant AUXF_IFID_OF_OWNER = 5; UUID_ARRAY if owned by this project, or
    string array of IFID of owner, or NULL to leave open
Constant AUXF_RESOURCE_ID = 6; Only for internal files, identified by Blorb resource

§11. Scope Searching Reasons. The parser makes use of a mechanism for searching through the objects currently "in scope", which basically means visible to the actor who would perform the action envisaged by the command being parsed. It is sometimes useful to behave differently depending on why this scope searching is being done, so the following constants enumerate the possibilities.

I6's EACH_TURN_REASON, REACT_BEFORE_REASON and REACT_AFTER_REASON have been removed from this list as no longer meaningful; hence the lacuna in numbering.

Constant PARSING_REASON       = 0;
Constant TALKING_REASON       = 1;
Constant EACH_TURN_REASON     = 2;
Constant LOOPOVERSCOPE_REASON = 5;
Constant TESTSCOPE_REASON     = 6;

§12. Token Types. Tokens are the indecomposable pieces of a grammar line making up a possible reading of a command; some are literal words, others stand for "any named object in scope", and so on. The following codes identify the possibilities. The *_TOKEN constants must not be altered without modifying the I6 compiler to match (so, basically, they must not be altered at all).

Constant ILLEGAL_TT         = 0;    Types of grammar token: illegal
Constant ELEMENTARY_TT      = 1;        (one of those below)
Constant PREPOSITION_TT     = 2;        e.g. 'into'
Constant ROUTINE_FILTER_TT  = 3;        e.g. noun=CagedCreature
Constant ATTR_FILTER_TT     = 4;        e.g. edible
Constant SCOPE_TT           = 5;        e.g. scope=Spells
Constant GPR_TT             = 6;        a general parsing routine

Constant NOUN_TOKEN         = 0;    The elementary grammar tokens, and
Constant HELD_TOKEN         = 1;    the numbers compiled by I6 to
Constant MULTI_TOKEN        = 2;    encode them
Constant MULTIHELD_TOKEN    = 3;
Constant MULTIEXCEPT_TOKEN  = 4;
Constant MULTIINSIDE_TOKEN  = 5;
Constant CREATURE_TOKEN     = 6;
Constant SPECIAL_TOKEN      = 7;
Constant NUMBER_TOKEN       = 8;
Constant TOPIC_TOKEN        = 9;
Constant ENDIT_TOKEN        = 15;   Value used to mean "end of grammar line"

§13. GPR Return Values. GRP stands for "General Parsing Routine", an I6 routine which acts as a grammar token: again, see the {\it Inform Designer's Manual}, 4th edition, for details.

In Library 6/11, GPR_NOUN is defined as $ff00, but this would fail on Glulx: it needs to be $ffffff00 on 32-bit virtual machines. It appears that GPR_NOUN to GPR_CREATURE, though documented in the old {\it Inform Translator's Manual}, were omitted when this was consolidated into the DM4, so that they effectively disappeared from view. But they might still be useful for implementing inflected forms of nouns, so we have retained them here regardless.

Constant GPR_FAIL           = -1;   Return values from General Parsing
Constant GPR_PREPOSITION    = 0;    Routines
Constant GPR_NUMBER         = 1;
Constant GPR_MULTIPLE       = 2;
Constant GPR_REPARSE        = REPARSE_CODE;
Constant GPR_NOUN           = -256; Reparse, but as NOUN_TOKEN this time
Constant GPR_HELD           = GPR_NOUN + 1; And so on
Constant GPR_MULTI          = GPR_NOUN + 2;
Constant GPR_MULTIHELD      = GPR_NOUN + 3;
Constant GPR_MULTIEXCEPT    = GPR_NOUN + 4;
Constant GPR_MULTIINSIDE    = GPR_NOUN + 5;
Constant GPR_CREATURE       = GPR_NOUN + 6;

§14. List Styles. These constants make up bitmaps of the options in use when listing objects.

Constant NEWLINE_BIT        = $$0000000000000001; New-line after each entry
Constant INDENT_BIT         = $$0000000000000010; Indent each entry by depth
Constant FULLINV_BIT        = $$0000000000000100; Full inventory information after entry
Constant ENGLISH_BIT        = $$0000000000001000; English sentence style, with commas and and
Constant RECURSE_BIT        = $$0000000000010000; Recurse downwards with usual rules
Constant ALWAYS_BIT         = $$0000000000100000; Always recurse downwards
Constant TERSE_BIT          = $$0000000001000000; More terse English style
Constant PARTINV_BIT        = $$0000000010000000; Only brief inventory information after entry
Constant DEFART_BIT         = $$0000000100000000; Use the definite article in list
Constant WORKFLAG_BIT       = $$0000001000000000; At top level (only), only list objects
                                                  which have the "workflag" attribute
Constant ISARE_BIT          = $$0000010000000000; Print " is" or " are" before list
Constant CONCEAL_BIT        = $$0000100000000000; Omit objects with "concealed" or "scenery":
                                                  if WORKFLAG_BIT also set, then does not
                                                  apply at top level, but does lower down
Constant NOARTICLE_BIT      = $$0001000000000000; Print no articles, definite or not
Constant EXTRAINDENT_BIT    = $$0010000000000000; New in I7: extra indentation of 1 level
Constant CFIRSTART_BIT      = $$0100000000000000; Capitalise first article in list

§15. Lengths Of Time. Inform measures time in minutes.

Constant QUARTER_HOUR = 15;
Constant HALF_HOUR = 30;
Constant ONE_HOUR = 60;
Constant TWELVE_HOURS = 720;
Constant TWENTY_FOUR_HOURS = 1440;

§16. Empty Text. The I6 compiler does not optimise string compilation: if it needs to compile the (packed, read-only) string "exemplum" twice, it will compile two copies. This is slightly wasteful on memory, though in practice the loss is not enough for us to care. But we do want to avoid this in I7 because, to make string-sorting algorithms more efficient, we want direct numerical comparison of packed addresses to be equivalent to string comparison: and that means the text "exemplum" has to be compiled once and once only. There's a general mechanism for this in Inform, but the single case most often needed is the empty text, since this is the default value for text variables and properties: we give it a name as follows.

Constant EMPTY_TEXT_PACKED "";
Array EMPTY_TEXT_VALUE --> CONSTANT_PACKED_TEXT_STORAGE EMPTY_TEXT_PACKED;

§17. Empty Table. Similarly: the default value for the "table" kind of value, a Table containing no rows and no columns.

Array TheEmptyTable --> 0 0;

§18. Empty Set. The falsity proposition describes the empty set of objects, and is the zero value for the "description" kind of value.

[ Prop_Falsity reason obj; return 0; ];

§19. Template Attributes. An I6 attribute is equivalent to an I7 "either/or property", though the latter are not always translated into I6 attributes because the Z-machine has only a limited number of attributes to use. Here, we define attributes used by the template.

Many concepts in I6 correspond directly to their successors in I7, even if details may vary. (Value properties are a case in point.) Attributes are the opposite of this: indeed, no I6 concept is more fragmented in its I7 equivalents. All but one of the old I6 library attributes are still used (the general attribute, for miscellaneous use, has been removed: it more often invited abuse than use); and a few new attributes have been added. But they are used for a variety of purposes. Some do correspond exactly to either/or properties in I7, but others are a sort of signature for I7 kinds. (So that for I7 use they are read-only.) Others still are used by the template layer as part of the implementation of services for I7, but are not visible to I7 source text as storage.

Attribute absent; Used to mark objects removed from play
Attribute animate; I6-level marker for I7 kind "person"
Attribute clothing; = I7 "wearable"
Attribute concealed; = I7 "undescribed"
Attribute container; I6-level marker for I7 kind "container"
Attribute door; I6-level marker for I7 kind "door"
Attribute edible; = I7 "edible" vs "inedible"
Attribute enterable; = I7 "enterable"
Attribute light; = I7 "lighted" vs "dark"
Attribute lockable; = I7 "lockable"
Attribute locked; = I7 "locked"
Attribute moved; = I7 "handled"
Attribute on; = I7 "switched on" vs "switched off"
Attribute open; = I7 "open" vs "closed"
Attribute openable; = I7 "openable"
Attribute scenery; = I7 "scenery"
Attribute static; = I7 "fixed in place" vs "portable"
Attribute supporter; I6-level marker for I7 kind "supporter"
Attribute switchable; I6-level marker for I7 kind "device"
Attribute talkable; Not currently used by I7, but retained for possible future use
Attribute transparent; = I7 "transparent" vs "opaque"
Attribute visited; = I7 "visited"
Attribute worn; marks that an object tree edge represents wearing

Attribute male; not directly used by I7, but available for languages with genders
Attribute female; = I7 "female" vs "male"
Attribute neuter; = I7 "neuter"
Attribute pluralname; = I7 "plural-named"
Attribute ambigpluralname; = I7 "ambiguously plural"
Attribute proper; = I7 "proper-named"
Attribute remove_proper; remember to remove proper again when using ChangePlayer next

Attribute privately_named; New in I7
Attribute mentioned; New in I7
Attribute pushable; New in I7

Attribute mark_as_room; Used in I7 to speed up testing "ofclass K1_room"
Attribute mark_as_thing; Used in I7 to speed up testing "ofclass K2_thing"

Attribute workflag; = I7 "marked for listing", but basically temporary workspace
Attribute workflag2; new in I7 and also temporary workspace
Constant list_filter_permits = privately_named; another I7 listwriter convenience

§20. Template Properties. As remarked above, these more often correspond to value properties in I7. To an experienced I6 user, though, the death toll of abolished I6 properties in I7 is breathtaking: in alphabetical order, after, cant_go, daemon, each_turn, invent, life, number, orders, react_after, react_before, time_left, time_out, when_closed, when_off, when_on, when_open. In May 2008, the direction properties n_to, s_to, e_to, ..., out_to joined the list of the missing.

The losses are numerous because of the shift from I6's object orientation to I7's rule orientation: information about the behaviour of objects is no longer thought of as data attached to them. At that, it could have been worse: a few unused I6 library properties have been retained for possible future use.

Property add_to_scope; used as in I6 to place component parts in scope
Property article "a"; used as in I6 to implement articles
Property capacity 100; = I7 "carrying capacity"
Property component_child; new in I7: forest structure holding "part of" relation
Property component_parent; new in I7
Property component_sibling; new in I7
Property description; = I7 "description"
Property door_dir; used to implement two-sided doors, but holds direction object, not a property
Property door_to; used as in I6 to implement two-sided doors
Property found_in; used as in I6 to implement two-sided doors and backdrops
Property initial; = I7 "initial description"
Property list_together; used as in I6 to implement "grouping together" activity
Property map_region; new in I7
Property parse_name 0; used as in I6 to implement "Understand... as..." grammars
Property plural; used as in I6 to implement plural names for duplicate objects
Property regional_found_in; new in I7
Property room_index; new in I7: storage for route-finding
Property short_name 0; = I7 "printed name"
Property saved_short_name 0; cache for ChangePlayer
Property vector; new in I7: storage for route-finding
Property with_key; = I7 "matching key"

Property KD_Count; Instance count of the kind of the current object
Property IK1_Count; These are instance counts within kinds K1, K2, ...
Property IK2_Count; and it is efficient to declare the common ones with Property
Property IK4_Count; since this results in a slightly smaller story file
Property IK5_Count;
Property IK6_Count;
Property IK8_Count;
Property IK3_Count;

Property IK1_link; These are for linked lists used to make searches faster
Property IK2_link; and again it's memory-efficient to declare the common ones
Property IK5_link; 
Property IK6_link; 
Property IK8_link; 

Property articles; not used by I7, but an interesting hook in the parser
Property grammar; not used by I7, but an interesting hook in the parser
Property inside_description; not used by I7, but an interesting hook in the locale code
Property short_name_indef 0; not used by I7, but an interesting hook in the listmaker

§21. Formal Parameters. These are needed for efficient run-time ambiguity resolution.

Global formal_rv;
Global formal_par0;
Global formal_par1;
Global formal_par2;
Global formal_par3;
Global formal_par4;
Global formal_par5;
Global formal_par6;
Global formal_par7;
Global unicode_temp;