1/* $NetBSD: fly.c,v 1.16 2021/05/02 12:50:43 rillig Exp $ */ 2 3/* 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33#ifndef lint 34#if 0 35static char sccsid[] = "@(#)fly.c 8.2 (Berkeley) 4/28/95"; 36#else 37__RCSID("$NetBSD: fly.c,v 1.16 2021/05/02 12:50:43 rillig Exp $"); 38#endif 39#endif /* not lint */ 40 41#include "extern.h" 42#undef UP 43#include <curses.h> 44#include <assert.h> 45 46#define MIDR (LINES/2 - 1) 47#define MIDC (COLS/2 - 1) 48 49static int row, column; 50static int dr = 0, dc = 0; 51static char destroyed; 52int ourclock = 120; /* time for all the flights in the game */ 53static char cross = 0; 54static sig_t oldsig; 55 56static void blast(void); 57static void endfly(void); 58static void moveenemy(int); 59static void notarget(void); 60static void screen(void); 61static void succumb(int); 62static void target(void); 63 64static void 65succumb(int dummy __unused) 66{ 67 if (oldsig == SIG_DFL) { 68 endfly(); 69 exit(1); 70 } 71 if (oldsig != SIG_IGN) { 72 endfly(); 73 (*oldsig) (SIGINT); 74 } 75} 76 77int 78visual(void) 79{ 80 destroyed = 0; 81 if (initscr() == NULL) { 82 puts("Whoops! No more memory..."); 83 return (0); 84 } 85 oldsig = signal(SIGINT, succumb); 86 cbreak(); 87 noecho(); 88 screen(); 89 row = rnd(LINES - 3) + 1; 90 column = rnd(COLS - 2) + 1; 91 moveenemy(0); 92 for (;;) { 93 switch (getchar()) { 94 95 case 'h': 96 case 'r': 97 dc = -1; 98 fuel--; 99 break; 100 101 case 'H': 102 case 'R': 103 dc = -5; 104 fuel -= 10; 105 break; 106 107 case 'l': 108 dc = 1; 109 fuel--; 110 break; 111 112 case 'L': 113 dc = 5; 114 fuel -= 10; 115 break; 116 117 case 'j': 118 case 'u': 119 dr = 1; 120 fuel--; 121 break; 122 123 case 'J': 124 case 'U': 125 dr = 5; 126 fuel -= 10; 127 break; 128 129 case 'k': 130 case 'd': 131 dr = -1; 132 fuel--; 133 break; 134 135 case 'K': 136 case 'D': 137 dr = -5; 138 fuel -= 10; 139 break; 140 141 case '+': 142 if (cross) { 143 cross = 0; 144 notarget(); 145 } else 146 cross = 1; 147 break; 148 149 case ' ': 150 case 'f': 151 if (torps) { 152 torps -= 2; 153 blast(); 154 if (row == MIDR && column < MIDC + 2 && 155 column > MIDC - 2) { 156 destroyed = 1; 157 alarm(0); 158 } 159 } else 160 mvaddstr(0, 0, "*** Out of torpedoes. ***"); 161 break; 162 163 case 'q': 164 endfly(); 165 return (0); 166 167 default: 168 mvaddstr(0, 26, "Commands = r,R,l,L,u,U,d,D,f,+,q"); 169 continue; 170 171 case EOF: 172 break; 173 } 174 if (destroyed) { 175 endfly(); 176 return (1); 177 } 178 if (ourclock <= 0) { 179 endfly(); 180 die(); 181 } 182 } 183} 184 185static void 186screen(void) 187{ 188 int r, c, n; 189 int i; 190 191 clear(); 192 i = rnd(100); 193 for (n = 0; n < i; n++) { 194 r = rnd(LINES - 3) + 1; 195 c = rnd(COLS); 196 mvaddch(r, c, '.'); 197 } 198 mvaddstr(LINES - 1 - 1, 21, "TORPEDOES FUEL TIME"); 199 refresh(); 200} 201 202static void 203target(void) 204{ 205 int n; 206 207 move(MIDR, MIDC - 10); 208 addstr("------- + -------"); 209 for (n = MIDR - 4; n < MIDR - 1; n++) { 210 mvaddch(n, MIDC, '|'); 211 mvaddch(n + 6, MIDC, '|'); 212 } 213} 214 215static void 216notarget(void) 217{ 218 int n; 219 220 move(MIDR, MIDC - 10); 221 addstr(" "); 222 for (n = MIDR - 4; n < MIDR - 1; n++) { 223 mvaddch(n, MIDC, ' '); 224 mvaddch(n + 6, MIDC, ' '); 225 } 226} 227 228static void 229blast(void) 230{ 231 int n; 232 233 alarm(0); 234 move(LINES - 1, 24); 235 printw("%3d", torps); 236 for (n = LINES - 1 - 2; n >= MIDR + 1; n--) { 237 mvaddch(n, MIDC + MIDR - n, '/'); 238 mvaddch(n, MIDC - MIDR + n, '\\'); 239 refresh(); 240 } 241 mvaddch(MIDR, MIDC, '*'); 242 for (n = LINES - 1 - 2; n >= MIDR + 1; n--) { 243 mvaddch(n, MIDC + MIDR - n, ' '); 244 mvaddch(n, MIDC - MIDR + n, ' '); 245 refresh(); 246 } 247 alarm(1); 248} 249 250static void 251moveenemy(int dummy __unused) 252{ 253 double d; 254 int oldr, oldc; 255 256 oldr = row; 257 oldc = column; 258 if (fuel > 0) { 259 if (row + dr <= LINES - 3 && row + dr > 0) 260 row += dr; 261 if (column + dc < COLS - 1 && column + dc > 0) 262 column += dc; 263 } else 264 if (fuel < 0) { 265 fuel = 0; 266 mvaddstr(0, 60, "*** Out of fuel ***"); 267 } 268 d = (double) ((row - MIDR) * (row - MIDR) + (column - MIDC) * 269 (column - MIDC)); 270 if (d < 16) { 271 row += (rnd(9) - 4) % (4 - abs(row - MIDR)); 272 column += (rnd(9) - 4) % (4 - abs(column - MIDC)); 273 } 274 ourclock--; 275 mvaddstr(oldr, oldc - 1, " "); 276 if (cross) 277 target(); 278 mvaddstr(row, column - 1, "/-\\"); 279 move(LINES - 1, 24); 280 printw("%3d", torps); 281 move(LINES - 1, 42); 282 printw("%3d", fuel); 283 move(LINES - 1, 57); 284 printw("%3d", ourclock); 285 refresh(); 286 signal(SIGALRM, moveenemy); 287 alarm(1); 288} 289 290static void 291endfly(void) 292{ 293 alarm(0); 294 signal(SIGALRM, SIG_DFL); 295 mvcur(0, COLS - 1, LINES - 1, 0); 296 endwin(); 297 signal(SIGTSTP, SIG_DFL); 298 signal(SIGINT, oldsig); 299} 300