Home | History | Annotate | Line # | Download | only in larn
tok.c revision 1.8
      1 /*	$NetBSD: tok.c,v 1.8 2008/02/03 20:01:24 dholland Exp $	*/
      2 
      3 /* tok.c		Larn is copyrighted 1986 by Noah Morgan. */
      4 #include <sys/cdefs.h>
      5 #ifndef lint
      6 __RCSID("$NetBSD: tok.c,v 1.8 2008/02/03 20:01:24 dholland Exp $");
      7 #endif				/* not lint */
      8 
      9 #include <sys/types.h>
     10 #include <string.h>
     11 #include <sys/ioctl.h>
     12 #include <stdlib.h>
     13 #include <unistd.h>
     14 #include <sys/wait.h>
     15 #include "header.h"
     16 #include "extern.h"
     17 
     18 static char     lastok = 0;
     19 int             yrepcount = 0;
     20 #ifndef FLUSHNO
     21 #define FLUSHNO 5
     22 #endif	/* FLUSHNO */
     23 static int      flushno = FLUSHNO;	/* input queue flushing threshold */
     24 #define MAXUM 52		/* maximum number of user re-named monsters */
     25 #define MAXMNAME 40		/* max length of a monster re-name */
     26 static char     usermonster[MAXUM][MAXMNAME];	/* the user named monster
     27 						 * name goes here */
     28 static u_char     usermpoint = 0;	/* the user monster pointer */
     29 
     30 /*
     31 	lexical analyzer for larn
     32  */
     33 int
     34 yylex()
     35 {
     36 	char            cc;
     37 	int             ic;
     38 	if (hit2flag) {
     39 		hit2flag = 0;
     40 		yrepcount = 0;
     41 		return (' ');
     42 	}
     43 	if (yrepcount > 0) {
     44 		--yrepcount;
     45 		return (lastok);
     46 	} else
     47 		yrepcount = 0;
     48 	if (yrepcount == 0) {
     49 		bottomdo();
     50 		showplayer();
     51 	}			/* show where the player is	 */
     52 	lflush();
     53 	while (1) {
     54 		c[BYTESIN]++;
     55 		if (ckpflag)
     56 			if ((c[BYTESIN] % 400) == 0) {	/* check for periodic
     57 							 * checkpointing */
     58 #ifndef DOCHECKPOINTS
     59 				savegame(ckpfile);
     60 #else
     61 				wait(0);	/* wait for other forks to
     62 						 * finish */
     63 				if (fork() == 0) {
     64 					savegame(ckpfile);
     65 					exit();
     66 				}
     67 #endif
     68 			}
     69 		do {		/* if keyboard input buffer is too big, flush
     70 				 * some of it */
     71 			ioctl(0, FIONREAD, &ic);
     72 			if (ic > flushno)
     73 				read(0, &cc, 1);
     74 		}
     75 		while (ic > flushno);
     76 
     77 		if (read(0, &cc, 1) != 1)
     78 			return (lastok = -1);
     79 
     80 		if (cc == 'Y' - 64) {	/* control Y -- shell escape */
     81 			resetscroll();
     82 			clear();/* scrolling region, home, clear, no
     83 				 * attributes */
     84 			if ((ic = fork()) == 0) {	/* child */
     85 				execl("/bin/csh", "/bin/csh", NULL);
     86 				exit(1);
     87 			}
     88 			wait(0);
     89 			if (ic < 0) {	/* error */
     90 				write(2, "Can't fork off a shell!\n", 25);
     91 				sleep(2);
     92 			}
     93 			setscroll();
     94 			return (lastok = 'L' - 64);	/* redisplay screen */
     95 		}
     96 		if ((cc <= '9') && (cc >= '0')) {
     97 			yrepcount = yrepcount * 10 + cc - '0';
     98 		} else {
     99 			if (yrepcount > 0)
    100 				--yrepcount;
    101 			return (lastok = cc);
    102 		}
    103 	}
    104 }
    105 
    106 /*
    107  *	flushall()		Function to flush all type-ahead in the input buffer
    108  */
    109 void
    110 flushall()
    111 {
    112 	char            cc;
    113 	int             ic;
    114 	for (;;) {		/* if keyboard input buffer is too big, flush
    115 				 * some of it */
    116 		ioctl(0, FIONREAD, &ic);
    117 		if (ic <= 0)
    118 			return;
    119 		while (ic > 0) {
    120 			read(0, &cc, 1);
    121 			--ic;
    122 		}		/* gobble up the byte */
    123 	}
    124 }
    125 
    126 /*
    127 	function to set the desired hardness
    128 	enter with hard= -1 for default hardness, else any desired hardness
    129  */
    130 void
    131 sethard(hard)
    132 	int             hard;
    133 {
    134 	int    j, k, i;
    135 	j = c[HARDGAME];
    136 	hashewon();
    137 	if (restorflag == 0) {	/* don't set c[HARDGAME] if restoring game */
    138 		if (hard >= 0)
    139 			c[HARDGAME] = hard;
    140 	} else
    141 		c[HARDGAME] = j;/* set c[HARDGAME] to proper value if
    142 				 * restoring game */
    143 
    144 	if ((k = c[HARDGAME]) != 0)
    145 		for (j = 0; j <= MAXMONST + 8; j++) {
    146 			i = ((6 + k) * monster[j].hitpoints + 1) / 6;
    147 			monster[j].hitpoints = (i < 0) ? 32767 : i;
    148 			i = ((6 + k) * monster[j].damage + 1) / 5;
    149 			monster[j].damage = (i > 127) ? 127 : i;
    150 			i = (10 * monster[j].gold) / (10 + k);
    151 			monster[j].gold = (i > 32767) ? 32767 : i;
    152 			i = monster[j].armorclass - k;
    153 			monster[j].armorclass = (i < -127) ? -127 : i;
    154 			i = (7 * monster[j].experience) / (7 + k) + 1;
    155 			monster[j].experience = (i <= 0) ? 1 : i;
    156 		}
    157 }
    158 
    159 /*
    160 	function to read and process the larn options file
    161  */
    162 void
    163 readopts()
    164 {
    165 	const char  *i;
    166 	int    j, k;
    167 	int             flag;
    168 	flag = 1;		/* set to 0 if he specifies a name for his
    169 				 * character */
    170 	if (lopen(optsfile) < 0) {
    171 		strcpy(logname, loginname);
    172 		return;		/* user name if no character name */
    173 	}
    174 	i = " ";
    175 	while (*i) {
    176 		if ((i = lgetw()) == NULL)
    177 			break;	/* check for EOF */
    178 		while ((*i == ' ') || (*i == '\t'))
    179 			i++;	/* eat leading whitespace */
    180 		switch (*i) {
    181 		case 'b':
    182 			if (strcmp(i, "bold-objects") == 0)
    183 				boldon = 1;
    184 			break;
    185 
    186 		case 'e':
    187 			if (strcmp(i, "enable-checkpointing") == 0)
    188 				ckpflag = 1;
    189 			break;
    190 
    191 		case 'i':
    192 			if (strcmp(i, "inverse-objects") == 0)
    193 				boldon = 0;
    194 			break;
    195 
    196 		case 'f':
    197 			if (strcmp(i, "female") == 0)
    198 				sex = 0;	/* male or female */
    199 			break;
    200 
    201 		case 'm':
    202 			if (strcmp(i, "monster:") == 0) {	/* name favorite monster */
    203 				if ((i = lgetw()) == 0)
    204 					break;
    205 				strlcpy(usermonster[usermpoint], i, MAXMNAME);
    206 				if (usermpoint >= MAXUM)
    207 					break;	/* defined all of em */
    208 				if (isalpha(j = usermonster[usermpoint][0])) {
    209 					for (k = 1; k < MAXMONST + 8; k++)	/* find monster */
    210 						if (monstnamelist[k] == j) {
    211 							monster[k].name = &usermonster[usermpoint++][0];
    212 							break;
    213 						}
    214 				}
    215 			} else if (strcmp(i, "male") == 0)
    216 				sex = 1;
    217 			break;
    218 
    219 		case 'n':
    220 			if (strcmp(i, "name:") == 0) {	/* defining players name */
    221 				if ((i = lgetw()) == 0)
    222 					break;
    223 				strlcpy(logname, i, LOGNAMESIZE);
    224 				flag = 0;
    225 			} else if (strcmp(i, "no-introduction") == 0)
    226 				nowelcome = 1;
    227 			else if (strcmp(i, "no-beep") == 0)
    228 				nobeep = 1;
    229 			break;
    230 
    231 		case 'p':
    232 			if (strcmp(i, "process-name:") == 0) {
    233 				if ((i = lgetw()) == 0)
    234 					break;
    235 				strlcpy(psname, i, PSNAMESIZE);
    236 			} else if (strcmp(i, "play-day-play") == 0) {
    237 				/* bypass time restrictions: ignored */
    238 			}
    239 			break;
    240 
    241 		case 's':
    242 			if (strcmp(i, "savefile:") == 0) {	/* defining savefilename */
    243 				if ((i = lgetw()) == 0)
    244 					break;
    245 				strcpy(savefilename, i);
    246 				flag = 0;
    247 			}
    248 			break;
    249 		};
    250 	}
    251 	if (flag)
    252 		strcpy(logname, loginname);
    253 }
    254