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