graphics.c 8.8 KB

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