1 /* $NetBSD: graphics.c,v 1.9 1999/09/10 00:16:43 jsm Exp $ */ 2 3 /*- 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Ed James. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. 41 * 42 * Copy permission is hereby granted provided that this notice is 43 * retained on all partial or complete copies. 44 * 45 * For more info on this and all of my stuff, mail edjames@berkeley.edu. 46 */ 47 48 #include <sys/cdefs.h> 49 #ifndef lint 50 #if 0 51 static char sccsid[] = "@(#)graphics.c 8.1 (Berkeley) 5/31/93"; 52 #else 53 __RCSID("$NetBSD: graphics.c,v 1.9 1999/09/10 00:16:43 jsm Exp $"); 54 #endif 55 #endif /* not lint */ 56 57 #include "include.h" 58 59 #define C_TOPBOTTOM '-' 60 #define C_LEFTRIGHT '|' 61 #define C_AIRPORT '=' 62 #define C_LINE '+' 63 #define C_BACKROUND '.' 64 #define C_BEACON '*' 65 #define C_CREDIT '*' 66 67 WINDOW *radar, *cleanradar, *credit, *input, *planes; 68 69 int 70 getAChar() 71 { 72 int c; 73 74 errno = 0; 75 while ((c = getchar()) == EOF && errno == EINTR) { 76 errno = 0; 77 clearerr(stdin); 78 } 79 return(c); 80 } 81 82 void 83 erase_all() 84 { 85 PLANE *pp; 86 87 for (pp = air.head; pp != NULL; pp = pp->next) { 88 wmove(cleanradar, pp->ypos, pp->xpos * 2); 89 wmove(radar, pp->ypos, pp->xpos * 2); 90 waddch(radar, winch(cleanradar)); 91 wmove(cleanradar, pp->ypos, pp->xpos * 2 + 1); 92 wmove(radar, pp->ypos, pp->xpos * 2 + 1); 93 waddch(radar, winch(cleanradar)); 94 } 95 } 96 97 void 98 draw_all() 99 { 100 PLANE *pp; 101 102 for (pp = air.head; pp != NULL; pp = pp->next) { 103 if (pp->status == S_MARKED) 104 wstandout(radar); 105 wmove(radar, pp->ypos, pp->xpos * 2); 106 waddch(radar, name(pp)); 107 waddch(radar, '0' + pp->altitude); 108 if (pp->status == S_MARKED) 109 wstandend(radar); 110 } 111 wrefresh(radar); 112 planewin(); 113 wrefresh(input); /* return cursor */ 114 fflush(stdout); 115 } 116 117 void 118 init_gr() 119 { 120 static char buffer[BUFSIZ]; 121 122 initscr(); 123 setbuf(stdout, buffer); 124 input = newwin(INPUT_LINES, COLS - PLANE_COLS, LINES - INPUT_LINES, 0); 125 credit = newwin(INPUT_LINES, PLANE_COLS, LINES - INPUT_LINES, 126 COLS - PLANE_COLS); 127 planes = newwin(LINES - INPUT_LINES, PLANE_COLS, 0, COLS - PLANE_COLS); 128 } 129 130 void 131 setup_screen(scp) 132 const C_SCREEN *scp; 133 { 134 int i, j; 135 char str[3]; 136 const char *airstr; 137 138 str[2] = '\0'; 139 140 if (radar != NULL) 141 delwin(radar); 142 radar = newwin(scp->height, scp->width * 2, 0, 0); 143 144 if (cleanradar != NULL) 145 delwin(cleanradar); 146 cleanradar = newwin(scp->height, scp->width * 2, 0, 0); 147 148 /* minus one here to prevent a scroll */ 149 for (i = 0; i < PLANE_COLS - 1; i++) { 150 wmove(credit, 0, i); 151 waddch(credit, C_CREDIT); 152 wmove(credit, INPUT_LINES - 1, i); 153 waddch(credit, C_CREDIT); 154 } 155 wmove(credit, INPUT_LINES / 2, 1); 156 waddstr(credit, AUTHOR_STR); 157 158 for (i = 1; i < scp->height - 1; i++) { 159 for (j = 1; j < scp->width - 1; j++) { 160 wmove(radar, i, j * 2); 161 waddch(radar, C_BACKROUND); 162 } 163 } 164 165 /* 166 * Draw the lines first, since people like to draw lines 167 * through beacons and exit points. 168 */ 169 str[0] = C_LINE; 170 for (i = 0; i < scp->num_lines; i++) { 171 str[1] = ' '; 172 draw_line(radar, scp->line[i].p1.x, scp->line[i].p1.y, 173 scp->line[i].p2.x, scp->line[i].p2.y, str); 174 } 175 176 str[0] = C_TOPBOTTOM; 177 str[1] = C_TOPBOTTOM; 178 wmove(radar, 0, 0); 179 for (i = 0; i < scp->width - 1; i++) 180 waddstr(radar, str); 181 waddch(radar, C_TOPBOTTOM); 182 183 str[0] = C_TOPBOTTOM; 184 str[1] = C_TOPBOTTOM; 185 wmove(radar, scp->height - 1, 0); 186 for (i = 0; i < scp->width - 1; i++) 187 waddstr(radar, str); 188 waddch(radar, C_TOPBOTTOM); 189 190 for (i = 1; i < scp->height - 1; i++) { 191 wmove(radar, i, 0); 192 waddch(radar, C_LEFTRIGHT); 193 wmove(radar, i, (scp->width - 1) * 2); 194 waddch(radar, C_LEFTRIGHT); 195 } 196 197 str[0] = C_BEACON; 198 for (i = 0; i < scp->num_beacons; i++) { 199 str[1] = '0' + i; 200 wmove(radar, scp->beacon[i].y, scp->beacon[i].x * 2); 201 waddstr(radar, str); 202 } 203 204 for (i = 0; i < scp->num_exits; i++) { 205 wmove(radar, scp->exit[i].y, scp->exit[i].x * 2); 206 waddch(radar, '0' + i); 207 } 208 209 airstr = "^?>?v?<?"; 210 for (i = 0; i < scp->num_airports; i++) { 211 str[0] = airstr[scp->airport[i].dir]; 212 str[1] = '0' + i; 213 wmove(radar, scp->airport[i].y, scp->airport[i].x * 2); 214 waddstr(radar, str); 215 } 216 217 overwrite(radar, cleanradar); 218 wrefresh(radar); 219 wrefresh(credit); 220 fflush(stdout); 221 } 222 223 void 224 draw_line(w, x, y, lx, ly, s) 225 WINDOW *w; 226 int x, y, lx, ly; 227 const char *s; 228 { 229 int dx, dy; 230 231 dx = SGN(lx - x); 232 dy = SGN(ly - y); 233 for (;;) { 234 wmove(w, y, x * 2); 235 waddstr(w, s); 236 if (x == lx && y == ly) 237 break; 238 x += dx; 239 y += dy; 240 } 241 } 242 243 void 244 ioclrtoeol(pos) 245 int pos; 246 { 247 wmove(input, 0, pos); 248 wclrtoeol(input); 249 wrefresh(input); 250 fflush(stdout); 251 } 252 253 void 254 iomove(pos) 255 int pos; 256 { 257 wmove(input, 0, pos); 258 wrefresh(input); 259 fflush(stdout); 260 } 261 262 void 263 ioaddstr(pos, str) 264 int pos; 265 const char *str; 266 { 267 wmove(input, 0, pos); 268 waddstr(input, str); 269 wrefresh(input); 270 fflush(stdout); 271 } 272 273 void 274 ioclrtobot() 275 { 276 wclrtobot(input); 277 wrefresh(input); 278 fflush(stdout); 279 } 280 281 void 282 ioerror(pos, len, str) 283 int pos, len; 284 const char *str; 285 { 286 int i; 287 288 wmove(input, 1, pos); 289 for (i = 0; i < len; i++) 290 waddch(input, '^'); 291 wmove(input, 2, 0); 292 waddstr(input, str); 293 wrefresh(input); 294 fflush(stdout); 295 } 296 297 void 298 quit(dummy) 299 int dummy __attribute__((__unused__)); 300 { 301 int c, y, x; 302 #ifdef BSD 303 struct itimerval itv; 304 #endif 305 306 getyx(input, y, x); 307 wmove(input, 2, 0); 308 waddstr(input, "Really quit? (y/n) "); 309 wclrtobot(input); 310 wrefresh(input); 311 fflush(stdout); 312 313 c = getchar(); 314 if (c == EOF || c == 'y') { 315 /* disable timer */ 316 #ifdef BSD 317 itv.it_value.tv_sec = 0; 318 itv.it_value.tv_usec = 0; 319 setitimer(ITIMER_REAL, &itv, NULL); 320 #endif 321 #ifdef SYSV 322 alarm(0); 323 #endif 324 fflush(stdout); 325 clear(); 326 refresh(); 327 endwin(); 328 log_score(0); 329 exit(0); 330 } 331 wmove(input, 2, 0); 332 wclrtobot(input); 333 wmove(input, y, x); 334 wrefresh(input); 335 fflush(stdout); 336 } 337 338 void 339 planewin() 340 { 341 PLANE *pp; 342 int warning = 0; 343 344 #ifdef BSD 345 wclear(planes); 346 #endif 347 348 wmove(planes, 0,0); 349 350 #ifdef SYSV 351 wclrtobot(planes); 352 #endif 353 wprintw(planes, "Time: %-4d Safe: %d", clck, safe_planes); 354 wmove(planes, 2, 0); 355 356 waddstr(planes, "pl dt comm"); 357 for (pp = air.head; pp != NULL; pp = pp->next) { 358 if (waddch(planes, '\n') == ERR) { 359 warning++; 360 break; 361 } 362 waddstr(planes, command(pp)); 363 } 364 waddch(planes, '\n'); 365 for (pp = ground.head; pp != NULL; pp = pp->next) { 366 if (waddch(planes, '\n') == ERR) { 367 warning++; 368 break; 369 } 370 waddstr(planes, command(pp)); 371 } 372 if (warning) { 373 wmove(planes, LINES - INPUT_LINES - 1, 0); 374 waddstr(planes, "---- more ----"); 375 wclrtoeol(planes); 376 } 377 wrefresh(planes); 378 fflush(stdout); 379 } 380 381 void 382 loser(p, s) 383 const PLANE *p; 384 const char *s; 385 { 386 int c; 387 #ifdef BSD 388 struct itimerval itv; 389 #endif 390 391 /* disable timer */ 392 #ifdef BSD 393 itv.it_value.tv_sec = 0; 394 itv.it_value.tv_usec = 0; 395 setitimer(ITIMER_REAL, &itv, NULL); 396 #endif 397 #ifdef SYSV 398 alarm(0); 399 #endif 400 401 wmove(input, 0, 0); 402 wclrtobot(input); 403 /* p may be NULL if we ran out of memory */ 404 if (p == NULL) 405 wprintw(input, "%s\n\nHit space for top players list...", s); 406 else 407 wprintw(input, "Plane '%c' %s\n\nHit space for top players list...", 408 name(p), s); 409 wrefresh(input); 410 fflush(stdout); 411 while ((c = getchar()) != EOF && c != ' ') 412 ; 413 clear(); /* move to top of screen */ 414 refresh(); 415 endwin(); 416 log_score(0); 417 exit(0); 418 } 419 420 void 421 redraw() 422 { 423 clear(); 424 refresh(); 425 426 touchwin(radar); 427 wrefresh(radar); 428 touchwin(planes); 429 wrefresh(planes); 430 touchwin(credit); 431 wrefresh(credit); 432 433 /* refresh input last to get cursor in right place */ 434 touchwin(input); 435 wrefresh(input); 436 fflush(stdout); 437 } 438 439 void 440 done_screen() 441 { 442 clear(); 443 refresh(); 444 endwin(); /* clean up curses */ 445 } 446