---------------
TECHNICAL GUIDE
---------------

  Although "Frotz" was written for MS-DOS only, it shouldn't be too
  difficult to port the interpreter to other operating systems. You
  are invited to write front-ends for other systems, but before you
  do so you should email me to avoid double efforts:

    jokisch@ls7.informatik.uni-dortmund.de

  Frotz is freeware. It may be used and distributed freely provided
  no commercial profit is involved. (c) 1995, 1996 Stefan Jokisch

~~~ (1) Manifest ~~~

The source code consists of the following files:

  BUFFER.C -- word wrapping routines; set_colour, set_text_style,
    set_font are also implemented here
  FASTMEM.C -- memory management: undo, restart, save, restore and
    verify; change this file if you want to use virtual memory
  HOTKEY.C -- generic functions which are called after a so-called
    hot key was pressed (e.g. multiple undo, playback...)
  INPUT.C -- high-level input routines; implements read_char and
    read opcodes
  MAIN.C -- the main routine of the interpreter; global variables
    are all defined here
  MATH.C -- arithmetic, boolean and comparison opcodes; pretty
    harmless stuff
  MENU.C -- some day this module might implement make_menu; up to
    now it contains only a dummy function
  OBJECT.C -- object and property manipulation opcodes (get_prop,
    put_prop, get_parent, get_child and so on) [*]
  PROCESS.C -- this is the heart of the Z-machine; interpreter main
    routine and controlling opcodes (call, jump etc.) [*]
  RANDOM.C -- implements the random opcode using stdlib functions
    rand and srand
  SCREEN.C -- generic screen manipulation routines; this module is
    now able to work in terms of screen units
  SOUND.C -- implementation of the sound_effect opcode; primitive,
    most of the work is passed to interface routines
  STREAM.C -- all file-related IO streams such as input recording,
    input playback and output transscription
  TABLE.C -- opcodes to manipulate table structures: loadb, loadw,
    storeb, storew, copy_table, scan_table
  TEXT.C -- high-level output routines; text encoding and decoding;
    tokenise opcode [*]
  VARIABLE.C -- implementation of opcodes which handle variables
    and the stack [*]

  BORLAND.C -- Borland C specific IO interface; replace this one
    with your own interface

  FROTZ.H -- include file used by all the modules mentioned above;
    global constants, variable declarations and prototypes

  GETOPT.C -- replacement for a Unix-style getopt function; quite
    useful for writing the os_process_arguments function

[*] These modules should be optimized for speed. All other modules may be
optimized for size. This strategy was used to build the DOS executable.

~~~ (2) Porting Frotz ~~~

To port "Frotz" you have to write a new IO interface to replace the DOS
interface borland.c. All functions named os_*** are required to build the
program; the comments in borland.c briefly specify the correct behaviour.
For a quick start, you might try the following generic definitions:

  os_display_char:    	if (cwin == 0) putchar (c);
  os_char_width:	return 1;
  os_string_width:    	return strlen (s);
  os_read:	    	gets (buffer); return 13;
  os_scroll_area:	if (cwin == 0) putchar ('\n');
  os_process_arguments:	story_name = "story.dat";
  os_init_screen:	h_screen_width = 79; h_screen_height = 25;
  os_fatal:		fprintf (stderr, "Fatal: %s\n", s); exit (1);

All other interface routines should do nothing. This will suffice to play
a simple V3 game (which must be named story.dat). Of course, this is a
very primitive interface that has a lot of serious limitations; there is
still a lot of work to do.

The only symbol you might need during compilation is MAX_FILE_NAME, which
defaults to 32 when it is undefined.

~~~ (3) Changes since version 1.01 ~~~

This is a (hopefully) complete list of all changes that porters should be
aware of. Although it looks alarmingly long, it is rather harmless. A few
extensions were necessary to support V6 games; a few changes have been
made to improve the design of the program. Most recent changes are listed
first.

* Generic macros

  The header file finally contains generic definitions for my notorious
  macros. I haven't tested them yet, but I'm confident that they should
  work for every OS which doesn't suffer from 64KB limitations like DOS.

