[comp.sources.games] v11i090: larn - dungeon type adventure game, Part07/11

billr@saab.CNA.TEK.COM (Bill Randle) (12/19/90)

Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 11, Issue 90
Archive-name: larn/Part07
Environment: Unix, VMS, MS-DOS, termcap



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 7 (of 11)."
# Contents:  bill.c global.c io.c
# Wrapped by billr@saab on Tue Dec 18 10:14:20 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'bill.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bill.c'\"
else
echo shar: Extracting \"'bill.c'\" \(7074 characters\)
sed "s/^X//" >'bill.c' <<'END_OF_FILE'
X#include "header.h"
X/* bill.c		 "Larn is copyrighted 1986 by Noah Morgan. */
X
X# ifdef MAIL
X# ifdef VMS
X# define MAILTMP	"sys$scratch:"
X# else
X# define MAILTMP	"/tmp/#"
X# endif
Xstatic int pid;
Xstatic char mail600[sizeof(MAILTMP)+sizeof("mail600")+20];
X# endif
X/*
X *	function to create the tax bill for the user
X */
X# ifdef MAIL
Xstatic letter1()
X# else
Xstatic letter1(gold)
Xlong gold;
X# endif
X  {
X# ifdef MAIL
X  sprintf(mail600,"%s%dmail600",MAILTMP,pid); /* prepare path */
X  if (lcreat(mail600) < 0) { write(1,"can't write 600 letter\n",23); return(0);}
X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
X# endif
X  standout("From:"); lprcat("  the LRS (Larn Revenue Service)\n");
X  standout("\nSubject:"); lprcat("  undeclared income\n");
X  lprcat("\n   We heard you survived the caverns of Larn.  Let me be the");
X  lprcat("\nfirst to congratulate you on your success.  It is quite a feat.");
X  lprcat("\nIt must also have been very profitable for you.");
X  lprcat("\n\n   The Dungeon Master has informed us that you brought");
X# ifdef MAIL
X  lprintf("\n%d gold pieces back with you from your journey.  As the",(long)c[GOLD]);
X# else
X  lprintf("\n%d gold pieces back with you from your journey.  As the", gold);
X# endif
X  lprcat("\ncounty of Larn is in dire need of funds, we have spared no time");
X  lprintf("\nin preparing your tax bill.  You owe %d gold pieces as",
X# ifdef MAIL
X	(long)c[GOLD]*TAXRATE);
X# else
X	gold * TAXRATE);
X# endif
X  lprcat("\nof this notice, and is due within 5 days.  Failure to pay will");
X  lprcat("\nmean penalties.  Once again, congratulations, We look forward");
X  lprcat("\nto your future successful expeditions.\n");
X# ifdef MAIL
X  lwclose();
X# endif
X  return(1);
X  }
X
Xstatic letter2()
X  {
X# ifdef MAIL
X  sprintf(mail600,"%s%dmail600",MAILTMP,pid); /* prepare path */
X  if (lcreat(mail600) < 0) { write(1,"can't write 601 letter\n",23); return(0);}
X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
X# endif
X  standout("From:"); lprcat("  His Majesty King Wilfred of Larndom\n");
X  standout("\nSubject:"); lprcat("  a noble deed\n");
X  lprcat("\n   I have heard of your magnificent feat, and I, King Wilfred,");
X  lprcat("\nforthwith declare today to be a national holiday.  Furthermore,");
X  lprcat("\nhence three days, Ye be invited to the castle to receive the");
X  lprcat("\nhonour of Knight of the realm.  Upon thy name shall it be written. . .");
X  lprcat("\nBravery and courage be yours.");
X  lprcat("\nMay you live in happiness forevermore . . .\n");
X# ifdef MAIL
X  lwclose();
X# endif
X  return(1);
X  }
X
Xstatic letter3()
X  {
X# ifdef MAIL
X  sprintf(mail600,"%s%dmail600",MAILTMP,pid); /* prepare path */
X  if (lcreat(mail600) < 0) { write(1,"can't write 602 letter\n",23); return(0);}
X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
X# endif
X  standout("From:"); lprcat("  Count Endelford\n");
X  standout("\nSubject:"); lprcat("  You Bastard!\n");
X  lprcat("\n   I heard (from sources) of your journey.  Congratulations!");
X  lprcat("\nYou Bastard!  With several attempts I have yet to endure the");
X  lprcat(" caves,\nand you, a nobody, makes the journey!  From this time");
X  lprcat(" onward, bewarned\nupon our meeting you shall pay the price!\n");
X# ifdef MAIL
X  lwclose();
X# endif
X  return(1);
X  }
X
Xstatic letter4()
X  {
X# ifdef MAIL
X  sprintf(mail600,"%s%dmail600", MAILTMP,pid); /* prepare path */
X  if (lcreat(mail600) < 0) { write(1,"can't write 603 letter\n",23); return(0);}
X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
X# endif
X  standout("From:"); lprcat("  Mainair, Duke of Larnty\n");
X  standout("\nSubject:"); lprcat("  High Praise\n");
X  lprcat("\n   With a certainty a hero I declare to be amongst us!  A nod of");
X  lprcat("\nfavour I send to thee.  Me thinks Count Endelford this day of");
X  lprcat("\nright breath'eth fire as of dragon of whom ye are slayer.  I");
X  lprcat("\nyearn to behold his anger and jealously.  Should ye choose to");
X  lprcat("\nunleash some of thy wealth upon those who be unfortunate, I,");
X  lprcat("\nDuke Mainair, Shall equal thy gift also.\n");
X# ifdef MAIL
X  lwclose();
X# endif
X  return(1);
X  }
X
Xstatic letter5()
X  {
X# ifdef MAIL
X  sprintf(mail600,"%s%dmail600", MAILTMP,pid); /* prepare path */
X  if (lcreat(mail600) < 0) { write(1,"can't write 604 letter\n",23); return(0);}
X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
X# endif
X  standout("From:"); lprcat("  St. Mary's Children's Home\n");
X  standout("\nSubject:"); lprcat("  these poor children\n");
X  lprcat("\n   News of your great conquests has spread to all of Larndom.");
X  lprcat("\nMight I have a moment of a great man's time.  We here at St.");
X  lprcat("\nMary's Children's Home are very poor, and many children are");
X  lprcat("\nstarving.  Disease is widespread and very often fatal without");
X  lprcat("\ngood food.  Could you possibly find it in your heart to help us");
X  lprcat("\nin our plight?  Whatever you could give will help much.");
X  lprcat("\n(your gift is tax deductible)\n");
X# ifdef MAIL
X  lwclose();
X# endif
X  return(1);
X  }
X
Xstatic letter6()
X  {
X# ifdef MAIL
X  sprintf(mail600, "%s%dmail600", MAILTMP, pid); /* prepare path */
X  if (lcreat(mail600) < 0) { write(1,"can't write 605 letter\n",23); return(0);}
X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
X# endif
X  standout("From:"); lprcat("  The National Cancer Society of Larn\n");
X  standout("\nSubject:"); lprcat("  hope\n");
X  lprcat("\nCongratulations on your successful expedition.  We are sure much");
X  lprcat("\ncourage and determination were needed on your quest.  There are");
X  lprcat("\nmany though, that could never hope to undertake such a journey");
X  lprcat("\ndue to an enfeebling disease -- cancer.  We at the National");
X  lprcat("\nCancer Society of Larn wish to appeal to your philanthropy in");
X  lprcat("\norder to save many good people -- possibly even yourself a few");
X  lprcat("\nyears from now.  Much work needs to be done in researching this");
X  lprcat("\ndreaded disease, and you can help today.  Could you please see it");
X  lprcat("\nin your heart to give generously?  Your continued good health");
X  lprcat("\ncan be your everlasting reward.\n");
X# ifdef MAIL
X  lwclose();
X# endif
X  return(1);
X  }
X
X
Xstatic int (*pfn[])()= { letter1, letter2, letter3, letter4, letter5, letter6 };
X
X# ifdef MAIL
X/*
X *	function to mail the letters to the player if a winner
X */
Xmailbill()
X	{
X#ifdef VMS
X	register int i;
X	char buf[128];
X	pid = getpid();
X	for (i=0; i<sizeof(pfn)/sizeof(int (*)()); i++)
X		if ((*pfn[i])()) {
X			sprintf(buf, "mail %s %s\n", loginname, mail600);
X			oneliner(buf);
X			delete(mail600);
X		}
X	}
X#else
X	register int i;
X	char buf[128];
X	wait(0);  pid=getpid();
X	if (fork() == 0)
X		{
X		resetscroll();
X		for (i=0; i<sizeof(pfn)/sizeof(int (*)()); i++)
X			if ((*pfn[i])())
X				{
X				sleep(20);
X				sprintf(buf,"mail %s < %s",loginname,mail600);
X				system(buf);  unlink(mail600);
X				}
X		exit();
X		}
X	}
X#endif
X# else
X
X/* Page the mail to the terminal	- dgk
X */
Xreadmail(gold)
Xlong	gold;
X{
X	register int i;
X
X	for (i = 0; i < (sizeof pfn) / (sizeof pfn[0]); i++) {
X		resetscroll();
X		clear();
X		(*pfn[i])(gold);	/* a bit dirty 'cause of args */
X		retcont();
X	}
X}
X# endif
END_OF_FILE
if test 7074 -ne `wc -c <'bill.c'`; then
    echo shar: \"'bill.c'\" unpacked with wrong size!
