billr@saab.CNA.TEK.COM (Bill Randle) (12/19/90)
Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley) Posting-number: Volume 11, Issue 91 Archive-name: larn/Part08 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 8 (of 11)." # Contents: create.c diag.c header.h nansi.doc # Wrapped by billr@saab on Tue Dec 18 10:14:21 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'create.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'create.c'\" else echo shar: Extracting \"'create.c'\" \(15787 characters\) sed "s/^X//" >'create.c' <<'END_OF_FILE' X/* create.c Larn is copyrighted 1986 by Noah Morgan. */ X#include "header.h" Xextern char spelknow[],larnlevels[]; Xextern char beenhere[],wizard,level; Xextern short oldx,oldy; X/* X makeplayer() X X subroutine to create the player and the players attributes X this is called at the beginning of a game and at no other time X */ Xmakeplayer() X { X register int i; X scbr(); clear(); X c[HPMAX]=c[HP]=10; /* start player off with 15 hit points */ X c[LEVEL]=1; /* player starts at level one */ X c[SPELLMAX]=c[SPELLS]=1; /* total # spells starts off as 3 */ X c[REGENCOUNTER]=16; c[ECOUNTER]=96; /*start regeneration correctly*/ X c[SHIELD] = c[WEAR] = c[WIELD] = -1; X for (i=0; i<26; i++) iven[i]=0; X spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/ X if (c[HARDGAME]<=0) X { X iven[0]=OLEATHER; iven[1]=ODAGGER; iven[2] = 0; X ivenarg[1]=ivenarg[0]=c[WEAR]=0; c[WIELD]=1; X } X playerx=rnd(MAXX-2); playery=rnd(MAXY-2); X oldx=0; oldy=25; X gtime=0; /* time clock starts at zero */ X cbak[SPELLS] = -50; X for (i=0; i<6; i++) c[i]=12; /* make the attributes, ie str, int, etc. */ X recalc(); X } X X/* X newcavelevel(level) X int level; X X function to enter a new level. This routine must be called anytime the X player changes levels. If that level is unknown it will be created. X A new set of monsters will be created for a new level, and existing X levels will get a few more monsters. X Note that it is here we remove genocided monsters from the present level. X */ Xnewcavelevel(x) X register int x; X { X register int i,j; X if (beenhere[level]) savelevel(); /* put the level back into storage */ X level = x; /* get the new level and put in working storage */ X if (beenhere[x]) X { X getlevel(); X sethp(0); X checkgen(); X return; X } X X /* fill in new level X */ X for (i=0; i<MAXY; i++) X for (j=0; j<MAXX; j++) X know[j][i]=mitem[j][i]=0; X makemaze(x); X makeobject(x); X beenhere[x]=1; X sethp(1); X checkgen(); /* wipe out any genocided monsters */ X X#if WIZID X if (wizard || x==0) X#else X if (x==0) X#endif X for (j=0; j<MAXY; j++) X for (i=0; i<MAXX; i++) X know[i][j] = KNOWALL; X } X X/* X makemaze(level) X int level; X X subroutine to make the caverns for a given level. only walls are made. X */ Xstatic int mx,mxl,mxh,my,myl,myh,tmp2; Xstatic makemaze(k) X int k; X { X register int i,j,tmp; X int z; X if (k > 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1)) X { X if (cannedlevel(k)); return; /* read maze from data file */ X } X if (k==0) tmp=0; else tmp=OWALL; X for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) item[j][i]=tmp; X if (k==0) return; eat(1,1); X if (k==1) item[33][MAXY-1]=0; /* exit from dungeon */ X X/* now for open spaces -- not on level 10 */ X if (k != MAXLEVEL-1) X { X tmp2 = rnd(3)+3; X for (tmp=0; tmp<tmp2; tmp++) X { X my = rnd(11)+2; myl = my - rnd(2); myh = my + rnd(2); X if (k < MAXLEVEL) X { X mx = rnd(44)+5; mxl = mx - rnd(4); mxh = mx + rnd(12)+3; X z=0; X } X else X { X mx = rnd(60)+3; mxl = mx - rnd(2); mxh = mx + rnd(2); X z = makemonst(k); X } X for (i=mxl; i<mxh; i++) for (j=myl; j<myh; j++) X { item[i][j]=0; X if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints; X } X } X } X if (k!=MAXLEVEL-1) { my=rnd(MAXY-2); for (i=1; i<MAXX-1; i++) item[i][my] = 0; } X if (k>1) treasureroom(k); X } X X/* X function to eat away a filled in maze X */ Xeat(xx,yy) X register int xx,yy; X { X register int dir,try; X dir = rnd(4); try=2; X while (try) X { X switch(dir) X { X case 1: if (xx <= 2) break; /* west */ X if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break; X item[xx-1][yy] = item[xx-2][yy] = 0; X eat(xx-2,yy); break; X X case 2: if (xx >= MAXX-3) break; /* east */ X if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break; X item[xx+1][yy] = item[xx+2][yy] = 0; X eat(xx+2,yy); break; X X case 3: if (yy <= 2) break; /* south */ X if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break; X item[xx][yy-1] = item[xx][yy-2] = 0; X eat(xx,yy-2); break; X X case 4: if (yy >= MAXY-3 ) break; /* north */ X if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break; X item[xx][yy+1] = item[xx][yy+2] = 0; X eat(xx,yy+2); break; X }; X if (++dir > 4) { dir=1; --try; } X } X } X X/* X * function to read in a maze from a data file X * X * Format of maze data file: 1st character = # of mazes in file (ascii digit) X * For each maze: 18 lines (1st 17 used) 67 characters per line X * X * Special characters in maze data file: X * X * # wall D door . random monster X * ~ eye of larn ! cure dianthroritis X * - random object X */ Xstatic cannedlevel(k) X int k; X { X char *row,*lgetl(); X register int i,j; X int it,arg,mit,marg; X if (lopen(larnlevels)<0) X { X write(1,"Can't open the maze data file\n",30); died(-282); return(0); X } X i=lgetc(); if (i<='0') { died(-282); return(0); } X for (i=18*rund(i-'0'); i>0; i--) lgetl(); /* advance to desired maze */ X for (i=0; i<MAXY; i++) X { X row = lgetl(); X for (j=0; j<MAXX; j++) X { X it = mit = arg = marg = 0; X switch(*row++) X { X case '#': it = OWALL; break; X case 'D': it = OCLOSEDDOOR; arg = rnd(30); break; X case '~': if (k!=MAXLEVEL-1) break; X it = OLARNEYE; X mit = rund(8)+DEMONLORD; X marg = monster[mit].hitpoints; break; X case '!': if (k!=MAXLEVEL+MAXVLEVEL-1) break; X it = OPOTION; arg = 21; X mit = DEMONLORD+7; X marg = monster[mit].hitpoints; break; X case '.': if (k<MAXLEVEL) break; X mit = makemonst(k+1); X marg = monster[mit].hitpoints; break; X case '-': it = newobject(k+1,&arg); break; X }; X item[j][i] = it; iarg[j][i] = arg; X mitem[j][i] = mit; hitp[j][i] = marg; X X#if WIZID X know[j][i] = (wizard) ? KNOWALL : 0; X#else X know[j][i] = 0; X#endif X } X } X lrclose(); X return(1); X } X X/* X function to make a treasure room on a level X level 10's treasure room has the eye in it and demon lords X level V3 has potion of cure dianthroritis and demon prince X */ Xstatic treasureroom(lv) X register int lv; X { X register int tx,ty,xsize,ysize; X X for (tx=1+rnd(10); tx<MAXX-10; tx+=10) X if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2) X { X xsize = rnd(6)+3; ysize = rnd(3)+3; X ty = rnd(MAXY-9)+1; /* upper left corner of room */ X if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1) X troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6); X else troom(lv,xsize,ysize,tx,ty,rnd(9)); X } X } X X/* X * subroutine to create a treasure room of any size at a given location X * room is filled with objects and monsters X * the coordinate given is that of the upper left corner of the room X */ Xstatic troom(lv,xsize,ysize,tx,ty,glyph) X int lv,xsize,ysize,tx,ty,glyph; X { X register int i,j; X int tp1,tp2; X for (j=ty-1; j<=ty+ysize; j++) X for (i=tx-1; i<=tx+xsize; i++) /* clear out space for room */ X item[i][j]=0; X for (j=ty; j<ty+ysize; j++) X for (i=tx; i<tx+xsize; i++) /* now put in the walls */ X { X item[i][j]=OWALL; mitem[i][j]=0; X } X for (j=ty+1; j<ty+ysize-1; j++) X for (i=tx+1; i<tx+xsize-1; i++) /* now clear out interior */ X item[i][j]=0; X X switch(rnd(2)) /* locate the door on the treasure room */ X { X case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR; X iarg[i][j] = glyph; /* on horizontal walls */ X break; X case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR; X iarg[i][j] = glyph; /* on vertical walls */ X break; X }; X X tp1=playerx; tp2=playery; playery=ty+(ysize>>1); X if (c[HARDGAME]<2) X for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2) X for (i=0, j=rnd(6); i<=j; i++) X { something(lv+2); createmonster(makemonst(lv+1)); } X else X for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2) X for (i=0, j=rnd(4); i<=j; i++) X { something(lv+2); createmonster(makemonst(lv+3)); } X X playerx=tp1; playery=tp2; X } X X/* X *********** X MAKE_OBJECT X *********** X subroutine to create the objects in the maze for the given level X */ Xstatic makeobject(j) X register int j; X { X register int i; X if (j==0) X { X fillroom(OENTRANCE,0); /* entrance to dungeon */ X fillroom(ODNDSTORE,0); /* the DND STORE */ X fillroom(OSCHOOL,0); /* college of Larn */ X fillroom(OBANK,0); /* 1st national bank of larn */ X fillroom(OVOLDOWN,0); /* volcano shaft to temple */ X fillroom(OHOME,0); /* the players home & family */ X fillroom(OTRADEPOST,0); /* the trading post */ X fillroom(OLRS,0); /* the larn revenue service */ X return; X } X X if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */ X X/* make the fixed objects in the maze STAIRS */ X if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1)) X fillroom(OSTAIRSDOWN,0); X if ((j > 1) && (j != MAXLEVEL)) X fillroom(OSTAIRSUP,0); X X/* make the random objects in the maze */ X X fillmroom(rund(3),OBOOK,j); fillmroom(rund(3),OALTAR,0); X fillmroom(rund(3),OSTATUE,0); fillmroom(rund(3),OPIT,0); X fillmroom(rund(3),OFOUNTAIN,0); fillmroom( rnd(3)-2,OIVTELETRAP,0); X fillmroom(rund(2),OTHRONE,0); fillmroom(rund(2),OMIRROR,0); X fillmroom(rund(2),OTRAPARROWIV,0); fillmroom( rnd(3)-2,OIVDARTRAP,0); X fillmroom(rund(3),OCOOKIE,0); X if (j==1) fillmroom(1,OCHEST,j); X else fillmroom(rund(2),OCHEST,j); X if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1)) X fillmroom(rund(2),OIVTRAPDOOR,0); X if (j<=10) X { X fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10); X fillmroom(rund(2),ORUBY,rnd(6*j+1)+6); X fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4); X fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2); X } X for (i=0; i<rnd(4)+3; i++) X fillroom(OPOTION,newpotion()); /* make a POTION */ X for (i=0; i<rnd(5)+3; i++) X fillroom(OSCROLL,newscroll()); /* make a SCROLL */ X for (i=0; i<rnd(12)+11; i++) X fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */ X if (j==5) fillroom(OBANK2,0); /* branch office of the bank */ X froom(2,ORING,0); /* a ring mail */ X froom(1,OSTUDLEATHER,0); /* a studded leather */ X froom(3,OSPLINT,0); /* a splint mail */ X froom(5,OSHIELD,rund(3)); /* a shield */ X froom(2,OBATTLEAXE,rund(3)); /* a battle axe */ X froom(5,OLONGSWORD,rund(3)); /* a long sword */ X froom(5,OFLAIL,rund(3)); /* a flail */ X froom(4,OREGENRING,rund(3)); /* ring of regeneration */ X froom(1,OPROTRING,rund(3)); /* ring of protection */ X froom(2,OSTRRING,4); /* ring of strength + 4 */ X froom(7,OSPEAR,rnd(5)); /* a spear */ X froom(3,OORBOFDRAGON,0); /* orb of dragon slaying*/ X froom(4,OSPIRITSCARAB,0); /*scarab of negate spirit*/ X froom(4,OCUBEofUNDEAD,0); /* cube of undead control */ X froom(2,ORINGOFEXTRA,0); /* ring of extra regen */ X froom(3,ONOTHEFT,0); /* device of antitheft */ X froom(2,OSWORDofSLASHING,0); /* sword of slashing */ X if (c[BESSMANN]==0) X { X froom(4,OHAMMER,0);/*Bessman's flailing hammer*/ c[BESSMANN]=1; X } X if (c[HARDGAME]<3 || (rnd(4)==3)) X { X if (j>3) X { X froom(3,OSWORD,3); /* sunsword + 3 */ X froom(5,O2SWORD,rnd(4)); /* a two handed sword */ X froom(3,OBELT,4); /* belt of striking */ X froom(3,OENERGYRING,3); /* energy ring */ X froom(4,OPLATE,5); /* platemail + 5 */ X } X } X } X X/* X subroutine to fill in a number of objects of the same kind X */ X Xstatic fillmroom(n,what,arg) X int n,arg; X char what; X { X register int i; X for (i=0; i<n; i++) fillroom(what,arg); X } Xstatic froom(n,itm,arg) X int n,arg; X char itm; X { if (rnd(151) < n) fillroom(itm,arg); } X X/* X subroutine to put an object into an empty room X * uses a random walk X */ Xstatic fillroom(what,arg) X int arg; X char what; X { X register int x,y; X X#ifdef EXTRA X c[FILLROOM]++; X#endif X X x=rnd(MAXX-2); y=rnd(MAXY-2); X while (item[x][y]) X { X X#ifdef EXTRA X c[RANDOMWALK]++; /* count up these random walks */ X#endif X X x += rnd(3)-2; y += rnd(3)-2; X if (x > MAXX-2) x=1; if (x < 1) x=MAXX-2; X if (y > MAXY-2) y=1; if (y < 1) y=MAXY-2; X } X item[x][y]=what; iarg[x][y]=arg; X } X X/* X subroutine to put monsters into an empty room without walls or other X monsters X */ Xfillmonst(what) X char what; X { X register int x,y,trys; X for (trys=5; trys>0; --trys) /* max # of creation attempts */ X { X x=rnd(MAXX-2); y=rnd(MAXY-2); X if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y))) X { X mitem[x][y] = what; know[x][y] &= ~KNOWHERE; X hitp[x][y] = monster[what].hitpoints; return(0); X } X } X return(-1); /* creation failure */ X } X X/* X creates an entire set of monsters for a level X must be done when entering a new level X if sethp(1) then wipe out old monsters else leave them there X */ Xstatic sethp(flg) X int flg; X { X register int i,j; X if (flg) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0; X if (level==0) { c[TELEFLAG]=0; return; } /* if teleported and found level 1 then know level we are on */ X if (flg) j = rnd(12) + 2 + (level>>1); else j = (level>>1) + 1; X for (i=0; i<j; i++) fillmonst(makemonst(level)); X positionplayer(); X } X X/* X * Function to destroy all genocided monsters on the present level X */ Xstatic checkgen() X { X register int x,y; X for (y=0; y<MAXY; y++) X for (x=0; x<MAXX; x++) X if (monster[mitem[x][y]].genocided) X mitem[x][y]=0; /* no more monster */ X } END_OF_FILE if test 15787 -ne `wc -c <'create.c'`; then echo shar: \"'create.c'\" unpacked with wrong size! fi # end of 'create.c' fi if test -f 'diag.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'diag.c'\" else echo shar: Extracting \"'diag.c'\" \(13978 characters\) sed "s/^X//" >'diag.c' <<'END_OF_FILE' X/* diag.c Larn is copyrighted 1986 by Noah Morgan. */ X#ifdef VMS X# include <types.h> X# include <stat.h> X#else X# include <sys/types.h> X# include <sys/stat.h> X#endif VMS X X#ifndef MSDOS X# ifndef VMS X# include <sys/times.h> X static struct tms cputime; X# endif VMS X#endif MSDOS X X#include "header.h" Xextern long int initialtime; Xextern int rmst,maxitm,lasttime; Xextern char nosignal; X X/* X *************************** X DIAG -- dungeon diagnostics X *************************** X X subroutine to print out data for debugging X */ X#ifdef EXTRA Xstatic int rndcount[16]; Xdiag() X { X register int i,j; X int hit,dam; X cursors(); lwclose(); X if (lcreat(diagfile) < 0) /* open the diagnostic file */ X { X lcreat((char*)0); lprcat("\ndiagnostic failure\n"); return(-1); X } X X write(1,"\nDiagnosing . . .\n",18); X lprcat("\n\nBeginning of DIAG diagnostics ----------\n"); X X/* for the character attributes */ X X lprintf("\n\nPlayer attributes:\n\nHit points: %2d(%2d)",(long)c[HP],(long)c[HPMAX]); X lprintf("\ngold: %d Experience: %d Character level: %d Level in caverns: %d", X (long)c[GOLD],(long)c[EXPERIENCE],(long)c[LEVEL],(long)level); X lprintf("\nTotal types of monsters: %d",(long)MAXMONST+8); X X lprcat("\f\nHere's the dungeon:\n\n"); X X i=level; X for (j=0; j<MAXLEVEL+MAXVLEVEL; j++) X { X newcavelevel(j); X lprintf("\nMaze for level %s:\n",levelname[level]); X diagdrawscreen(); X } X newcavelevel(i); X X lprcat("\f\nNow for the monster data:\n\n"); X lprcat(" Monster Name LEV AC DAM ATT DEF GOLD HP EXP \n"); X lprcat("--------------------------------------------------------------------------\n"); X for (i=0; i<=MAXMONST+8; i++) X { X lprintf("%19s %2d %3d ",monster[i].name,(long)monster[i].level,(long)monster[i].armorclass); X lprintf(" %3d %3d %3d ",(long)monster[i].damage,(long)monster[i].attack,(long)monster[i].defense); X lprintf("%6d %3d %6d\n",(long)monster[i].gold,(long)monster[i].hitpoints,(long)monster[i].experience); X } X X lprcat("\n\nHere's a Table for the to hit percentages\n"); X lprcat("\n We will be assuming that players level = 2 * monster level"); X lprcat("\n and that the players dexterity and strength are 16."); X lprcat("\n to hit: if (rnd(22) < (2[monst AC] + your level + dex + WC/8 -1)/2) then hit"); X lprcat("\n damage = rund(8) + WC/2 + STR - c[HARDGAME] - 4"); X lprcat("\n to hit: if rnd(22) < to hit then player hits\n"); X lprcat("\n Each entry is as follows: to hit / damage / number hits to kill\n"); X lprcat("\n monster WC = 4 WC = 20 WC = 40"); X lprcat("\n---------------------------------------------------------------"); X for (i=0; i<=MAXMONST+8; i++) X { X hit = 2*monster[i].armorclass+2*monster[i].level+16; X dam = 16 - c[HARDGAME]; X lprintf("\n%20s %2d/%2d/%2d %2d/%2d/%2d %2d/%2d/%2d", X monster[i].name, X (long)(hit/2),(long)max(0,dam+2),(long)(monster[i].hitpoints/(dam+2)+1), X (long)((hit+2)/2),(long)max(0,dam+10),(long)(monster[i].hitpoints/(dam+10)+1), X (long)((hit+5)/2),(long)max(0,dam+20),(long)(monster[i].hitpoints/(dam+20)+1)); X } X X lprcat("\n\nHere's the list of available potions:\n\n"); X for (i=0; i<MAXPOTION; i++) lprintf("%20s\n",&potionname[i][1]); X lprcat("\n\nHere's the list of available scrolls:\n\n"); X for (i=0; i<MAXSCROLL; i++) lprintf("%20s\n",&scrollname[i][1]); X lprcat("\n\nHere's the spell list:\n\n"); X lprcat("spell name description\n"); X lprcat("-------------------------------------------------------------------------------------------\n\n"); X for (j=0; j<SPNUM; j++) X { X lprc(' '); lprcat(spelcode[j]); X lprintf(" %21s %s\n",spelname[j],speldescript[j]); X } X X lprcat("\n\nFor the c[] array:\n"); X for (j=0; j<100; j+=10) X { X lprintf("\nc[%2d] = ",(long)j); for (i=0; i<9; i++) lprintf("%5d ",(long)c[i+j]); X } X X lprcat("\n\nTest of random number generator ----------------"); X lprcat("\n for 25,000 calls divided into 16 slots\n\n"); X X for (i=0; i<16; i++) rndcount[i]=0; X for (i=0; i<25000; i++) rndcount[rund(16)]++; X for (i=0; i<16; i++) { lprintf(" %5d",(long)rndcount[i]); if (i==7) lprc('\n'); } X X lprcat("\n\n"); lwclose(); X lcreat((char*)0); lprcat("Done Diagnosing . . ."); X return(0); X } X/* X subroutine to count the number of occurrences of an object X */ Xdcount(l) X int l; X { X register int i,j,p; X int k; X k=0; X for (i=0; i<MAXX; i++) X for (j=0; j<MAXY; j++) X for (p=0; p<MAXLEVEL; p++) X if (cell[(long) p*MAXX*MAXY+i*MAXY+j].item == l) k++; X return(k); X } X X/* X subroutine to draw the whole screen as the player knows it X */ Xdiagdrawscreen() X { X register int i,j,k; X X for (i=0; i<MAXY; i++) X X/* for the east west walls of this line */ X { X for (j=0; j<MAXX; j++) if (k=mitem[j][i]) lprc(monstnamelist[k]); else X lprc(objnamelist[item[j][i]]); X lprc('\n'); X } X } X#endif X X/* X to save the game in a file X */ Xstatic long int zzz=0; Xsavegame(fname) X char *fname; X { X extern char lastmonst[], course[]; X register int i,k; X register struct sphere *sp; X struct stat statbuf; X# ifdef MSDOS X struct cel buf[MAXX]; X RAMBLOCK *rp; X DISKBLOCK *dp; X# endif X X nosignal=1; lflush(); savelevel(); X ointerest(); X if (lcreat(fname) < 0) X { X lcreat((char*)0); lprintf("\nCan't open file <%s> to save game\n",fname); X nosignal=0; return(-1); X } X X set_score_output(); X X# ifdef MSDOS X lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL); X X /* Some levels may be out on disk, some are in memory. X */ X for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++) X if (beenhere[k]) { X X /* Is the level in memory already ? X */ X for (rp = ramblks; rp; rp = rp->next) X if (rp->level == k) X break; X if (rp != NULL) { X lwrite((char *) &rp->gtime, sizeof (long)); X warn(" %d", k); X# ifdef ndef X warn("From memory\n", k); X# endif X lwrite((char *) rp->cell, sizeof rp->cell); X continue; X } X X /* Is it on disk ? X */ X for (dp = diskblks; dp; dp = dp->next) X if (dp->level == k) X break; X X if (dp == NULL) { X levelinfo(); X error("Level %d is neither in memory nor on disk\n", k); X } X X /* Copy the contents of the SWAPFILE */ X lwrite((char *) &dp->gtime, sizeof (long)); X# ifdef ndef X warn("From swap file...\n", k); X# endif X warn(" %ds", k); X if (lseek(swapfd, dp->fpos, 0) < 0) { X warn("Can't seek to %ld\n", dp->fpos); X return -1; X } X for (i = 0; i < MAXY; i++) { X# ifdef ndef X warn("Copying swap file...\n"); X# endif X if (vread(swapfd, (char *) buf, sizeof buf) != X sizeof buf) { X warn("Swap file short!\n"); X return -1; X } X lwrite((char *) buf, sizeof buf); X } X } X# else X lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL); X for (k=0; k<MAXLEVEL+MAXVLEVEL; k++) X if (beenhere[k]) X lwrite((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX); X# endif X#ifndef VMS X# ifndef MSDOS X times(&cputime); /* get cpu time */ X c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60; X# endif MSDOS X#endif VMS X lwrite((char*)&c[0],100*sizeof(long)); X lprint((long)gtime); lprc(level); X lprc(playerx); lprc(playery); X lwrite((char*)iven,26); lwrite((char*)ivenarg,26*sizeof(short)); X for (k=0; k<MAXSCROLL; k++) lprc(scrollname[k][0]); X for (k=0; k<MAXPOTION; k++) lprc(potionname[k][0]); X lwrite((char*)spelknow,SPNUM); lprc(wizard); X lprc(rmst); /* random monster generation counter */ X for (i=0; i<90; i++) lprc(itm[i].qty); X lwrite((char*)course,25); lprc(cheat); lprc(VERSION); X for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */ X for (sp=spheres; sp; sp=sp->p) X lwrite((char*)sp,sizeof(struct sphere)); /* save spheres of annihilation */ X time(&zzz); lprint((long)(zzz-initialtime)); X lwrite((char*)&zzz,sizeof(long)); X# ifndef MSDOS X if (fstat(lfd,&statbuf)< 0) lprint(0L); X else lprint((long)statbuf.st_ino); /* inode # */ X# endif X X lwclose(); lastmonst[0] = 0; X#ifndef VT100 X setscroll(); X#endif VT100 X lcreat((char*)0); nosignal=0; X return(0); X } X Xrestoregame(fname) X char *fname; X { X register int i,k; X register struct sphere *sp,*sp2; X struct stat filetimes; X# ifdef MSDOS X RAMBLOCK *rp, *getramblk(); X# endif X X cursors(); lprcat("\nRestoring . . ."); lflush(); X if (lopen(fname) <= 0) X { X lcreat((char*)0); lprintf("\nCan't open file <%s>to restore game\n",fname); X nap(2000); c[GOLD]=c[BANKACCOUNT]=0; died(-265); return; X } X lrfill((char*)beenhere,MAXLEVEL+MAXVLEVEL); X X# ifdef MSDOS X /* As levels get read in from the save file, store them away X * by calling putsavelevel. X */ X for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++) X if (beenhere[k]) { X rp = getramblk(k); X lrfill((char *) &rp->gtime, sizeof (long)); X lrfill((char *) rp->cell, sizeof rp->cell); X rp->level = k; X } X# else X for (k=0; k<MAXLEVEL+MAXVLEVEL; k++) X if (beenhere[k]) X lrfill((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX); X# endif X X lrfill((char*)&c[0],100*sizeof(long)); gtime = lrint(); X level = c[CAVELEVEL] = lgetc(); X playerx = lgetc(); playery = lgetc(); X lrfill((char*)iven,26); lrfill((char*)ivenarg,26*sizeof(short)); X for (k=0; k<MAXSCROLL; k++) scrollname[k][0] = lgetc(); X for (k=0; k<MAXPOTION; k++) potionname[k][0] = lgetc(); X lrfill((char*)spelknow,SPNUM); wizard = lgetc(); X rmst = lgetc(); /* random monster creation flag */ X X for (i=0; i<90; i++) itm[i].qty = lgetc(); X lrfill((char*)course,25); cheat = lgetc(); X if (VERSION != lgetc()) /* version number */ X { X cheat=1; X lprcat("Sorry, But your save file is for an older version of larn\n"); X nap(2000); c[GOLD]=c[BANKACCOUNT]=0; died(-266); return; X } X X for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc(); /* genocide info */ X for (sp=0,i=0; i<c[SPHCAST]; i++) X { X sp2 = sp; X sp = (struct sphere *)malloc(sizeof(struct sphere)); X if (sp==0) { write(2,"Can't malloc() for sphere space\n",32); break; } X lrfill((char*)sp,sizeof(struct sphere)); /* get spheres of annihilation */ X sp->p=0; /* null out pointer */ X if (i==0) spheres=sp; /* beginning of list */ X else sp2->p = sp; X } X X time(&zzz); X initialtime = zzz-lrint(); X fstat(fd,&filetimes); /* get the creation and modification time of file */ X lrfill((char*)&zzz,sizeof(long)); zzz += 6; X if (filetimes.st_ctime > zzz) fsorry(); /* file create time */ X else if (filetimes.st_mtime > zzz) fsorry(); /* file modify time */ X if (c[HP]<0) { died(284); return; } /* died a post mortem death */ X X oldx = oldy = 0; X#ifndef VMS X# ifndef MSDOS X i = lrint(); /* inode # */ X if (i && (filetimes.st_ino!=i)) fsorry(); X# endif MSDOS X#endif VMS X lrclose(); X if (strcmp(fname,ckpfile) == 0) X { X if (lappend(fname) < 0) fcheat(); else { lprc(' '); lwclose(); } X lcreat((char*)0); X } X else if (unlink(fname) < 0) fcheat(); /* can't unlink save file */ X/* for the greedy cheater checker */ X for (k=0; k<6; k++) if (c[k]>99) greedy(); X if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy(); X if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) /* if patch up lev 25 player */ X { X long tmp; X tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */ X c[EXPERIENCE] = skill[24]; X raiseexperience((long)tmp); X } X getlevel(); lasttime=gtime; X } X X/* X subroutine to not allow greedy cheaters X */ Xstatic greedy() X { X#if WIZID X if (wizard) return; X#endif X X lprcat("\n\nI am so sorry, but your character is a little TOO good! Since this\n"); X lprcat("cannot normally happen from an honest game, I must assume that you cheated.\n"); X lprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n"); X lprcat("to continue.\n"); nap(5000); c[GOLD]=c[BANKACCOUNT]=0; died(-267); return; X } X X/* X subroutine to not allow altered save files and terminate the attempted X restart X */ Xstatic fsorry() X { X lprcat("\nSorry, but your savefile has been altered.\n"); X lprcat("However, seeing as I am a good sport, I will let you play.\n"); X lprcat("Be advised though, you won't be placed on the normal scoreboard."); X cheat = 1; nap(4000); X } X X/* X subroutine to not allow game if save file can't be deleted X */ Xstatic fcheat() X { X#if WIZID X if (wizard) return; X#endif X X lprcat("\nSorry, but your savefile can't be deleted. This can only mean\n"); X lprcat("that you tried to CHEAT by protecting the directory the savefile\n"); X lprcat("is in. Since this is unfair to the rest of the larn community, I\n"); X lprcat("cannot let you play this game.\n"); X nap(5000); c[GOLD]=c[BANKACCOUNT]=0; died(-268); return; X } END_OF_FILE if test 13978 -ne `wc -c <'diag.c'`; then echo shar: \"'diag.c'\" unpacked with wrong size! fi # end of 'diag.c' fi if test -f 'header.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'header.h'\" else echo shar: Extracting \"'header.h'\" \(14883 characters\) sed "s/^X//" >'header.h' <<'END_OF_FILE' X/* header.h Larn is copyrighted 1986 by Noah Morgan. */ X X#ifdef MSDOS X# define LARNHOME "\\" X#endif X X#ifndef WIZID X# define WIZID 1000 X#endif X X#define TRUE 1 X#define FALSE 0 X#define VER 12 X#define SUBVER 2 X X#ifdef VMS X#define unlink(x) delete(x) /* remove a file */ X#endif X X#define SCORENAME "larn.scr" X#define LOGFNAME "larn.log" X#define HELPNAME "larn.hlp" X#define LEVELSNAME "larn.maz" X#define FORTSNAME "larn.ftn" X#define PLAYERIDS "larn.pid" X#define HOLIFILE "holidays" X#ifdef MSDOS X# define LARNOPTS "larn.opt" X# define SAVEFILE "larn.sav" X# define SWAPFILE "larn.swp" X# define CKPFILE "larn.ckp" X#else X# ifdef VMS X# define LARNOPTS "larn.opt" X# define SAVEFILE "larn.sav" X# define CKPFILE "larn.ckp" X# else X# define LARNOPTS ".larnopts" X# define SAVEFILE "Larn.sav" X# define CKPFILE "larn.ckp" X# define MAIL /* disable the mail routines for MSDOS */ X# endif VMS X#endif MSDOS X X#define MAXLEVEL 11 /* max # levels in the dungeon */ X#define MAXVLEVEL 3 /* max # of levels in the temple of the luran */ X#define MAXX 67 X#define MAXY 17 X X#define SCORESIZE 10 /* this is the number of people on a scoreboard max */ X#define MAXPLEVEL 100 /* maximum player level allowed */ X#define MAXMONST 56 /* maximum # monsters in the dungeon */ X#define SPNUM 38 /* maximum number of spells in existance */ X#define MAXSCROLL 28 /* maximum number of scrolls that are possible */ X#define MAXPOTION 35 /* maximum number of potions that are possible */ X#define TIMELIMIT 30000 /* maximum number of moves before the game is called */ X#define TAXRATE 1/20 /* tax rate for the LRS */ X#define MAXOBJ 93 /* the maximum number of objects n < MAXOBJ */ X X/* this is the structure definition of the monster data X*/ Xstruct monst X { X char *name; X char level; X short armorclass; X char damage; X char attack; X char defense; X char genocided; X char intelligence; /* monsters intelligence -- used to choose movement */ X short gold; X short hitpoints; X unsigned long experience; X }; X X/* this is the structure definition for the items in the dnd store */ Xstruct _itm X { X short price; X char **mem; X char obj; X char arg; X char qty; X }; X X/* this is the structure that holds the entire dungeon specifications */ Xstruct cel X { X short hitp; /* monster's hit points */ X char mitem; /* the monster ID */ X char item; /* the object's ID */ X short iarg; /* the object's argument */ X char know; /* have we been here before*/ X }; X X/* this is the structure for maintaining & moving the spheres of annihilation */ Xstruct sphere X { X struct sphere *p; /* pointer to next structure */ X char x,y,lev; /* location of the sphere */ X char dir; /* direction sphere is going in */ X char lifetime; /* duration of the sphere */ X }; X X# ifdef MSDOS X/* Since only 1 level is needed at one time, each level can be swapped X * to disk if there is not enough memory to allocate it. Thus, there X * need only be room for 1 level. When a level is needed, if it is X * already in memory, there is nothing to do. If it isn't, get it from X * disk after swapping out the oldest level - dgk. X */ X# define FREEBLOCK -99 Xtypedef struct _ramblock RAMBLOCK; Xtypedef struct _diskblock DISKBLOCK; Xstruct _ramblock { X RAMBLOCK *next; /* For a linked list */ X int level; /* Level stored or FREEBLOCK */ X long gtime; /* The time stored */ X struct cel cell[MAXX * MAXY]; /* The storage */ X}; Xstruct _diskblock { X DISKBLOCK *next; /* For linked list */ X int level; /* Level stored or FREEBLOCK */ X long gtime; /* The time stored */ X long fpos; /* The disk position */ X}; Xextern RAMBLOCK *ramblks; Xextern DISKBLOCK *diskblks; X X# endif MSDOS X X/* defines for the character attribute array c[] */ X#define STRENGTH 0 /* characters physical strength not due to objects */ X#define INTELLIGENCE 1 X#define WISDOM 2 X#define CONSTITUTION 3 X#define DEXTERITY 4 X#define CHARISMA 5 X#define HPMAX 6 X#define HP 7 X#define GOLD 8 X#define EXPERIENCE 9 X#define LEVEL 10 X#define REGEN 11 X#define WCLASS 12 X#define AC 13 X#define BANKACCOUNT 14 X#define SPELLMAX 15 X#define SPELLS 16 X#define ENERGY 17 X#define ECOUNTER 18 X#define MOREDEFENSES 19 X#define WEAR 20 X#define PROTECTIONTIME 21 X#define WIELD 22 X#define AMULET 23 X#define REGENCOUNTER 24 X#define MOREDAM 25 X#define DEXCOUNT 26 X#define STRCOUNT 27 X#define BLINDCOUNT 28 X#define CAVELEVEL 29 X#define CONFUSE 30 X#define ALTPRO 31 X#define HERO 32 X#define CHARMCOUNT 33 X#define INVISIBILITY 34 X#define CANCELLATION 35 X#define HASTESELF 36 X#define EYEOFLARN 37 X#define AGGRAVATE 38 X#define GLOBE 39 X#define TELEFLAG 40 X#define SLAYING 41 X#define NEGATESPIRIT 42 X#define SCAREMONST 43 X#define AWARENESS 44 X#define HOLDMONST 45 X#define TIMESTOP 46 X#define HASTEMONST 47 X#define CUBEofUNDEAD 48 X#define GIANTSTR 49 X#define FIRERESISTANCE 50 X#define BESSMANN 51 X#define NOTHEFT 52 X#define HARDGAME 53 X#define CPUTIME 54 X#define BYTESIN 55 X#define BYTESOUT 56 X#define MOVESMADE 57 X#define MONSTKILLED 58 X#define SPELLSCAST 59 X#define LANCEDEATH 60 X#define SPIRITPRO 61 X#define UNDEADPRO 62 X#define SHIELD 63 X#define STEALTH 64 X#define ITCHING 65 X#define LAUGHING 66 X#define DRAINSTRENGTH 67 X#define CLUMSINESS 68 X#define INFEEBLEMENT 69 X#define HALFDAM 70 X#define SEEINVISIBLE 71 X#define FILLROOM 72 X#define RANDOMWALK 73 X#define SPHCAST 74 /* nz if an active sphere of annihilation */ X#define WTW 75 /* walk through walls */ X#define STREXTRA 76 /* character strength due to objects or enchantments */ X#define TMP 77 /* misc scratch space */ X#define LIFEPROT 78 /* life protection counter */ X X/* defines for the objects in the game */ X#define MAXOBJECT 92 X X#define OALTAR 1 X#define OTHRONE 2 X#define OORB 3 X#define OPIT 4 X#define OSTAIRSUP 5 X#define OELEVATORUP 6 X#define OFOUNTAIN 7 X#define OSTATUE 8 X#define OTELEPORTER 9 X#define OSCHOOL 10 X#define OMIRROR 11 X#define ODNDSTORE 12 X#define OSTAIRSDOWN 13 X#define OELEVATORDOWN 14 X#define OBANK2 15 X#define OBANK 16 X#define ODEADFOUNTAIN 17 X#define OMAXGOLD 70 X#define OGOLDPILE 18 X#define OOPENDOOR 19 X#define OCLOSEDDOOR 20 X#define OWALL 21 X#define OTRAPARROW 66 X#define OTRAPARROWIV 67 X X#define OLARNEYE 22 X X#define OPLATE 23 X#define OCHAIN 24 X#define OLEATHER 25 X#define ORING 60 X#define OSTUDLEATHER 61 X#define OSPLINT 62 X#define OPLATEARMOR 63 X#define OSSPLATE 64 X#define OSHIELD 68 X#define OELVENCHAIN 92 X X#define OSWORDofSLASHING 26 X#define OHAMMER 27 X#define OSWORD 28 X#define O2SWORD 29 X#define OSPEAR 30 X#define ODAGGER 31 X#define OBATTLEAXE 57 X#define OLONGSWORD 58 X#define OFLAIL 59 X#define OLANCE 65 X#define OVORPAL 90 X#define OSLAYER 91 X X#define ORINGOFEXTRA 32 X#define OREGENRING 33 X#define OPROTRING 34 X#define OENERGYRING 35 X#define ODEXRING 36 X#define OSTRRING 37 X#define OCLEVERRING 38 X#define ODAMRING 39 X X#define OBELT 40 X X#define OSCROLL 41 X#define OPOTION 42 X#define OBOOK 43 X#define OCHEST 44 X#define OAMULET 45 X X#define OORBOFDRAGON 46 X#define OSPIRITSCARAB 47 X#define OCUBEofUNDEAD 48 X#define ONOTHEFT 49 X X#define ODIAMOND 50 X#define ORUBY 51 X#define OEMERALD 52 X#define OSAPPHIRE 53 X X#define OENTRANCE 54 X#define OVOLDOWN 55 X#define OVOLUP 56 X#define OHOME 69 X X#define OKGOLD 71 X#define ODGOLD 72 X#define OIVDARTRAP 73 X#define ODARTRAP 74 X#define OTRAPDOOR 75 X#define OIVTRAPDOOR 76 X#define OTRADEPOST 77 X#define OIVTELETRAP 78 X#define ODEADTHRONE 79 X#define OANNIHILATION 80 /* sphere of annihilation */ X#define OTHRONE2 81 X#define OLRS 82 /* Larn Revenue Service */ X#define OCOOKIE 83 X#define OURN 84 X#define OBRASSLAMP 85 X#define OHANDofFEAR 86 /* hand of fear */ X#define OSPHTAILSMAN 87 /* tailsman of the sphere */ X#define OWWAND 88 /* wand of wonder */ X#define OPSTAFF 89 /* staff of power */ X/* used up to 92 */ X X/* defines for the monsters as objects */ X X#define BAT 1 X#define GNOME 2 X#define HOBGOBLIN 3 X#define JACKAL 4 X#define KOBOLD 5 X#define ORC 6 X#define SNAKE 7 X#define CENTIPEDE 8 X#define JACULI 9 X#define TROGLODYTE 10 X#define ANT 11 X#define EYE 12 X#define LEPRECHAUN 13 X#define NYMPH 14 X#define QUASIT 15 X#define RUSTMONSTER 16 X#define ZOMBIE 17 X#define ASSASSINBUG 18 X#define BUGBEAR 19 X#define HELLHOUND 20 X#define ICELIZARD 21 X#define CENTAUR 22 X#define TROLL 23 X#define YETI 24 X#define WHITEDRAGON 25 X#define ELF 26 X#define CUBE 27 X#define METAMORPH 28 X#define VORTEX 29 X#define ZILLER 30 X#define VIOLETFUNGI 31 X#define WRAITH 32 X#define FORVALAKA 33 X#define LAMANOBE 34 X#define OSEQUIP 35 X#define ROTHE 36 X#define XORN 37 X#define VAMPIRE 38 X#define INVISIBLESTALKER 39 X#define POLTERGEIST 40 X#define DISENCHANTRESS 41 X#define SHAMBLINGMOUND 42 X#define YELLOWMOLD 43 X#define UMBERHULK 44 X#define GNOMEKING 45 X#define MIMIC 46 X#define WATERLORD 47 X#define BRONZEDRAGON 48 X#define GREENDRAGON 49 X#define PURPLEWORM 50 X#define XVART 51 X#define SPIRITNAGA 52 X#define SILVERDRAGON 53 X#define PLATINUMDRAGON 54 X#define GREENURCHIN 55 X#define REDDRAGON 56 X#define DEMONLORD 57 X#define DEMONPRINCE 64 X X# ifdef MSDOS X# define NULL 0L /* For large model only */ X# else X# define NULL 0 X# endif MSDOS X#define BUFBIG 4096 /* size of the output buffer */ X#define MAXIBUF 4096 /* size of the input buffer */ X#define LOGNAMESIZE 40 /* max size of the players name */ X#define PSNAMESIZE 40 /* max size of the process name */ X#define SAVEFILENAMESIZE 128 /* max size of the savefile path */ X X#ifndef NODEFS Xextern char floorc, wallc; Xextern char boldobjects; Xextern char auto_pickup; Xextern char VERSION,SUBVERSION; Xextern char aborted[],beenhere[],boldon,cheat,ckpfile[],ckpflag; Xextern char *class[],course[],diagfile[],fortfile[],helpfile[],holifile[]; Xextern char ckpfile[]; X# ifdef MSDOS Xextern int swapfd; Xextern char swapfile[]; Xextern long tell(), lseek(); X# endif Xextern char *inbuffer; Xextern char item[MAXX][MAXY],iven[],know[MAXX][MAXY],larnlevels[],lastmonst[]; Xextern char level,*levelname[],logfile[],loginname[],logname[],*lpbuf,*lpend; Xextern char *lpnt,mitem[MAXX][MAXY],monstlevel[]; Xextern char monstnamelist[],nch[],ndgg[],nlpts[],nomove,nosignal,nowelcome; Xextern char nplt[],nsw[],*objectname[]; Xextern char hacklike_objnamelist[]; Xextern char original_objnamelist[]; Xextern char objnamelist[],optsfile[],*potionname[],playerids[],potprob[]; Xextern char predostuff,psname[],restorflag,savefilename[],scorefile[],scprob[]; Xextern char screen[MAXX][MAXY],*scrollname[],sex,*spelcode[],*speldescript[]; Xextern char spelknow[],*spelname[],*spelmes[],spelweird[MAXMONST+8][SPNUM]; Xextern char splev[],stealth[MAXX][MAXY],wizard; Xextern short diroffx[],diroffy[],hitflag,hit2flag,hit3flag,hitp[MAXX][MAXY]; Xextern short iarg[MAXX][MAXY],ivenarg[],lasthx,lasthy,lastnum,lastpx,lastpy; Xextern short nobeep,oldx,oldy,playerx,playery; Xextern int dayplay,enable_scroll,srcount,yrepcount,userid,wisid,lfd,fd; Xextern long initialtime,outstanding_taxes,skill[],gtime,c[],cbak[]; Xextern unsigned long lrandx; X# ifndef MSDOS /* Different storage under MSDOS */ Xextern struct cel *cell; X# endif Xextern struct monst monster[]; Xextern struct sphere *spheres; Xextern struct _itm itm[]; X Xvoid *malloc(); Xchar *fortune(),*getenv(),*getlogin(),*lgetw(),*lgetl(),*ctime(); Xchar *tmcapcnv(),*tgetstr(),*tgoto(); Xlong paytaxes(),lgetc(),lrint(),time(); Xunsigned long readnum(); X X /* macro to create scroll #'s with probability of occurrence */ X#define newscroll() (scprob[rund(81)]) X /* macro to return a potion # created with probability of occurrence */ X#define newpotion() (potprob[rund(41)]) X /* macro to return the + points on created leather armor */ X#define newleather() (nlpts[rund(c[HARDGAME]?13:15)]) X /* macro to return the + points on chain armor */ X#define newchain() (nch[rund(10)]) X /* macro to return + points on plate armor */ X#define newplate() (nplt[rund(c[HARDGAME]?4:12)]) X /* macro to return + points on new daggers */ X#define newdagger() (ndgg[rund(13)]) X /* macro to return + points on new swords */ X#define newsword() (nsw[rund(c[HARDGAME]?6:13)]) X /* macro to destroy object at present location */ X#define forget() (item[playerx][playery]=know[playerx][playery]=0) X /* macro to wipe out a monster at a location */ X#define disappear(x,y) (mitem[x][y]=know[x][y]=0) X X#ifdef VT100 X /* macro to turn on bold display for the terminal */ X#define setbold() (lprcat(boldon?"\33[1m":"\33[7m")) X /* macro to turn off bold display for the terminal */ X#define resetbold() (lprcat("\33[m")) X /* macro to setup the scrolling region for the terminal */ X#define setscroll() (lprcat("\33[20;24r")) X /* macro to clear the scrolling region for the terminal */ X#define resetscroll() (lprcat("\33[;24r")) X /* macro to clear the screen and home the cursor */ X#define clear() (lprcat("\33[2J\33[f"), cbak[SPELLS]= -50) X#define cltoeoln() lprcat("\33[K") X#else /* VT100 */ X /* defines below are for use in the termcap mode only */ X#define ST_START 1 X#define ST_END 2 X#define BOLD 3 X#define END_BOLD 4 X#define CLEAR 5 X#define CL_LINE 6 X#define T_INIT 7 X#define T_END 8 X#define CL_DOWN 14 X#define CURSOR 15 X /* macro to turn on bold display for the terminal */ X#define setbold() (*lpnt++ = ST_START) X /* macro to turn off bold display for the terminal */ X#define resetbold() (*lpnt++ = ST_END) X /* macro to setup the scrolling region for the terminal */ X#define setscroll() enable_scroll=1 X /* macro to clear the scrolling region for the terminal */ X#define resetscroll() enable_scroll=0 X /* macro to clear the screen and home the cursor */ X#define clear() (*lpnt++ =CLEAR, cbak[SPELLS]= -50) X /* macro to clear to end of line */ X#define cltoeoln() (*lpnt++ = CL_LINE) X#endif /* VT100 */ X X /* macro to output one byte to the output buffer */ X#define lprc(ch) ((lpnt>=lpend)?(*lpnt++ =(ch), lflush()):(*lpnt++ =(ch))) X X /* macro to seed the random number generator */ X#define srand(x) (lrandx=x) X#ifdef MACRORND X /* macros to generate random numbers 1<=rnd(N)<=N 0<=rund(N)<=N-1 */ X#define rnd(x) ((((lrandx=lrandx*1103515245+12345)>>7)%(x))+1) X#define rund(x) ((((lrandx=lrandx*1103515245+12345)>>7)%(x)) ) X#endif /* MACRORND */ X X# ifdef DGK X# define HAVESEEN 0x1 X# define KNOWHERE 0x2 X# define KNOWALL (HAVESEEN | KNOWHERE) X# ifdef DGK_MSDOS X# define PATHLEN 80 X# define DIRLEN 64 X extern char larndir[]; X extern int raw_io, DECRainbow, keypad, ramlevels, cursorset; X extern unsigned char cursorstart, cursorend; X# endif DGK_MSDOS X#endif DGK Xextern char prompt_mode ; X#endif /* NODEFS */ END_OF_FILE if test 14883 -ne `wc -c <'header.h'`; then echo shar: \"'header.h'\" unpacked with wrong size! fi # end of 'header.h' fi if test -f 'nansi.doc' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'nansi.doc'\" else echo shar: Extracting \"'nansi.doc'\" \(6967 characters\) sed "s/^X//" >'nansi.doc' <<'END_OF_FILE' XSYNOPSIS X Include in \config.sys the line X device=nansi.sys X XDESCRIPTION X Nansi.sys is a console driver which understands ANSI control X sequences. It has several advantages over ANSI.SYS (the driver X supplied with DOS): X 1. It supports new escape sequences (see below). X 2. It provides MUCH faster output under certain conditions. X 3. It supports the 43-line mode of the EGA. X 4. The darned bell is now 1/4 second instead of 1/2 second long. X X What a console driver does: X When you, for example, type X C:> type foo.txt X COMMAND.COM opens the file foo.txt, reads it, and writes it to X the console driver, which puts it up on the screen. X X Both ansi.sys and nansi.sys use IBM Video BIOS to control the screen. X However, nansi.sys bypasses BIOS if the screen is in a text mode; this X allows much faster operation under certain conditions. X X While putting text up on the screen, (n)ansi.sys keeps a lookout for X the escape character (chr(27), known as ESC); this character signals X the start of a terminal control sequence. X Terminal control sequences follow the format X ESC [ param; param; ...; param cmd X where X ESC is the escape character chr$(27). X [ is the left bracket character. X param is an ASCII decimal number, or a string in quotes. X cmd is a case-specific letter identifying the command. X Usually, zero, one, or two parameters are given. If parameters X are omitted, they usually default to 1; however, some commands X (KKR and DKOCT) treat the no-parameter case specially. X Spaces are not allowed between parameters. X X For example, both ESC[1;1H and ESC[H send the cursor to the home X position (1,1), which is the upper left. X X Either single or double quotes may be used to quote a string. X Each character inside a quoted string is equivalent to one numeric X parameter. Quoted strings are normally used only for the Keyboard X Key Reassignment command. X XControl Sequences X The following table lists the sequences understood by nansi.sys. X Differences between nansi.sys and the standard ansi.sys are marked X with a vertical bar (|). X XCursor Positioning XShort Long name Format Notes XCUP cursor position ESC[y;xH Sets cursor position. XHVP cursor position ESC[y;xf Same as CUP; not recommended. XCUU cursor up ESC[nA n = # of lines to move XCUD cursor down ESC[nB XCUF cursor forward ESC[nC n = # of columns to move XCUB cursor backward ESC[nD XDSR Device Status, Report! ESC[6n Find out cursor position. XCPR Cursor Position report ESC[y;xR Response to DSR, as if typed. XSCP Save Cursor Position ESC[s Not nestable. XRCP Restore Cursor Position ESC[u X XEditing XED Erase in Display ESC[2J Clears screen. XEL Erase in Line ESC[K Clears to end of line. XIL | Insert Lines ESC[nL Inserts n blank lines at cursor line. XDL | Delete Lines ESC[nM Deletes n lines including cursor line. XICH | Insert Characters ESC[n@ Inserts n blank chars at cursor. XDCH | Delete Characters ESC[nP Deletes n chars including cursor char. X X XMode-Setting XSGR Set Graphics Rendition ESC[n;n;...nm See character attribute table. XSM Set Mode ESC[=nh See screen mode table. XRM Reset Mode ESC[=nl See screen mode table. XIBMKKR Keyboard Key Reass. ESC["string"p X The first char of the string gives the key to redefine; the rest X of the string is the key's new value. X To specify unprintable chars, give the ASCII value of the char X outside of quotes, as a normal parameter. X IBM function keys are two byte strings; see the IBM Basic manual. X For instance, ESC[0;";dir a:";13;p redefines function key 1 to X have the value "dir a:" followed by the ENTER key. X | If no parameters given, all keys are reset to their default values. X XDKOCT | Output char translate ESC[n;ny X | When first char is encountered in output request, it is replaced with X | the second char. This might be useful for previewing text before X | sending it to a printer with a funny print wheel. X | If no parameters are given, all chars are reset to normal. X X XCharacter Attributes X The Set Graphics Rendition command is used to select foreground X and background colors or attributes. X When you use multiple parameters, they are executed in sequence, and X the effects are cumulative. X Attrib code Value X 0 All attributes off (normal white on black) X 1 Bold X 4 Underline X 5 Blink X 7 Reverse Video X 8 Invisible (but why?) X 30-37 foregnd blk/red/grn/yel/blu/magenta/cyan/white X 40-47 background X XScreen Modes X The IBM BIOS supports several video modes; the codes given in the X BIOS documentation are used as parameters to the Set Mode command. X | (In bitmap modes, the cursor is simulated with a small blob (^V).) X Mode Code Value X 0 text 40x25 Black & White X 1 text 40x25 Color X 2 text 80x25 Black & White X 3 text 80x25 Color X 4 bitmap 320x200 4 bits/pixel X 5 bitmap 320x200 1 bit/pixel X 6 bitmap 640x200 1 bit/pixel X 7 (cursor wrap kludge) X 13 (EGA) bitmap 320x200 4 bits/pixel ? X 14 (EGA) bitmap 640x200 4 bits/pixel X 16 (EGA) bitmap 640x350 4 bits/pixel X Mode 7 is an unfortunate kludge; Setting mode 7 tells the cursor X to wrap around to the next line when it passes the end of a line; X Resetting mode 7 tells the cursor to not wrap, but rather stay put. X | If your computer has the Enhanced Graphics Adaptor, modes between X | 8 and 15 are also supported; see the EGA BIOS for info. X | The EGA also lets you use a shorter character cell in text modes X | in order to squeeze 43 lines of text out of the 25-line text modes. X | To enter 43 line mode, set the desired 25-line text mode (0 to 3), X | then Set Mode 43. For instance: ESC[=3h ESC[=43h. X | To exit 43 line mode, set the desired 25-line text mode again. X | Nansi.sys ignores mode 43 unless there is an EGA on your computer. X XFaster Output X | Any program that sets the console to RAW mode, and buffers its X | output properly, can achieve extremely high screen update speeds in X | return for giving up the special functions of the keys ^C, ^S, and ^P. X | See IOCTL in the MS-DOS 3.x Technical Reference for more info. X Also, a small improvement in speed may be noticed with some X programs that use the DOS console in normal mode, as this driver X efficiently implements the (standard but undocumented) INT 29h X most-favored-device putchar used by DOS. X XBUGS X Insert and delete character do not work in graphics modes. X Graphics mode writing is slow. X The simulated cursor in graphics mode slows down single-char X writes by a factor of 3; it should be disable-able. X Does not support erase-to-end-of-screen and other useful functions. X XVersion X This version, 2.2, created February 1986. Problems should X be reported to Daniel Kegel, 1-60 CIT, Pasadena, CA 91126 X (or, after June 1986, 2648 169th Ave SE, Bellevue, Wa. 98008). X Your suggestions for improvement would be most welcome. X XNOTE X This program may be distributed for educational and personal use X only. Commercial use is verboten; get in touch with the author. END_OF_FILE if test 6967 -ne `wc -c <'nansi.doc'`; then echo shar: \"'nansi.doc'\" unpacked with wrong size! fi # end of 'nansi.doc' fi echo shar: End of archive 8 \(of 11\). cp /dev/null ark8isdone 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