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