-+-+-+-+-+-+-+-+ START OF PART 45 -+-+-+-+-+-+-+-+
X    bp = _tcpbuf;
X    while ((bp = index(bp,':')) != NULL) `7B
X    bp++;
X    if (*bp++ == id`5B0`5D && *bp != NULL && *bp++ == id`5B1`5D) `7B
X        if (*bp != NULL && *bp++ != '=') `7B
X        return(NULL);
X        `7D else `7B
X        return(decode(bp,area));
X        `7D
X    `7D
X    `7D
X    return(NULL);
X`7D
X`0C
X/*
X *  INTERNAL FUNCTION
X *
X *  decode   transfer string capability, decoding escapes
X *
X *  SYNOPSIS
X *
X *  static char *decode(bp,area)
X *  char *bp;
X *  char **area;
X *
X *  DESCRIPTION
X *
X *  Transfers the string capability, up to the next ':'
X *  character, or null, to the buffer pointed to by
X *  the pointer in *area.  Note that the initial
X *  value of *area and *area is updated to point
X *  to the next available location after the null
X *  terminating the transfered string.
X *
X *  BUGS
X *
X *  There is no overflow checking done on the destination
X *  buffer, so it better be large enough to hold
X *  all expected strings.
X *
X */
X`0C
X/*
X *  PSEUDO CODE
X *
X *  Begin decode
X *      Initialize the transfer pointer.
X *      While there is an input character left to process
X *      Switch on input character
X *      Case ESCAPE:
X *          Decode and xfer the escaped sequence.
X *          Break
X *      Case CONTROLIFY:
X *          Controlify and xfer the next character.
X *          Advance the buffer pointer.
X *          Break
X *      Default:
X *          Xfer a normal character.
X *      End switch
X *      End while
X *      Null terminate the output string.
X *      Remember where the output string starts.
X *      Update the output buffer pointer.
X *      Return pointer to the output string.
X *  End decode
X *
X */
X
Xstatic char *decode(bp,area)
Xchar *bp;
Xchar **area;
X`7B
X    char *cp, *bgn;
X    char *do_esc();
X
X    cp = *area;
X    while (*bp != NULL && *bp != ':') `7B
X    switch(*bp) `7B
X    case '\\':
X        bp = do_esc(cp++,++bp);
X        break;
X    case '`5E':
X        *cp++ = *++bp & 037;
X        bp++;
X        break;
X    default:
X        *cp++ = *bp++;
X        break;
X    `7D
X    `7D
X    *cp++ = (char) NULL;
X    bgn = *area;
X    *area = cp;
X    return(bgn);
X`7D
X`0C
X/*
X *  INTERNAL FUNCTION
X *
X *  do_esc    process an escaped sequence
X *
X *  SYNOPSIS
X *
X *  char *do_esc(out,in);
X *  char *out;
X *  char *in;
X *
X *  DESCRIPTION
X *
X *  Processes an escape sequence pointed to by
X *  in, transfering it to location pointed to
X *  by out, and updating the pointer to in.
X *
X */
X`0C
X/*
X *  PSEUDO CODE
X *
X *  Begin do_esc
X *      If the first character is not a NULL then
X *      If is a digit then
X *          Set value to zero.
X *          For up to 3 digits
X *              Accumulate the sum.
X *          End for
X *          Transfer the sum.
X *          Else if character is in remap list then
X *          Transfer the remapped character.
X *          Advance the input pointer once.
X *          Else
X *          Simply transfer the character.
X *          End if
X *      End if
X *      Return updated input pointer.
X *  End do_esc
X *
X */
X
Xstatic char *maplist = `7B
X    "E\033b\bf\fn\nr\rt\t"
X`7D;
X
Xchar *do_esc(out,in)
Xchar *out;
Xchar *in;
X`7B
X    int count;
X    char ch;
X    char *cp;
X
X    if (*in != NULL) `7B
X    if (isdigit(*in)) `7B
X        ch = 0;
X        for (count = 0; count < 3 && isdigit(*in); in++) `7B
X         ch <<= 3;
X         ch `7C= (*in - '0');
X        `7D
X        *out++ = ch;
X    `7D else if ((cp = index(maplist,*in)) != NULL) `7B
X        *out++ = *++cp;
X        in++;
X    `7D else `7B
X        *out++ = *in++;
X    `7D
X    `7D
X    return(in);
X`7D
$ CALL UNPACK TGETSTR.C;1 1279942953
$ create 'f'
X/************************************************************************
X *                                  *
X *          Copyright (c) 1982, Fred Fish           *
X *              All Rights Reserved             *
X *                                  *
X *  This software and/or documentation is released for public   *
X *  distribution for personal, non-commercial use only.     *
X *  Limited rights to use, modify, and redistribute are hereby  *
X *  granted for non-commercial purposes, provided that all      *
X *  copyright notices remain intact and all changes are clearly *
X *  documented.  The author makes no warranty of any kind with  *
X *  respect to this product and explicitly disclaims any implied    *
X *  warranties of merchantability or fitness for any particular *
X *  purpose.                            *
X *                                  *
X ************************************************************************
X */
X
X`0C
X/*
X *  LIBRARY FUNCTION
X *
X *  tgoto   expand cursor addressing string from cm capability
X *
X *  KEY WORDS
X *
X *  termcap
X *
X *  SYNOPSIS
X *
X *  char *tgoto(cm,destcol,destline)
X *  char *cm;
X *  int destcol;
X *  int destline;
X *
X *  DESCRIPTION
X *
X *  Returns cursor addressing string, decoded from the cm
X *  capability string, to move cursor to column destcol on
X *  line destline.
X *
X *  The following sequences uses one input argument, either
X *  line or column, and place the appropriate substitution
X *  in the output string:
X *
X *      %d  substitute decimal value (in ASCII)
X *      %2  like %d but forces field width to 2
X *      %3  like %d but forces field width to 3
X *      %.  like %c
X *      %+x like %c but adds ASCII value of x
X *
X *  The following sequences cause processing modifications
X *  but do not "use up" one of the arguments.  If they
X *  act on an argument they act on the next one to
X *  be converted.
X *
X *      %>xy    if next value to be converted is
X *          greater than value of ASCII char x
X *          then add value of ASCII char y.
X *      %r  reverse substitution of line
X *          and column (line is substituted
X *          first by default).
X *      %i  causes input values destcol and
X *          destline to be incremented.
X *      %%  gives single % character in output.
X *
X *  BUGS
X *
X *  Does not implement some of the more arcane sequences for
X *  radically weird terminals (specifically %n, %B, & %D).
X *  If you have one of these you deserve whatever happens.
X *
X */
X`0C
X/*
X *  Miscellaneous stuff
X */
X
X#include <stdio.h>
X
X#define MAXARGS 2
X
Xstatic char *in;        /* Internal copy of input string pointer */
Xstatic char *out;       /* Pointer to output array */
Xstatic int args`5BMAXARGS`5D;   /* Maximum number of args to convert */
Xstatic int pcount;      /* Count of args processed */
Xstatic char output`5B64`5D;     /* Converted string */
X
X`0C
X/*
X *  PSEUDO CODE
X *
X *  Begin tgoto
X *      If no string to process then
X *      Return pointer to error string.
X *      Else
X *      Initialize pointer to input string.
X *      Initialize pointer to result string.
X *      First arg is line number by default.
X *      Second arg is col number by default.
X *      No arguments processed yet.
X *      While there is another character to process
X *          If character is a not a % character then
X *          Simply copy to output.
X *          Else
X *          Process the control sequence.
X *          End if
X *      End while
X *      TERMINATE STRING!  (rde)
X *      Return pointer to static output string.
X *      End if
X *  End tgoto
X *
X */
X
Xchar *tgoto(cm,destcol,destline)
Xchar *cm;
Xint destcol;
Xint destline;
X`7B
X    if (cm == NULL) `7B
X    return("OOPS");
X    `7D else `7B
X    in = cm;
X    out = output;
X    args`5B0`5D = destline;
X    args`5B1`5D = destcol;
X    pcount = 0;
X    while (*in != NULL) `7B
X        if (*in != '%') `7B
X        *out++ = *in++;
X        `7D else `7B
X        process();
X        `7D
X    `7D
X    *out = '\0';    /* rde 18-DEC-86: don't assume out was all zeros */
X    return(output);
X    `7D
X`7D
X`0C
X/*
X *  INTERNAL FUNCTION
X *
X *  process   process the conversion/command sequence
X *
X *  SYNOPSIS
X *
X *  static process()
X *
X *  DESCRIPTION
X *
X *  Processes the sequence beginning with the % character.
X *  Directly manipulates the input string pointer, the
X *  output string pointer, and the arguments.  Leaves
X *  the input string pointer pointing to the next character
X *  to be processed, and the output string pointer pointing
X *  to the next output location.  If conversion of
X *  one of the numeric arguments occurs, then the pcount
X *  is incremented.
X *
X */
X`0C
X/*
X *  PSEUDO CODE
X *
X *  Begin process
X *      Skip over the % character.
X *      Switch on next character after %
X *      Case 'd':
X *      Process %d type conversion (variable width).
X *      Reinitialize output pointer.
X *      Break;
X *      Case '2':
X *      Process %d type conversion (width 2).
X *      Reinitialize output pointer.
X *      Break;
X *      Case '3':
X *      Process %d type conversion (width 3).
X *      Reinitialize output pointer.
X *      Break;
X *      Case '.'
X *      Process %c type conversion.
X *      Break;
X *      Case '+':
X *      Process %c type conversion with offset.
X *      Break;
X *      Case '>':
X *      Process argument modification.
X *      Break;
X *      Case 'r':
X *      Process argument reversal.
X *      Break;
X *      Case 'i':
X *      Increment argument values.
X *      Break;
X *      Case '%':
X *      Copy to output, incrementing pointers.
X *      Break;
X *      End switch
X *  End process
X *
X */
X
X`0C
Xstatic process()
X`7B
X    int temp;
X
X    in++;
X    switch(*in++) `7B
X    case 'd':
X    sprintf(out,"%d",args`5Bpcount++`5D);
X    out = &output`5Bstrlen(output)`5D; `20
X    break;
X    case '2':
X    sprintf(out,"%02d",args`5Bpcount++`5D);
X    out += 2 ;
X/*
X    out = &output`5Bstrlen(output)`5D;
X*/
X    break;
X    case '3':
X    sprintf(out,"%03d",args`5Bpcount++`5D);
X    out = &output`5Bstrlen(output)`5D;
X    break;
X    case '.':
X    *out++ = args`5Bpcount++`5D;
X    break;
X    case '+':
X    *out++ = args`5Bpcount++`5D + *in++;
X    break;
X    case '>':
X    if (args`5Bpcount`5D > *in++) `7B
X        args`5Bpcount`5D += *in++;
X    `7D else `7B
X        in++;
X    `7D
X    break;
X    case 'r':
X    temp = args`5Bpcount`5D;
X    args`5Bpcount`5D = args`5Bpcount+1`5D;
X    args`5Bpcount+1`5D = temp;
X    break;
X    case 'i':
X    args`5Bpcount`5D++;
X    args`5Bpcount+1`5D++;
X    break;
X    case '%':
X    *out++ = '%';
X    break;
X    `7D
X`7D
$ CALL UNPACK TGOTO.C;1 1666862541
$ create 'f'
Xmain.obj object.obj create.obj tok.obj display.obj +
Xglobal.obj data.obj io.obj monster.obj action.obj  +
Xiventory.obj vms.obj store.obj diag.obj help.obj   +
Xconfig.obj nap.obj bill.obj scores.obj signal.obj  +
Xmoreobj.obj spheres.obj spells.obj movem.obj       +
Xregen.obj fortune.obj savelev.obj msdos.obj        +
Xfgetlr.obj tgoto.obj tgetent.obj tgetstr.obj tputs.obj
$ CALL UNPACK TLINK.RSP;1 2105419770
$ create 'f'
X/* tok.c */
X/*
X   yylex()
X   flushall()
X   sethard()
X   readopts()
X   actual_readopts()
X*/
X#ifdef VMS
X#include <types.h>
X#include <file.h>
X#include <iodef.h>
X#else VMS
X#include <sys/types.h>
X#ifdef SYSV
X#include <fcntl.h>
X# ifndef MSDOS
X#   include <termio.h>
X# endif
X#else SYSV
X# ifndef MSDOS
X#   include <sys/ioctl.h>
X# endif
X#endif SYSV
X#endif VMS
X
X#include <ctype.h>
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X#ifdef __STDC__
Xstatic void actual_readopts( char*, char* );
X#else
Xstatic void actual_readopts();
X#endif
X
X# define CHKPTINT   400
X
Xstatic char lastok=0;
Xint yrepcount=0;
Xchar move_no_pickup = FALSE ;
X
X#ifdef TIMECHECK
Xint dayplay=0;
X#endif TIMECHECK
X
X#ifndef FLUSHNO
X#define FLUSHNO 5
X#endif FLUSHNO
Xstatic int flushno=FLUSHNO; /* input queue flushing threshold */
X#define MAXUM 52    /* maximum number of user re-named monsters */
X#define MAXMNAME 40 /* max length of a monster re-name */
Xstatic char usermonster`5BMAXUM`5D`5BMAXMNAME`5D; /* the user named monster
V name goes here */
Xstatic char usermpoint=0;           /* the user monster pointer */
X#ifdef MSDOS
X extern int rawio;
X#endif
X
X/*
X    lexical analyzer for larn
X */
Xyylex()
X    `7B
X    char cc;
X    int ic;
X    char firsttime = TRUE;
X
X    if (hit2flag)
X        `7B
X        hit2flag=0;
X        yrepcount=0;
X        return(' ');
X        `7D
X    if (yrepcount>0)
X        `7B
X        --yrepcount;
X        return(lastok);
X        `7D
X    else
X        yrepcount=0;
X    if (yrepcount==0)`20
X        `7B`20
X        bottomdo();`20
X        showplayer();               /* show where the player is */
X        move_no_pickup = FALSE;     /* clear 'm' flag */
X        `7D
X
X    lflush();
X    while (1)
X        `7B
X        c`5BBYTESIN`5D++;
X        if (ckpflag)
X          if ((c`5BBYTESIN`5D % CHKPTINT) == 0) /* check for periodic checkp
Vointing */
X            `7B
X#ifndef DOCHECKPOINTS
X#ifdef MSDOS
X            cursors();
X            lprcat("\nCheckpointing . . .");
X            savegame(ckpfile);
X            lprcat("\nDone\n");
X            showplayer();
X            lflush();
X            lflushall(); /* Kill any stored key strokes */
X#else
X#ifdef VMS
X            savegame(ckpfile);
X#else
X            wait(0);    /* wait for other forks to finish */
X            if (fork() == 0) `7B savegame(ckpfile); exit(); `7D
X#endif
X#endif
X#else
X#ifdef VMS
X            savegame(ckpfile);
X#else
X            wait(0);    /* wait for other forks to finish */
X            if (fork() == 0) `7B savegame(ckpfile); exit(); `7D
X#endif
X#endif
X
X#ifdef TIMECHECK
X            if (dayplay==0)
X              if (playable())
X                `7B
X                cursor(1,19);
X                lprcat("\nSorry, but it is now time for work.  Your game has
V been saved.\n"); beep();
X                lflush();
X                savegame(savefilename);
X                wizard=nomove=1;
X                sleep(4);
X                died(-257);
X                `7D
+-+-+-+-+-+-+-+-  END  OF PART 45 +-+-+-+-+-+-+-+-
