a688c43e78b63478965401401b20d564f9950586
[dragonfly.git] / games / battlestar / fly.c
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(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         signal(SIGTSTP, SIG_DFL);
290         signal(SIGINT, oldsig);
291 }