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 22 static char lastok = 0; 23 int yrepcount = 0; 24 #ifndef FLUSHNO 25 #define FLUSHNO 5 26 #endif /* FLUSHNO */ 27 static 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 */ 30 static char usermonster[MAXUM][MAXMNAME]; /* the user named monster 31 * name goes here */ 32 static u_char usermpoint = 0; /* the user monster pointer */ 33 34 /* 35 lexical analyzer for larn 36 */ 37 int 38 yylex() 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 */ 113 void 114 flushall() 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 */ 134 void 135 sethard(hard) 136 int hard; 137 { 138 int j, k, i; 139 struct monst *mp; 140 141 j = c[HARDGAME]; 142 hashewon(); 143 if (restorflag == 0) { /* don't set c[HARDGAME] if restoring game */ 144 if (hard >= 0) 145 c[HARDGAME] = hard; 146 } else 147 c[HARDGAME] = j;/* set c[HARDGAME] to proper value if 148 * restoring game */ 149 150 if ((k = c[HARDGAME]) != 0) 151 for (j = 0; j <= MAXMONST + 8; j++) { 152 mp = &monster[j]; 153 i = ((6 + k) * mp->hitpoints + 1) / 6; 154 mp->hitpoints = (i < 0) ? 32767 : i; 155 i = ((6 + k) * mp->damage + 1) / 5; 156 mp->damage = (i > 127) ? 127 : i; 157 i = (10 * mp->gold) / (10 + k); 158 mp->gold = (i > 32767) ? 32767 : i; 159 i = mp->armorclass - k; 160 mp->armorclass = (i < -127) ? -127 : i; 161 i = (7 * mp->experience) / (7 + k) + 1; 162 mp->experience = (i <= 0) ? 1 : i; 163 } 164 } 165 166 /* 167 function to read and process the larn options file 168 */ 169 void 170 readopts() 171 { 172 const char *i; 173 int j, k; 174 int flag; 175 176 flag = 1; /* set to 0 if a name is specified */ 177 178 if (lopen(optsfile) < 0) { 179 strcpy(logname, loginname); 180 return; /* user name if no character name */ 181 } 182 i = " "; 183 while (*i) { 184 if ((i = lgetw()) == NULL) 185 break; /* check for EOF */ 186 while ((*i == ' ') || (*i == '\t')) 187 i++; /* eat leading whitespace */ 188 189 if (strcmp(i, "bold-objects") == 0) 190 boldon = 1; 191 else if (strcmp(i, "enable-checkpointing") == 0) 192 ckpflag = 1; 193 else if (strcmp(i, "inverse-objects") == 0) 194 boldon = 0; 195 else if (strcmp(i, "female") == 0) 196 sex = 0; /* male or female */ 197 else if (strcmp(i, "monster:") == 0) { /* name favorite monster */ 198 if ((i = lgetw()) == 0) 199 break; 200 strlcpy(usermonster[usermpoint], i, MAXMNAME); 201 if (usermpoint >= MAXUM) 202 continue; /* defined all of em */ 203 if (isalpha(j = usermonster[usermpoint][0])) { 204 for (k = 1; k < MAXMONST + 8; k++) /* find monster */ 205 if (monstnamelist[k] == j) { 206 monster[k].name = &usermonster[usermpoint++][0]; 207 break; 208 } 209 } 210 } else if (strcmp(i, "male") == 0) 211 sex = 1; 212 else if (strcmp(i, "name:") == 0) { /* defining players name */ 213 if ((i = lgetw()) == 0) 214 break; 215 strlcpy(logname, i, LOGNAMESIZE); 216 flag = 0; 217 } else if (strcmp(i, "no-introduction") == 0) 218 nowelcome = 1; 219 else if (strcmp(i, "no-beep") == 0) 220 nobeep = 1; 221 else if (strcmp(i, "process-name:") == 0) { 222 if ((i = lgetw()) == 0) 223 break; 224 strlcpy(psname, i, PSNAMESIZE); 225 } else if (strcmp(i, "play-day-play") == 0) { 226 /* bypass time restrictions: ignored */ 227 } else if (strcmp(i, "savefile:") == 0) { /* defining savefilename */ 228 if ((i = lgetw()) == 0) 229 break; 230 strcpy(savefilename, i); 231 flag = 0; 232 } 233 } 234 if (flag) 235 strcpy(logname, loginname); 236 } 237