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