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