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