fi
# end of 'bill.c'
fi
if test -f 'global.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'global.c'\"
else
echo shar: Extracting \"'global.c'\" \(17640 characters\)
sed "s/^X//" >'global.c' <<'END_OF_FILE'
X/*  global.c        Larn is copyrighted 1986 by Noah Morgan.
X *
X *  raiselevel()        subroutine to raise the player one level
X *  loselevel()     subroutine to lower the player by one level
X *  raiseexperience(x)  subroutine to increase experience points
X *  loseexperience(x)   subroutine to lose experience points
X *  losehp(x)           subroutine to remove hit points from the player
X *  losemhp(x)          subroutine to remove max # hit points from the player
X *  raisehp(x)          subroutine to gain hit points
X *  raisemhp(x)         subroutine to gain maximum hit points
X *  losemspells(x)      subroutine to lose maximum spells
X *  raisemspells(x)     subroutine to gain maximum spells
X *  makemonst(lev)      function to return monster number for a randomly selected monster
X *  positionplayer()    function to be sure player is not in a wall
X *  recalc()            function to recalculate the armor class of the player
X *  quit()              subroutine to ask if the player really wants to quit
X *  more()
X *  take()
X *  drop_object()
X *  enchantarmor()
X *  enchweapon()
X *  pocketfull()
X *  nearbymonst()
X *  stealsomething()
X *  emptyhanded()
X *  creategem()
X *  adjustcvalues()
X *  gettokstr()
X *  getpassword()
X *  getyn()
X *  packweight()
X */
X
X#include "header.h"
Xextern int score[],srcount,dropflag;
Xextern short playerx,playery,lastnum;
Xextern char cheat,level,monstnamelist[];
Xextern char lastmonst[],*what[],*who[]; 
Xextern char winner[];
Xextern char logname[],monstlevel[];
Xextern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
X
X/*
X    raiselevel()
X
X    subroutine to raise the player one level
X    uses the skill[] array to find level boundarys
X    uses c[EXPERIENCE]  c[LEVEL]
X */
Xraiselevel()
X    {
X    if (c[LEVEL] < MAXPLEVEL) raiseexperience((long)(skill[c[LEVEL]]-c[EXPERIENCE]));
X    }
X
X/*
X    loselevel()
X
X    subroutine to lower the players character level by one
X */
Xloselevel()
X    {
X    if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL]-1] + 1));
X    }
X
X/*
X    raiseexperience(x)
X
X    subroutine to increase experience points
X */
Xraiseexperience(x)
X    register long x;
X    {
X    register int i,tmp;
X    i=c[LEVEL]; c[EXPERIENCE]+=x;
X    while (c[EXPERIENCE] >= skill[c[LEVEL]] && (c[LEVEL] < MAXPLEVEL))
X        {
X        tmp = (c[CONSTITUTION]-c[HARDGAME])>>1;
X        c[LEVEL]++; raisemhp((int)(rnd(3)+rnd((tmp>0)?tmp:1)));
X        raisemspells((int)rund(3));
X        if (c[LEVEL] < 7-c[HARDGAME]) raisemhp((int)(c[CONSTITUTION]>>2));
X        }
X    if (c[LEVEL] != i)
X        {
X        cursors();
X        beep(); lprintf("\nWelcome to level %d",(long)c[LEVEL]);    /* if we changed levels */
X        }
X    bottomline();
X    }
X
X/*
X    loseexperience(x)
X
X    subroutine to lose experience points
X */
Xloseexperience(x)
X    register long x;
X    {
X    register int i,tmp;
X    i=c[LEVEL];     c[EXPERIENCE]-=x;
X    if (c[EXPERIENCE] < 0) c[EXPERIENCE]=0;
X    while (c[EXPERIENCE] < skill[c[LEVEL]-1])
X        {
X        if (--c[LEVEL] <= 1) c[LEVEL]=1;    /*  down one level      */
X        tmp = (c[CONSTITUTION]-c[HARDGAME])>>1; /* lose hpoints */
X        losemhp((int)rnd((tmp>0)?tmp:1));   /* lose hpoints */
X        if (c[LEVEL] < 7-c[HARDGAME]) losemhp((int)(c[CONSTITUTION]>>2));
X        losemspells((int)rund(3));              /*  lose spells     */
X        }
X    if (i!=c[LEVEL])
X        {
X        cursors();
X        beep(); lprintf("\nYou went down to level %d!",(long)c[LEVEL]);
X        }
X    bottomline();
X    }
X
X/*
X    losehp(x)
X    losemhp(x)
X
X    subroutine to remove hit points from the player
X    warning -- will kill player if hp goes to zero
X */
Xlosehp(x)
X    register int x;
X    {
X    if ((c[HP] -= x) <= 0)
X        {
X        beep(); lprcat("\n");  nap(3000);  died(lastnum);
X        }
X    }
X
Xlosemhp(x)
X    register int x;
X    {
X    c[HP] -= x;     if (c[HP] < 1)      c[HP]=1;
X    c[HPMAX] -= x;  if (c[HPMAX] < 1)   c[HPMAX]=1;
X    }
X
X/*
X    raisehp(x)
X    raisemhp(x)
X
X    subroutine to gain maximum hit points
X */
Xraisehp(x)
X    register int x;
X    {
X    if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX];
X    }
X
Xraisemhp(x)
X    register int x;
X    {
X    c[HPMAX] += x;  c[HP] += x;
X    }
X
X/*
X    raisemspells(x)
X
X    subroutine to gain maximum spells
X*/
Xraisemspells(x)
X    register int x;
X    {
X    c[SPELLMAX]+=x; c[SPELLS]+=x;
X    }
X
X/*
X    losemspells(x)
X
X    subroutine to lose maximum spells
X*/
Xlosemspells(x)
X    register int x;
X    {
X    if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX]=0;
X    if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
X    }
X
X/*
X    makemonst(lev)
X        int lev;
X
X    function to return monster number for a randomly selected monster
X        for the given cave level    
X */
Xmakemonst(lev)
X    register int lev;
X    {
X    register int tmp,x;
X    if (lev < 1)
X	lev = 1;
X    if (lev > 12)
X	lev = 12;
X    if (lev < 5)
X	tmp=rnd((x=monstlevel[lev-1])?x:1);
X    else
X        tmp=rnd((x=monstlevel[lev-1]-monstlevel[lev-4])?x:1)+monstlevel[lev-4];
X
X    while (monster[tmp].genocided && tmp<MAXMONST)
X	tmp++; /* genocided? */
X    return(tmp);
X    }
X
X/*
X    positionplayer()
X
X    function to be sure player is not in a wall
X */
Xpositionplayer()
X    {
X    int try;
X    try = 2;
X    while ((item[playerx][playery] || mitem[playerx][playery]) && (try))
X        if (++playerx >= MAXX-1)
X            {
X            playerx = 1;
X            if (++playery >= MAXY-1)
X                {   playery = 1;    --try;  }
X            }
X    if (try==0)  lprcat("Failure in positionplayer\n");
X    }
X
X/*
X    recalc()    function to recalculate the armor class of the player
X */
Xrecalc()
X    {
X    register int i,j,k;
X    c[AC] = c[MOREDEFENSES];
X    if (c[WEAR] >= 0)  
X        switch(iven[c[WEAR]])
X            {
X            case OSHIELD:       c[AC] += 2 + ivenarg[c[WEAR]]; break;
X            case OLEATHER:      c[AC] += 2 + ivenarg[c[WEAR]]; break;
X            case OSTUDLEATHER:  c[AC] += 3 + ivenarg[c[WEAR]]; break;
X            case ORING:         c[AC] += 5 + ivenarg[c[WEAR]]; break;
X            case OCHAIN:        c[AC] += 6 + ivenarg[c[WEAR]]; break;
X            case OSPLINT:       c[AC] += 7 + ivenarg[c[WEAR]]; break;
X            case OPLATE:        c[AC] += 9 + ivenarg[c[WEAR]]; break;
X            case OPLATEARMOR:   c[AC] += 10 + ivenarg[c[WEAR]]; break;
X            case OSSPLATE:      c[AC] += 12 + ivenarg[c[WEAR]]; break;
X            }
X
X    if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]];
X    if (c[WIELD] < 0)  c[WCLASS] = 0;  else
X        {
X        i = ivenarg[c[WIELD]];
X        switch(iven[c[WIELD]])
X            {
X            case ODAGGER:    c[WCLASS] =  3 + i;  break;
X            case OBELT:      c[WCLASS] =  7 + i;  break;
X            case OSHIELD:    c[WCLASS] =  8 + i;  break;
X            case OSPEAR:     c[WCLASS] = 10 + i;  break;
X            case OFLAIL:     c[WCLASS] = 14 + i;  break;
X            case OBATTLEAXE: c[WCLASS] = 17 + i;  break;
X            case OLANCE:     c[WCLASS] = 19 + i;  break;
X            case OLONGSWORD: c[WCLASS] = 22 + i;  break;
X            case O2SWORD:    c[WCLASS] = 26 + i;  break;
X            case OSWORD:     c[WCLASS] = 32 + i;  break;
X            case OSWORDofSLASHING: c[WCLASS] = 30 + i; break;
X            case OHAMMER:    c[WCLASS] = 35 + i;  break;
X            default:         c[WCLASS] = 0;
X            }
X        }
X    c[WCLASS] += c[MOREDAM];
X
X/*  now for regeneration abilities based on rings   */
X    c[REGEN]=1;     c[ENERGY]=0;
X    j=0;  for (k=25; k>0; k--)  if (iven[k]) {j=k; k=0; }
X    for (i=0; i<=j; i++)
X        {
X        switch(iven[i])
X            {
X            case OPROTRING: c[AC]     += ivenarg[i] + 1;    break;
X            case ODAMRING:  c[WCLASS] += ivenarg[i] + 1;    break;
X            case OBELT:     c[WCLASS] += ((ivenarg[i]<<1)) + 2; break;
X
X            case OREGENRING:    c[REGEN]  += ivenarg[i] + 1;    break;
X            case ORINGOFEXTRA:  c[REGEN]  += 5 * (ivenarg[i]+1); break;
X            case OENERGYRING:   c[ENERGY] += ivenarg[i] + 1;    break;
X            }
X        }
X    }
X
X
X/*
X    quit()
X
X    subroutine to ask if the player really wants to quit
X */
Xquit()
X    {
X    register int i;
X    cursors();  strcpy(lastmonst,"");
X    lprcat("\n\nDo you really want to quit?");
X    while (1)
X        {
X        i=ttgetch();
X        if (i == 'y')   { died(300); return; }
X        if ((i == 'n') || (i == '\33')) { lprcat(" no"); lflush(); return; }
X        lprcat("\n");  setbold();  lprcat("Yes");  resetbold();  lprcat(" or ");
X        setbold();  lprcat("No");  resetbold();  lprcat(" please?   Do you want to quit? ");
X        }   
X    }
X
X/*
X    function to ask --more-- then the user must enter a space
X */
Xmore()
X    {
X    lprcat("\n  --- press ");  standout("space");  lprcat(" to continue --- ");
X    while (ttgetch() != ' ');
X    }
X
X/*
X    function to put something in the players inventory
X    returns 0 if success, 1 if a failure
X */
Xtake(itm,arg)
X    int itm,arg;
X    {
X    register int i,limit;
X/*  cursors(); */
X    if ((limit = 15+(c[LEVEL]>>1)) > 26)  limit=26;
X    for (i=0; i<limit; i++)
X        if (iven[i]==0)
X            {
X            iven[i] = itm;  ivenarg[i] = arg;  limit=0;
X            switch(itm)
X                {
X                case OPROTRING: case ODAMRING: case OBELT: limit=1;  break;
X                case ODEXRING:      c[DEXTERITY] += ivenarg[i]+1; limit=1;  break;
X                case OSTRRING:      c[STREXTRA]  += ivenarg[i]+1;   limit=1; break;
X                case OCLEVERRING:   c[INTELLIGENCE] += ivenarg[i]+1;  limit=1; break;
X                case OHAMMER:       c[DEXTERITY] += 10; c[STREXTRA]+=10;
X                                    c[INTELLIGENCE]-=10;    limit=1;     break;
X
X                case OORBOFDRAGON:  c[SLAYING]++;       break;
X                case OSPIRITSCARAB: c[NEGATESPIRIT]++;  break;
X                case OCUBEofUNDEAD: c[CUBEofUNDEAD]++;  break;
X                case ONOTHEFT:      c[NOTHEFT]++;       break;
X                case OSWORDofSLASHING:  c[DEXTERITY] +=5;   limit=1; break;
X                };
X            lprcat("\nYou pick up:"); srcount=0;  show3(i);
X            if (limit) bottomline();  return(0);
X            }
X    lprcat("\nYou can't carry anything else");  return(1);
X    }
X
X/*
X    subroutine to drop an object  returns 1 if something there already else 0
X */
Xdrop_object(k)
X    int k;
X    {
X    int itm;
X    if ((k<0) || (k>25)) return(0);
X    itm = iven[k];  cursors();
X    if (itm==0) { lprintf("\nYou don't have item %c! ",k+'a'); return(1); }
X    if (item[playerx][playery])
X        { beep(); lprcat("\nThere's something here already"); return(1); }
X    if (playery==MAXY-1 && playerx==33) return(1); /* not in entrance */
X    item[playerx][playery] = itm;
X    iarg[playerx][playery] = ivenarg[k];
X    srcount=0; lprcat("\n  You drop:"); show3(k); /* show what item you dropped*/
X    know[playerx][playery] = 0;  iven[k]=0; 
X    if (c[WIELD]==k) c[WIELD]= -1;      if (c[WEAR]==k)  c[WEAR] = -1;
X    if (c[SHIELD]==k) c[SHIELD]= -1;
X    adjustcvalues(itm,ivenarg[k]);
X    dropflag=1; /* say dropped an item so wont ask to pick it up right away */
X    return(0);
X    }
X
X/*
X    function to enchant armor player is currently wearing
X */
Xenchantarmor()
X    {
X    register int tmp;
X    if (c[WEAR]<0) { if (c[SHIELD] < 0)
X        { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
X                    else { tmp=iven[c[SHIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[SHIELD]]++; bottomline(); } } }
X    tmp = iven[c[WEAR]];
X    if (tmp!=OSCROLL) if (tmp!=OPOTION)  { ivenarg[c[WEAR]]++;  bottomline(); }
X    }
X
X/*
X    function to enchant a weapon presently being wielded
X */
Xenchweapon()
X    {
X    register int tmp;
X    if (c[WIELD]<0)
X        { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
X    tmp = iven[c[WIELD]];
X    if (tmp!=OSCROLL) if (tmp!=OPOTION)
X        { ivenarg[c[WIELD]]++;
X          if (tmp==OCLEVERRING) c[INTELLIGENCE]++;  else
X          if (tmp==OSTRRING)    c[STREXTRA]++;  else
X          if (tmp==ODEXRING)    c[DEXTERITY]++;       bottomline(); }
X    }
X
X/*
X    routine to tell if player can carry one more thing
X    returns 1 if pockets are full, else 0
X */
Xpocketfull()
X    {
X    register int i,limit; 
X    if ((limit = 15+(c[LEVEL]>>1)) > 26)  limit=26;
X    for (i=0; i<limit; i++) if (iven[i]==0) return(0);
X    return(1);
X    }
X
X/*
X    function to return 1 if a monster is next to the player else returns 0
X */
Xnearbymonst()
X    {
X    register int tmp,tmp2;
X    for (tmp=playerx-1; tmp<playerx+2; tmp++)
X        for (tmp2=playery-1; tmp2<playery+2; tmp2++)
X            if (mitem[tmp][tmp2]) return(1); /* if monster nearby */
X    return(0);
X    }
X
X/*
X    function to steal an item from the players pockets
X    returns 1 if steals something else returns 0
X */
Xstealsomething()
X    {
X    register int i,j;
X    j=100;
X    while (1)
X        {
X        i=rund(26);
X        if (iven[i]) if (c[WEAR]!=i) if (c[WIELD]!=i) if (c[SHIELD]!=i)
X            {
X            srcount=0; show3(i);
X            adjustcvalues(iven[i],ivenarg[i]);  iven[i]=0; return(1);
X            }
X        if (--j <= 0) return(0);
X        }
X    }
X
X/*
X    function to return 1 is player carrys nothing else return 0
X */
Xemptyhanded()
X    {
X    register int i;
X    for (i=0; i<26; i++)
X        if (iven[i]) if (i!=c[WIELD]) if (i!=c[WEAR]) if (i!=c[SHIELD]) return(0);
X    return(1);
X    }
X
X/*
X    function to create a gem on a square near the player
X */
Xcreategem()
X    {
X    register int i,j;
X    switch(rnd(4))
X        {
X        case 1:  i=ODIAMOND;    j=50;   break;
X        case 2:  i=ORUBY;       j=40;   break;
X        case 3:  i=OEMERALD;    j=30;   break;
X        default: i=OSAPPHIRE;   j=20;   break;
X        };
X    createitem(i,rnd(j)+j/10);
X    }
X
X/*
X    function to change character levels as needed when dropping an object
X    that affects these characteristics
X */
Xadjustcvalues(itm,arg)
X    int itm,arg;
X    {
X    register int flag;
X    flag=0;
X    switch(itm)
X        {
X        case ODEXRING:  c[DEXTERITY] -= arg+1;  flag=1; break;
X        case OSTRRING:  c[STREXTRA]  -= arg+1;  flag=1; break;
X        case OCLEVERRING: c[INTELLIGENCE] -= arg+1;  flag=1; break;
X        case OHAMMER:   c[DEXTERITY] -= 10; c[STREXTRA] -= 10;
X                        c[INTELLIGENCE] += 10; flag=1; break;
X        case OSWORDofSLASHING:  c[DEXTERITY] -= 5;  flag=1; break;
X        case OORBOFDRAGON:      --c[SLAYING];       return;
X        case OSPIRITSCARAB:     --c[NEGATESPIRIT];  return;
X        case OCUBEofUNDEAD:     --c[CUBEofUNDEAD];  return;
X        case ONOTHEFT:          --c[NOTHEFT];       return;
X        case OLANCE:        c[LANCEDEATH]=0;    return;
X        case OPOTION:   case OSCROLL:   return;
X
X        default:    flag=1;
X        };
X    if (flag) bottomline();
X    }
X
X/*
X    function to ask user for a password (no echo)
X    returns 1 if entered correctly, 0 if not
X */
Xstatic char gpwbuf[33];
Xgetpassword()
X    {
X    register int i,j;
X    register char *gpwp;
X    extern char *password;
X    scbr(); /*  system("stty -echo cbreak"); */
X    gpwp = gpwbuf;  lprcat("\nEnter Password: "); lflush();
X    i = strlen(password);
X    for (j=0; j<i; j++) 
X        *gpwp++ = ttgetch();
X    gpwbuf[i]=0;
X    sncbr(); /* system("stty echo -cbreak"); */
X    if (strcmp(gpwbuf,password) != 0)
X        {   lprcat("\nSorry\n");  lflush(); return(0);  }
X    else  return(1);
X    }
X
X/*
X    subroutine to get a yes or no response from the user
X    returns y or n
X */
Xgetyn()
X    {
X    register int i;
X    i=0; while (i!='y' && i!='n' && i!='\33') i=ttgetch();
X    return(i);
X    }
X
X/*
X    function to calculate the pack weight of the player
X    returns the number of pounds the player is carrying
X */
Xpackweight()
X    {
X    register int i,j,k;
X    k=c[GOLD]/1000; j=25;  while ((iven[j]==0) && (j>0)) --j;
X    for (i=0; i<=j; i++)
X        switch(iven[i])
X            {
X            case 0:                                             break;
X            case OSSPLATE:   case OPLATEARMOR:      k += 40;    break;
X            case OPLATE:                            k += 35;    break;
X            case OHAMMER:                           k += 30;    break;
X            case OSPLINT:                           k += 26;    break;
X            case OSWORDofSLASHING:  case OCHAIN:
X            case OBATTLEAXE:        case O2SWORD:   k += 23;    break;
X            case OLONGSWORD:        case OSWORD:
X            case ORING:             case OFLAIL:    k += 20;    break;
X            case OLANCE:        case OSTUDLEATHER:  k += 15;    break;
X            case OLEATHER:          case OSPEAR:    k += 8;     break;
X            case OORBOFDRAGON:      case OBELT:     k += 4;     break;
X            case OSHIELD:                           k += 7;     break;
X            case OCHEST:        k += 30 + ivenarg[i];           break;
X            default:                                k++;
X            };
X    return(k);
X    }
X
X#ifndef MACRORND
X    /* macros to generate random numbers   1<=rnd(N)<=N   0<=rund(N)<=N-1 */
Xrnd(x)
X    int x;
X    {
X    return((((lrandx=lrandx*1103515245+12345)>>7)%(x))+1);
X    }
X
Xrund(x)
X    int x;
X    {
X    return((((lrandx=lrandx*1103515245+12345)>>7)%(x))  );
X    }
X#endif MACRORND
X
X/*
X    function to read a string from token input "string"
X    returns a pointer to the string
X */
Xgettokstr(str)
X    register char *str;
X    {
X    register int i,j;
X    i=50;
X    while ((ttgetch() != '"') && (--i > 0));
X    i=36;
X    while (--i > 0)
X        {
X        if ((j=ttgetch()) != '"') *str++ = j;  else i=0;
X        }
X    *str = 0;
X    i=50;
X    if (j != '"') while ((ttgetch() != '"') && (--i > 0)); /* if end due to too long, then find closing quote */
X    }
END_OF_FILE
if test 17640 -ne `wc -c <'global.c'`; then
    echo shar: \"'global.c'\" unpacked with wrong size!
fi
# end of 'global.c'
fi
if test -f 'io.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'io.c'\"
else
echo shar: Extracting \"'io.c'\" \(25801 characters\)
sed "s/^X//" >'io.c' <<'END_OF_FILE'
X/* io.c			 Larn is copyrighted 1986 by Noah Morgan.
X *
X *	Below are the functions in this file:
X *
X *	setupvt100() 	Subroutine to set up terminal in correct mode for game
X *	clearvt100()  	Subroutine to clean up terminal when the game is over
X *	ttgetch() 		Routine to read in one character from the terminal
X *	scbr()			Function to set cbreak -echo for the terminal
X *	sncbr()			Function to set -cbreak echo for the terminal
X *	newgame() 		Subroutine to save the initial time and seed rnd()
X *
X *	FILE OUTPUT ROUTINES
X *
X *	lprintf(format,args . . .)	printf to the output buffer
X *	lprint(integer)			send binary integer to output buffer
X *	lwrite(buf,len)			write a buffer to the output buffer
X *	lprcat(str)			sent string to output buffer
X *
X *	FILE OUTPUT MACROS (in header.h)
X *
X *	lprc(character)			put the character into the output buffer
X *
X *	FILE INPUT ROUTINES
X *
X *	long lgetc()			read one character from input buffer
X *	long lrint()			read one integer from input buffer
X *	lrfill(address,number)		put input bytes into a buffer
X *	char *lgetw()			get a whitespace ended word from input
X *	char *lgetl()			get a \n or EOF ended line from input
X *
X *	FILE OPEN / CLOSE ROUTINES
X *
X *	lcreat(filename)		create a new file for write
X *	lopen(filename)			open a file for read
X *	lappend(filename)		open for append to an existing file
X *	lrclose()			close the input file
X *	lwclose()			close output file
X *	lflush()			flush the output buffer
X *
X *	Other Routines
X *
X *	cursor(x,y)		position cursor at [x,y]
X *	cursors()		position cursor at [1,24] (saves memory)
X * 	cl_line(x,y)         	Clear line at [1,y] and leave cursor at [x,y]
X * 	cl_up(x,y)    		Clear screen from [x,1] to current line.
X * 	cl_dn(x,y) 		Clear screen from [1,y] to end of display. 
X * 	standout(str)	 	Print the string in standout mode.
X * 	set_score_output() 	Called when output should be literally printed.
X **	ttputch(ch)		Print one character in decoded output buffer.
X **	flush_buf()		Flush buffer with decoded output.
X **	init_term()		Terminal initialization -- setup termcap info
X **	char *tmcapcnv(sd,ss)  	Routine to convert VT100 \33's to termcap format
X *	beep()			Routine to emit a beep if enabled (see no-beep in .larnopts)
X *
X * Note: ** entries are available only in termcap mode.
X */
X
X#include "header.h"
X#include <ctype.h>
X
X#ifdef SYSV	/* system III or system V */
X# ifndef MSDOS
X#   include <termio.h>
X# endif
X#define sgttyb termio
X#define stty(_a,_b) ioctl(_a,TCSETA,_b)
X#define gtty(_a,_b) ioctl(_a,TCGETA,_b)
Xstatic int rawflg = 0;
Xstatic char saveeof,saveeol;
X#define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\
X    _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL)
X#define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL
X#else not SYSV
X#ifdef VMS
X#include	<descrip.h>
X#include	<ssdef.h>
X#include	<stsdef.h>
X#include	<iodef.h>
X#include	<ttdef.h>
X#include	<tt2def.h>
X#else VMS
X#ifndef BSD
X#define CBREAK RAW		/* V7 has no CBREAK */
X#endif
X#define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO)
X#define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO)
X#include <sgtty.h>
X#endif not SYSV
X#endif VMS
X
X#ifndef NOVARARGS	/* if we have varargs */
X#include <varargs.h>
X#else NOVARARGS	/* if we don't have varargs */
Xtypedef char *va_list;
X#define va_dcl int va_alist;
X#define va_start(plist) plist = (char *) &va_alist
X#define va_end(plist)
X#define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1]
X#endif NOVARARGS
X
X#define LINBUFSIZE 128		/* size of the lgetw() and lgetl() buffer		*/
Xint lfd;			/*  output file numbers		*/
Xint fd;				/*  input file numbers		*/
X# ifndef MSDOS
X# ifndef VMS
Xstatic struct sgttyb ttx;	/* storage for the tty modes					*/
X# else
Xint	iochan;			/* storage for the tty channel	*/
Xint	ttx[3];			/* storage for the tty modes	*/
Xint	cbflag;			/* cbreak flag.  Set when SCBRd */
X# endif
X# endif
Xstatic int ipoint=MAXIBUF,iepoint=MAXIBUF;	/*  input buffering pointers    */
Xstatic char lgetwbuf[LINBUFSIZE];	/* get line (word) buffer				*/
X
X#ifdef DGK_MSDOS
X# include <setjmp.h>
X extern jmp_buf save_jbuf;
X extern int save_mode;
X#endif
X
X# ifdef MSDOS
X# include <fcntl.h>		/* For O_BINARY */
Xstatic int (*getchfn)();
Xint getche(), kgetch();
X# endif
X
X/*
X *	setupvt100() 		Subroutine to set up terminal in correct mode for game
X *
X *	Attributes off, clear screen, set scrolling region, set tty mode 
X */
Xsetupvt100()
X	{
X#ifdef VMS
X	struct  dsc$descriptor  idsc;
X	register int		status;
X
X	idsc.dsc$a_pointer = "SYS$COMMAND";
X	idsc.dsc$w_length  = strlen(idsc.dsc$a_pointer);
X	idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
X	idsc.dsc$b_class   = DSC$K_CLASS_S;
X	status = SYS$ASSIGN(&idsc, &iochan, 0, 0);
X	if (status&STS$M_SUCCESS == 0)
X		exit(status);
X#endif
X	lprc(T_INIT);
X	clear();  setscroll();  scbr(); /* system("stty cbreak -echo"); */
X# ifdef DGK_MSDOS
X	setraw();
X	setcursor();
X
X	/* Select normal ASCII and line drawing character sets.
X	 */
X	if (DECRainbow)
X		lprcat("\033(B\033)0");
X# endif
X	}
X
X/*
X *	clearvt100() 	 	Subroutine to clean up terminal when the game is over
X *
X *	Attributes off, clear screen, unset scrolling region, restore tty mode 
X */
Xclearvt100()
X	{
X	lprc(T_END);
X	resetscroll();  clear();  sncbr(); /* system("stty -cbreak echo"); */
X# ifdef DGK_MSDOS
X	unsetraw();
X	resetcursor();
X# endif
X#ifdef VMS
X	SYS$DASSGN(iochan);
X#endif
X	}
X
X/*
X *	ttgetch() 		Routine to read in one character from the terminal
X */
Xttgetch()
X	{
X	char byt;
X#ifdef EXTRA
X	c[BYTESIN]++;
X#endif EXTRA
X	lflush();		/* be sure output buffer is flushed */
X# ifdef MSDOS
X	if ((byt = (*getchfn)()) == '\r')
X		byt = '\n';
X	return byt;
X#endif MSDOS
X
X#ifdef VMS
X        {
X	extern vms_ttgetch();
X        return (vms_ttgetch());
X	}
X#else VMS
X	read(0,&byt,1); 	/* get byte from terminal */
X	return(byt);
X# endif VMS
X	}
X
X/*
X *	scbr()		Function to set cbreak -echo for the terminal
X *
X *	like: system("stty cbreak -echo")
X */
Xscbr()
X	{
X# ifdef MSDOS
X	/* Set up to use the direct console input call which may
X	 * read from the keypad;
X	 */
X	getchfn = kgetch;
X# else
X# ifdef VMS
X	int	status;
X	int	iosb[2];
X
X	cbflag = 1;
X	status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
X			  ttx, sizeof(ttx), 0, 0, 0, 0);
X	if (status&STS$M_SUCCESS == 0)
X		exit(status);
X	ttx[1] |= TT$M_NOECHO;
X	ttx[2] |= TT2$M_PASTHRU;
X	status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
X			  ttx, sizeof(ttx), 0, 0, 0, 0);
X	if (status&STS$M_SUCCESS == 0)
X		exit(status);
X# else
X	gtty(0,&ttx);		doraw(ttx);		stty(0,&ttx);
X# endif
X# endif
X	}
X
X/*
X *	sncbr()		Function to set -cbreak echo for the terminal
X *
X *	like: system("stty -cbreak echo")
X */
Xsncbr()
X	{
X# ifdef MSDOS
X	/* Set up to use the direct console input call with echo, getche()
X	 */
X	getchfn = getche;
X# else
X# ifdef VMS
X	int	status;
X	int	iosb[2];
X	cbflag = 0;
X	status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
X			  ttx, sizeof(ttx), 0, 0, 0, 0);
X	if (status&STS$M_SUCCESS == 0)
X		exit(status);
X	ttx[1] &= ~TT$M_NOECHO;
X	ttx[2] &= ~TT2$M_PASTHRU;
X	status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
X			  ttx, sizeof(ttx), 0, 0, 0, 0);
X	if (status&STS$M_SUCCESS == 0)
X		exit(status);
X# else
X	gtty(0,&ttx);		unraw(ttx);		stty(0,&ttx);
X# endif
X# endif
X	}
X
X/*
X *	newgame() 		Subroutine to save the initial time and seed rnd()
X */
Xnewgame()
X{
X	register long *p,*pe;
X	for (p=c,pe=c+100; p<pe; *p++ =0);
X	time(&initialtime);
X	srand(initialtime);
X	lcreat((char*)0);	/* open buffering for output to terminal */
X}
X
X/*
X *	lprintf(format,args . . .)		printf to the output buffer
X *		char *format;
X *		??? args . . .
X *
X *	Enter with the format string in "format", as per printf() usage
X *		and any needed arguments following it
X *	Note: lprintf() only supports %s, %c and %d, with width modifier and left
X *		or right justification.
X *	No correct checking for output buffer overflow is done, but flushes 
X *		are done beforehand if needed.
X *	Returns nothing of value.
X */
X#ifdef lint
X/*VARARGS*/
Xlprintf(str)
X	char *str;
X	{
X	char *str2;
X	str2 = str;
X	str = str2; /* to make lint happy */
X	}
X/*VARARGS*/
Xsprintf(str)
X	char *str;
X	{
X	char *str2;
X	str2 = str;
X	str = str2; /* to make lint happy */
X	}
X#else lint
X/*VARARGS*/
Xlprintf(va_alist)
Xva_dcl
X    {
X	va_list ap;	/* pointer for variable argument list */
X	register char *fmt;
X	register char *outb,*tmpb;
X	register long wide,left,cont,n;		/* data for lprintf	*/
X	char db[12];			/* %d buffer in lprintf	*/
X
X	va_start(ap);	/* initialize the var args pointer */
X	fmt = va_arg(ap, char *);	/* pointer to format string */
X	if (lpnt >= lpend) lflush(); 
X	outb = lpnt;
X	for ( ; ; )
X		{
X		while (*fmt != '%')
X			if (*fmt) *outb++ = *fmt++;  else { lpnt=outb;  return; }
X		wide = 0;	left = 1;	cont=1;
X		while (cont)
X		  switch(*(++fmt))
X			{
X			case 'd':	n = va_arg(ap, long);
X						if (n<0) { n = -n;  *outb++ = '-';  if (wide) --wide; }
X						tmpb = db+11;	*tmpb = (char)(n % 10 + '0');
X						while (n>9)  *(--tmpb) = (char)((n /= 10) % 10 + '0');
X						if (wide==0)  while (tmpb < db+12) *outb++ = *tmpb++;
X						else
X							{
X							wide -= db-tmpb+12;
X							if (left)  while (wide-- > 0) *outb++ = ' ';
X							while (tmpb < db+12) *outb++ = *tmpb++;
X							if (left==0)  while (wide-- > 0) *outb++ = ' ';
X							}
X						cont=0;	break;
X
X			case 's':	tmpb = va_arg(ap, char *);
X						if (wide==0)  { while (*outb++ = *tmpb++);  --outb; } 
X						else
X							{
X							n = wide - strlen(tmpb);
X							if (left)  while (n-- > 0) *outb++ = ' ';
X							while (*outb++ = *tmpb++);  --outb;
X							if (left==0)  while (n-- > 0) *outb++ = ' ';
X							}
X						cont=0;	break;
X
X			case 'c':	*outb++ = va_arg(ap, int);	cont=0;  break;
X
X			case '0':
X			case '1':
X			case '2':
X			case '3':
X			case '4':
X			case '5':
X			case '6':
X			case '7':
X			case '8':
X			case '9':	wide = 10*wide + *fmt - '0';	break;
X
X			case '-':	left = 0;	break;
X
X			default:	*outb++ = *fmt;  cont=0;	break;
X			};
X		fmt++;
X		}
X	va_end(ap);
X	}
X#endif lint
X
X/*
X *	lprint(long-integer)				send binary integer to output buffer
X *		long integer;
X *
X *		+---------+---------+---------+---------+
X *		|	high  |			|		  |	  low	|
X *		|  order  |			|		  |  order	|
X *		|   byte  |			|		  |	  byte	|
X *		+---------+---------+---------+---------+
X *	   31  ---  24 23 --- 16 15 ---  8 7  ---   0
X *
X *	The save order is low order first, to high order (4 bytes total)
X *		and is written to be system independent.
X *	No checking for output buffer overflow is done, but flushes if needed!
X *	Returns nothing of value.
X */
Xlprint(x)
X	register long x;
X	{
X	if (lpnt >= lpend) lflush();
X	*lpnt++ =  255 & x;			*lpnt++ =  255 & (x>>8);
X	*lpnt++ =  255 & (x>>16);	*lpnt++ =  255 & (x>>24);
X	}
X
X/*
X *	lwrite(buf,len)			write a buffer to the output buffer
X *		char *buf;
X *		int len;
X *	
X *	Enter with the address and number of bytes to write out
X *	Returns nothing of value
X */
Xlwrite(buf,len)
X    register char *buf;
X    int len;
X    {
X	register char *str;
X	register int num2;
X	if (len > 399)  /* don't copy data if can just write it */
X		{
X#ifdef EXTRA
X		c[BYTESOUT] += len;
X#endif
X
X#ifndef VT100
X		for (str=buf;  len>0; --len)
X			lprc(*str++);
X#else VT100
X		lflush();
X		write(lfd,buf,len);
X#endif VT100
X		} 
X	else while (len)
X		{
X		if (lpnt >= lpend) lflush();	/* if buffer is full flush it	*/
X		num2 = lpbuf+BUFBIG-lpnt;	/*	# bytes left in output buffer	*/
X		if (num2 > len) num2=len;
X		str = lpnt;  len -= num2;
X		while (num2--)  *str++ = *buf++;	/* copy in the bytes */
X		lpnt = str;
X		}
X    }
X
X/*
X *	long lgetc()		Read one character from input buffer
X *
X *  Returns 0 if EOF, otherwise the character
X */
Xlong lgetc()
X    {
X    register int i;
X
X    if (ipoint != iepoint)  return(inbuffer[ipoint++]);
X    if (iepoint!=MAXIBUF)   return(0);
X    if ((i=vread(fd,inbuffer,MAXIBUF))<=0) {
X    	if (i!=0)
X        	write(1,"error reading from input file\n",30);
X	iepoint = ipoint = 0;
X	return(0);
X    }
X    ipoint=1;  iepoint=i;  return(*inbuffer);
X}
X
X/*
X *	long lrint()			Read one integer from input buffer
X *
X *		+---------+---------+---------+---------+
X *		|	high  |			|		  |	  low	|
X *		|  order  |			|		  |  order	|
X *		|   byte  |			|		  |	  byte	|
X *		+---------+---------+---------+---------+
X *	   31  ---  24 23 --- 16 15 ---  8 7  ---   0
X *
X *	The save order is low order first, to high order (4 bytes total)
X *	Returns the int read
X */
Xlong lrint()
X	{
X	register unsigned long i;
X	i  = 255 & lgetc();				i |= (255 & lgetc()) << 8;
X	i |= (255 & lgetc()) << 16;		i |= (255 & lgetc()) << 24;
X	return(i);
X	}
X
X/*
X *	lrfill(address,number)			put input bytes into a buffer
X *		char *address;
X *		int number;
X *
X *	Reads "number" bytes into the buffer pointed to by "address".
X *	Returns nothing of value
X */
Xlrfill(adr,num)
X	register char *adr;
X	int num;
X	{
X	register char *pnt;
X	register int num2;
X	while (num)
X		{
X		if (iepoint == ipoint)
X			{
X			if (num>5) /* fast way */
X				{
X				if (vread(fd,adr,num) != num)
X					write(2,"error reading from input file\n",30);
X				num=0;
X				}
X			else { *adr++ = lgetc();  --num; }
X			}
X		else
X			{
X			num2 = iepoint-ipoint;	/*	# of bytes left in the buffer	*/
X			if (num2 > num) num2=num;
X			pnt = inbuffer+ipoint;	num -= num2;  ipoint += num2;
X			while (num2--)  *adr++ = *pnt++;
X			}
X		}
X	}
X
X/*
X *	char *lgetw()			Get a whitespace ended word from input
X *
X *	Returns pointer to a buffer that contains word.  If EOF, returns a NULL
X */
Xchar *lgetw()
X	{
X	register char *lgp,cc;
X	register int n=LINBUFSIZE,quote=0;
X	lgp = lgetwbuf;
X	do cc=lgetc();  while ((cc <= 32) && (cc > NULL));  /* eat whitespace */
X	for ( ; ; --n,cc=lgetc())
X		{
X		if ((cc==NULL) && (lgp==lgetwbuf))  return(NULL);	/* EOF */
X		if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); }
X		if (cc != '"') *lgp++ = cc;   else quote ^= 1;
X		}
X	}
X
X/*
X *	char *lgetl()		Function to read in a line ended by newline or EOF
X *
X *	Returns pointer to a buffer that contains the line.  If EOF, returns NULL
X */
Xchar *lgetl()
X{
X	register int i=LINBUFSIZE,ch;
X	register char *str=lgetwbuf;
X	for ( ; ; --i) {
X		*str++ = ch = lgetc();
X		if (ch == 0) {
X			if (str == lgetwbuf+1)
X				return(NULL);	/* EOF */
X		ot:	*str = 0;
X			return(lgetwbuf);	/* line ended by EOF */
X		}
X		if ((ch=='\n') || (i<=1))
X			goto ot;		/* line ended by \n */
X	}
X}
X
X/*
X *	lcreat(filename)			Create a new file for write
X *		char *filename;
X *
X *	lcreat((char*)0); means to the terminal
X *	Returns -1 if error, otherwise the file descriptor opened.
X */
Xlcreat(str)
X	char *str;
X	{
X	lpnt = lpbuf;	lpend = lpbuf+BUFBIG;
X	if (str==NULL) return(lfd=1);
X	if ((lfd=creat(str,0644)) < 0) 
X		{
X		lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1);
X		}
X# ifdef MSDOS
X	setmode(lfd, O_BINARY);
X# endif
X	return(lfd);
X	}
X
X/*
X *	lopen(filename)			Open a file for read
X *		char *filename;
X *
X *	lopen(0) means from the terminal
X *	Returns -1 if error, otherwise the file descriptor opened.
X */
Xlopen(str)
X	char *str;
X	{
X	ipoint = iepoint = MAXIBUF;
X	if (str==NULL) return(fd=0);
X	if ((fd=open(str,0)) < 0)
X		{
X		lwclose(); lfd=1; lpnt=lpbuf; return(-1);
X		}
X# ifdef MSDOS
X	setmode(fd, O_BINARY);
X# endif
X	return(fd);
X	}
X
X/*
X *	lappend(filename)		Open for append to an existing file
X *		char *filename;
X *
X *	lappend(0) means to the terminal
X *	Returns -1 if error, otherwise the file descriptor opened.
X */
Xlappend(str)
X	char *str;
X	{
X	lpnt = lpbuf;	lpend = lpbuf+BUFBIG;
X	if (str==NULL) return(lfd=1);
X	if ((lfd=open(str,2)) < 0)
X		{
X		lfd=1; return(-1);
X		}
X# ifdef MSDOS
X	setmode(lfd, O_BINARY);
X# endif
X	lseek(lfd,0L,2);	/* seek to end of file */
X	return(lfd);
X	}
X
X/*
X *	lrclose()						close the input file
X *
X *	Returns nothing of value.
X */
Xlrclose()
X	{
X	if (fd > 0) close(fd);
X	}
X
X/*
X *	lwclose()						close output file flushing if needed
X *
X *	Returns nothing of value.
X */
Xlwclose()
X	{
X	lflush();	if (lfd > 2) close(lfd);
X	}
X
X/*
X *	lprcat(string)					append a string to the output buffer
X *								    avoids calls to lprintf (time consuming)
X */
Xlprcat(str)
X    register char *str;
X    {
X	register char *str2;
X	if (lpnt >= lpend) lflush(); 
X	str2 = lpnt;
X	while (*str2++ = *str++);
X	lpnt = str2 - 1;
X    }
X
X#ifdef VT100
X/*
X *	cursor(x,y) 		Subroutine to set the cursor position
X *
X *	x and y are the cursor coordinates, and lpbuff is the output buffer where
X *	escape sequence will be placed. 
X */
Xstatic char *y_num[]= { "\33[","\33[","\33[2","\33[3","\33[4","\33[5","\33[6",
X	"\33[7","\33[8","\33[9","\33[10","\33[11","\33[12","\33[13","\33[14",
X	"\33[15","\33[16","\33[17","\33[18","\33[19","\33[20","\33[21","\33[22",
X	"\33[23","\33[24" };
X
Xstatic char *x_num[]= { "H","H",";2H",";3H",";4H",";5H",";6H",";7H",";8H",";9H",
X	";10H",";11H",";12H",";13H",";14H",";15H",";16H",";17H",";18H",";19H",
X	";20H",";21H",";22H",";23H",";24H",";25H",";26H",";27H",";28H",";29H",
X	";30H",";31H",";32H",";33H",";34H",";35H",";36H",";37H",";38H",";39H",
X	";40H",";41H",";42H",";43H",";44H",";45H",";46H",";47H",";48H",";49H",
X	";50H",";51H",";52H",";53H",";54H",";55H",";56H",";57H",";58H",";59H",
X	";60H",";61H",";62H",";63H",";64H",";65H",";66H",";67H",";68H",";69H",
X	";70H",";71H",";72H",";73H",";74H",";75H",";76H",";77H",";78H",";79H",
X	";80H" };
X
Xcursor(x,y)
X	int x,y;
X	{
X	register char *p;
X	if (lpnt >= lpend) lflush();
X
X	p = y_num[y];	/* get the string to print */
X	while (*p) *lpnt++ = *p++;	/* print the string */
X
X	p = x_num[x];	/* get the string to print */
X	while (*p) *lpnt++ = *p++;	/* print the string */
X	}
X#else VT100
X/*
X * cursor(x,y)	  Put cursor at specified coordinates staring at [1,1] (termcap)
X */
Xcursor (x,y)
X	int x,y;
X	{
X	if (lpnt >= lpend) lflush ();
X
X	*lpnt++ = CURSOR;		*lpnt++ = x;		*lpnt++ = y;
X	}
X#endif VT100
X
X/*
X *	Routine to position cursor at beginning of 24th line
X */
Xcursors()
X	{
X	cursor(1,24);
X	}
X
X#ifndef VT100
X/*
X * Warning: ringing the bell is control code 7. Don't use in defines.
X * Don't change the order of these defines.
X * Also used in helpfiles. Codes used in helpfiles should be \E[1 to \E[7 with
X * obvious meanings.
X */
X
Xstatic char cap[256];
Xstatic char *CM, *CE, *CD, *CL, *SO, *SE, *AL, *DL, *TI, *TE;/* Termcap capabilities */
Xstatic char *outbuf=0;	/* translated output buffer */
X
Xstatic int ttputch ();
X
X/*
X * init_term()		Terminal initialization -- setup termcap info
X */
Xinit_term()
X	{
X	char termbuf[1024];
X	char *capptr = cap+10;
X	char *term;
X
X# ifdef MSDOS
X	term = getenv("TERM");
X	if (term == NULL)
X		term = "ibmpc-mono";
X	switch (tgetent(termbuf, term))
X# else
X# ifdef VMS
X	term = getenv("TERMINAL");
X	if (term == NULL)
X		term = getenv("TERM");
X	switch (tgetent(termbuf, term))
X# else
X	switch (tgetent(termbuf, term = getenv("TERM")))
X# endif
X# endif
X		{
X		case -1: 
X			write(2, "Cannot open termcap file.\n", 26); exit();
X		case 0: 
X			write(2, "Cannot find entry of ", 21);
X			write(2, term, strlen (term));
X			write(2, " in termcap\n", 12);
X			exit();
X		};
X
X	CM = tgetstr("cm", &capptr);  /* Cursor motion */
X	CE = tgetstr("ce", &capptr);  /* Clear to eoln */
X	CL = tgetstr("cl", &capptr);  /* Clear screen */
X
X/* OPTIONAL */
X	AL = tgetstr("al", &capptr);  /* Insert line */
X	DL = tgetstr("dl", &capptr);  /* Delete line */
X	SO = tgetstr("so", &capptr);  /* Begin standout mode */
X	SE = tgetstr("se", &capptr);  /* End standout mode */
X	CD = tgetstr("cd", &capptr);  /* Clear to end of display */
X	TI = tgetstr("ti", &capptr);  /* Terminal initialization */
X	TE = tgetstr("te", &capptr);  /* Terminal end */
X
X	if (!CM)	/* can't find cursor motion entry */
X		{
X		write(2, "Sorry, for a ",13);		write(2, term, strlen(term));
X		write(2, ", I can't find the cursor motion entry in termcap\n",50);
X		exit();
X		}
X	if (!CE)	/* can't find clear to end of line entry */
X		{
X		write(2, "Sorry, for a ",13);		write(2, term, strlen(term));
X		write(2,", I can't find the clear to end of line entry in termcap\n",57);
X		exit();
X		}
X	if (!CL)	/* can't find clear entire screen entry */
X		{
X		write(2, "Sorry, for a ",13);		write(2, term, strlen(term));
X		write(2, ", I can't find the clear entire screen entry in termcap\n",56);
X		exit();
X		}
X	if ((outbuf=(char *)malloc(BUFBIG+16))==0) /* get memory for decoded output buffer*/
X		{
X		write(2,"Error malloc'ing memory for decoded output buffer\n",50);
X		died(-285);	/* malloc() failure */
X		}
X	}
X#endif VT100
X
X/*
X * cl_line(x,y)  Clear the whole line indicated by 'y' and leave cursor at [x,y]
X */
Xcl_line(x,y)
X	int x,y;
X	{
X#ifdef VT100
X	cursor(x,y);		lprcat("\33[2K");
X#else VT100
X	cursor(1,y);		*lpnt++ = CL_LINE;		cursor(x,y);
X#endif VT100
X	}
X
X/*
X * cl_up(x,y) Clear screen from [x,1] to current position. Leave cursor at [x,y]
X */
Xcl_up(x,y)
X	register int x,y;
X	{
X#ifdef VT100
X	cursor(x,y);  lprcat("\33[1J\33[2K");
X#else VT100
X	register int i;
X	cursor(1,1);
X	for (i=1; i<=y; i++)   { *lpnt++ = CL_LINE;  *lpnt++ = '\n'; }
X	cursor(x,y);
X#endif VT100
X	}
X
X/*
X * cl_dn(x,y) 	Clear screen from [1,y] to end of display. Leave cursor at [x,y]
X */
Xcl_dn(x,y)
X	register int x,y;
X	{
X#ifdef VT100
X	cursor(x,y); lprcat("\33[J\33[2K");
X#else VT100
X	register int i;
X	cursor(1,y);
X	if (!CD)
X		{
X		*lpnt++ = CL_LINE;
X		for (i=y; i<=24; i++) { *lpnt++ = CL_LINE;  if (i!=24) *lpnt++ = '\n'; }
X		cursor(x,y);
X		}
X	else
X		*lpnt++ = CL_DOWN;
X	cursor(x,y);
X#endif VT100
X	}
X
X/*
X * standout(str)	Print the argument string in inverse video (standout mode).
X */
Xstandout(str)
X	register char *str;
X	{
X#ifdef VT100
X	setbold();
X	while (*str)
X		*lpnt++ = *str++;
X	resetbold();
X#else VT100
X	*lpnt++ = ST_START;
X	while (*str)
X		*lpnt++ = *str++;
X	*lpnt++ = ST_END;
X#endif VT100
X	}
X
X/*
X * set_score_output() 	Called when output should be literally printed.
X */
Xset_score_output()
X	{
X	enable_scroll = -1;
X	}
X
X/*
X *	lflush()						Flush the output buffer
X *
X *	Returns nothing of value.
X *	for termcap version: Flush output in output buffer according to output
X *	                     status as indicated by `enable_scroll'
X */
X#ifndef VT100
Xstatic int scrline=18; /* line # for wraparound instead of scrolling if no DL */
Xlflush ()
X	{
X	register int lpoint;
X	register char *str;
X	static int curx = 0;
X	static int cury = 0;
X
X	if ((lpoint = lpnt - lpbuf) > 0)
X		{
X#ifdef EXTRA
X		c[BYTESOUT] += lpoint;
X#endif
X		if (enable_scroll <= -1) {
X			flush_buf();
X# ifdef DGK_MSDOS
X			/* Catch write errors on save files
X			 */
X	        	if (write(lfd,lpbuf,lpoint) != lpoint) {
X	        		if (save_mode)
X	        			longjmp(save_jbuf, -1);
X	        		else
X	        			warn("Error writing output file\n");
X	        	}
X# else
X	        	if (write(lfd,lpbuf,lpoint) != lpoint)
X				write(2,"error writing to output file\n",29);
X# endif
X			lpnt = lpbuf;	/* point back to beginning of buffer */
X			return;
X		}
X		for (str = lpbuf; str < lpnt; str++)
X			{
X			if (*str>=32)	{ ttputch (*str); curx++; }
X			else switch (*str) {
X				case CLEAR:		tputs (CL, 0, ttputch);		curx = cury = 0;
X								break;
X
X				case CL_LINE:	tputs (CE, 0, ttputch);
X								break;
X
X				case CL_DOWN:	tputs (CD, 0, ttputch);
X								break;
X
X				case ST_START:	tputs (SO, 0, ttputch);
X								break;
X
X				case ST_END:	tputs (SE, 0, ttputch);
X								break;
X
X				case CURSOR:	curx = *++str - 1;		cury = *++str - 1;
X								tputs (tgoto (CM, curx, cury), 0, ttputch);
X								break;
X
X				case '\n':		if ((cury == 23) && enable_scroll)
X								  {
X								  if (!DL || !AL) /* wraparound or scroll? */
X									{
X									if (++scrline > 23) scrline=19;
X
X									if (++scrline > 23) scrline=19;
X									tputs (tgoto (CM, 0, scrline), 0, ttputch);
X									tputs (CE, 0, ttputch);
X
X									if (--scrline < 19) scrline=23;
X									tputs (tgoto (CM, 0, scrline), 0, ttputch);
X									tputs (CE, 0, ttputch);
X									}
X								  else
X									{
X									tputs (tgoto (CM, 0, 19), 0, ttputch);
X									tputs (DL, 0, ttputch);
X									tputs (tgoto (CM, 0, 23), 0, ttputch);
X								/*	tputs (AL, 0, ttputch); */
X									}
X								  }
X								else
X								  {
X								  ttputch ('\n');		cury++;
X								  }
X								curx = 0;
X								break;
X				case T_INIT:
X					if (TI)
X						tputs(TI, 0, ttputch);
X					break;
X				case T_END:
X					if (TE)
X						tputs(TE, 0, ttputch);
X					break;
X				default:
X					ttputch (*str);
X					curx++;
X				}
X			}
X		}
X	lpnt = lpbuf;
X	flush_buf();	/* flush real output buffer now */
X	}
X#else VT100
X/*
X *	lflush()						flush the output buffer
X *
X *	Returns nothing of value.
X */
Xlflush()
X    {
X	register int lpoint;
X	if ((lpoint = lpnt - lpbuf) > 0)
X        {
X#ifdef EXTRA
X		c[BYTESOUT] += lpoint;
X#endif
X        if (write(lfd,lpbuf,lpoint) != lpoint)
X			write(2,"error writing to output file\n",29);
X        }
X	lpnt = lpbuf;	/* point back to beginning of buffer */
X    }
X#endif VT100
X
X#ifndef VT100
Xstatic int index=0;
X/*
X * ttputch(ch)		Print one character in decoded output buffer.
X */
Xstatic int ttputch(c)
Xint c;
X	{
X	outbuf[index++] = c;
X	if (index >= BUFBIG)  flush_buf();
X	}
X
X/*
X * flush_buf()			Flush buffer with decoded output.
X */
Xstatic flush_buf()
X	{
X	if (index) write(lfd, outbuf, index);
X	index = 0;
X	}
X
X/*
X *	char *tmcapcnv(sd,ss)  Routine to convert VT100 escapes to termcap format
X *
X *	Processes only the \33[#m sequence (converts . files for termcap use 
X */
Xchar *tmcapcnv(sd,ss)  
X	register char *sd,*ss;
X	{
X	register int tmstate=0;	/* 0=normal, 1=\33 2=[ 3=# */
X	char tmdigit=0;	/* the # in \33[#m */
X	while (*ss)
X		{
X		switch(tmstate)
X			{
X			case 0:	if (*ss=='\33')  { tmstate++; break; }
X			  ign:  *sd++ = *ss;
X			  ign2: tmstate = 0;
X					break;
X			case 1: if (*ss!='[') goto ign;
X					tmstate++;
X					break;
X			case 2: if (isdigit(*ss)) { tmdigit= *ss-'0'; tmstate++; break; }
X					if (*ss == 'm') { *sd++ = ST_END; goto ign2; }
X					goto ign;
X			case 3: if (*ss == 'm')
X						{
X						if (tmdigit) *sd++ = ST_START;
X							else *sd++ = ST_END;
X						goto ign2;
X						}
X			default: goto ign;
X			};
X		ss++;
X		}
X	*sd=0; /* NULL terminator */
X	return(sd);
X	}
X#endif VT100
X
X/*
X *	beep()		Routine to emit a beep if enabled (see no-beep in .larnopts)
X */
Xbeep() {
X	if (!nobeep) *lpnt++ = '\7';
X	}
END_OF_FILE
if test 25801 -ne `wc -c <'io.c'`; then
    echo shar: \"'io.c'\" unpacked with wrong size!
fi
# end of 'io.c'
fi
echo shar: End of archive 7 \(of 11\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0