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