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