Building LORD FP (Linux and DOS)
================================

One source tree builds two versions of the game:

  Linux   bin/lord and bin/lordcfg - native x86-64 programs, built with
          Free Pascal 3.2.2 for Linux.  They play a lord.js game
          directory (player.bin, state.bin, .lrd files).
  DOS     LORD.EXE, LORDCFG.EXE and LORDFP.STR - 16-bit DOS programs built
          with Free Pascal 3.2.2's i8086 cross compiler (target msdos,
          large memory model).  They drop into a LORD 4.06 directory.

Both builds run on a Linux PC.  The code that differs is inside
{$IFDEF MSDOS} ... {$ELSE} ... {$ENDIF}: the DOS side talks to a COM port
(doordos.inc), the Linux side to stdin/stdout (doorunix.inc).


Files
-----
  Makefile          the Linux build
  dosbuild.sh       the DOS build
  mkdos.py          splits the game into units and makes LORDFP.STR (DOS)
  rttidecl.diff     a fix for FPC 3.2.2's i8086 RTL (DOS - see below)
  gen_records.py    makes src/records_*.inc from ref/recorddefs.js
  gen_tables.py     makes src/tables.inc from ref/lordtables.json
                    (the generated files are included; only needed if
                    the record layouts or tables change: make
                    src/records_intf.inc src/tables.inc)
  src/lord.pas      the game: globals and tables, then the include files
  src/*.inc         the game, by area (town, inn, forest, battle, ...)
  src/doorkit.pas   door I/O: drop files, ANSI output, keys, line input
  src/doordos.inc   FOSSIL / UART / local screen layer for doorkit (DOS)
  src/doorunix.inc  stdin/stdout and tty layer for doorkit (Linux)
  src/igm.inc       Other Places: runs DOS LORD IGMs (under dosemu on
                    Linux, by exiting to START.BAT on DOS)
  src/lady.inc      runs LORD 4.06 LADY scripts (LORD.LDY forest events)
  src/lordrec.pas   data files: player.bin / PLAYER.DAT, state, lord.ini,
                    locks
  src/lordcfg.pas   the set-up program; its units:
  src/cfgui.pas       screen and file helpers
  src/cfgev.pas       LADY event installer (E)
  src/cfg406.pas      LORD 4.06 tools (-406): PLAYER.DAT editor, Register
  src/lsys.pas      the SysUtils routines the DOS build uses (see below)
  src/strtab.pas    reads the game's text from LORDFP.STR (DOS)
  PORTING.md        design notes for the port from lord.js
  SYSOP.TXT         installing and running the Linux version
  LORDFP.DOC        installing and running the DOS version


Building the Linux version
--------------------------
Tested on Ubuntu 24.04 (x86-64).

1. Install Free Pascal and make:

     sudo apt install fpc make

2. In the directory LORDSRC.ZIP was unzipped into:

     make

   This makes bin/lord and bin/lordcfg (statically linked, so they run on
   any x86-64 Linux).  "make clean" removes the build.

3. Copy bin/lord and bin/lordcfg into the game directory and set it up as
   SYSOP.TXT describes.


Building the DOS version
------------------------
Tested on Ubuntu (x86-64).  Any Linux with these packages should do.

1. Install the tools.  FPC 3.2.2 for Linux is the starting compiler that
   builds the cross compiler; NASM is the assembler the msdos target uses.

     sudo apt install fpc nasm git make python3 unzip patch

2. Get the Free Pascal 3.2.2 source:

     git clone --depth 1 --branch release_3_2_2 \
       https://gitlab.com/freepascal.org/fpc/source.git fpcsrc

3. Apply the RTL fix in rttidecl.diff (from this zip):

     cd fpcsrc
     patch -p1 < /path/to/rttidecl.diff

   Why: the compiler writes record field offsets in RTTI as PtrUInt, which
   is 4 bytes in the large memory model, but the RTL reads
   TRecordElement.Offset as SizeInt (2 bytes).  Copying or freeing a record
   with two or more AnsiString fields then jumps to a bad address.  The
   game copies such records all the time, so it crashes without the fix.

4. Build and install the i8086-msdos cross compiler and its units, large
   memory model (takes a few minutes):

     make all OS_TARGET=msdos CPU_TARGET=i8086 BINUTILSPREFIX= \
       CROSSOPT="-WmLarge -CX -XX"
     make crossinstall OS_TARGET=msdos CPU_TARGET=i8086 BINUTILSPREFIX= \
       CROSSOPT="-WmLarge -CX -XX" INSTALL_PREFIX=$HOME/fpc-i8086

   BINUTILSPREFIX= (empty) makes it call nasm rather than msdos-nasm.
   This puts ppcross8086 and units/msdos in $HOME/fpc-i8086/lib/fpc/3.2.2.

5. Build the game, in the directory LORDSRC.ZIP was unzipped into:

     sh dosbuild.sh

   If the cross compiler is somewhere else:

     FPCDIR=/somewhere/lib/fpc/3.2.2 sh dosbuild.sh

   This makes bin-dos/lord.exe, bin-dos/lordcfg.exe and bin-dos/LORDFP.STR.
   Copy them into the LORD directory as LORD.EXE, LORDCFG.EXE and
   LORDFP.STR.  Built this way they are identical to the ones in
   LORDFP.ZIP.

   Steps 1-4 are only needed once.  The Linux build (above) does not need
   the cross compiler.


How the DOS build fits in 640K
------------------------------
- An 8086 code segment is at most 64K, and so is the data group (DGROUP)
  that holds the global variables and constants.  mkdos.py makes the
  sources in build-dos-src/:
    lordglob.pas  the globals, types and tables from lord.pas
    lfp_*.pas     one unit per include file; its interface is the file's
                  top-level procedure and function headers
    lord.pas      a small main program that uses all the units
- String literals of 8 characters or more are moved to LORDFP.STR and
  read back with S_(n) (strtab.pas), which keeps the text out of DGROUP.
- lsys.pas replaces FPC's SysUtils, whose exception and Format code
  pulls in the floating point formatter and fills DGROUP (the Linux build
  keeps SysUtils).  The game uses no floating point; the clock helpers in
  lordrec.pas use integers.
- LORDTXT.LRD is indexed by file offset and read one section at a time.


Naming
------
The game is a line-by-line port of lord.js, so the lord.js function names
are kept (sln, lw, lln, more_nomail, ...) and comments give lord.js line
numbers.  Internally the files keep their lord.js names (player.bin,
state.bin, lognow.lrd, mail<n>.lrd); on DOS, dos_name in lordrec.pas maps
them to the LORD 4.06 names (PLAYER.DAT, LORDFPS.DAT, LOGNOW.TXT,
MAIL<n>.DAT).
A comment starting "JS:" marks a lord.js bug fixed here.

Debugging: set LORDTRACE=<file> and LORD.EXE writes a trace to that file.
