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