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