1 1.2 kamil char rcsid[] = "@(#)Header: warp.c,v 7.0.1.3 86/12/12 17:07:44 lwall Exp"; 2 1.1 kamil 3 1.1 kamil /* warp -- a real-time space war program 4 1.1 kamil * author: Larry Wall 5 1.1 kamil * helpers: Jonathan and Mark Biggar, and Dan Faigin 6 1.1 kamil * special thanks to my sweetie Gloria who suggested the Planet Crusher 7 1.1 kamil * 8 1.6 kamil * Copyright (c) 2020 The NetBSD Foundation, Inc. 9 1.6 kamil * All rights reserved. 10 1.8 rillig * 11 1.6 kamil * This code is derived from software contributed to The NetBSD Foundation 12 1.6 kamil * by Larry Wall. 13 1.8 rillig * 14 1.6 kamil * Redistribution and use in source and binary forms, with or without 15 1.6 kamil * modification, are permitted provided that the following conditions 16 1.6 kamil * are met: 17 1.6 kamil * 1. Redistributions of source code must retain the above copyright 18 1.6 kamil * notice, this list of conditions and the following disclaimer. 19 1.6 kamil * 2. Redistributions in binary form must reproduce the above copyright 20 1.6 kamil * notice, this list of conditions and the following disclaimer in the 21 1.6 kamil * documentation and/or other materials provided with the distribution. 22 1.8 rillig * 23 1.6 kamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 1.6 kamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 1.6 kamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 1.6 kamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 27 1.6 kamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 1.6 kamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 1.6 kamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 1.6 kamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 1.6 kamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 1.6 kamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 1.6 kamil * POSSIBILITY OF SUCH DAMAGE. 34 1.8 rillig * 35 1.1 kamil * version 5.0 04/20/83 36 1.1 kamil * 5.1 05/05/83 various tidbits 37 1.1 kamil * 5.2 05/12/83 VAX -> vax, ifdef'ed a SIGCONT 38 1.1 kamil * 5.3 05/24/83 RCS 39 1.1 kamil * 40 1.2 kamil * Log: warp.c,v 41 1.1 kamil * Revision 7.0.1.3 86/12/12 17:07:44 lwall 42 1.1 kamil * Baseline for net release. 43 1.8 rillig * 44 1.1 kamil * Revision 7.0.1.2 86/10/20 12:08:00 lwall 45 1.1 kamil * Made all exits reset tty. 46 1.8 rillig * 47 1.1 kamil * Revision 7.0.1.1 86/10/16 10:54:13 lwall 48 1.1 kamil * Added Damage. Fixed random bugs. 49 1.8 rillig * 50 1.1 kamil * Revision 7.0 86/10/08 15:14:47 lwall 51 1.1 kamil * Split into separate files. Added amoebas and pirates. 52 1.8 rillig * 53 1.1 kamil * Revision 6.4 83/12/16 13:11:45 lwall 54 1.1 kamil * Handled 15 bit random number generators. 55 1.8 rillig * 56 1.1 kamil * Fixed array overflow bug on multiple zaps. 57 1.8 rillig * 58 1.1 kamil * Multiple zaps now consolidated to minimize output. 59 1.8 rillig * 60 1.1 kamil * Tholian jackpot games outlawed under difficulty 15. 61 1.8 rillig * 62 1.1 kamil * Revision 6.3 83/08/24 11:17:49 lwall 63 1.1 kamil * Fixed array overflow bug on multiple zap. 64 1.8 rillig * 65 1.1 kamil * Revision 6.2 83/08/23 18:06:37 lwall 66 1.1 kamil * Added zap command. 67 1.1 kamil * Warp -s should now work on dumb terminals 68 1.1 kamil * Specifying difficulty >= 40 now just makes it a special game. 69 1.1 kamil * SIGTTOU #ifdef'ed. 70 1.1 kamil * No-delay read provided as alternative to FIONREAD. 71 1.1 kamil * Warp won't report "-1 obsolete" when there are no Enterprises left. 72 1.1 kamil * Some high-difficulty tuning. 73 1.8 rillig * 74 1.1 kamil * Revision 6.1 83/08/17 08:49:03 lwall 75 1.1 kamil * Fixed obscure bug in storing UP that caused a %. in CM to occasionally 76 1.1 kamil * foist garbage onto the screen. 77 1.8 rillig * 78 1.1 kamil * Revision 6.0 83/08/08 17:09:26 lwall 79 1.1 kamil * New baseline version for net release. 80 1.8 rillig * 81 1.1 kamil * Revision 5.5 83/08/01 10:59:56 lwall 82 1.1 kamil * Cloaking for the Enterprise. 83 1.1 kamil * Difficulty now goes to 99, and many activities depending on difficulty 84 1.1 kamil * have been adjusted in frequency. 85 1.1 kamil * Simplified exit sequence, and reduced dependencies on control 86 1.1 kamil * characters. You needn't see the scoreboard if you don't want to. 87 1.1 kamil * Hitting i,w,c, or v switches to Enterprise. Hitting p switches to Base. 88 1.1 kamil * Excessive use of q is not allowed. 89 1.1 kamil * Excessive use of D is not allowed. 90 1.1 kamil * Scoreboard may depend on either full name or login name. 91 1.1 kamil * Integrated scoreboard lister. Login name now shows up on scoreboard. 92 1.1 kamil * "Hidden" startup options are now upper case. 93 1.1 kamil * Checks upon startup for no cursor movement, or screen too small. 94 1.1 kamil * Checks upon startup that WARPDIR is correctly protected, and that warp 95 1.1 kamil * is running setuid. As an additional bonus this prevents root from 96 1.1 kamil * running warp, which mucks things up, UN*X be blessed. 97 1.1 kamil * All gets's turned into fgets's for safety. 98 1.1 kamil * Bonus Enterprises and Bases. 99 1.1 kamil * Escalating bonuses for saving Base and Enterprise. 100 1.1 kamil * Escalating Enterprise energy. 101 1.1 kamil * Turbolasers decrease with distance. 102 1.1 kamil * Really smart enemies can see through stars occasionally. 103 1.1 kamil * Occasional Tholian jackpot waves. Tholians are a trifle nastier. 104 1.1 kamil * Choleric Gorns. 105 1.1 kamil * An O or o can miss seeing you. Enemies can avoid a stationary O, o, or X. 106 1.1 kamil * Warp 3 enemies and other nastinesses are possible in massacre mode. 107 1.1 kamil * Enemies that decide to navigate when they see you can do other things than 108 1.1 kamil * just come toward you. 109 1.1 kamil * Gorns occasionally launch a salvo for the fun of it. 110 1.1 kamil * Only star and enemy explosions can keep the round going now. 111 1.1 kamil * Bounces don't always go back to starting spot now. 112 1.1 kamil * Better full name processing. USG quirks handled. & substitution also 113 1.1 kamil * handled now (whoever dreamed up that one must have been in the middle 114 1.1 kamil * of the night before the morning after). 115 1.1 kamil * Catch ^D on fgets. 116 1.1 kamil * Version number printer. 117 1.1 kamil * Less signal catching during debugging. 118 1.8 rillig * 119 1.1 kamil * Revision 5.4 83/06/24 09:28:38 lwall 120 1.1 kamil * 16 bit random number generators are now supported. 121 1.1 kamil * Made warp not blow up on a null save file. 122 1.1 kamil * Warp now prints E and B before the stars. 123 1.1 kamil * Fixed bug which caused torp count to get decremented even when no torp 124 1.1 kamil * was launched because of an obstacle. 125 1.1 kamil * Put %<n>ld formats where appropriate. 126 1.1 kamil * Fixed E: 0 0 bug on refresh. 127 1.8 rillig * 128 1.1 kamil * Revision 5.3 83/05/24 14:03:10 lwall 129 1.1 kamil * Starting RCS 130 1.8 rillig * 131 1.1 kamil */ 132 1.1 kamil 133 1.1 kamil #include "INTERN.h" 134 1.1 kamil #include "warp.h" 135 1.1 kamil #include "EXTERN.h" 136 1.1 kamil #include "bang.h" 137 1.1 kamil #include "init.h" 138 1.1 kamil #include "intrp.h" 139 1.1 kamil #include "object.h" 140 1.1 kamil #include "move.h" 141 1.1 kamil #include "play.h" 142 1.1 kamil #include "score.h" 143 1.1 kamil #include "sig.h" 144 1.1 kamil #include "term.h" 145 1.1 kamil #include "them.h" 146 1.1 kamil #include "us.h" 147 1.1 kamil #include "util.h" 148 1.1 kamil #include "version.h" 149 1.1 kamil #include "weapon.h" 150 1.1 kamil 151 1.3 kamil int 152 1.4 christos main(int argc, char *argv[]) 153 1.1 kamil { 154 1.1 kamil char tmp, *s, *tcbuf; 155 1.1 kamil 156 1.1 kamil FILE *savfil; 157 1.1 kamil 158 1.1 kamil #ifdef lint /* to suppress "defined but never used" */ 159 1.1 kamil # ifdef SIGTSTP 160 1.1 kamil (void)stop_catcher(); 161 1.1 kamil # endif 162 1.1 kamil # ifdef SIGCONT 163 1.1 kamil (void)cont_catcher(); 164 1.1 kamil # endif 165 1.1 kamil #endif 166 1.1 kamil 167 1.1 kamil while (--argc > 0 && (*++argv)[0] == '-') 168 1.1 kamil for (s = argv[0]+1; *s != '\0'; s++) 169 1.1 kamil switch (*s) { 170 1.1 kamil case '&': 171 1.4 christos amoebaspec = true; 172 1.4 christos beginner = true; 173 1.1 kamil break; 174 1.1 kamil case 'A': 175 1.4 christos apolspec = true; 176 1.4 christos beginner = true; 177 1.1 kamil break; 178 1.1 kamil case 'b': 179 1.4 christos beginner = true; 180 1.1 kamil break; 181 1.1 kamil case 'C': 182 1.4 christos crushspec = true; 183 1.4 christos beginner = true; 184 1.1 kamil break; 185 1.1 kamil case 'D': 186 1.4 christos debugging = true; 187 1.1 kamil #ifdef DEBUGGING 188 1.1 kamil debug = atoi(++s); 189 1.1 kamil #endif 190 1.1 kamil s += strlen(s)-1; 191 1.1 kamil break; 192 1.1 kamil case 'd': 193 1.1 kamil s++; 194 1.1 kamil if (*s == '=') s++; 195 1.1 kamil ismarts = atoi(s); 196 1.1 kamil if (ismarts <= 0) 197 1.1 kamil ismarts = 1; 198 1.1 kamil if (ismarts > 99) 199 1.1 kamil ismarts = 99; 200 1.1 kamil if (ismarts > 40) 201 1.4 christos beginner = true; 202 1.1 kamil s += strlen(s)-1; 203 1.1 kamil break; 204 1.1 kamil case 'E': 205 1.4 christos klingspec = true; 206 1.4 christos beginner = true; 207 1.1 kamil s++; 208 1.1 kamil if (*s == '=') s++; 209 1.1 kamil inumenemies = atoi(s); 210 1.1 kamil s += strlen(s)-1; 211 1.1 kamil break; 212 1.1 kamil case 'F': 213 1.4 christos friendspec = true; 214 1.4 christos beginner = true; 215 1.1 kamil s++; 216 1.1 kamil if (*s == '=') s++; 217 1.1 kamil inumfriends = atoi(s); 218 1.1 kamil s += strlen(s)-1; 219 1.1 kamil break; 220 1.1 kamil case 'G': 221 1.4 christos gornspec = true; 222 1.4 christos beginner = true; 223 1.1 kamil break; 224 1.1 kamil case 'l': 225 1.4 christos lowspeed = true; 226 1.1 kamil break; 227 1.1 kamil case 'm': 228 1.4 christos metakey = true; 229 1.1 kamil break; 230 1.1 kamil case 'M': 231 1.4 christos massacre = true; 232 1.1 kamil break; 233 1.1 kamil case 'P': 234 1.4 christos piratespec = true; 235 1.4 christos beginner = true; 236 1.1 kamil s++; 237 1.1 kamil if (*s == '=') s++; 238 1.1 kamil inumpirates = atoi(s); 239 1.1 kamil s += strlen(s)-1; 240 1.1 kamil break; 241 1.1 kamil case 'S': 242 1.4 christos prespec = true; 243 1.4 christos beginner = true; 244 1.1 kamil s++; 245 1.1 kamil if (*s == '=') s++; 246 1.1 kamil if (*s) 247 1.1 kamil prescene = atoi(s); 248 1.1 kamil else 249 1.1 kamil prescene = -1; 250 1.1 kamil s += strlen(s)-1; 251 1.1 kamil break; 252 1.1 kamil case 'R': 253 1.4 christos romspec = true; 254 1.4 christos beginner = true; 255 1.1 kamil break; 256 1.1 kamil case '*': 257 1.4 christos starspec = true; 258 1.4 christos beginner = true; 259 1.1 kamil s++; 260 1.1 kamil if (*s == '=') s++; 261 1.1 kamil inumstars = atoi(s); 262 1.1 kamil s += strlen(s)-1; 263 1.1 kamil break; 264 1.1 kamil case 's': 265 1.4 christos scorespec = true; 266 1.1 kamil break; 267 1.1 kamil case 'T': 268 1.4 christos tholspec = true; 269 1.4 christos beginner = true; 270 1.1 kamil break; 271 1.1 kamil case 'x': 272 1.4 christos experimenting = true; 273 1.1 kamil break; 274 1.1 kamil case 'v': 275 1.1 kamil version(); 276 1.1 kamil exit(0); 277 1.1 kamil break; 278 1.1 kamil default: 279 1.1 kamil fprintf(stderr,"warp: illegal option %c\n", *s); 280 1.1 kamil fprintf(stderr, "Usage: warp -dn -b -x -v -s\n"); 281 1.1 kamil exit(1); 282 1.1 kamil } 283 1.1 kamil if (argc != 0) { 284 1.1 kamil fprintf(stderr, "Usage: warp -dn -b -x -v -s\n"); 285 1.1 kamil exit(1); 286 1.1 kamil } 287 1.1 kamil bang_init(); 288 1.1 kamil move_init(); 289 1.1 kamil object_init(); 290 1.1 kamil play_init(); 291 1.1 kamil them_init(); 292 1.1 kamil us_init(); 293 1.1 kamil util_init(); 294 1.1 kamil weapon_init(); 295 1.1 kamil 296 1.1 kamil tcbuf = malloc(1024); 297 1.1 kamil intrp_init(tcbuf); 298 1.1 kamil 299 1.1 kamil if (chdir(warplib) < 0) 300 1.4 christos fprintf(stderr,NOCD,warplib); 301 1.1 kamil 302 1.1 kamil term_init(); 303 1.1 kamil 304 1.1 kamil term_set(tcbuf); 305 1.1 kamil free(tcbuf); 306 1.1 kamil 307 1.1 kamil umask(022); /* mustn't rely on incoming umask--could be 033 which */ 308 1.1 kamil /* would disable people from running wscore */ 309 1.1 kamil 310 1.1 kamil score_init(); 311 1.1 kamil 312 1.1 kamil sig_init(); 313 1.1 kamil 314 1.1 kamil if (totalscore) { 315 1.1 kamil clear(); 316 1.1 kamil mvaddstr(12,25,"*** restoring saved game ***"); 317 1.1 kamil roundsleep(1); 318 1.1 kamil } 319 1.1 kamil 320 1.7 christos srandom(getpid()); 321 1.1 kamil 322 1.1 kamil do { 323 1.4 christos for (keepgoing = true;;) { 324 1.1 kamil if (!experimenting) { 325 1.1 kamil if ((savfil = fopen(savefilename,"w")) == NULL) { 326 1.1 kamil resetty(); 327 1.5 christos printf("Can't open savefile `%s'\r\n", savefilename); 328 1.1 kamil finalize(1); 329 1.1 kamil } 330 1.1 kamil fprintf(savfil, 331 1.1 kamil "%-8s %10ld, %2d,%5d,%2d,%2d,%3d %c%c%c%c%c%c%c%c%c\n", 332 1.1 kamil logname, totalscore, smarts, cumsmarts, 333 1.1 kamil numents, numbases, wave, 334 1.1 kamil apolspec ? 'a' : ' ', 335 1.1 kamil beginner ? 'b' : ' ', 336 1.1 kamil crushspec ? 'c' : ' ', 337 1.1 kamil gornspec ? 'g' : ' ', 338 1.1 kamil massacre ? 'm' : ' ', 339 1.1 kamil romspec ? 'r' : ' ', 340 1.1 kamil tholspec ? 't' : ' ', 341 1.1 kamil lowspeed ? 'l' : ' ', 342 1.1 kamil amoebaspec ? '&' : ' ' 343 1.1 kamil ); 344 1.1 kamil fprintf(savfil," running on %s, process #%d\n", 345 1.1 kamil term+5,getpid()); 346 1.4 christos fclose(savfil); 347 1.1 kamil } 348 1.1 kamil 349 1.1 kamil lastscore = totalscore; 350 1.1 kamil initialize(); 351 1.1 kamil play(); 352 1.1 kamil cumsmarts += smarts; 353 1.1 kamil wavescore(); 354 1.1 kamil if (numents<=0 && numbases<=0) 355 1.4 christos keepgoing = false; 356 1.1 kamil if (!keepgoing) break; 357 1.1 kamil do { 358 1.1 kamil if (experimenting) { 359 1.1 kamil mvaddstr(23,15, 360 1.1 kamil " [Hit space to continue, 'q' to quit] "); 361 1.1 kamil } 362 1.1 kamil else { 363 1.1 kamil mvaddstr(23,15, 364 1.1 kamil "[Hit space to continue, 's' to save, 'q' to quit]"); 365 1.1 kamil } 366 1.1 kamil sleep(1); 367 1.4 christos fflush(stdout); 368 1.1 kamil eat_typeahead(); 369 1.1 kamil getcmd(&tmp); 370 1.1 kamil if (tmp == BREAKCH || tmp == INTRCH) { 371 1.1 kamil mvaddstr(23,15, 372 1.1 kamil " "); 373 1.1 kamil mvaddstr(23,33, 374 1.1 kamil "Really quit? "); 375 1.1 kamil getcmd(&tmp); 376 1.1 kamil if (tmp == 'y' || tmp == 'Y') 377 1.1 kamil tmp = 'q'; 378 1.1 kamil else 379 1.1 kamil tmp = 1; 380 1.1 kamil } 381 1.7 christos } while (tmp != INTRCH && tmp != BREAKCH && !strchr(" qQs",tmp)); 382 1.1 kamil if (tmp != ' ' && tmp != 's') break; 383 1.1 kamil if (!beginner && smarts < 20) 384 1.1 kamil smarts += 4; 385 1.1 kamil else if (!beginner && smarts < 35) 386 1.1 kamil smarts += 2; 387 1.1 kamil else if (smarts < 99) 388 1.1 kamil smarts++; 389 1.1 kamil if (tmp == 's') save_game(); 390 1.1 kamil } 391 1.1 kamil score(); 392 1.1 kamil 393 1.1 kamil } while (justonemoretime); 394 1.1 kamil 395 1.1 kamil if (!experimenting) 396 1.1 kamil unlink(savefilename); 397 1.1 kamil 398 1.1 kamil clear(); 399 1.1 kamil resetty(); 400 1.1 kamil exit(0); 401 1.1 kamil } 402