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