1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32: #include <sys/cdefs.h>
33: #ifndef lint
34: #if 0
35: static char sccsid[] = "@(#)pl_7.c 8.1 (Berkeley) 5/31/93";
36: #else
37: __RCSID("$NetBSD: pl_7.c,v 1.27 2003/08/07 09:37:44 agc Exp $");
38: #endif
39: #endif
40:
41: #include <curses.h>
42: #include <signal.h>
43: #include <stdarg.h>
44: #include <stdio.h>
45: #include <stdlib.h>
46: #include <unistd.h>
47: #include <string.h>
48: #include "extern.h"
49: #include "player.h"
50: #include "display.h"
51:
52: static void Scroll(void);
53: static void endprompt(int);
54: static void adjustview(void);
55:
56:
57:
58:
59:
60: static char sc_hasprompt;
61: static const char *sc_prompt;
62: static const char *sc_buf;
63: static int sc_line;
64:
65: WINDOW *view_w;
66: WINDOW *slot_w;
67: WINDOW *scroll_w;
68: WINDOW *stat_w;
69: WINDOW *turn_w;
70:
71: int done_curses;
72: int loaded, fired, changed, repaired;
73: int dont_adjust;
74: int viewrow, viewcol;
75: char movebuf[sizeof SHIP(0)->file->movebuf];
76: int player;
77: struct ship *ms;
78: struct File *mf;
79: struct shipspecs *mc;
80:
81: void
82: initscreen(void)
83: {
84: if (!SCREENTEST()) {
85: printf("Can't sail on this terminal.\n");
86: exit(1);
87: }
88:
89: view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L);
90: slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L);
91: scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L);
92: stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L);
93: turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L);
94: done_curses++;
95: leaveok(view_w, 1);
96: leaveok(slot_w, 1);
97: leaveok(stat_w, 1);
98: leaveok(turn_w, 1);
99: noecho();
100: cbreak();
101: }
102:
103: void
104: cleanupscreen(void)
105: {
106:
107: if (done_curses) {
108: wmove(scroll_w, SCROLL_Y - 1, 0);
109: wclrtoeol(scroll_w);
110: draw_screen();
111: endwin();
112: }
113: }
114:
115:
116: void
117: newturn(int n __attribute__((__unused__)))
118: {
119: repaired = loaded = fired = changed = 0;
120: movebuf[0] = '\0';
121:
122: 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: wmove(scroll_w, sc_line, 0);
140: wclrtoeol(scroll_w);
141: }
142: if (Sync() < 0)
143: leave(LEAVE_SYNC);
144: if (!hasdriver)
145: leave(LEAVE_DRIVER);
146: if (sc_hasprompt)
147: 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: signal(SIGALRM, newturn);
167: alarm(7);
168: }
169:
170:
171: void
172: Signal(const char *fmt, struct ship *ship, ...)
173: {
174: va_list ap;
175: char format[BUFSIZ];
176:
177: if (!done_curses)
178: return;
179: va_start(ap, ship);
180: if (*fmt == '\7')
181: putchar(*fmt++);
182: fmtship(format, sizeof(format), fmt, ship);
183: vwprintw(scroll_w, format, ap);
184: va_end(ap);
185: Scroll();
186: }
187:
188:
189: void
190: Msg(const char *fmt, ...)
191: {
192: va_list ap;
193:
194: if (!done_curses)
195: return;
196: va_start(ap, fmt);
197: if (*fmt == '\7')
198: putchar(*fmt++);
199: vwprintw(scroll_w, fmt, ap);
200: va_end(ap);
201: Scroll();
202: }
203:
204: static void
205: Scroll(void)
206: {
207: if (++sc_line >= SCROLL_Y)
208: sc_line = 0;
209: wmove(scroll_w, sc_line, 0);
210: wclrtoeol(scroll_w);
211: }
212:
213: void
214: prompt(const char *p, struct ship *ship)
215: {
216: static char buf[BUFSIZ];
217:
218: fmtship(buf, sizeof(buf), p, ship);
219: sc_prompt = buf;
220: sc_buf = "";
221: sc_hasprompt = 1;
222: waddstr(scroll_w, buf);
223: }
224:
225: static void
226: endprompt(int flag)
227: {
228: sc_hasprompt = 0;
229: if (flag)
230: Scroll();
231: }
232:
233: int
234: sgetch(const char *p, struct ship *ship, int flag)
235: {
236: int c;
237: prompt(p, ship);
238: blockalarm();
239: wrefresh(scroll_w);
240: unblockalarm();
241: while ((c = wgetch(scroll_w)) == EOF)
242: ;
243: if (flag && c >= ' ' && c < 0x7f)
244: waddch(scroll_w, c);
245: endprompt(flag);
246: return c;
247: }
248:
249: void
250: sgetstr(const char *pr, char *buf, int n)
251: {
252: int c;
253: char *p = buf;
254:
255: prompt(pr, (struct ship *)0);
256: sc_buf = buf;
257: for (;;) {
258: *p = 0;
259: blockalarm();
260: wrefresh(scroll_w);
261: unblockalarm();
262: while ((c = wgetch(scroll_w)) == EOF)
263: ;
264: switch (c) {
265: case '\n':
266: case '\r':
267: endprompt(1);
268: return;
269: case '\b':
270: if (p > buf) {
271: waddstr(scroll_w, "\b \b");
272: p--;
273: }
274: break;
275: default:
276: if (c >= ' ' && c < 0x7f && p < buf + n - 1) {
277: *p++ = c;
278: waddch(scroll_w, c);
279: } else
280: putchar('\a');
281: }
282: }
283: }
284:
285: void
286: draw_screen(void)
287: {
288: draw_view();
289: draw_turn();
290: draw_stat();
291: draw_slot();
292: wrefresh(scroll_w);
293: }
294:
295: void
296: draw_view(void)
297: {
298: struct ship *sp;
299:
300: werase(view_w);
301: foreachship(sp) {
302: if (sp->file->dir
303: && sp->file->row > viewrow
304: && sp->file->row < viewrow + VIEW_Y
305: && sp->file->col > viewcol
306: && sp->file->col < viewcol + VIEW_X) {
307: wmove(view_w, sp->file->row - viewrow,
308: sp->file->col - viewcol);
309: waddch(view_w, colours(sp));
310: wmove(view_w,
311: sternrow(sp) - viewrow,
312: sterncol(sp) - viewcol);
313: waddch(view_w, sterncolour(sp));
314: }
315: }
316: wrefresh(view_w);
317: }
318:
319: void
320: draw_turn(void)
321: {
322: wmove(turn_w, 0, 0);
323: wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn);
324: wrefresh(turn_w);
325: }
326:
327: void
328: draw_stat(void)
329: {
330: wmove(stat_w, STAT_1, 0);
331: wprintw(stat_w, "Points %3d\n", mf->points);
332: wprintw(stat_w, "Fouls %2d\n", fouled(ms));
333: wprintw(stat_w, "Grapples %2d\n", grappled(ms));
334:
335: wmove(stat_w, STAT_2, 0);
336: wprintw(stat_w, " 0 %c(%c)\n",
337: maxmove(ms, winddir + 3, -1) + '0',
338: maxmove(ms, winddir + 3, 1) + '0');
339: waddstr(stat_w, " \\|/\n");
340: wprintw(stat_w, " -^-%c(%c)\n",
341: maxmove(ms, winddir + 2, -1) + '0',
342: maxmove(ms, winddir + 2, 1) + '0');
343: waddstr(stat_w, " /|\\\n");
344: wprintw(stat_w, " | %c(%c)\n",
345: maxmove(ms, winddir + 1, -1) + '0',
346: maxmove(ms, winddir + 1, 1) + '0');
347: wprintw(stat_w, " %c(%c)\n",
348: maxmove(ms, winddir, -1) + '0',
349: maxmove(ms, winddir, 1) + '0');
350:
351: wmove(stat_w, STAT_3, 0);
352: wprintw(stat_w, "Load %c%c %c%c\n",
353: loadname[mf->loadL], readyname(mf->readyL),
354: loadname[mf->loadR], readyname(mf->readyR));
355: wprintw(stat_w, "Hull %2d\n", mc->hull);
356: wprintw(stat_w, "Crew %2d %2d %2d\n",
357: mc->crew1, mc->crew2, mc->crew3);
358: wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR);
359: wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR);
360: wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3);
361: if (mc->rig4 < 0)
362: waddch(stat_w, '-');
363: else
364: wprintw(stat_w, "%d", mc->rig4);
365: wrefresh(stat_w);
366: }
367:
368: void
369: draw_slot(void)
370: {
371: if (!boarding(ms, 0)) {
372: mvwaddstr(slot_w, 0, 0, " ");
373: mvwaddstr(slot_w, 1, 0, " ");
374: } else
375: mvwaddstr(slot_w, 1, 0, "OBP");
376: if (!boarding(ms, 1)) {
377: mvwaddstr(slot_w, 2, 0, " ");
378: mvwaddstr(slot_w, 3, 0, " ");
379: } else
380: mvwaddstr(slot_w, 3, 0, "DBP");
381:
382: wmove(slot_w, SLOT_Y-4, 0);
383: if (mf->RH)
384: wprintw(slot_w, "%dRH", mf->RH);
385: else
386: waddstr(slot_w, " ");
387: wmove(slot_w, SLOT_Y-3, 0);
388: if (mf->RG)
389: wprintw(slot_w, "%dRG", mf->RG);
390: else
391: waddstr(slot_w, " ");
392: wmove(slot_w, SLOT_Y-2, 0);
393: if (mf->RR)
394: wprintw(slot_w, "%dRR", mf->RR);
395: else
396: waddstr(slot_w, " ");
397:
398: #define Y (SLOT_Y/2)
399: wmove(slot_w, 7, 1);
400: wprintw(slot_w,"%d", windspeed);
401: mvwaddch(slot_w, Y, 0, ' ');
402: mvwaddch(slot_w, Y, 2, ' ');
403: mvwaddch(slot_w, Y-1, 0, ' ');
404: mvwaddch(slot_w, Y-1, 1, ' ');
405: mvwaddch(slot_w, Y-1, 2, ' ');
406: mvwaddch(slot_w, Y+1, 0, ' ');
407: mvwaddch(slot_w, Y+1, 1, ' ');
408: mvwaddch(slot_w, Y+1, 2, ' ');
409: wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]);
410: switch (winddir) {
411: case 1:
412: case 5:
413: waddch(slot_w, '|');
414: break;
415: case 2:
416: case 6:
417: waddch(slot_w, '/');
418: break;
419: case 3:
420: case 7:
421: waddch(slot_w, '-');
422: break;
423: case 4:
424: case 8:
425: waddch(slot_w, '\\');
426: break;
427: }
428: mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+');
429: wrefresh(slot_w);
430: }
431:
432: void
433: draw_board(void)
434: {
435: int n;
436:
437: clear();
438: werase(view_w);
439: werase(slot_w);
440: werase(scroll_w);
441: werase(stat_w);
442: werase(turn_w);
443:
444: sc_line = 0;
445:
446: move(BOX_T, BOX_L);
447: for (n = 0; n < BOX_X; n++)
448: addch('-');
449: move(BOX_B, BOX_L);
450: for (n = 0; n < BOX_X; n++)
451: addch('-');
452: for (n = BOX_T+1; n < BOX_B; n++) {
453: mvaddch(n, BOX_L, '|');
454: mvaddch(n, BOX_R, '|');
455: }
456: mvaddch(BOX_T, BOX_L, '+');
457: mvaddch(BOX_T, BOX_R, '+');
458: mvaddch(BOX_B, BOX_L, '+');
459: mvaddch(BOX_B, BOX_R, '+');
460: refresh();
461:
462: #define WSaIM "Wooden Ships & Iron Men"
463: wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2);
464: waddstr(view_w, WSaIM);
465: wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2);
466: waddstr(view_w, cc->name);
467: wrefresh(view_w);
468:
469: move(LINE_T, LINE_L);
470: printw("Class %d %s (%d guns) '%s' (%c%c)",
471: mc->class,
472: classname[mc->class],
473: mc->guns,
474: ms->shipname,
475: colours(ms),
476: sterncolour(ms));
477: refresh();
478: }
479:
480: void
481: centerview(void)
482: {
483: viewrow = mf->row - VIEW_Y / 2;
484: viewcol = mf->col - VIEW_X / 2;
485: }
486:
487: void
488: upview(void)
489: {
490: viewrow -= VIEW_Y / 3;
491: }
492:
493: void
494: downview(void)
495: {
496: viewrow += VIEW_Y / 3;
497: }
498:
499: void
500: leftview(void)
501: {
502: viewcol -= VIEW_X / 5;
503: }
504:
505: void
506: rightview(void)
507: {
508: viewcol += VIEW_X / 5;
509: }
510:
511: static void
512: adjustview(void)
513: {
514: if (dont_adjust)
515: return;
516: if (mf->row < viewrow + VIEW_Y/4)
517: viewrow = mf->row - (VIEW_Y - VIEW_Y/4);
518: else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4))
519: viewrow = mf->row - VIEW_Y/4;
520: if (mf->col < viewcol + VIEW_X/8)
521: viewcol = mf->col - (VIEW_X - VIEW_X/8);
522: else if (mf->col > viewcol + (VIEW_X - VIEW_X/8))
523: viewcol = mf->col - VIEW_X/8;
524: }