1 /* $OpenBSD: fly.c,v 1.14 2015/12/31 17:51:19 mestre 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. 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 <curses.h>
34 #include <signal.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37
38 #include "extern.h"
39
40 #undef UP
41
42 #define MIDR (LINES/2 - 1)
43 #define MIDC (COLS/2 - 1)
44
45 int ourclock = 120; /* time for all the flights in the game */
46
47 static int row, column;
48 static int dr = 0, dc = 0;
49 static char destroyed;
50 static char cross = 0;
51 static 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 screen(void);
58 static void succumb(int);
59 static void target(void);
60
61 static void
succumb(int sigraised)62 succumb(int sigraised)
63 {
64 if (oldsig == SIG_DFL) {
65 endfly();
66 exit(1);
67 }
68 if (oldsig != SIG_IGN) {
69 endfly();
70 (*oldsig)(SIGINT);
71 }
72 }
73
74 int
visual(void)75 visual(void)
76 {
77 destroyed = 0;
78 if (initscr() == NULL) {
79 puts("Whoops! No more memory...");
80 return (0);
81 }
82 oldsig = signal(SIGINT, succumb);
83 cbreak();
84 noecho();
85 screen();
86 row = rnd(LINES - 3) + 1;
87 column = rnd(COLS - 2) + 1;
88 moveenemy(0);
89 for (;;) {
90 switch (getchar()) {
91
92 case 'h':
93 case 'r':
94 dc = -1;
95 fuel--;
96 break;
97
98 case 'H':
99 case 'R':
100 dc = -5;
101 fuel -= 10;
102 break;
103
104 case 'l':
105 dc = 1;
106 fuel--;
107 break;
108
109 case 'L':
110 dc = 5;
111 fuel -= 10;
112 break;
113
114 case 'j':
115 case 'u':
116 dr = 1;
117 fuel--;
118 break;
119
120 case 'J':
121 case 'U':
122 dr = 5;
123 fuel -= 10;
124 break;
125
126 case 'k':
127 case 'd':
128 dr = -1;
129 fuel--;
130 break;
131
132 case 'K':
133 case 'D':
134 dr = -5;
135 fuel -= 10;
136 break;
137
138 case '+':
139 if (cross) {
140 cross = 0;
141 notarget();
142 } else
143 cross = 1;
144 break;
145
146 case ' ':
147 case 'f':
148 if (torps) {
149 torps -= 2;
150 blast();
151 if (row == MIDR && column - MIDC < 2 && MIDC - column < 2) {
152 destroyed = 1;
153 alarm(0);
154 }
155 } else
156 mvaddstr(0, 0, "*** Out of torpedoes. ***");
157 break;
158
159 case 'q':
160 endfly();
161 return (0);
162
163 default:
164 mvaddstr(0, 26, "Commands = r,R,l,L,u,U,d,D,f,+,q");
165 continue;
166
167 case EOF:
168 break;
169 }
170 if (destroyed) {
171 endfly();
172 return (1);
173 }
174 if (ourclock <= 0) {
175 endfly();
176 die(0);
177 }
178 }
179 }
180
181 static void
screen(void)182 screen(void)
183 {
184 int r, c, n;
185 int i;
186
187 clear();
188 i = rnd(100);
189 for (n = 0; n < i; n++) {
190 r = rnd(LINES - 3) + 1;
191 c = rnd(COLS);
192 mvaddch(r, c, '.');
193 }
194 mvaddstr(LINES - 1 - 1, 21, "TORPEDOES FUEL TIME");
195 refresh();
196 }
197
198 static void
target(void)199 target(void)
200 {
201 int n;
202
203 move(MIDR, MIDC - 10);
204 addstr("------- + -------");
205 for (n = MIDR - 4; n < MIDR - 1; n++) {
206 mvaddch(n, MIDC, '|');
207 mvaddch(n + 6, MIDC, '|');
208 }
209 }
210
211 static void
notarget(void)212 notarget(void)
213 {
214 int n;
215
216 move(MIDR, MIDC - 10);
217 addstr(" ");
218 for (n = MIDR - 4; n < MIDR - 1; n++) {
219 mvaddch(n, MIDC, ' ');
220 mvaddch(n + 6, MIDC, ' ');
221 }
222 }
223
224 static void
blast(void)225 blast(void)
226 {
227 int n;
228
229 alarm(0);
230 move(LINES - 1, 24);
231 printw("%3d", torps);
232 for(n = LINES - 1 - 2; n >= MIDR + 1; n--) {
233 mvaddch(n, MIDC + MIDR - n, '/');
234 mvaddch(n, MIDC - MIDR + n, '\\');
235 refresh();
236 }
237 mvaddch(MIDR, MIDC, '*');
238 for (n = LINES - 1 - 2; n >= MIDR + 1; n--) {
239 mvaddch(n, MIDC + MIDR - n, ' ');
240 mvaddch(n, MIDC - MIDR + n, ' ');
241 refresh();
242 }
243 alarm(1);
244 }
245
246 static void
moveenemy(int sigraised)247 moveenemy(int sigraised)
248 {
249 double d;
250 int oldr, oldc;
251
252 oldr = row;
253 oldc = column;
254 if (fuel > 0) {
255 if (row + dr <= LINES - 3 && row + dr > 0)
256 row += dr;
257 if (column + dc < COLS - 1 && column + dc > 0)
258 column += dc;
259 } else
260 if (fuel < 0) {
261 fuel = 0;
262 mvaddstr(0, 60, "*** Out of fuel ***");
263 }
264 d = (double) ((row - MIDR) * (row - MIDR) + (column - MIDC) * (column - MIDC));
265 if (d < 16) {
266 row += (rnd(9) - 4) % (4 - abs(row - MIDR));
267 column += (rnd(9) - 4) % (4 - abs(column - MIDC));
268 }
269 ourclock--;
270 mvaddstr(oldr, oldc - 1, " ");
271 if (cross)
272 target();
273 mvaddstr(row, column - 1, "/-\\");
274 move(LINES - 1, 24);
275 printw("%3d", torps);
276 move(LINES - 1, 42);
277 printw("%3d", fuel);
278 move(LINES - 1, 57);
279 printw("%3d", ourclock);
280 refresh();
281 signal(SIGALRM, moveenemy);
282 alarm(1);
283 }
284
285 static void
endfly(void)286 endfly(void)
287 {
288 alarm(0);
289 signal(SIGALRM, SIG_DFL);
290 mvcur(0, COLS - 1, LINES - 1, 0);
291 endwin();
292 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
293 signal(SIGTSTP, SIG_DFL);
294 signal(SIGINT, oldsig);
295 }
296