xref: /dragonfly/games/battlestar/fly.c (revision 0066c2fb)
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  */
32 
33 #include "externs.h"
34 #undef UP
35 #include <curses.h>
36 
37 #define MIDR  (LINES / 2 - 1)
38 #define MIDC  (COLS / 2 - 1)
39 
40 int row, column;
41 int dr = 0, dc = 0;
42 char destroyed;
43 int gclock = 120;               /* gtime for all the flights in the game */
44 char cross = 0;
45 sig_t oldsig;
46 
47 static void     blast(void);
48 static void     endfly(void);
49 static void     moveenemy(int);
50 static void     notarget(void);
51 static void     succumb(int);
52 static void     screen(void);
53 static void     target(void);
54 
55 static void
56 succumb(int sig __unused)
57 {
58 	if (oldsig == SIG_DFL) {
59 		endfly();
60 		exit(1);
61 	}
62 	if (oldsig != SIG_IGN) {
63 		endfly();
64 		(*oldsig)(SIGINT);
65 	}
66 }
67 
68 int
69 visual(void)
70 {
71 	destroyed = 0;
72 	if (initscr() == NULL) {
73 		puts("Whoops!  No more memory...");
74 		return (0);
75 	}
76 	oldsig = signal(SIGINT, succumb);
77 	cbreak();
78 	noecho();
79 	screen();
80 	row = rnd(LINES - 3) + 1;
81 	column = rnd(COLS - 2) + 1;
82 	moveenemy(0);
83 	for (;;) {
84 		switch (getchar()) {
85 		case 'h':
86 		case 'r':
87 			dc = -1;
88 			fuel--;
89 			break;
90 
91 		case 'H':
92 		case 'R':
93 			dc = -5;
94 			fuel -= 10;
95 			break;
96 
97 		case 'l':
98 			dc = 1;
99 			fuel--;
100 			break;
101 
102 		case 'L':
103 			dc = 5;
104 			fuel -= 10;
105 			break;
106 
107 		case 'j':
108 		case 'u':
109 			dr = 1;
110 			fuel--;
111 			break;
112 
113 		case 'J':
114 		case 'U':
115 			dr = 5;
116 			fuel -= 10;
117 			break;
118 
119 		case 'k':
120 		case 'd':
121 			dr = -1;
122 			fuel--;
123 			break;
124 
125 		case 'K':
126 		case 'D':
127 			dr = -5;
128 			fuel -= 10;
129 			break;
130 
131 		case '+':
132 			if (cross) {
133 				cross = 0;
134 				notarget();
135 			} else
136 				cross = 1;
137 			break;
138 
139 		case ' ':
140 		case 'f':
141 			if (torps) {
142 				torps -= 2;
143 				blast();
144 				if (row == MIDR && column - MIDC < 2 &&
145 				    MIDC - column < 2) {
146 					destroyed = 1;
147 					alarm(0);
148 				}
149 			} else
150 				mvaddstr(0, 0, "*** Out of torpedoes. ***");
151 			break;
152 
153 		case 'q':
154 			endfly();
155 			return (0);
156 
157 		default:
158 			mvaddstr(0, 26, "Commands = r,R,l,L,u,U,d,D,f,+,q");
159 			continue;
160 
161 		case EOF:
162 			break;
163 		}
164 		if (destroyed) {
165 			endfly();
166 			return (1);
167 		}
168 		if (gclock <= 0) {
169 			endfly();
170 			die(0);
171 		}
172 	}
173 	/* NOTREACHED */
174 	return (1);
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((char *)(uintptr_t)(const void *)"%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(__unused int sig)
244 {
245 	double d;
246 	int oldr, oldc;
247 
248 	sig = 0;
249 	oldr = row;
250 	oldc = column;
251 	if (fuel > 0) {
252 		if (row + dr <= LINES - 3 && row + dr > 0)
253 			row += dr;
254 		if (column + dc < COLS - 1 && column + dc > 0)
255 			column += dc;
256 	} else 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 	gclock--;
267 	mvaddstr(oldr, oldc - 1, "   ");
268 	if (cross)
269 		target();
270 	mvaddstr(row, column - 1, "/-\\");
271 	move(LINES - 1, 24);
272 	printw((char *)(uintptr_t)(const void *)"%3d", torps);
273 	move(LINES - 1, 42);
274 	printw((char *)(uintptr_t)(const void *)"%3d", fuel);
275 	move(LINES - 1, 57);
276 	printw((char *)(uintptr_t)(const void *)"%3d", gclock);
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 	setlinebuf(stdout);
290 	signal(SIGTSTP, SIG_DFL);
291 	signal(SIGINT, oldsig);
292 }
293