Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!batcomputer!cornell!uw-beaver!zephyr.ens.tek.com!master!saab!billr From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v12i063: larn2 - dungeon type adventure game (V12.3), Part10/12 Message-ID: <1125@masterCNA.TEK.COM> Date: 23 Apr 91 20:59:56 GMT Sender: news@masterCNA.TEK.COM Lines: 1806 Approved: billr@saab.CNA.TEK.COM Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley) Posting-number: Volume 12, Issue 63 Archive-name: larn2/Part10 Supersedes: larn: Volume 11, Issue 84-94 Environment: Unix, VMS, MS-DOS, OS/2, 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 'fortune.c' <<'END_OF_FILE' X/* fortune.c */ X#ifdef VMS X#include X#include X#include X#else X# include X# include X# ifndef BSD4.1 X# include X# else BSD4.1 X# define O_RDONLY 0 X# endif BSD4.1 X#endif VMS X X#include "header.h" X#include "player.h" X#include "larndefs.h" Xextern char fortfile[]; X Xoutfortune() X { X char *p; X X lprcat("\nThe cookie was delicious."); X if (c[BLINDCOUNT]) X return; X#ifdef MSDOS X msdosfortune(); X#else X if (p=fortune(fortfile)) X { X lprcat(" Inside you find a scrap of paper that says:\n"); X lprcat(p); X } X#endif X } X X# ifdef MSDOS X# include X/* Rumors has been entirely rewritten to be disk based. This is marginally X * slower, but requires no mallocked memory. Notice this in only valid for X * files smaller than 32K. X */ Xstatic int fortsize = 0; X Xstatic msdosfortune() X{ X int fd, status, i; X char buf[BUFSIZ], ch; X X if (fortsize < 0) /* We couldn't open fortunes */ X return; X if ((fd = open(fortfile, O_RDONLY | O_BINARY)) >= 0) { X if (fortsize == 0) X fortsize = (int) lseek(fd, 0L, 2); X if (lseek(fd, (long) rund(fortsize), 0) < 0) X return; X X /* Skip to next newline or EOF X */ X do { X status = read(fd, &ch, 1); X } while (status != EOF && ch != '\n'); X if (status == EOF) X if (lseek(fd, 0L, 0) < 0) /* back to the beginning */ X return; X X /* Read in the line. Search for CR ('\r'), not NL X */ X for (i = 0; i < BUFSIZ - 1; i++) X if (read(fd, &buf[i], 1) == EOF || buf[i] == '\r') X break; X buf[i] = '\0'; X X /* And spit it out X */ X lprcat(" Inside you find a scrap of paper that says:\n"); X lprcat(buf); X close(fd); X } else X fortsize = -1; /* Don't try opening it again */ X} X X# else X X/* X * function to return a random fortune from the fortune file X */ Xstatic char *base=0; /* pointer to the fortune text */ Xstatic char **flines=0; /* array of pointers to each fortune */ Xstatic int fd=0; /* true if we have load the fortune info */ Xstatic int nlines=0; /* # lines in fortune database */ X Xstatic char *fortune(file) Xchar *file; X{ X register char *p; X register int lines,tmp; X struct stat stat; X void *malloc(); X X if (fd == 0) { X if ((fd=open(file,O_RDONLY)) < 0) /* open the file */ X return(0); /* can't find file */ X X /* find out how big fortune file is and get memory for it */ X stat.st_size = 16384; X if ((fstat(fd,&stat) < 0) X || ((base=(char *)malloc(1+stat.st_size)) == 0)) { X close(fd); X fd= -1; X free((char*)base); X return(0); /* can't stat file */ X } X X /* read in the entire fortune file */ X#ifdef VMS X /* X * fstat lies about the size (each record has up to X * three bytes of fill reported as actual size). X * vread returns correct size. X */ X stat.st_size = vread(fd,base,stat.st_size); X if (stat.st_size <= 0) X#else X if (vread(fd,base,stat.st_size) != stat.st_size) X#endif X { X close(fd); X fd= -1; X free((char*)base); X return(0); /* can't read file */ X } X close(fd); X base[stat.st_size]=0; /* final NULL termination */ X X /* count up all the lines (and 0 terminate) to know memory X * needs X */ X for (p=base,lines=0; p 2) /* if we have a database to look at */ X return(flines[rund((nlines<=0)?1:nlines)]); X else X return(0); X} X# endif END_OF_FILE if test 4263 -ne `wc -c <'fortune.c'`; then echo shar: \"'fortune.c'\" unpacked with wrong size! fi # end of 'fortune.c' fi if test -f 'iventory.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'iventory.c'\" else echo shar: Extracting \"'iventory.c'\" \(12705 characters\) sed "s/^X//" >'iventory.c' <<'END_OF_FILE' X#include "header.h" X#include "larndefs.h" X#include "objects.h" X#include "player.h" X X#ifdef __STDC__ X show1( int, char*[] ); X show3( int ); Xstatic show2( int ); Xstatic void t_setup( int ); Xstatic void t_endup( int ); X X#define SIGNED signed X#else X show1( ); X show3( ); Xstatic show2( ); Xstatic void t_setup( ); Xstatic void t_endup( ); X X#define SIGNED X#endif X Xstatic int qshowstr(); Xshowwear(); Xshowwield(); Xshowread(); Xshowquaff(); Xshoweat(); Xextern int dropflag; X X/* Allow only 26 items (a to z) in the player's inventory */ X#define MAXINVEN 26 X X/* The starting limit to the number of items the player can carry. X The limit should probably be based on player strength and the X weight of the items. X*/ X#define MIN_LIMIT 15 X X/* define a sentinel to place at the end of the sorted inventory. X (speeds up display reads ) X*/ X#define END_SENTINEL 255 X X/* declare the player's inventory. These should only be referenced X in this module. X iven - objects in the player's inventory X ivenarg - attribute of each item ( + values, etc ) X ivensort - sorted inventory (so we don't sort each time) X*/ Xchar iven[MAXINVEN]; XSIGNED short ivenarg[MAXINVEN]; Xunsigned char ivensort[MAXINVEN+1]; /* extra is for sentinel */ X Xstatic char srcount = 0 ; /* line counter for showstr() */ X X/* X Initialize the player's inventory X*/ Xvoid init_inventory( ) X { X int i; X X for ( i = 0; i < MAXINVEN ; i++ ) X { X iven[i] = ivenarg[i] = 0; X ivensort[i] = END_SENTINEL ; X } X ivensort[MAXINVEN] = END_SENTINEL; X X /* For zero difficulty games, start the player out with armor and weapon. X We can sort the inventory right away because a dagger is 'later' than X leather armor. X */ X if (c[HARDGAME] <= 0) X { X iven[0] = OLEATHER; X iven[1] = ODAGGER; X ivenarg[0] = ivenarg[1] = c[WEAR] = ivensort[0] = 0; X ivensort[1] = c[WIELD] = 1; X } X } X X/* X show character's inventory X*/ Xshowstr(select_allowed) Xchar select_allowed; X { X register int i,number, item_select; X X for (number=3, i=0; i=0; k--) X if (iven[k]) X { X for (i=22; i<84; i++) X for (j=0; j<=k; j++) X if (i==iven[j]) X { X itemselect = show2(j); X if (itemselect && select_allowed) X goto quitit; X } X k=0; X } X X lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100)); X itemselect = more(select_allowed); Xquitit: X nosignal=sigsav; X if (select_allowed) X return( (itemselect > 0) ? itemselect : 0 ); X else X return( 0 ); X } X X/* X subroutine to clear screen depending on # lines to display X X*/ Xstatic void t_setup(count) Xregister int count; X { X if (count<20) /* how do we clear the screen? */ X { X cl_up(79,count); X cursor(1,1); X } X else X { X resetscroll(); X clear(); X } X } X X/* X subroutine to restore normal display screen depending on t_setup() X X*/ Xstatic void t_endup(count) Xregister int count; X { X if (count<18) /* how did we clear the screen? */ X draws(0,MAXX,0,(count>MAXY) ? MAXY : count); X else X { X drawscreen(); X setscroll(); X } X } X X/* X function to show the things player is wearing only X */ Xshowwear() X { X register int i,j,sigsav,count,itemselect=0; X X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) /* count number of items we will display */ X if (i=iven[j]) X switch(i) X { X case OLEATHER: case OPLATE: case OCHAIN: X case ORING: case OSTUDLEATHER: case OSPLINT: X case OPLATEARMOR: case OSSPLATE: case OSHIELD: X count++; X }; X X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OLEATHER: case OPLATE: case OCHAIN: X case ORING: case OSTUDLEATHER: case OSPLINT: X case OPLATEARMOR: case OSSPLATE: case OSHIELD: X if (itemselect = show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1) ? itemselect : 0 ); X } X X/* X function to show the things player can wield only X */ Xshowwield() X { X register int i,j,sigsav,count,itemselect=0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) /* count how many items */ X if (i=iven[j]) X switch(i) X { X case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: X case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: X case OSPIRITSCARAB: case OCUBEofUNDEAD: X case OPOTION: case OSCROLL: break; X default: count++; X }; X X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: X case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: X case OSPIRITSCARAB: case OCUBEofUNDEAD: X case OPOTION: case OSCROLL: X break; X default: X if (itemselect = show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1) ? itemselect : 0 ); X } X X/* X * function to show the things player can read only X */ Xshowread() X { X register int i,j,sigsav,count,itemselect = 0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) X switch(iven[j]) X { X case OBOOK: case OSCROLL: count++; X }; X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OBOOK: case OSCROLL: X if (itemselect = show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return((itemselect > 1) ? itemselect : 0 ); X } X X/* X * function to show the things player can eat only X */ Xshoweat() X { X register int i,j,sigsav,count,itemselect=0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) X switch(iven[j]) X { X case OCOOKIE: count++; X }; X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OCOOKIE: X if (itemselect=show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1) ? itemselect : 0 ); X } X X/* X function to show the things player can quaff only X */ Xshowquaff() X { X register int i,j,sigsav,count,itemselect=0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) X switch(iven[j]) X { X case OPOTION: count++; X }; X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OPOTION: X if (itemselect=show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1 ) ? itemselect : 0 ); X } X Xshow1(idx,str2) X register int idx; X register char *str2[]; X { X lprc('\n'); X cltoeoln(); X if (str2==0) X lprintf("%c) %s",idx+'a',objectname[iven[idx]]); X else if (*str2[ivenarg[idx]]==0) X lprintf("%c) %s",idx+'a',objectname[iven[idx]]); X else X lprintf("%c) %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]); X } X Xshow3(index) Xregister int index ; X { X srcount=0; X return( show2(index) ); X } X Xstatic int show2(index) Xregister int index; X { X register int itemselect = 0; X X switch(iven[index]) X { X case OPOTION: show1(index,potionname); break; X case OSCROLL: show1(index,scrollname); break; X X case OLARNEYE: case OBOOK: case OSPIRITSCARAB: X case ODIAMOND: case ORUBY: case OCUBEofUNDEAD: X case OEMERALD: case OCHEST: case OCOOKIE: X case OSAPPHIRE: case ONOTHEFT: show1(index,(char **)0); break; X X default: X lprc('\n'); X cltoeoln(); X lprintf("%c) %s",index+'a',objectname[iven[index]]); X if (ivenarg[index]>0) X lprintf(" + %d",(long)ivenarg[index]); X else if (ivenarg[index]<0) X lprintf(" %d",(long)ivenarg[index]); X break; X } X if (c[WIELD]==index) lprcat(" (weapon in hand)"); X if ((c[WEAR]==index) || (c[SHIELD]==index)) lprcat(" (being worn)"); X if (++srcount>=22) X { X srcount=0; X itemselect = more(TRUE); X clear(); X } X return( itemselect ); 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)) > MAXINVEN) X limit=MAXINVEN; X for (i=0; i=MAXINVEN)) X 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 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 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 = MIN_LIMIT + (c[LEVEL]>>1) ) > MAXINVEN ) X limit = MAXINVEN; X for (i=0; i'larnhlp.uue' <<'END_OF_FILE' Xbegin 644 larn.hlp XM-R`@("!796QC;VUE('1O('1H92!G86UE(&]F($QA2!E9F9E8W0N XM("!9;W4@2!T;R!S879E(&AE2X* XM4&5R:&%P65A2!M:7)A8W5L;W5S('-U8V-E XM6]U"!S=&%T=7,*:2`@:6YV96YT;W)Y('EO=7(@<&]C XM:V5T2!H97)E"G`@('!R87D@870@86X@86QT87(@("`@ XM("`@(%`@(&=I=F4@=&%X('-T871U2`@;6]V92!N;W)T:'=E6]U('1Y<&4@)RHG(&%S('EO=7(@86UO=6YT XM+"!A;&P@>6]U6]U(&]U="X*"E=H96X@ XM8V%S=&EN9R!A('-P96QL+"!I9B!Y;W4@;F5E9"!A(&QI6]U6]U(&UA>2!E;G1E XM2!W;W)K6]U('=I2X*("`@("`@("`@("`@("`@("`@("`@("`@ XM&ULW;4QA2!D:69F:6-U;'1Y(&]F('1H92!G86UE"FQA6]U(&UU6]U(&AE XM87)D(&]F(&$@;&%N9"!O9B!G2!Y96%R2!A;&]N9R!Y;W5R(%!!5$@N"D$@2!W:&ET97-P86-E(&ES('5S960@ XM=&\@2!O<'1I;VYS+@H*("`@(%=O7!A XM9"`@("`@("`@("`@("`@("`@("`@96YA8FQE('1H92!N=6UE7!A XM9"!F;W(@;6]V:6YG"B`@("!L87)N9&ER.B`@9&ER96-T;W)Y("`@("`@('1H XM92!D:7)E8W1O6]U2!I;G1R;R!M97-S86=E"B`@ XM("!S879E9FEL93H@0IB92!U<"!T;R`S-"!C XM:&%R86-T97)S(&QO;F71H:6YG(&5N8VQO'!L XM86YA=&EO;B!O9B!T:&4@3&%R;B!S8V]R96)O87)D(&9A8VEL:71Y&UMM"@H@ XM("`@3&%R;B!S=7!P;W)T65R("AB>2!U65R:60L('-E92!524130T]212!I XM;B!-86ME9FEL92D*:7,@86QL;W=E9"!O;F4@2!I65R(B!H87,@82!S8V]R92!O9B`Q,C@P,#,@;VX@=&AE('-C;W)E8F]A2!O;B!T XM:&4@65R(&1I97,L XM('1H92!I;G9E;G1O'msdos.c' <<'END_OF_FILE' X#ifdef MSDOS X# include X# include X# include X# include X# include X# include X# include "header.h" X# include "larndefs.h" X X# define DEVICE 0x80 X# define RAW 0x20 X# define IOCTL 0x44 X# define STDIN 0 X# define STDOUT 1 X# define GETBITS 0 X# define SETBITS 1 X# define PATHSEP ';' X X/* Normal characters are output when the shift key is not pushed. X * Shift characters are output when either shift key is pushed. X */ X# define KEYPADHI 83 X# define KEYPADLOW 71 X# define iskeypad(x) (KEYPADLOW <= (x) && (x) <= KEYPADHI) Xstatic struct { X char normal, shift; X } pad[KEYPADHI - KEYPADLOW + 1] = { X {'y', 'Y'}, /* 7 */ X {'k', 'K'}, /* 8 */ X {'u', 'U'}, /* 9 */ X {' ', ' '}, /* - */ X {'h', 'H'}, /* 4 */ X {' ', ' '}, /* 5 */ X {'l', 'L'}, /* 6 */ X {' ', ' '}, /* + */ X {'b', 'B'}, /* 1 */ X {'j', 'J'}, /* 2 */ X {'n', 'N'}, /* 3 */ X {'i', 'i'}, /* Ins */ X {'.', '.'} /* Del */ X}; X X/* BIOSgetch gets keys directly with a BIOS call. X */ X#ifdef OS2LARN X# define SHIFT (RIGHTSHIFT | LEFTSHIFT) X#else X# define SHIFT (0x1 | 0x2) X#endif X# define KEYBRD_BIOS 0x16 X Xstatic char XBIOSgetch() { X unsigned char scan, shift, ch; X union REGS regs; X X#ifdef OS2LARN X KBDKEYINFO kbd; X X KbdCharIn(&kbd,IO_WAIT,(HKBD) 0); X ch = kbd.chChar; X scan = kbd.chScan; X shift = kbd.fsState; X#else X /* Get scan code. X */ X regs.h.ah = 0; X int86(KEYBRD_BIOS, ®s, ®s); X ch = regs.h.al; X scan = regs.h.ah; X X /* Get shift status. X */ X regs.h.ah = 2; X int86(KEYBRD_BIOS, ®s, ®s); X shift = regs.h.al; X#endif X X /* If scan code is for the keypad, translate it. X */ X if (iskeypad(scan)) { X if (shift & SHIFT) X ch = pad[scan - KEYPADLOW].shift; X else X ch = pad[scan - KEYPADLOW].normal; X } X return ch; X} X Xkgetch() X{ X /* BIOSgetch can use the numeric key pad on IBM compatibles. */ X if (keypad) X return BIOSgetch(); X else X return getch(); X} X Xdoshell() X{ X char *comspec = getenv("COMSPEC"); X X clear(); X lflush(); X if (comspec == NULL X || (spawnl(P_WAIT, comspec, comspec, NULL) < 0)) { X write(2, "A> ", 3); X while (getche() != '\r') X ; X } X} X Xstatic unsigned old_stdin, old_stdout, ioctl(); X Xstatic unsigned Xioctl(handle, mode, setvalue) Xunsigned setvalue; X{ X#ifndef OS2LARN X union REGS regs; X X regs.h.ah = IOCTL; X regs.h.al = mode; X regs.x.bx = handle; X regs.h.dl = setvalue; X regs.h.dh = 0; /* Zero out dh */ X intdos(®s, ®s); X return (regs.x.dx); X#endif X} X Xint rawio; Xvoid Xsetraw() X{ X if (!rawio) X return; X old_stdin = ioctl(STDIN, GETBITS, 0); X old_stdout = ioctl(STDOUT, GETBITS, 0); X if (old_stdin & DEVICE) X (void) ioctl(STDIN, SETBITS, old_stdin | RAW); X if (old_stdout & DEVICE) X (void) ioctl(STDOUT, SETBITS, old_stdout | RAW); X} X Xvoid Xunsetraw() X{ X if (!rawio) X return; X if (old_stdin) X (void) ioctl(STDIN, SETBITS, old_stdin); X if (old_stdout) X (void) ioctl(STDOUT, SETBITS, old_stdout); X} X X X/* Add a backslash to any name not ending in /, \ or : There must X * be room for the \ X */ Xvoid Xappend_slash(name) Xchar *name; X{ X char *ptr; X X if (!*name) X return; X ptr = name + (strlen(name) - 1); X if (*ptr != '\\' && *ptr != '/' && *ptr != ':') { X *++ptr = '\\'; X *++ptr = '\0'; X } X} X X/* Lopen a file somewhere along the PATH X */ Xplopen(name) Xchar *name; X{ X char buf[PATHLEN], *bp, *pp, lastch, *strchr(); X int fd; X X /* Try the default directory first. Then look along PATH unless X * the name has path components. X */ X if ((fd = lopen(name)) >= 0) X return fd; X else if (strpbrk(name, "\\/:") == NULL) { X pp = getenv("PATH"); X while (pp && *pp) { X bp = buf; X while (*pp && *pp != PATHSEP) X lastch = *bp++ = *pp++; X if (strchr("\\/:", lastch) == NULL) X *bp++ = '\\'; X strcpy(bp, name); X if ((fd = lopen(buf)) >= 0) X return fd; X if (*pp) X pp++; X } X } X return -1; X} X X X/* Follow the PATH, trying to fopen the file. Takes one additional X * argument which can be NULL. Otherwise this argument gets filled X * in the full path to the file. Returns as does fopen(). X */ XFILE * Xfopenp(name, mode, pathname) Xchar *name, *mode, *pathname; X{ X char buffer[BUFSIZ], *buf, *bufp, *pathp, *getenv(), lastch; X FILE *fp; X X /* If pathname is given, use it instead of buf so the calling X * process knows the path we found name under X */ X if (pathname) X buf = pathname; X else X buf = buffer; X X /* Try the default directory first. If the file can't be opened, X * start looking along the path. X */ X strcpy(buf, name); X if (fp = fopen(buf, mode)) X return fp; X else if (strpbrk(name, "\\/:") == NULL) { X pathp = getenv("PATH"); X while (pathp && *pathp) { X bufp = buf; X while (*pathp && *pathp != PATHSEP) X lastch = *bufp++ = *pathp++; X if (lastch != '\\' && lastch != '/') X *bufp++ = '\\'; X strcpy(bufp, name); X if (fp = fopen(buf, mode)) X return fp; X if (*pathp) X pathp++; X } X } X return NULL; X} X X/* Diagnositic information about the disposition of levels between ram X * and disk. X */ Xlevelinfo() X{ X DISKBLOCK *dp; X RAMBLOCK *rp; X X cursors(); X lflush(); X fprintf(stderr, "\nRAM:\n"); X for (rp = ramblks; rp; rp = rp->next) X fprintf(stderr, "%4d gt:%6ld\n", rp->level, rp->gtime); X fprintf(stderr, "\nDISK:\n"); X for (dp = diskblks; dp; dp = dp->next) X fprintf(stderr, "%4d gt:%6ld fpos:%ld\n", X dp->level, dp->gtime, dp->fpos); X nomove=1; X return (yrepcount = 0); X} X Xint swapfd = 0; /* file descriptor for the swap file */ Xint ramlevels = MAXLEVEL + MAXVLEVEL; /* the maximum */ X X X/* Allocate as many levels as possible, then check that the swap file X * will have enough storage for the overflow. You must be able to allocate X * at least one level or there will be nowhere to swap to/from. If a swap X * file is opened it remains open for the whole game. X */ Xallocate_memory() X{ X register int i; X DISKBLOCK *dp, *dp2; X RAMBLOCK *rp; X X /* First allocate the maximum number of disk blocks, some of which X * may not be used, but must do the allocation now since we don't X * yet know how many levels will be allocatable. X */ X for (i = 0; i < MAXLEVEL + MAXVLEVEL; i++) { X if ((dp = (DISKBLOCK *) malloc(sizeof(DISKBLOCK))) == NULL) X died(-285); X dp->next = diskblks; X diskblks = dp; X } X dp = diskblks; /* Move this along in the next loop */ X X /* Now allocate ram storage, up to ramlevels in count. X */ X for (i = 0; i < MAXLEVEL + MAXVLEVEL; i++) { X if (i < ramlevels) X rp = (RAMBLOCK *) malloc(sizeof(RAMBLOCK)); X else X rp = NULL; X if (rp == NULL) { X if (i == 0) X died(-285); /* have to have at least one */ X X /* Open the swap file if not yet done so X */ X if (swapfd == 0) { X swapfd = open(swapfile, X O_RDWR | O_CREAT | O_TRUNC | O_BINARY, X S_IWRITE | S_IREAD); X if (swapfd < 0) X error("Can't open swapfile `%s'\n", X swapfile); X X /* First block is FREE and will be used to X * swap out the first level. When another X * level gets swapped in, its block will be X * FREE. X */ X if (dp == NULL) X error("NULL1 disk pointer?\n"); X dp->level = FREEBLOCK; X dp->fpos = 0; X dp->gtime = 0; X lseek(swapfd, (long) sizeof rp->cell, 0); X } X X /* And try to seek the size of this level X */ X dp = dp->next; X if (dp == NULL) X error("NULL2 disk pointer?\n"); X dp->level = FREEBLOCK; X dp->gtime = 0; X dp->fpos = tell(swapfd); X if (lseek(swapfd, (long) sizeof rp->cell, 1) < 0L) X error("Not enough disk space for swapfile `%s'\n", X swapfile); X } else { X rp->next = ramblks; X ramblks = rp; X rp->level = FREEBLOCK; X rp->gtime = 0; X } X } X X /* dp now points to the last diskblock used. Truncate the diskblock X * list here and free up the other blocks (for what it's worth ...) X */ X dp2 = dp->next; X dp->next = NULL; X dp = dp2; X while (dp) { X dp2 = dp->next; X free((char *) dp); X dp = dp2; X } X} X X X/* VARARGS1 */ Xwarn(format, a1, a2, a3) Xchar *format; Xlong a1, a2, a3; X{ X fprintf(stderr, format, a1, a2, a3); X} X X/* VARARGS1 */ Xerror(format, a1, a2, a3, a4) Xchar *format; Xlong a1, a2, a3, a4; X{ X unsetraw(); X resetcursor(); X fputc('\n', stderr); X fprintf(stderr, format, a1, a2, a3, a4); X sleep(5); X exit(1); X} X Xstatic unsigned char ocursorstart, ocursorend; Xunsigned char cursorstart, cursorend; Xint cursorset; X X/* Save the old value of the cursor then put in the new value. X */ X# define READCURSORPOS 0x03 X# define SETCURSORTYPE 0x01 X# define BIOSVIDEO 0x10 Xsetcursor() X{ X#ifdef OS2LARN X USHORT rc; X VIOCURSORINFO curinfo; X X if (cursorset == 0) X return; X X /* Save the cursor type in 'ocursorstart' and 'ocursorend'. X */ X rc = VioGetCurType((PVIOCURSORINFO) &curinfo, (HVIO) NULL); X if (rc != 0) X { X /* errors don't happen. */ X } X ocursorstart = curinfo.yStart; X ocursorend = curinfo.cEnd; X X /* set the cursor type according to global variables X 'cursorstart' and 'cursorend'. X */ X curinfo.cEnd = cursorend; X curinfo.yStart = cursorstart; X curinfo.cx = 0; /* default width, 1 char */ X curinfo.attr = 0; /* 'Normal' attribute */ X X rc = VioSetCurType((PVIOCURSORINFO) &curinfo, (HVIO) NULL); X if (rc != 0) X { X /* errors don't happen. */ X } X X#else X union REGS regs; X X if (cursorset == 0) X return; X X regs.h.ah = READCURSORPOS; X regs.h.bh = 0; X int86(BIOSVIDEO, ®s, ®s); X ocursorstart = regs.h.ch; X ocursorend = regs.h.cl; X X regs.h.ah = SETCURSORTYPE; X regs.h.bh = 0; X regs.h.ch = cursorstart; X#if 0 X regs.h.ch = 0x20 ; X#endif X regs.h.cl = cursorend; X int86(BIOSVIDEO, ®s, ®s); X#endif X} X X/* Restore the old cursor upon exit X */ Xresetcursor() X{ X#ifdef OS2LARN X VIOCURSORINFO curinfo; X X if (cursorset == 0) X return; X X curinfo.cEnd = ocursorend; X curinfo.yStart = ocursorstart; X curinfo.cx = 0; /* default width, 1 char */ X curinfo.attr = 0; /* 'Normal' attribute */ X X VioSetCurType((PVIOCURSORINFO) &curinfo, (HVIO) NULL); X#else X union REGS regs; X X if (cursorset == 0) X return; X regs.h.ah = SETCURSORTYPE; X regs.h.bh = 0; X regs.h.ch = ocursorstart; X regs.h.cl = ocursorend; X int86(BIOSVIDEO, ®s, ®s); X#endif X} X# endif /* MSDOS */ END_OF_FILE if test 11570 -ne `wc -c <'msdos.c'`; then echo shar: \"'msdos.c'\" unpacked with wrong size! fi # end of 'msdos.c' fi if test -f 'tgetent.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'tgetent.c'\" else echo shar: Extracting \"'tgetent.c'\" \(10470 characters\) sed "s/^X//" >'tgetent.c' <<'END_OF_FILE' X/************************************************************************ X * * X * Copyright (c) 1982, Fred Fish * X * All Rights Reserved * X * * X * This software and/or documentation is released for public * X * distribution for personal, non-commercial use only. * X * Limited rights to use, modify, and redistribute are hereby * X * granted for non-commercial purposes, provided that all * X * copyright notices remain intact and all changes are clearly * X * documented. The author makes no warranty of any kind with * X * respect to this product and explicitly disclaims any implied * X * warranties of merchantability or fitness for any particular * X * purpose. * X * * X ************************************************************************ X */ X X/* X * LIBRARY FUNCTION X * X * tgetent load buffer with entry for specified terminal X * X * KEY WORDS X * X * termcap functions X * utility routines X * X * SYNOPSIS X * X * int tgetent(bp,name) X * char *bp; X * char *name; X * X * DESCRIPTION X * X * Extracts the entry for terminal from the termcap file X * and places it in the character buffer . It is currently X * assumed that bp is at least 1024 characters. If the entry in X * the termcap file is larger than 1023 characters the excess X * characters will be discarded and appropriate status will X * be returned. X * X * Also note that since bp is used by other termcap X * routines, the storage associated with the termcap entry X * cannot be freed until all termcap calls are completed. X * X * Tgetent can be directed to look in a file other than X * the default (/etc/termcap) by defining an environment X * variable called TERMCAP to be the pathname of the desired X * termcap file. This is useful for debugging new entries. X#ifndef VMS X * NOTE: the pathname MUST begin with a '/' character. X * X * Also, if the string assigned to TERMCAP does not begin with X * a '/' and if the environment variable TERM matches then X * the string assigned to TERMCAP is copied to buffer X * instead of reading a termcap file. X#endif X * X * If the termcap entry contains a "tc" string then the termcap X * entry named in the string is appended to the buffer (minus the X * names). X * X * RETURNS X * X * -1 if the termcap file cannot be opened X * 0 if no entry in termcap file matches X * 1 if extraction is successful with no errors X * 2 if extraction is successful but entry truncated X * X * SEE ALSO X * X * tgetnum extract numeric type capability X * tgetflag test boolean type capability X * tgetstr get string value of capability X * X * AUTHOR X * X * Fred Fish X * X */ X X#include X X#define TRUE 1 X#define FALSE 0 X#define BUFSIZE 1024 /* Assumed size of external buffer */ X X#define NO_FILE -1 /* Returned if can't open file */ X#define NO_ENTRY 0 /* Returned if can't find entry */ X#define SUCCESS 1 /* Returned if entry found ok */ X#define TRUNCATED 2 /* Returned if entry found but trunc */ X X#ifdef MSDOS XFILE *fopenp(); X#endif X X#define DEFAULT_ROOT "termcap" /* name without path component */ X#ifdef VMS X#define DEFAULT_FILE "sys$library:termcap" X#else X#define DEFAULT_FILE "/etc/termcap" /* default termcap filename */ X#endif VMS X Xchar *_tcpbuf; /* Place to remember buffer pointer */ X X/* X * PSEUDO CODE X * X * Begin tgetent X * Erase any previous buffer contents. X * Remember the buffer pointer. X * If termcap file is not found then X * If buffer was filled anyway then X * Return SUCCESS. X * Else X * Return NO_FILE. X * End if X * Else X * While records left to process X * If this is entry is what we want then X * Close the termcap file. X * If entry was truncated then X * Return TRUNCATED status X * Else X * Return SUCCESS status. X * End if X * End if X * End while X * Return NO_ENTRY status. X * End if X * End tgetent X * X */ X Xint tgetent(bp,name) Xchar *bp; /* Pointer to buffer (1024 char min) */ Xchar *name; /* Pointer to terminal entry to find */ X{ X FILE *fp, *find_file(); X char *nbp, tc[80]; X X *bp = (char)NULL; X _tcpbuf = bp; X if ((fp = find_file(bp)) == NULL) { X if (*bp != NULL) { X return(SUCCESS); X } else { X return(NO_FILE); X } X } else { X while (fgetlr(bp,BUFSIZE,fp)) { X if (gotcha(bp,name)) { X fclose(fp); X nbp = &bp[strlen(bp)-1]; X if (*nbp != '\n') { X return(TRUNCATED); X } else { X /* check for a recursive call (i.e. :tc=vt100:) X * added 18-dec-86 RDE (single recursion...) X */ X char *area; X area = &tc[0]; X if (tgetstr("tc", &area) == NULL) X return(SUCCESS); X else { X fp = find_file(0); /* know it works and is file */ X while (fgetlr(nbp, BUFSIZE-(nbp-bp), fp)) { X if (gotcha(nbp,tc)) { X char *cp1, *cp2; /* scrunch out names */ X fclose(fp); X cp1 = nbp; X while (*cp1++ != ':') /* search for first */ X ; X cp2 = nbp; X while (*cp2++ = *cp1++) /* move the chars. */ X ; X if (bp[strlen(bp)-1] != '\n') { X return(TRUNCATED); X } else { X return(SUCCESS); X } X } X } X return (NO_ENTRY); X } X } X } X } X return(NO_ENTRY); X } X} X X/* X * INTERNAL FUNCTION X * X * find_file find the termcap file and open it if possible X * X * KEY WORDS X * X * internal functions X * find_file X * X * SYNOPSIS X * X * static FILE *find_file(bp) X * char *bp; X * X * DESCRIPTION X * X * Attempts to locate and open the termcap file. Also handles X * using the environment TERMCAP string as the actual buffer X * (that's why bp has to be an input parameter). X * X#ifdef VMS X * If TERMCAP is defined as a valid filespec then it will be X * opened. If this fails then the default termcap file will X * be used. X#else X * If TERMCAP is defined an begins with a '/' character then X * it is taken to be the pathname of the termcap file and X * an attempt is made to open it. If this fails then X * the default termcap file is used instead. X * X * If TERMCAP is defined but does not begin with a '/' then X * it is assumed to be the actual buffer contents provided X * that matches the environment variable TERM. X#endif X * X * BUGS X * X * There is currently no way to be sure which termcap X * file was opened since the default will always be X * tried. X * X */ X X/* X * PSEUDO CODE X * X * Begin find_file X * If there is a TERMCAP environment string then X * If the string is not null then X * If the string is a pathname then X * If that file is opened successfully then X * Return its pointer. X * End if X * Else X * If there is a TERM environment string then X * If TERM matches then X * Copy TERMCAP string to buffer. X * Return NULL for no file. X * End if X * End if X * End if X * End if X * End if X * Open default termcap file and return results. X * End find_file X * X */ X Xstatic FILE *find_file(bp) Xchar *bp; X{ X FILE *fp, *fopen(); X char *cp, *ncp, *getenv(); X X if ((cp = getenv("TERMCAP")) != NULL) { X if (*cp != NULL) { X#ifdef VMS X if ((fp = fopen(cp, "r")) != NULL) X return(fp); X#else X if (*cp == '/' || *cp == '\\') { X if ((fp = fopen(cp,"r")) != NULL) { X return(fp); X } X } else { X if ((ncp = getenv("TERM")) != NULL) { X if (strcmp(cp,ncp) == 0) { X strcpy(bp,cp); X return((FILE *)NULL); X } X } X } X#endif X } X } X /* X * Try current directory, then /etc/termcap X */ X if (fp = fopen(DEFAULT_ROOT, "r")) X return fp; X else X#ifdef MSDOS X if (fp = fopen(DEFAULT_FILE, "r") ) X return fp; X else /* try along the PATH */ X return( fopenp(DEFAULT_ROOT, "r", NULL)); X#else X return (fopen(DEFAULT_FILE, "r")); X#endif X} X X X/* X * INTERNAL FUNCTION X * X * gotcha test to see if entry is for specified terminal X * X * SYNOPSIS X * X * gotcha(bp,name) X * char *bp; X * char *name; X * X * DESCRIPTION X * X * Tests to see if the entry in buffer bp matches the terminal X * specified by name. Returns TRUE if match is detected, FALSE X * otherwise. X * X */ X X/* X * PSEUDO CODE X * X * Begin gotcha X * If buffer character is comment character then X * Return FALSE since remainder is comment X * Else X * Initialize name scan pointer. X * Compare name and buffer until end or mismatch. X * If valid terminators for both name and buffer strings X * Return TRUE since a match was found. X * Else X * Find next non-name character in buffer. X * If not an alternate name separater character X * Return FALSE since no more names to check. X * Else X * Test next name and return results. X * End if X * End if X * End if X * End gotcha X * X */ X Xgotcha(bp,name) Xchar *bp; Xchar *name; X{ X char *np; X X if (*bp == '#') { X return(FALSE); X } else { X np = name; X while (*np == *bp && *np != NULL) {np++; bp++;} X if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) { X return(TRUE); X } else { X while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;} X if (*bp != '|') { X return(FALSE); X } else { X return(gotcha(++bp,name)); X } X } X } X} X X#ifdef MSDOS X/* X * index(buffer, char) X * Find character in buffer. Return the pointer X * to it. Shouldn't be necessary to write this X * myself but VMS didn't. Oh Well... X * Used by lots of files in the termcap library. X * Rich Ellison, 16-DEC-1986 X */ Xchar X*index(buf, ch) Xchar *buf; Xchar ch; X{ X register int c; X while ((c= *buf++) != '\0') X if (c == ch) X return (buf-1); X return (NULL); X} X#endif END_OF_FILE if test 10470 -ne `wc -c <'tgetent.c'`; then echo shar: \"'tgetent.c'\" unpacked with wrong size! fi # end of 'tgetent.c' fi echo shar: End of archive 10 \(of 12\). cp /dev/null ark10isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 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