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
45int     ourclock = 120;	/* time for all the flights in the game */
46
47static int     row, column;
48static int     dr = 0, dc = 0;
49static char    destroyed;
50static char    cross = 0;
51static sig_t   oldsig;
52
53static void blast(void);
54static void endfly(void);
55static void moveenemy(int);
56static void notarget(void);
57static void screen(void);
58static void succumb(int);
59static void target(void);
60
61static void
62succumb(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
74int
75visual(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
181static void
182screen(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
198static void
199target(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
211static void
212notarget(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
224static void
225blast(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
246static void
247moveenemy(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
285static void
286endfly(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