xref: /dragonfly/games/battlestar/fly.c (revision d5d36918)
1 /*	@(#)fly.c	8.2 (Berkeley) 4/28/95				*/
2 /*	$NetBSD: fly.c,v 1.15 2012/10/13 19:58:53 dholland 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 "extern.h"
34 #undef UP
35 #include <curses.h>
36 #include <assert.h>
37 
38 #define MIDR  (LINES/2 - 1)
39 #define MIDC  (COLS/2 - 1)
40 
41 static int     row, column;
42 static int     dr = 0, dc = 0;
43 static char    destroyed;
44 int     ourclock = 120;		/* time for all the flights in the game */
45 static char    cross = 0;
46 static sig_t   oldsig;
47 
48 static void blast(void);
49 static void endfly(void);
50 static void moveenemy(int);
51 static void notarget(void);
52 static void screen(void);
53 static void succumb(int);
54 static void target(void);
55 
56 static void
57 succumb(int dummy __unused)
58 {
59 	if (oldsig == SIG_DFL) {
60 		endfly();
61 		exit(1);
62 	}
63 	if (oldsig != SIG_IGN) {
64 		endfly();
65 		(*oldsig) (SIGINT);
66 	}
67 }
68 
69 int
70 visual(void)
71 {
72 	destroyed = 0;
73 	if (initscr() == NULL) {
74 		puts("Whoops!  No more memory...");
75 		return (0);
76 	}
77 	oldsig = signal(SIGINT, succumb);
78 	cbreak();
79 	noecho();
80 	screen();
81 	row = rnd(LINES - 3) + 1;
82 	column = rnd(COLS - 2) + 1;
83 	moveenemy(0);
84 	for (;;) {
85 		switch (getchar()) {
86 
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 				    column > MIDC - 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 (ourclock <= 0) {
171 			endfly();
172 			die();
173 		}
174 	}
175 }
176 
177 static void
178 screen(void)
179 {
180 	int     r, c, n;
181 	int     i;
182 
183 	clear();
184 	i = rnd(100);
185 	for (n = 0; n < i; n++) {
186 		r = rnd(LINES - 3) + 1;
187 		c = rnd(COLS);
188 		mvaddch(r, c, '.');
189 	}
190 	mvaddstr(LINES - 1 - 1, 21, "TORPEDOES           FUEL           TIME");
191 	refresh();
192 }
193 
194 static void
195 target(void)
196 {
197 	int     n;
198 
199 	move(MIDR, MIDC - 10);
200 	addstr("-------   +   -------");
201 	for (n = MIDR - 4; n < MIDR - 1; n++) {
202 		mvaddch(n, MIDC, '|');
203 		mvaddch(n + 6, MIDC, '|');
204 	}
205 }
206 
207 static void
208 notarget(void)
209 {
210 	int     n;
211 
212 	move(MIDR, MIDC - 10);
213 	addstr("                     ");
214 	for (n = MIDR - 4; n < MIDR - 1; n++) {
215 		mvaddch(n, MIDC, ' ');
216 		mvaddch(n + 6, MIDC, ' ');
217 	}
218 }
219 
220 static void
221 blast(void)
222 {
223 	int     n;
224 
225 	alarm(0);
226 	move(LINES - 1, 24);
227 	printw("%3d", torps);
228 	for (n = LINES - 1 - 2; n >= MIDR + 1; n--) {
229 		mvaddch(n, MIDC + MIDR - n, '/');
230 		mvaddch(n, MIDC - MIDR + n, '\\');
231 		refresh();
232 	}
233 	mvaddch(MIDR, MIDC, '*');
234 	for (n = LINES - 1 - 2; n >= MIDR + 1; n--) {
235 		mvaddch(n, MIDC + MIDR - n, ' ');
236 		mvaddch(n, MIDC - MIDR + n, ' ');
237 		refresh();
238 	}
239 	alarm(1);
240 }
241 
242 static void
243 moveenemy(int dummy __unused)
244 {
245 	double  d;
246 	int     oldr, oldc;
247 
248 	oldr = row;
249 	oldc = column;
250 	if (fuel > 0) {
251 		if (row + dr <= LINES - 3 && row + dr > 0)
252 			row += dr;
253 		if (column + dc < COLS - 1 && column + dc > 0)
254 			column += dc;
255 	} else
256 		if (fuel < 0) {
257 			fuel = 0;
258 			mvaddstr(0, 60, "*** Out of fuel ***");
259 		}
260 	d = (double) ((row - MIDR) * (row - MIDR) + (column - MIDC) *
261 	    (column - MIDC));
262 	if (d < 16) {
263 		row += (rnd(9) - 4) % (4 - abs(row - MIDR));
264 		column += (rnd(9) - 4) % (4 - abs(column - MIDC));
265 	}
266 	ourclock--;
267 	mvaddstr(oldr, oldc - 1, "   ");
268 	if (cross)
269 		target();
270 	mvaddstr(row, column - 1, "/-\\");
271 	move(LINES - 1, 24);
272 	printw("%3d", torps);
273 	move(LINES - 1, 42);
274 	printw("%3d", fuel);
275 	move(LINES - 1, 57);
276 	printw("%3d", ourclock);
277 	refresh();
278 	signal(SIGALRM, moveenemy);
279 	alarm(1);
280 }
281 
282 static void
283 endfly(void)
284 {
285 	alarm(0);
286 	signal(SIGALRM, SIG_DFL);
287 	mvcur(0, COLS - 1, LINES - 1, 0);
288 	endwin();
289 	signal(SIGTSTP, SIG_DFL);
290 	signal(SIGINT, oldsig);
291 }
292