1 /* $NetBSD: tok.c,v 1.5 1997/10/18 20:03:54 christos 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.5 1997/10/18 20:03:54 christos 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, dayplay = 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 70 #ifdef TIMECHECK 71 if (dayplay == 0) 72 if (playable()) { 73 cursor(1, 19); 74 lprcat("\nSorry, but it is now time for work. Your game has been saved.\n"); 75 beep(); 76 lflush(); 77 savegame(savefilename); 78 wizard = nomove = 1; 79 sleep(4); 80 died(-257); 81 } 82 #endif /* TIMECHECK */ 83 84 } 85 do { /* if keyboard input buffer is too big, flush 86 * some of it */ 87 ioctl(0, FIONREAD, &ic); 88 if (ic > flushno) 89 read(0, &cc, 1); 90 } 91 while (ic > flushno); 92 93 if (read(0, &cc, 1) != 1) 94 return (lastok = -1); 95 96 if (cc == 'Y' - 64) { /* control Y -- shell escape */ 97 resetscroll(); 98 clear();/* scrolling region, home, clear, no 99 * attributes */ 100 if ((ic = fork()) == 0) { /* child */ 101 execl("/bin/csh", 0); 102 exit(1); 103 } 104 wait(0); 105 if (ic < 0) { /* error */ 106 write(2, "Can't fork off a shell!\n", 25); 107 sleep(2); 108 } 109 setscroll(); 110 return (lastok = 'L' - 64); /* redisplay screen */ 111 } 112 if ((cc <= '9') && (cc >= '0')) { 113 yrepcount = yrepcount * 10 + cc - '0'; 114 } else { 115 if (yrepcount > 0) 116 --yrepcount; 117 return (lastok = cc); 118 } 119 } 120 } 121 122 /* 123 * flushall() Function to flush all type-ahead in the input buffer 124 */ 125 void 126 flushall() 127 { 128 char cc; 129 int ic; 130 for (;;) { /* if keyboard input buffer is too big, flush 131 * some of it */ 132 ioctl(0, FIONREAD, &ic); 133 if (ic <= 0) 134 return; 135 while (ic > 0) { 136 read(0, &cc, 1); 137 --ic; 138 } /* gobble up the byte */ 139 } 140 } 141 142 /* 143 function to set the desired hardness 144 enter with hard= -1 for default hardness, else any desired hardness 145 */ 146 void 147 sethard(hard) 148 int hard; 149 { 150 int j, k, i; 151 j = c[HARDGAME]; 152 hashewon(); 153 if (restorflag == 0) { /* don't set c[HARDGAME] if restoring game */ 154 if (hard >= 0) 155 c[HARDGAME] = hard; 156 } else 157 c[HARDGAME] = j;/* set c[HARDGAME] to proper value if 158 * restoring game */ 159 160 if ((k = c[HARDGAME]) != 0) 161 for (j = 0; j <= MAXMONST + 8; j++) { 162 i = ((6 + k) * monster[j].hitpoints + 1) / 6; 163 monster[j].hitpoints = (i < 0) ? 32767 : i; 164 i = ((6 + k) * monster[j].damage + 1) / 5; 165 monster[j].damage = (i > 127) ? 127 : i; 166 i = (10 * monster[j].gold) / (10 + k); 167 monster[j].gold = (i > 32767) ? 32767 : i; 168 i = monster[j].armorclass - k; 169 monster[j].armorclass = (i < -127) ? -127 : i; 170 i = (7 * monster[j].experience) / (7 + k) + 1; 171 monster[j].experience = (i <= 0) ? 1 : i; 172 } 173 } 174 175 /* 176 function to read and process the larn options file 177 */ 178 void 179 readopts() 180 { 181 char *i; 182 int j, k; 183 int flag; 184 flag = 1; /* set to 0 if he specifies a name for his 185 * character */ 186 if (lopen(optsfile) < 0) { 187 strcpy(logname, loginname); 188 return; /* user name if no character name */ 189 } 190 i = " "; 191 while (*i) { 192 if ((i = (char *) lgetw()) == 0) 193 break; /* check for EOF */ 194 while ((*i == ' ') || (*i == '\t')) 195 i++; /* eat leading whitespace */ 196 switch (*i) { 197 case 'b': 198 if (strcmp(i, "bold-objects") == 0) 199 boldon = 1; 200 break; 201 202 case 'e': 203 if (strcmp(i, "enable-checkpointing") == 0) 204 ckpflag = 1; 205 break; 206 207 case 'i': 208 if (strcmp(i, "inverse-objects") == 0) 209 boldon = 0; 210 break; 211 212 case 'f': 213 if (strcmp(i, "female") == 0) 214 sex = 0; /* male or female */ 215 break; 216 217 case 'm': 218 if (strcmp(i, "monster:") == 0) { /* name favorite monster */ 219 if ((i = lgetw()) == 0) 220 break; 221 if (strlen(i) >= MAXMNAME) 222 i[MAXMNAME - 1] = 0; 223 strcpy(usermonster[usermpoint], i); 224 if (usermpoint >= MAXUM) 225 break; /* defined all of em */ 226 if (isalpha(j = usermonster[usermpoint][0])) { 227 for (k = 1; k < MAXMONST + 8; k++) /* find monster */ 228 if (monstnamelist[k] == j) { 229 monster[k].name = &usermonster[usermpoint++][0]; 230 break; 231 } 232 } 233 } else if (strcmp(i, "male") == 0) 234 sex = 1; 235 break; 236 237 case 'n': 238 if (strcmp(i, "name:") == 0) { /* defining players name */ 239 if ((i = lgetw()) == 0) 240 break; 241 if (strlen(i) >= LOGNAMESIZE) 242 i[LOGNAMESIZE - 1] = 0; 243 strcpy(logname, i); 244 flag = 0; 245 } else if (strcmp(i, "no-introduction") == 0) 246 nowelcome = 1; 247 else if (strcmp(i, "no-beep") == 0) 248 nobeep = 1; 249 break; 250 251 case 'p': 252 if (strcmp(i, "process-name:") == 0) { 253 if ((i = lgetw()) == 0) 254 break; 255 if (strlen(i) >= PSNAMESIZE) 256 i[PSNAMESIZE - 1] = 0; 257 strcpy(psname, i); 258 } else if (strcmp(i, "play-day-play") == 0) 259 dayplay = 1; 260 break; 261 262 case 's': 263 if (strcmp(i, "savefile:") == 0) { /* defining savefilename */ 264 if ((i = lgetw()) == 0) 265 break; 266 strcpy(savefilename, i); 267 flag = 0; 268 } 269 break; 270 }; 271 } 272 if (flag) 273 strcpy(logname, loginname); 274 } 275