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