Banner - Inform Glux/Glk for Dunces. Banner includes a dunce cap and the three, say no evil, hear no evil, see no evil monkeys.


  1. How is Glk like a forest?

    A giggling monkey. Because it has rocks, streams, and trees. Before proceeding, we need to get some Glky terms out of the way. (Heheh. As an animal, I really like this part. Sorry, I just had to say it.)

    Glk Geology (Structure)
    Objects/Classes
    Windows (independent screen areas)
    Streams (text output/input)
    Sound channels (audio output)
    File references (pointers to external files)

    Blorb Resources
    Images - JPEG (JPG), PNG
    Sounds - AIFF, MOD
    Events Event Originator
    Line input Player
    Character input Player
    Mouse input Player
    Hyperlink selection Player
    Arrange window (resize) Player
    Redraw graphic window Player/
    Internal
    Timed events (Timer) Author

    Objects - Glk objects are an instance of a class, as is often the case in regular Inform. So a window object is an instance of the Window class, a stream object is an instance of the Stream class, etc. But there the similarity to regular Inform objects ends. Glk objects are dynamic -- created at run-time in the interpreter's memory. So, as an Inform programmer, you cannot code a Glk object directly. Instead, you declare a global variable that will "point" to it, a reference (point at its memory address -- actually point at an entry in a hash table). Using such a global variable (declared by yourself or the Glulx Inform library), you can then call Glk functions to directly affect Glk objects.

    Events - Events are input/output actions. They are trapped by the new built-in Inform function, [HandleGlkEvent]. This guide won't cover the Glk timer (the only output event), which is a timed event handled by Glk. However, note that Glk's timer is based on actual time passed, while regular Inform's timer routine is based on the number of turns passed.

    Blorb Resources - Blorb resources are not PART of Glk -- they are external resources that can be loaded into Glk objects:  graphic images into graphic windows; sound files into sound channels. This means that the graphic/sound file formats that blorb supports can be added onto over time.

    Glk Biology (Terminology)

    1. Gestalt (the forest) - The gestalt is essentially Glk's overall potential configuration, since not all interpreters support all Glk functions. So when writing a game, you need to call Glk's gestalt functions to test if the player's interpreter supports a specific Glk I/O capability, such as sound, before attempting to play the sound.

    2. Rocks - Rocks are ID numbers that function as anchors for each Glk object. When creating a new Glk object reference, you need to give it a unique rock number. This also becomes very important when you use Glulx Inform's Glk entry point:   IdentifyGlkObj (see Part 3, Glk Entry Points).

      Since these rock numbers are already defined as constants in the bi-platform library, they should be considered "reserved":

      GG_MAINWIN_ROCK
      201
      main text window windows
      GG_STATUSWIN_ROCK
      202
      status line window
      GG_QUOTEWIN_ROCK
      203
      quote box window
      GG_SAVESTR_ROCK
      301
      save file streams
      (open files)
      GG_SCRIPTSTR_ROCK
      302
      transcript file
      GG_COMMANDRSTR_ROCK
      303
      command file
      (for debugging)
      GG_COMMANDRSTR_ROCK
      304
      (ditto)
      GG_SCRIPTFREF_ROCK
      401
      script file name file references


      Following this numbering convention, Zarf recommends that when you create new windows, you should start with a rock number of 210. Start new streams with 310, and new file references with 410. (Leave some room between the last of the pre-defined constants and your numbers, in case new constants are added in the future.)

    3. Streams - A stream is basically a flow of data. All Glk character output is handled by streams, so each window also has a default stream associated with it for text. However, where they become crucial is with Glk's file I/O. But we'll cross that stream when we come to it. :-)

    4. Trees - Glk has trees similar to regular Inform's trees. But these trees are only associated with windows. When new windows are created they become branches and leaves of a tree. So a window can have a parent and a sibling (but, again, no bananas).

    A peeling banana.

    <bgsound src="stripper2.wav">
    (Click to play sound.)

  2. What multimedia capabilities does Glk have?

    Glk's multimedia capabilities include:   text formatting, creating new windows, drawing graphic images, playing sounds, file writing/reading, keyboard input, mouse input, and hyperlinks.

    The outline below doesn't go into detail about each Glk function. Instead, attached to this guide is the infglk Wrapper Reference, which is a summary of infglk wrappers (and, thus, Glk functions). This guide acts as a supplemental outline to the attached wrapper reference.

    Notations Used in This Tutorial

    Functions - Glk functions are enclosed in [brackets]. Most Glk functions have to have one or more values or references passed to their argument lists, function(arguments). In other words, the curved brackets and argument lists normally following a function are not shown, although certain values or references are mentioned.

    Constants - Glk functions may need specific numbers (selected from a range of specific numbers) passed to certain arguments. In the infglk.h include file, these numbers are defined as Inform constants (with names). Some functions rely heavily on these constants and some don't. In the sections below, those Glk io techniques that use functions which rely heavily on constants are asterisked *. The constants themselves are double asterisked **.

    Types - Whether something is a Glk object, Glk event, or Blorb resource is noted in italics.

    1. * Text Formatting - {Stream objects - output to a screen window or disk file}   Like regular Inform, Glulx Inform (Glk) is capable of basic text formatting (boldface, etc). It is also capable of much fancier formatting. But the Glk API (depending on the platform) may allow players to select their own fonts, font sizes, font styles, and font colors from within an interpreter. Since the player can change all this, the game author may not have the control that they might think they will have over text appearance. For this reason there are two sets of text formatting constants and routines.

      Fonts - Since players can choose fonts from within an interpreter, the author can't select specific fonts, only font styles. This is because the author really has no idea what fonts players may have on their machines. However, the interpreter can simply read them in from the player's machine and create a list for the player during game play.

      1. ** Styles - The first of style constants is based on meaning. These text style categories have no universal appearance -- how they are initially displayed depends on the programmer of each glulxe interpreter. In other words, they are preset for each interpreter. Also the player may change their appearance during game play. So, although appearance conventions are followed, how they will look depends on both the interpreter and player. The game author, however, can select/set them for various types of text:  normal, bold, etc.

        The style constants are:   Normal, Emphasized, Preformatted, Header, Subheader, Alert (warns of a dangerous condition), Note (an interesting condition, such score notification), BlockQuote (similar to HTML's block quote), Input (the player's input), and User1/User2 (author defined).

      2. ** Style Hints - (Optional) The second set of style constants gives the interpreter suggestions on how to display the above style categories. Style hints are only used when you want to change the preset appearance of a style. The interpreter will display text styles the style-hinted way:  if it is capable of displaying them that way; and if the player doesn't chose something else. In other words, style hints are suggestions which may or may not work.

        The style hint constants are:   Indentation, ParaIndentation (paragraphs), Justification, Just_LeftFlush, Just_RightFlush, Just_Centered, Just_LeftRight (full justification), Size (relative to the current font size, like HTML's +1), Weight (bold, normal, light), Oblique (italic), TextColor, BackColor, and ReverseColor.

        Cumulative - Styles (categories) are not cumulative, while style hints are. As these constants appear in infglk.h, the first set is proceeded by style, the second by style_hint, such as:   style_Emphasized; stylehint_Proportional. Until they are cleared, style hints accumulate. This means with repeated calls to [glk_stylehint_set] you can suggest additional attributes:  justification, weight, etc. (see Functions below).

      3. Functions - Text styles can be set [glk_set_style], a stream's (to a window or a file) text styles can be set [glk_set_style_stream], style hints can be suggested [glk_stylehint_set], style hints cleared [glk_stylehint_clear], and specific style attributes determined [glk_style_measure] and [glk_style_distinguish].

        Setting window text styles does not affect existing windows, only those opened subsequently. So if you want a certain text format in a window, suggest style hints prior to opening that window. (Note that this will affect ALL the windows opened subsequently.) However, setting text styles in file streams will probably be ignored, although not necessarily. While the setting of text styles in memory streams will always be ignored (see File References below).

    2. * Windows - {Objects}   A window is a rectangular area of the screen that works independently from other areas of the screen. Regular Inform uses windows. The main text screen is one window, the status line is another. When an Inform menu is drawn on the screen it also uses windows. But in regular Inform, window capabilities are rather limited. In Glulx Inform, they are infinite, or as infinite as the size of the player's computer screen.

      Default Windows - Upon game start, InitGlkWindow (see Part 3, Glk Entry Points ) is called before Initialise to set up three default windows:  gg_mainwin (main text window - text buffer), gg_statuswin (status line - text grid), and gg_quotewin (quote box - text buffer). The rest of this section concentrates on author-created windows.

      Borders - Windows may be displayed with borders or not -- it depends on the glulxe interpreter.

      1. ** Types - There are three basic types of windows. The constants for them are:   TextBuffer, TextGrid, and Graphic. TextBuffer windows are windows which input/outpout a text stream (with a buffer). They are what we are all familiar with, the player can type in sentences and the text scrolls and rolls off the screen. TextGrid windows are really character arrays -- text is put in a grid, one character to one square (although the grid is without lines between each square, and thus not visible as a grid, it's still a grid). A fixed-width font must be used in a text grid window. Text doesn't scroll off the screen, so new text can overwrite each or all of the boxes. Text grids can be used for special effects. Graphic windows are just for displaying graphic images -- no text may be written in them.

      2. ** Methods

        1. Splitting Methods - When a new window is opened, it essentially splits the original window (the window it was opened in) in two. So a new window can split the original window vertically or horizontally, but not both vertically and horizontally.

          above (B)

          original (A)

          original (A)

          right (B)


          The new window becomes the "child" of the original window; the original window becomes the parent of the new window. Since Glk windows are created by splitting, they "tile" not "cascade."

          above (B)
          (child of A,
          A is key window
          in first split)
          right (C)
          (child of B,
          B is key window
          in second split)
          original (A)



          So if you want, let's say, a small window in the upper right corner (see above), you have to split windows several times. In this case, the second split (C) would divide the second window (B), not the original window (A). (This is also how window trees are created -- consult Zarf's Glk Specifications for a very detailed explanation. ;-) )

          These splitting constants are:  Above, Below, Left, and Right.

        2. Sizing Methods - Window methods also set a new window's type of sizing. It can be either a fixed size or a proportional percentage of the original window. So those constants are   Fixed or Proportional.

        Additive - Window constants are additive when passed as a argument to a Glk function. However, since there are two types of methods, splitting and sizing, they *must* be passed/added in a pair combination -- one splitting method (direction) plus one sizing method. In infglk, they are preceeded by winmethod. So a fixed window opened above the original window would be: winmethod_Above+winmethod_Fixed.

      3. Sizes - As might be obvious, the actual numercial size of text buffer/grid windows are measured in number of characters or lines of text. Graphic windows are measured in pixels. But only one size is set -- the height if the window is split above/below, the width if it is split left/right. So a text window opened above/below, is sized by height in number of lines of text down. If opened left/right, it is sized by width in number of characters across. While a graphic window is sized by pixels in either direction, height or width.

      4. Input:

        Window type Input type supported Not supported
        text buffer line input
        character input
        hyperlink selection
        mouse input
        text grid line input
        character input
        mouse input
        hyperlink selection
        graphic mouse input line input
        character input
        hyperlink selection

        The three different types of windows accept different types of input. Of course, mouse input and hyperlink selections are only accepted if the glulxe interpreter used also supports them.

      5. Resizing (Arranging), Redrawing - Some glulxe interpreters let players resize the overall application window, but not the individual Glk windows in relation to each other. However, this would still change the sizes of all the windows within the application window. Also, if the player fools with their monitor resolution or color settings and messes them up, graphics in graphic windows can also get messed up. As an Inform author, you need to be aware of these conditions. They are tested and handled by the new Glk entry point, HandleGlkEvent (see Part 3, Glk Entry Points ).

      6. Colors - Text buffer/grid windows colors may be set by using style hints to suggest text (foreground) and background colors (see Style Hints above). Graphic windows colors are set by special routines just for graphic windows (see Functions below). Colors can be designated with either decimal or hexadecimal notation. Hexadecimal numbers are actually the easiest to use because are also used by HTML, and there are tons of HTML color charts on the Net (there is even one attached to this guide ;-) ). So $FFFFFF would be white, and $FF0000, bright red.

      7. Functions:

        1. All Windows - Windows can be opened [glk_window_open], closed [glk_window_close], switched between [glk_set_window], and have their original configuration rearranged [glk_window_set_arrangement]. They can also be checked to determine their current:  type [glk_window_get_type], size [glk_window_get_size], configuration [glk_window_get_arrangement], rock id number [glk_window_get_rock], parent [glk_window_get_parent], and sibling [glk_window_get_sibling]. And the root of the window tree can be found [glk_window_get_root].

        2. Text Grid Windows - The cursor can be moved to x, y (vertical, horizontal) coordinates [glk_window_move_cursor].

        3. Graphic Windows - Graphic windows have some additional capabilities. They can be set to a background color [glk_window_set_background_color]. However, this does not affect what is currently displayed, only subsequent window clears and resizes. (So if you want to change the background color of a graphic window immediately, after setting its background color immediately clear the window.) Rectangular areas can also be filled with a specific background color [glk_window_fill_rect], and cleared to the default background color [glk_window_erase_rect]. These color-fill functions can also operate as crude direct-to-screen drawing, but you are much better off just inserting image files.

    3. Graphic Images - {Blorb Resources}  Currently, blorb files only support JPEG (JPG) and PNG graphic images. But it is anticipated that someday MNG (animated PNGs) may also be supported. Graphic images can be inserted into either text buffer or graphics windows, but not into text grid windows.

      1. * Graphics in a Text Buffer Window - When graphic images are inserted in a text buffer window, the image will roll off the screen with the text. Depending on what you want to do, this can be an advantage or a disadvantage.

        1. ** Image Positioning - Positioning the graphic in relation to the text in the window is accomplished similarly to HTML img positioning:   InlineUp (image bottom is aligned with the text baseline, the rest of the image sticks up), InlineDown (image top is aligned with the top of the text, the rest sticks down), InlineCenter (image is aligned with both the text top and bottom), MarginLeft (image aligned with the left margin of the window), and MarginRight (the reverse). In infglk.h these constants are preceeded by imagealign:   imagealign_InlineUp.

      2. Graphics in a Graphic Window - When a graphic image is inserted in a graphic window, it doesn't scroll off the screen, because the window is just for the graphic (remember, graphic windows cannot contain text). The text in the main text window scrolls independently while the graphic window stays in place. A graphic window only disappears when you remove it. For instance, you might open a graphic window and draw a graphic image in it of the current game "room". When the player moves to another room, you keep the graphic window in place, but change the image to show the new room.

      3. Animation - Animated graphic images are currently not supported by blorb. However, Adam Cadre's Gull reveals a nifty trick to load successive images into a graphic window, creating a basic animation effect.

      4. Functions - Graphic images can be drawn in text or graphic windows [glk_image_draw]. Or they may be drawn to scale (displayed in sizes other than their actual sizes) [glk_image_draw_scaled]. They can also be checked to see what their actual sizes are [glk_image_get_info]. When drawn in a graphic window the second argument to glk_image_draw is the x coordinate, the third is the y coordinate. In a text buffer window, the second argument is one of the image positioning constants shown above, and the third is zero.

    4. Sound Channels - {Objects}  Sounds are played in channels, one sound per channel. Technically two sounds could play in two channels at once, creating a mixing effect (a sound effect heard over background music). However, this can get tricky and is not guaranteed to work in all instances. MOD files demand more of each player's computer resources and players' computers differ. So L. Ross Raszewski recommends when "mixing", combine one AIFF with one MOD, or combine two AIFFs. While David Kinder states that one MOD file will take all Windows Glulxe's resources, so if playing two sound files simultaneously they should both be AIFF (see Interpreter Chart ).

      1. Sounds - {Blorb Resources}  Currently blorb supports AIFF and MOD.

      2. Functions - Sound channels can be:   created [glk_schannel_create], destroyed when no longer needed [glk_schannel_destroy], started playing their sounds [glk_schannel_play], started playing with repeats, [glk_schannel_play_ext], stopped playing [glk_schannel_stop], and their volume adjusted [glk_schannel_set_volume]. Volume changes take effect immediately.

    5. * File I/O - The Glulx Inform bi-platform library has already been rewritten to use streams to automatically handle what you would expect:  output/input to the main text window, saving a game, restoring a game, writing a command file (for debugging), and writing a transcript file. So you only need to use Glk's file reference and stream functions when you want to read/write write specialized files and/or affect/change window streams. Except for suggesting style hints, this guide doesn't cover affecting window or memory streams.

      1. * File References - {Objects}   - File References operate like file names, but actually they are objects that store both file names and pointers to external files. And, although they are used to access those files, actual writing/reading is done by streams.

        1. ** File Usage

          1. Data Usage - When files are opened, they are opened for certain data purposes. The constants are:   Data, SavedGame, Transcript, and InputRecord. Data is a miscellaneous file type for anything that doesn't fall into the other categories.

          2. Format Usage - They are also be saved in specific file formats:   BinaryMode, and TextMode.

          Additive - Like window methods, file usages are additive when passed as a argument to a Glk function. Again, because they are two types of usages, they *must* be added in a simple pair combination -- one data type plus one format type. In infglk, these constants are preceeded by fileusage, so a text transcript would be:   fileusage_Transcript + fileusage_TextMode.

        2. Functions - File references are really only used to open files. Since writing/reading files is done by streams, it is even legal to destroy a file reference while its file is still open (because closing the associated stream will close the file). So a file reference can be used to:  create a temporary file [glk_fileref_create_temp] which will be deleted when the player exits, create a file with a name supplied by the game author [glk_fileref_create_by_name], or by asking the player to enter a file name [glk_fileref_create_by_prompt]. If the game author provides a name, due to platform differences it is safest to keep to eight characters. An extension may be attached by the interpreter based on usage.

          A file reference can also be copied, copying the name but changing the usage [glk_fileref_create_from_fileref]. And it can be destroyed [glk_fileref_destroy], which destroys the object but does not delete the disk file. To actually delete the disk file use [glk_fileref_delete_file], and to test if it even exists use [glk_fileref_does_file_exist].

      2. Streams - {Objects}   - Streams are used to "flow" text/data to/from output/input destinations. In Glulx Inform there are three major destinations, so there are three types of streams. They are:  windows, memory, and files. To outline how streams are used to write to files, we first need to look out how file writing occurs (in all computer languages). A read/write marker, a pointer, is used to keep track of the current position in a file where the next byte/character will be read from/written to. When a new file is opened, it starts at 0 and moves to the end as the file is written. Existing files opened with the mark at the beginning of the file (Write) will be erased, so they are usually opened with the mark at the end (Append).

        V          V          V  read/write mark
        Start      Current    End
        
        1. ** File Modes - The various ways a stream can be opened are:   Write (output stream), Read (input stream), ReadWrite (both an input and output stream), and WriteAppend (output stream, but data will be appended to the end, instead of replacing it). As these constants appear in infglk, they are preceeded by filemode:   filemode_ReadWrite.

        2. ** Marker Positioning (Seek Modes) - The read/write mark position can also be reported on and/or advanced by functions that keep track of the byte/character count read/written from the beginning of a file. For binary file streams, this position will be the exact number of bytes read or written. For text file streams, character count it is very inexact, all you can count on is that the marker advances while the file is written. So it can be at the:   Start, Current, or End. Sometimes the mark position can also be combined with a number. For instance, a stream could be opened in Write mode with the mark positioned at Start + 3 (3 bytes after the beginning of the file). As these positioning constants appear in infglk they are preceeded by seekmode:   seekmode_Start.

        3. Functions - Window streams are created automatically, but they can still be accessed by the game author [glk_stream_get_current], and switched between [glk_stream_set_current]. The two other type of streams can be created:  those that read/write to memory [glk_stream_open_memory], or to a disk file [gk_stream_open_file]. The last would be passed the file reference created earlier which actually named/opened the disk file.

          Once created, streams can be written to:   [glk_put_char], [glk_put_char_stream], [glk_put_string], [glk_put_string_stream], [glk_put_buffer], [glk_put_buffer_stream], and/or read from:  [glk_get_char_stream], [glk_get_line_stream], [glk_get_buffer_stream]. The read/write mark can also be positioned:   [glk_stream_get_position] and [glk_stream_set_position]. Additionally, the rock number of a stream can be determined [glk_stream_get_rock], and a stream's text formatting set (see Text Formatting above).

    6. Player Input - {Events}   - There are four types of input events:  line, character, mouse, and hyperlink. The first two are handled automatically by Glulx Inform, the last two are extended input events that you need to handle.

      1. Requesting:  All four types have to be requested by the Glulx Inform library or the game author before they can be processed. Except for timer events, these requests are tied to specific windows. For instance, the player might click the mouse all over a certain window, but unless mouse input was requested for that window, it would be ignored. That is how the wheat is separated from the chaff (or the banana from its peel ;-)).

        A request does not halt the game until the player responds. But once the player does respond with:   a line, a character, mouse click, or hyperlink selection; if requested, that event is considered complete and arrives at HandleGlKEvent for processing. This is where you would put code to respond to mouse and hyperlink events (see Glk Entry Points ). After completion, if you want more player input of that same type, then you have to request it again.

      2. Canceling:  Input requests can also be cancelled. This cancels pending input requests, not necessarily any input itself. Usually an incomplete request, one the player has not responded to yet, is what is actually canceled.

      3. Input Event Types:

        1. Line Input - Unless you do some fancy g-machine abuse, you can pretty much ignore line input, as it is handled automatically by Glulx Inform. It takes care of the requesting and processing. As you would expect, the flow is:   line input --> HandleGlkEvent --> Inform parser.

          1. Functions - Line input can be requested for a specific window [glk_request_line_event], and a line input request in a window can be canceled [glk_cancel_line_event]. Line input can be requested for text buffer and text grid windows.

        2. Character Input - You can also sidestep character input requesting. A new routine has been added to Glulx Inform, KeyCharPrimitive, which returns one character. (It replaces regular Inform's @read_char.) The character will be:  a letter, number, function key (F1 - F12), or direction key (Home, etc.) (Constants for these special keys have been provided in infglk.h, so you can compare the character to them.) So you need not concern yourself with requesting/canceling character input, just use KeyCharPrimitive instead (see Zarf's Game Author's Guide to Glulx Inform).

          1. Functions - Character input can be requested for a specific window [glk_request_char_event], and a character input request in a window can be canceled [glk_cancel_char_event]. Character input can be requested for text buffer and text grid windows.

        3. Mouse Input - This guide has tried to refer to mouse clicks as mouse input. That is because it depends on the player's platform/interpreter whether mouse input will be accepted as a single or double click. Also whether it will accept the only button, left button, right button, and/or all buttons. However it is accepted, the mouse's x, y coordinates, when it was clicked, will also be sent to HandleGlkEvent along with the mouse input event.

          1. Functions - Mouse input can be requested for a specific window [glk_request_mouse_event], and a mouse input request in a window can be canceled [glk_cancel_mouse_event]. Mouse input can be requested for graphic and text grid windows (for the interpreters that support each).

        4. Hyperlink Selection - How hyperlinks are displayed depends on the interpreter used, but usually they will be blue underlined text.

          1. Functions - Hyperlink selection can be requested for a specific window [glk_request_hyperlink_event], and a hyperlink selection request in a window can be canceled [glk_cancel_hyperlink_event]. Hyperlinks selection can be requested for text buffer and text grid windows (for the interpreters that support each).

            Hyperlinks are turned on and off similar to HTML's <h> and </h>, with [glk_set_hyperlink]. It is called first with a unique hyperlink number to turn it on, then with zero to turn it off. Example:  glk_set_hyperlink(1); print "this text is hyperlinked"; glk_set_hyperlink(0);.



     Part One      Part Three      Part Four      Top of Page
     Appendix One (infglk Wrapper Reference)
     Appendix Two (Interpreter & Color Charts)
Monkey in dunce cap. doeadeer3@aol.com