pl_7.c revision 1.14 1 /* $NetBSD: pl_7.c,v 1.14 2000/01/31 11:08:53 jsm Exp $ */
2
3 /*
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)pl_7.c 8.1 (Berkeley) 5/31/93";
40 #else
41 __RCSID("$NetBSD: pl_7.c,v 1.14 2000/01/31 11:08:53 jsm Exp $");
42 #endif
43 #endif /* not lint */
44
45 #include <sys/ttydefaults.h>
46 #include "player.h"
47 #ifdef __STDC__
48 #include <stdarg.h>
49 #else
50 #include <varargs.h>
51 #endif
52 #include <unistd.h>
53
54
55 /*
56 * Display interface
57 */
58
59 static char sc_hasprompt;
60 static const char *sc_prompt;
61 static const char *sc_buf;
62 static int sc_line;
63
64 WINDOW *view_w;
65 WINDOW *slot_w;
66 WINDOW *scroll_w;
67 WINDOW *stat_w;
68 WINDOW *turn_w;
69
70 char done_curses;
71 char loaded, fired, changed, repaired;
72 char dont_adjust;
73 int viewrow, viewcol;
74 char movebuf[sizeof SHIP(0)->file->movebuf];
75 int player;
76 struct ship *ms; /* memorial structure, &cc->ship[player] */
77 struct File *mf; /* ms->file */
78 struct shipspecs *mc; /* ms->specs */
79
80 void
81 initscreen()
82 {
83 if (!SCREENTEST()) {
84 printf("Can't sail on this terminal.\n");
85 exit(1);
86 }
87 /* initscr() already done in SCREENTEST() */
88 view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L);
89 slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L);
90 scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L);
91 stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L);
92 turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L);
93 done_curses++;
94 (void) leaveok(view_w, 1);
95 (void) leaveok(slot_w, 1);
96 (void) leaveok(stat_w, 1);
97 (void) leaveok(turn_w, 1);
98 noecho();
99 crmode();
100 }
101
102 void
103 cleanupscreen()
104 {
105 /* alarm already turned off */
106 if (done_curses) {
107 (void) wmove(scroll_w, SCROLL_Y - 1, 0);
108 (void) wclrtoeol(scroll_w);
109 draw_screen();
110 endwin();
111 }
112 }
113
114 /*ARGSUSED*/
115 void
116 newturn(n)
117 int n __attribute__((__unused__));
118 {
119 repaired = loaded = fired = changed = 0;
120 movebuf[0] = '\0';
121
122 (void) alarm(0);
123 if (mf->readyL & R_LOADING) {
124 if (mf->readyL & R_DOUBLE)
125 mf->readyL = R_LOADING;
126 else
127 mf->readyL = R_LOADED;
128 }
129 if (mf->readyR & R_LOADING) {
130 if (mf->readyR & R_DOUBLE)
131 mf->readyR = R_LOADING;
132 else
133 mf->readyR = R_LOADED;
134 }
135 if (!hasdriver)
136 Write(W_DDEAD, SHIP(0), 0, 0, 0, 0);
137
138 if (sc_hasprompt) {
139 (void) wmove(scroll_w, sc_line, 0);
140 (void) wclrtoeol(scroll_w);
141 }
142 if (Sync() < 0)
143 leave(LEAVE_SYNC);
144 if (!hasdriver)
145 leave(LEAVE_DRIVER);
146 if (sc_hasprompt)
147 (void) wprintw(scroll_w, "%s%s", sc_prompt, sc_buf);
148
149 if (turn % 50 == 0)
150 Write(W_ALIVE, SHIP(0), 0, 0, 0, 0);
151 if (mf->FS && (!mc->rig1 || windspeed == 6))
152 Write(W_FS, ms, 0, 0, 0, 0);
153 if (mf->FS == 1)
154 Write(W_FS, ms, 2, 0, 0, 0);
155
156 if (mf->struck)
157 leave(LEAVE_QUIT);
158 if (mf->captured != 0)
159 leave(LEAVE_CAPTURED);
160 if (windspeed == 7)
161 leave(LEAVE_HURRICAN);
162
163 adjustview();
164 draw_screen();
165
166 (void) signal(SIGALRM, newturn);
167 (void) alarm(7);
168 }
169
170 /*VARARGS2*/
171 void
172 #ifdef __STDC__
173 Signal(const char *fmt, struct ship *ship, ...)
174 #else
175 Signal(va_alist)
176 va_dcl
177 #endif
178 {
179 va_list ap;
180 char format[BUFSIZ];
181 #ifndef __STDC__
182 const char *fmt;
183 struct ship *ship;
184
185 va_start(ap);
186 fmt = va_arg(ap, const char *);
187 ship = va_arg(ap, struct ship *);
188 #else
189 va_start(ap, ship);
190 #endif
191 if (!done_curses)
192 return;
193 if (*fmt == '\7')
194 putchar(*fmt++);
195 fmtship(format, sizeof(format), fmt, ship);
196 (void) vwprintw(scroll_w, format, ap);
197 va_end(ap);
198 Scroll();
199 }
200
201 /*VARARGS2*/
202 void
203 #ifdef __STDC__
204 Msg(const char *fmt, ...)
205 #else
206 Msg(va_alist)
207 va_dcl
208 #endif
209 {
210 va_list ap;
211 #ifndef __STDC__
212 const char *fmt;
213
214 va_start(ap);
215 fmt = va_arg(ap, const char *);
216 #else
217 va_start(ap, fmt);
218 #endif
219
220 if (!done_curses)
221 return;
222 if (*fmt == '\7')
223 putchar(*fmt++);
224 (void) vwprintw(scroll_w, fmt, ap);
225 va_end(ap);
226 Scroll();
227 }
228
229 void
230 Scroll()
231 {
232 if (++sc_line >= SCROLL_Y)
233 sc_line = 0;
234 (void) wmove(scroll_w, sc_line, 0);
235 (void) wclrtoeol(scroll_w);
236 }
237
238 void
239 prompt(p, ship)
240 const char *p;
241 struct ship *ship;
242 {
243 static char buf[BUFSIZ];
244
245 fmtship(buf, sizeof(buf), p, ship);
246 sc_prompt = buf;
247 sc_buf = "";
248 sc_hasprompt = 1;
249 (void) waddstr(scroll_w, buf);
250 }
251
252 void
253 endprompt(flag)
254 char flag;
255 {
256 sc_hasprompt = 0;
257 if (flag)
258 Scroll();
259 }
260
261 int
262 sgetch(p, ship, flag)
263 const char *p;
264 struct ship *ship;
265 char flag;
266 {
267 int c;
268 prompt(p, ship);
269 blockalarm();
270 (void) wrefresh(scroll_w);
271 unblockalarm();
272 while ((c = wgetch(scroll_w)) == EOF)
273 ;
274 if (flag && c >= ' ' && c < 0x7f)
275 (void) waddch(scroll_w, c);
276 endprompt(flag);
277 return c;
278 }
279
280 void
281 sgetstr(pr, buf, n)
282 const char *pr;
283 char *buf;
284 int n;
285 {
286 int c;
287 char *p = buf;
288
289 prompt(pr, (struct ship *)0);
290 sc_buf = buf;
291 for (;;) {
292 *p = 0;
293 blockalarm();
294 (void) wrefresh(scroll_w);
295 unblockalarm();
296 while ((c = wgetch(scroll_w)) == EOF)
297 ;
298 switch (c) {
299 case '\n':
300 case '\r':
301 endprompt(1);
302 return;
303 case '\b':
304 if (p > buf) {
305 (void) waddstr(scroll_w, "\b \b");
306 p--;
307 }
308 break;
309 default:
310 if (c >= ' ' && c < 0x7f && p < buf + n - 1) {
311 *p++ = c;
312 (void) waddch(scroll_w, c);
313 } else
314 (void) putchar('\a');
315 }
316 }
317 }
318
319 void
320 draw_screen()
321 {
322 draw_view();
323 draw_turn();
324 draw_stat();
325 draw_slot();
326 (void) wrefresh(scroll_w); /* move the cursor */
327 }
328
329 void
330 draw_view()
331 {
332 struct ship *sp;
333
334 (void) werase(view_w);
335 foreachship(sp) {
336 if (sp->file->dir
337 && sp->file->row > viewrow
338 && sp->file->row < viewrow + VIEW_Y
339 && sp->file->col > viewcol
340 && sp->file->col < viewcol + VIEW_X) {
341 (void) wmove(view_w, sp->file->row - viewrow,
342 sp->file->col - viewcol);
343 (void) waddch(view_w, colours(sp));
344 (void) wmove(view_w,
345 sternrow(sp) - viewrow,
346 sterncol(sp) - viewcol);
347 (void) waddch(view_w, sterncolour(sp));
348 }
349 }
350 (void) wrefresh(view_w);
351 }
352
353 void
354 draw_turn()
355 {
356 (void) wmove(turn_w, 0, 0);
357 (void) wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn);
358 (void) wrefresh(turn_w);
359 }
360
361 void
362 draw_stat()
363 {
364 (void) wmove(stat_w, STAT_1, 0);
365 (void) wprintw(stat_w, "Points %3d\n", mf->points);
366 (void) wprintw(stat_w, "Fouls %2d\n", fouled(ms));
367 (void) wprintw(stat_w, "Grapples %2d\n", grappled(ms));
368
369 (void) wmove(stat_w, STAT_2, 0);
370 (void) wprintw(stat_w, " 0 %c(%c)\n",
371 maxmove(ms, winddir + 3, -1) + '0',
372 maxmove(ms, winddir + 3, 1) + '0');
373 (void) waddstr(stat_w, " \\|/\n");
374 (void) wprintw(stat_w, " -^-%c(%c)\n",
375 maxmove(ms, winddir + 2, -1) + '0',
376 maxmove(ms, winddir + 2, 1) + '0');
377 (void) waddstr(stat_w, " /|\\\n");
378 (void) wprintw(stat_w, " | %c(%c)\n",
379 maxmove(ms, winddir + 1, -1) + '0',
380 maxmove(ms, winddir + 1, 1) + '0');
381 (void) wprintw(stat_w, " %c(%c)\n",
382 maxmove(ms, winddir, -1) + '0',
383 maxmove(ms, winddir, 1) + '0');
384
385 (void) wmove(stat_w, STAT_3, 0);
386 (void) wprintw(stat_w, "Load %c%c %c%c\n",
387 loadname[mf->loadL], readyname(mf->readyL),
388 loadname[mf->loadR], readyname(mf->readyR));
389 (void) wprintw(stat_w, "Hull %2d\n", mc->hull);
390 (void) wprintw(stat_w, "Crew %2d %2d %2d\n",
391 mc->crew1, mc->crew2, mc->crew3);
392 (void) wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR);
393 (void) wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR);
394 (void) wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3);
395 if (mc->rig4 < 0)
396 (void) waddch(stat_w, '-');
397 else
398 (void) wprintw(stat_w, "%d", mc->rig4);
399 (void) wrefresh(stat_w);
400 }
401
402 void
403 draw_slot()
404 {
405 if (!boarding(ms, 0)) {
406 (void) mvwaddstr(slot_w, 0, 0, " ");
407 (void) mvwaddstr(slot_w, 1, 0, " ");
408 } else
409 (void) mvwaddstr(slot_w, 1, 0, "OBP");
410 if (!boarding(ms, 1)) {
411 (void) mvwaddstr(slot_w, 2, 0, " ");
412 (void) mvwaddstr(slot_w, 3, 0, " ");
413 } else
414 (void) mvwaddstr(slot_w, 3, 0, "DBP");
415
416 (void) wmove(slot_w, SLOT_Y-4, 0);
417 if (mf->RH)
418 (void) wprintw(slot_w, "%dRH", mf->RH);
419 else
420 (void) waddstr(slot_w, " ");
421 (void) wmove(slot_w, SLOT_Y-3, 0);
422 if (mf->RG)
423 (void) wprintw(slot_w, "%dRG", mf->RG);
424 else
425 (void) waddstr(slot_w, " ");
426 (void) wmove(slot_w, SLOT_Y-2, 0);
427 if (mf->RR)
428 (void) wprintw(slot_w, "%dRR", mf->RR);
429 else
430 (void) waddstr(slot_w, " ");
431
432 #define Y (SLOT_Y/2)
433 (void) wmove(slot_w, 7, 1);
434 (void) wprintw(slot_w,"%d", windspeed);
435 (void) mvwaddch(slot_w, Y, 0, ' ');
436 (void) mvwaddch(slot_w, Y, 2, ' ');
437 (void) mvwaddch(slot_w, Y-1, 0, ' ');
438 (void) mvwaddch(slot_w, Y-1, 1, ' ');
439 (void) mvwaddch(slot_w, Y-1, 2, ' ');
440 (void) mvwaddch(slot_w, Y+1, 0, ' ');
441 (void) mvwaddch(slot_w, Y+1, 1, ' ');
442 (void) mvwaddch(slot_w, Y+1, 2, ' ');
443 (void) wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]);
444 switch (winddir) {
445 case 1:
446 case 5:
447 (void) waddch(slot_w, '|');
448 break;
449 case 2:
450 case 6:
451 (void) waddch(slot_w, '/');
452 break;
453 case 3:
454 case 7:
455 (void) waddch(slot_w, '-');
456 break;
457 case 4:
458 case 8:
459 (void) waddch(slot_w, '\\');
460 break;
461 }
462 (void) mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+');
463 (void) wrefresh(slot_w);
464 }
465
466 void
467 draw_board()
468 {
469 int n;
470
471 (void) clear();
472 (void) werase(view_w);
473 (void) werase(slot_w);
474 (void) werase(scroll_w);
475 (void) werase(stat_w);
476 (void) werase(turn_w);
477
478 sc_line = 0;
479
480 (void) move(BOX_T, BOX_L);
481 for (n = 0; n < BOX_X; n++)
482 (void) addch('-');
483 (void) move(BOX_B, BOX_L);
484 for (n = 0; n < BOX_X; n++)
485 (void) addch('-');
486 for (n = BOX_T+1; n < BOX_B; n++) {
487 (void) mvaddch(n, BOX_L, '|');
488 (void) mvaddch(n, BOX_R, '|');
489 }
490 (void) mvaddch(BOX_T, BOX_L, '+');
491 (void) mvaddch(BOX_T, BOX_R, '+');
492 (void) mvaddch(BOX_B, BOX_L, '+');
493 (void) mvaddch(BOX_B, BOX_R, '+');
494 (void) refresh();
495
496 #define WSaIM "Wooden Ships & Iron Men"
497 (void) wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2);
498 (void) waddstr(view_w, WSaIM);
499 (void) wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2);
500 (void) waddstr(view_w, cc->name);
501 (void) wrefresh(view_w);
502
503 (void) move(LINE_T, LINE_L);
504 (void) printw("Class %d %s (%d guns) '%s' (%c%c)",
505 mc->class,
506 classname[mc->class],
507 mc->guns,
508 ms->shipname,
509 colours(ms),
510 sterncolour(ms));
511 (void) refresh();
512 }
513
514 void
515 centerview()
516 {
517 viewrow = mf->row - VIEW_Y / 2;
518 viewcol = mf->col - VIEW_X / 2;
519 }
520
521 void
522 upview()
523 {
524 viewrow -= VIEW_Y / 3;
525 }
526
527 void
528 downview()
529 {
530 viewrow += VIEW_Y / 3;
531 }
532
533 void
534 leftview()
535 {
536 viewcol -= VIEW_X / 5;
537 }
538
539 void
540 rightview()
541 {
542 viewcol += VIEW_X / 5;
543 }
544
545 void
546 adjustview()
547 {
548 if (dont_adjust)
549 return;
550 if (mf->row < viewrow + VIEW_Y/4)
551 viewrow = mf->row - (VIEW_Y - VIEW_Y/4);
552 else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4))
553 viewrow = mf->row - VIEW_Y/4;
554 if (mf->col < viewcol + VIEW_X/8)
555 viewcol = mf->col - (VIEW_X - VIEW_X/8);
556 else if (mf->col > viewcol + (VIEW_X - VIEW_X/8))
557 viewcol = mf->col - VIEW_X/8;
558 }
559