* Extensions for Amiga

  For the benefit of the Amiga port, following changes are available
  when AMIGA is set:

  - an additional function resize_screen in screen.c,
  - a call to CheckReset after every restart,
  - more efficient macros in frotz.h (let's hope they work),
  - beyond_zork_flag/german_zork_flag are no longer set by load_header.

* Width of characters and strings

  os_text_length has been re-named to os_string_width. Its defintion has
  been changed several times, so take a look at the latest version in
  borland.c. There is also a new interface function os_char_width that
  returns the width of a given character. This function should be fast as
  Frotz makes frequent use of it.

* Reading the cursor position

  The interface routine os_get_cursor has vanished.

* Primitive memory management

  os_init can set the long variable reserve_mem to reserve any arbitrary
  number of bytes for later use; otherwise Frotz may allocate memory for
  multiple undo which would be needed for other purposes (such as loading
  a sound file, opening a file requester etc.) later on.

* Character output routines

  A new interface routine os_display_string was introduced to display a
  string of characters on the screen. It may pass all the characters to
  os_display_char. Important: os_read may use os_display_string, it may
  no longer use display_string. The same applies to os_more_prompt.

  Other routines (e.g. os_get_file_name) should use the display_***
  routines. Note that display_string is able to handle newlines, e.g.:

  display_string ("Enter a file name:\n")

* More colours

  The colour scheme has been enhanced. In addition to the Z-machine
  colours, the interface can define the colours from 16 to 255 for its
  own use. This is particular important for the new interface routine
  os_peek_colour which returns the colour of the pixel at the current
  cursor position. This function is mostly used to write text on top of
  pictures; however, pictures may consist of non-standard colours.

  There are also a few more standard colours. For MS-DOS only, there is
  a GREY_COLOUR. For Amiga only, there is LIGHT-, MEDIUM-, and DARKGREY_
  COLOUR. No extra colours for the rest of the world.

* Messages (os_message_start)

  For those who have copied the code from borland.c: The condition in
  os_message_start that decides whether we need to insert a newline must
  be replaced by (get_line_width (cwin) != get_units_left ()).

* Input routine

  os_read got a new argument: It gives the number of screen units in
  which the input line (including the cursor) must fit.

* Picture support

  os_picture_data and os_draw_picture are needed for pictures; see
  borland.c for details.

* Mouse windows

  A new interface function os_mouse_area has been added to restrict the
  movement of the mouse cursor. This is only used by Arthur (when the map
  is selected); the interpreter need not implement it.

* No support for menus

  Make sure os_init clears the MENU_FLAG.

* More modules

  There are three new modules: VARIABLE.C, RANDOM.C and MENU.C.

* Bells and whistles

  There is a new option_left_margin that does the obvious thing (and
  usually fails in V6). There are also new hot keys:

  HOT_KEY_RESTART (Alt-N == new game) and
  HOT_KEY_QUIT (Alt-X == exit game).

  Another new option is the option_piracy. When this variable is set, the
  piracy opcode does not branch (which would make the game believe it was
  a pirated copy). In practice, this opcode wasn't used, and therefore it
  is pretty pointless to set the flag. DOS Frotz provided an undocumented
  command line switch to set the option, anyway.

  Equally useless is the header entry h_user_name. This array can hold a
  user name of up to 8 letters. It can be set by os_init_screen, but it
  won't have any effect.

* Indentations

  os_display_char, os_display_string, os_char_width and os_string_width
  must be able to cope with with characters 9 (paragraph indentation) and
  11 (gap between two sentences).

* Making the cursor [in]visible

  Two new interface routines: os_cursor_on and os_cursor_off. Note that
  the cursor need only be visible during input actions.

* European characters

  First, new constants EURO_MIN (155) and EURO_MAX (223) have been added.
  Second, the array euro_substitute (STREAM.C) is no longer static. This
  might be helpful for any OS that cannot display European characters.

* Tandy flag

  The interface is now responsible for setting the Tandy flag; the global
  variable option_tandy_bit has been removed. If your interface shall
  support the Tandy bit then you should add a line to os_init_screen that
  looks like

  if (h_version == V3 && user_wants_tandy_bit != 0)
      h_config |= CONFIG_TANDY;

* Scrolling up and down

  os_scroll_area has got an additional argument giving the number of
  screen units to scroll. In theory, the area must scroll down when this
  value is negative. In practice, negative values don't happen.

* Screen units instead of character grid positions

  Frotz is now able to work with screen units. You don't have to set the
  header entries "h_font_width" and "h_font_height" to 1 if you want to
  use pixels rather than character grid positions. In addition, if you
  are still using character grid positions, then you don't have to set
  these two variables at all (because they default to 1).

  Furthermore, os_set_font has got two additional pointer arguments: The
  font width and height must be stored in these variables. Once again,
  both values default to 1 if you don't set them at all.

* File naming

  All arrays that store file names (script_name, command_name, save_name
  and auxilary_name) are no longer "static", just in case the interface
  wants to provide more intelligent default file names than "story.scr",
  "story.cmd" and so on.

* Vanishing constants

  The constants LOWER_WINDOW (0), UPPER_WINDOW (1) and ROMAN_STYLE (0)
  have been removed.

* Text style

  The specification of os_set_text_style has changed. You don't have to
  combine the flags of the old style with the flags of the new style as
  the new style contains all the flags that are currently active. In
  particular, Frotz takes care to select the FIXED_WIDTH_STYLE whenever
  the fixed font bit is set or when the upper window is active in V1-V5.
