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