xref: /original-bsd/games/atc/graphics.c (revision 42f60e33)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Ed James.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 /*
12  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
13  *
14  * Copy permission is hereby granted provided that this notice is
15  * retained on all partial or complete copies.
16  *
17  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
18  */
19 
20 #ifndef lint
21 static char sccsid[] = "@(#)graphics.c	8.1 (Berkeley) 05/31/93";
22 #endif /* not lint */
23 
24 #include "include.h"
25 #ifdef SYSV
26 #include <errno.h>
27 #endif
28 
29 #define C_TOPBOTTOM		'-'
30 #define C_LEFTRIGHT		'|'
31 #define C_AIRPORT		'='
32 #define C_LINE			'+'
33 #define C_BACKROUND		'.'
34 #define C_BEACON		'*'
35 #define C_CREDIT		'*'
36 
37 WINDOW	*radar, *cleanradar, *credit, *input, *planes;
38 
39 getAChar()
40 {
41 #ifdef BSD
42 	return (getchar());
43 #endif
44 #ifdef SYSV
45 	int c;
46 
47 	while ((c = getchar()) == -1 && errno == EINTR) ;
48 	return(c);
49 #endif
50 }
51 
52 erase_all()
53 {
54 	PLANE	*pp;
55 
56 	for (pp = air.head; pp != NULL; pp = pp->next) {
57 		wmove(cleanradar, pp->ypos, pp->xpos * 2);
58 		wmove(radar, pp->ypos, pp->xpos * 2);
59 		waddch(radar, winch(cleanradar));
60 		wmove(cleanradar, pp->ypos, pp->xpos * 2 + 1);
61 		wmove(radar, pp->ypos, pp->xpos * 2 + 1);
62 		waddch(radar, winch(cleanradar));
63 	}
64 }
65 
66 draw_all()
67 {
68 	PLANE	*pp;
69 
70 	for (pp = air.head; pp != NULL; pp = pp->next) {
71 		if (pp->status == S_MARKED)
72 			wstandout(radar);
73 		wmove(radar, pp->ypos, pp->xpos * 2);
74 		waddch(radar, name(pp));
75 		waddch(radar, '0' + pp->altitude);
76 		if (pp->status == S_MARKED)
77 			wstandend(radar);
78 	}
79 	wrefresh(radar);
80 	planewin();
81 	wrefresh(input);		/* return cursor */
82 	fflush(stdout);
83 }
84 
85 init_gr()
86 {
87 	static char	buffer[BUFSIZ];
88 
89 	initscr();
90 	setbuf(stdout, buffer);
91 	input = newwin(INPUT_LINES, COLS - PLANE_COLS, LINES - INPUT_LINES, 0);
92 	credit = newwin(INPUT_LINES, PLANE_COLS, LINES - INPUT_LINES,
93 		COLS - PLANE_COLS);
94 	planes = newwin(LINES - INPUT_LINES, PLANE_COLS, 0, COLS - PLANE_COLS);
95 }
96 
97 setup_screen(scp)
98 	C_SCREEN	*scp;
99 {
100 	register int	i, j;
101 	char		str[3], *airstr;
102 
103 	str[2] = '\0';
104 
105 	if (radar != NULL)
106 		delwin(radar);
107 	radar = newwin(scp->height, scp->width * 2, 0, 0);
108 
109 	if (cleanradar != NULL)
110 		delwin(cleanradar);
111 	cleanradar = newwin(scp->height, scp->width * 2, 0, 0);
112 
113 	/* minus one here to prevent a scroll */
114 	for (i = 0; i < PLANE_COLS - 1; i++) {
115 		wmove(credit, 0, i);
116 		waddch(credit, C_CREDIT);
117 		wmove(credit, INPUT_LINES - 1, i);
118 		waddch(credit, C_CREDIT);
119 	}
120 	wmove(credit, INPUT_LINES / 2, 1);
121 	waddstr(credit, AUTHOR_STR);
122 
123 	for (i = 1; i < scp->height - 1; i++) {
124 		for (j = 1; j < scp->width - 1; j++) {
125 			wmove(radar, i, j * 2);
126 			waddch(radar, C_BACKROUND);
127 		}
128 	}
129 
130 	/*
131 	 * Draw the lines first, since people like to draw lines
132 	 * through beacons and exit points.
133 	 */
134 	str[0] = C_LINE;
135 	for (i = 0; i < scp->num_lines; i++) {
136 		str[1] = ' ';
137 		draw_line(radar, scp->line[i].p1.x, scp->line[i].p1.y,
138 			scp->line[i].p2.x, scp->line[i].p2.y, str);
139 	}
140 
141 	str[0] = C_TOPBOTTOM;
142 	str[1] = C_TOPBOTTOM;
143 	wmove(radar, 0, 0);
144 	for (i = 0; i < scp->width - 1; i++)
145 		waddstr(radar, str);
146 	waddch(radar, C_TOPBOTTOM);
147 
148 	str[0] = C_TOPBOTTOM;
149 	str[1] = C_TOPBOTTOM;
150 	wmove(radar, scp->height - 1, 0);
151 	for (i = 0; i < scp->width - 1; i++)
152 		waddstr(radar, str);
153 	waddch(radar, C_TOPBOTTOM);
154 
155 	for (i = 1; i < scp->height - 1; i++) {
156 		wmove(radar, i, 0);
157 		waddch(radar, C_LEFTRIGHT);
158 		wmove(radar, i, (scp->width - 1) * 2);
159 		waddch(radar, C_LEFTRIGHT);
160 	}
161 
162 	str[0] = C_BEACON;
163 	for (i = 0; i < scp->num_beacons; i++) {
164 		str[1] = '0' + i;
165 		wmove(radar, scp->beacon[i].y, scp->beacon[i].x * 2);
166 		waddstr(radar, str);
167 	}
168 
169 	for (i = 0; i < scp->num_exits; i++) {
170 		wmove(radar, scp->exit[i].y, scp->exit[i].x * 2);
171 		waddch(radar, '0' + i);
172 	}
173 
174 	airstr = "^?>?v?<?";
175 	for (i = 0; i < scp->num_airports; i++) {
176 		str[0] = airstr[scp->airport[i].dir];
177 		str[1] = '0' + i;
178 		wmove(radar, scp->airport[i].y, scp->airport[i].x * 2);
179 		waddstr(radar, str);
180 	}
181 
182 	overwrite(radar, cleanradar);
183 	wrefresh(radar);
184 	wrefresh(credit);
185 	fflush(stdout);
186 }
187 
188 draw_line(w, x, y, lx, ly, s)
189 	WINDOW	*w;
190 	char	*s;
191 {
192 	int	dx, dy;
193 
194 	dx = SGN(lx - x);
195 	dy = SGN(ly - y);
196 	for (;;) {
197 		wmove(w, y, x * 2);
198 		waddstr(w, s);
199 		if (x == lx && y == ly)
200 			break;
201 		x += dx;
202 		y += dy;
203 	}
204 }
205 
206 ioclrtoeol(pos)
207 {
208 	wmove(input, 0, pos);
209 	wclrtoeol(input);
210 	wrefresh(input);
211 	fflush(stdout);
212 }
213 
214 iomove(pos)
215 {
216 	wmove(input, 0, pos);
217 	wrefresh(input);
218 	fflush(stdout);
219 }
220 
221 ioaddstr(pos, str)
222 	char	*str;
223 {
224 	wmove(input, 0, pos);
225 	waddstr(input, str);
226 	wrefresh(input);
227 	fflush(stdout);
228 }
229 
230 ioclrtobot()
231 {
232 	wclrtobot(input);
233 	wrefresh(input);
234 	fflush(stdout);
235 }
236 
237 ioerror(pos, len, str)
238 	char	*str;
239 {
240 	int	i;
241 
242 	wmove(input, 1, pos);
243 	for (i = 0; i < len; i++)
244 		waddch(input, '^');
245 	wmove(input, 2, 0);
246 	waddstr(input, str);
247 	wrefresh(input);
248 	fflush(stdout);
249 }
250 
251 quit()
252 {
253 	int			c, y, x;
254 #ifdef BSD
255 	struct itimerval	itv;
256 #endif
257 
258 	getyx(input, y, x);
259 	wmove(input, 2, 0);
260 	waddstr(input, "Really quit? (y/n) ");
261 	wclrtobot(input);
262 	wrefresh(input);
263 	fflush(stdout);
264 
265 	c = getchar();
266 	if (c == EOF || c == 'y') {
267 		/* disable timer */
268 #ifdef BSD
269 		itv.it_value.tv_sec = 0;
270 		itv.it_value.tv_usec = 0;
271 		setitimer(ITIMER_REAL, &itv, NULL);
272 #endif
273 #ifdef SYSV
274 		alarm(0);
275 #endif
276 		fflush(stdout);
277 		clear();
278 		refresh();
279 		endwin();
280 		log_score(0);
281 		exit(0);
282 	}
283 	wmove(input, 2, 0);
284 	wclrtobot(input);
285 	wmove(input, y, x);
286 	wrefresh(input);
287 	fflush(stdout);
288 	return;
289 }
290 
291 planewin()
292 {
293 	PLANE	*pp;
294 	char	*command();
295 	int	warning = 0;
296 
297 #ifdef BSD
298 	wclear(planes);
299 #endif
300 
301 	wmove(planes, 0,0);
302 
303 #ifdef SYSV
304 	wclrtobot(planes);
305 #endif
306 	wprintw(planes, "Time: %-4d Safe: %d", clck, safe_planes);
307 	wmove(planes, 2, 0);
308 
309 	waddstr(planes, "pl dt  comm");
310 	for (pp = air.head; pp != NULL; pp = pp->next) {
311 		if (waddch(planes, '\n') == ERR) {
312 			warning++;
313 			break;
314 		}
315 		waddstr(planes, command(pp));
316 	}
317 	waddch(planes, '\n');
318 	for (pp = ground.head; pp != NULL; pp = pp->next) {
319 		if (waddch(planes, '\n') == ERR) {
320 			warning++;
321 			break;
322 		}
323 		waddstr(planes, command(pp));
324 	}
325 	if (warning) {
326 		wmove(planes, LINES - INPUT_LINES - 1, 0);
327 		waddstr(planes, "---- more ----");
328 		wclrtoeol(planes);
329 	}
330 	wrefresh(planes);
331 	fflush(stdout);
332 }
333 
334 loser(p, s)
335 	PLANE	*p;
336 	char	*s;
337 {
338 	int			c;
339 #ifdef BSD
340 	struct itimerval	itv;
341 #endif
342 
343 	/* disable timer */
344 #ifdef BSD
345 	itv.it_value.tv_sec = 0;
346 	itv.it_value.tv_usec = 0;
347 	setitimer(ITIMER_REAL, &itv, NULL);
348 #endif
349 #ifdef SYSV
350 	alarm(0);
351 #endif
352 
353 	wmove(input, 0, 0);
354 	wclrtobot(input);
355 	wprintw(input, "Plane '%c' %s\n\nHit space for top players list...",
356 		name(p), s);
357 	wrefresh(input);
358 	fflush(stdout);
359 	while ((c = getchar()) != EOF && c != ' ')
360 		;
361 	clear();	/* move to top of screen */
362 	refresh();
363 	endwin();
364 	log_score(0);
365 	exit(0);
366 }
367 
368 redraw()
369 {
370 	clear();
371 	refresh();
372 
373 	touchwin(radar);
374 	wrefresh(radar);
375 	touchwin(planes);
376 	wrefresh(planes);
377 	touchwin(credit);
378 	wrefresh(credit);
379 
380 	/* refresh input last to get cursor in right place */
381 	touchwin(input);
382 	wrefresh(input);
383 	fflush(stdout);
384 }
385 
386 
387 done_screen()
388 {
389 	clear();
390 	refresh();
391 	endwin();	  /* clean up curses */
392 }
393