pl_7.c revision 1.40 1 1.40 dholland /* $NetBSD: pl_7.c,v 1.40 2010/08/06 09:14:40 dholland Exp $ */
2 1.6 cgd
3 1.1 cgd /*
4 1.6 cgd * Copyright (c) 1983, 1993
5 1.6 cgd * The Regents of the University of California. All rights reserved.
6 1.1 cgd *
7 1.1 cgd * Redistribution and use in source and binary forms, with or without
8 1.1 cgd * modification, are permitted provided that the following conditions
9 1.1 cgd * are met:
10 1.1 cgd * 1. Redistributions of source code must retain the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer.
12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 cgd * notice, this list of conditions and the following disclaimer in the
14 1.1 cgd * documentation and/or other materials provided with the distribution.
15 1.27 agc * 3. Neither the name of the University nor the names of its contributors
16 1.1 cgd * may be used to endorse or promote products derived from this software
17 1.1 cgd * without specific prior written permission.
18 1.1 cgd *
19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 1.1 cgd * SUCH DAMAGE.
30 1.1 cgd */
31 1.1 cgd
32 1.7 christos #include <sys/cdefs.h>
33 1.1 cgd #ifndef lint
34 1.6 cgd #if 0
35 1.6 cgd static char sccsid[] = "@(#)pl_7.c 8.1 (Berkeley) 5/31/93";
36 1.6 cgd #else
37 1.40 dholland __RCSID("$NetBSD: pl_7.c,v 1.40 2010/08/06 09:14:40 dholland Exp $");
38 1.6 cgd #endif
39 1.1 cgd #endif /* not lint */
40 1.1 cgd
41 1.20 jwise #include <curses.h>
42 1.29 dholland #include <err.h>
43 1.35 dholland #include <errno.h>
44 1.19 jwise #include <signal.h>
45 1.7 christos #include <stdarg.h>
46 1.18 jwise #include <stdio.h>
47 1.23 cgd #include <stdlib.h>
48 1.22 itojun #include <string.h>
49 1.40 dholland #include <unistd.h>
50 1.35 dholland #include "array.h"
51 1.20 jwise #include "extern.h"
52 1.18 jwise #include "player.h"
53 1.20 jwise #include "display.h"
54 1.6 cgd
55 1.35 dholland /*
56 1.35 dholland * Use values above KEY_MAX for custom keycodes. (blymn@ says this is ok)
57 1.35 dholland */
58 1.35 dholland #define KEY_ESC(ch) (KEY_MAX+10+ch)
59 1.35 dholland
60 1.1 cgd
61 1.1 cgd /*
62 1.1 cgd * Display interface
63 1.1 cgd */
64 1.1 cgd
65 1.35 dholland static void draw_view(void);
66 1.35 dholland static void draw_turn(void);
67 1.35 dholland static void draw_stat(void);
68 1.35 dholland static void draw_slot(void);
69 1.35 dholland static void draw_board(void);
70 1.35 dholland
71 1.35 dholland static struct stringarray *sc_lines;
72 1.35 dholland static unsigned sc_scrollup;
73 1.35 dholland static bool sc_hasprompt;
74 1.35 dholland static bool sc_hideprompt;
75 1.11 jsm static const char *sc_prompt;
76 1.11 jsm static const char *sc_buf;
77 1.13 jsm
78 1.33 dholland static WINDOW *view_w;
79 1.35 dholland static WINDOW *turn_w;
80 1.35 dholland static WINDOW *stat_w;
81 1.33 dholland static WINDOW *slot_w;
82 1.33 dholland static WINDOW *scroll_w;
83 1.35 dholland
84 1.35 dholland static bool obp[3];
85 1.35 dholland static bool dbp[3];
86 1.13 jsm
87 1.21 jwise int done_curses;
88 1.40 dholland static bool ingame;
89 1.21 jwise int loaded, fired, changed, repaired;
90 1.21 jwise int dont_adjust;
91 1.38 dholland static int viewrow, viewcol;
92 1.13 jsm char movebuf[sizeof SHIP(0)->file->movebuf];
93 1.13 jsm int player;
94 1.13 jsm struct ship *ms; /* memorial structure, &cc->ship[player] */
95 1.13 jsm struct File *mf; /* ms->file */
96 1.13 jsm struct shipspecs *mc; /* ms->specs */
97 1.1 cgd
98 1.35 dholland ////////////////////////////////////////////////////////////
99 1.35 dholland // overall initialization
100 1.35 dholland
101 1.35 dholland static
102 1.35 dholland void
103 1.35 dholland define_esc_key(int ch)
104 1.35 dholland {
105 1.35 dholland char seq[3] = { '\x1b', ch, 0 };
106 1.35 dholland
107 1.35 dholland define_key(seq, KEY_ESC(ch));
108 1.35 dholland }
109 1.35 dholland
110 1.7 christos void
111 1.16 jwise initscreen(void)
112 1.1 cgd {
113 1.35 dholland int ch;
114 1.35 dholland
115 1.35 dholland sc_lines = stringarray_create();
116 1.35 dholland if (sc_lines == NULL) {
117 1.35 dholland err(1, "malloc");
118 1.35 dholland }
119 1.35 dholland
120 1.33 dholland if (signal(SIGTSTP, SIG_DFL) == SIG_ERR) {
121 1.33 dholland err(1, "signal(SIGTSTP)");
122 1.33 dholland }
123 1.33 dholland
124 1.33 dholland if (initscr() == NULL) {
125 1.29 dholland errx(1, "Can't sail on this terminal.");
126 1.14 jsm }
127 1.33 dholland if (STAT_R >= COLS || SCROLL_Y <= 0) {
128 1.33 dholland errx(1, "Window/terminal not large enough.");
129 1.33 dholland }
130 1.33 dholland
131 1.1 cgd view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L);
132 1.1 cgd slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L);
133 1.1 cgd scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L);
134 1.1 cgd stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L);
135 1.1 cgd turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L);
136 1.33 dholland
137 1.33 dholland if (view_w == NULL ||
138 1.33 dholland slot_w == NULL ||
139 1.33 dholland scroll_w == NULL ||
140 1.33 dholland stat_w == NULL ||
141 1.33 dholland turn_w == NULL) {
142 1.33 dholland endwin();
143 1.33 dholland errx(1, "Curses initialization failed.");
144 1.33 dholland }
145 1.33 dholland
146 1.16 jwise leaveok(view_w, 1);
147 1.16 jwise leaveok(slot_w, 1);
148 1.16 jwise leaveok(stat_w, 1);
149 1.16 jwise leaveok(turn_w, 1);
150 1.1 cgd noecho();
151 1.26 blymn cbreak();
152 1.33 dholland
153 1.35 dholland /*
154 1.35 dholland * Define esc-x keys
155 1.35 dholland */
156 1.40 dholland #if 0
157 1.35 dholland for (ch = 0; ch < 127; ch++) {
158 1.40 dholland if (ch != '[' && ch != 'O') {
159 1.39 dholland define_esc_key(ch);
160 1.39 dholland }
161 1.35 dholland }
162 1.40 dholland #else
163 1.40 dholland (void)ch;
164 1.40 dholland (void)define_esc_key;
165 1.40 dholland #endif
166 1.40 dholland
167 1.40 dholland keypad(stdscr, 1);
168 1.40 dholland keypad(view_w, 1);
169 1.40 dholland keypad(slot_w, 1);
170 1.40 dholland keypad(scroll_w, 1);
171 1.40 dholland keypad(stat_w, 1);
172 1.40 dholland keypad(turn_w, 1);
173 1.35 dholland
174 1.33 dholland done_curses++;
175 1.1 cgd }
176 1.1 cgd
177 1.7 christos void
178 1.16 jwise cleanupscreen(void)
179 1.1 cgd {
180 1.1 cgd /* alarm already turned off */
181 1.1 cgd if (done_curses) {
182 1.40 dholland if (ingame) {
183 1.40 dholland wmove(scroll_w, SCROLL_Y - 1, 0);
184 1.40 dholland wclrtoeol(scroll_w);
185 1.40 dholland display_redraw();
186 1.40 dholland } else {
187 1.40 dholland move(LINES-1, 0);
188 1.40 dholland clrtoeol();
189 1.40 dholland }
190 1.1 cgd endwin();
191 1.1 cgd }
192 1.1 cgd }
193 1.1 cgd
194 1.35 dholland ////////////////////////////////////////////////////////////
195 1.40 dholland // curses utility functions
196 1.40 dholland
197 1.40 dholland /*
198 1.40 dholland * fill to eol with spaces
199 1.40 dholland * (useful with A_REVERSE since cleartoeol() does not clear to reversed)
200 1.40 dholland */
201 1.40 dholland static void
202 1.40 dholland filltoeol(void)
203 1.40 dholland {
204 1.40 dholland int x;
205 1.40 dholland
206 1.40 dholland for (x = getcurx(stdscr); x < COLS; x++) {
207 1.40 dholland addch(' ');
208 1.40 dholland }
209 1.40 dholland }
210 1.40 dholland
211 1.40 dholland /*
212 1.40 dholland * Add a maybe-selected string.
213 1.40 dholland *
214 1.40 dholland * Place strings starting at (Y0, X0); this is string ITEM; CURITEM
215 1.40 dholland * is the selected one; WIDTH is the total width. STR is the string.
216 1.40 dholland */
217 1.40 dholland static void
218 1.40 dholland mvaddselstr(int y, int x0, int item, int curitem,
219 1.40 dholland size_t width, const char *str)
220 1.40 dholland {
221 1.40 dholland size_t i, len;
222 1.40 dholland
223 1.40 dholland len = strlen(str);
224 1.40 dholland
225 1.40 dholland move(y, x0);
226 1.40 dholland if (curitem == item) {
227 1.40 dholland attron(A_REVERSE);
228 1.40 dholland }
229 1.40 dholland addstr(str);
230 1.40 dholland if (curitem == item) {
231 1.40 dholland for (i=len; i<width; i++) {
232 1.40 dholland addch(' ');
233 1.40 dholland }
234 1.40 dholland attroff(A_REVERSE);
235 1.40 dholland }
236 1.40 dholland }
237 1.40 dholland
238 1.40 dholland /*
239 1.40 dholland * Likewise but a printf.
240 1.40 dholland */
241 1.40 dholland static void
242 1.40 dholland mvselprintw(int y, int x0, int item, int curitem,
243 1.40 dholland size_t width, const char *fmt, ...)
244 1.40 dholland {
245 1.40 dholland va_list ap;
246 1.40 dholland size_t x;
247 1.40 dholland
248 1.40 dholland move(y, x0);
249 1.40 dholland if (curitem == item) {
250 1.40 dholland attron(A_REVERSE);
251 1.40 dholland }
252 1.40 dholland va_start(ap, fmt);
253 1.40 dholland vwprintw(stdscr, fmt, ap);
254 1.40 dholland va_end(ap);
255 1.40 dholland if (curitem == item) {
256 1.40 dholland for (x = getcurx(stdscr); x < x0 + width; x++) {
257 1.40 dholland addch(' ');
258 1.40 dholland }
259 1.40 dholland attroff(A_REVERSE);
260 1.40 dholland }
261 1.40 dholland }
262 1.40 dholland
263 1.40 dholland /*
264 1.40 dholland * Move up by 1, scrolling if needed.
265 1.40 dholland */
266 1.40 dholland static void
267 1.40 dholland up(int *posp, int *scrollp)
268 1.40 dholland {
269 1.40 dholland if (*posp > 0) {
270 1.40 dholland (*posp)--;
271 1.40 dholland }
272 1.40 dholland if (scrollp != NULL) {
273 1.40 dholland if (*posp < *scrollp) {
274 1.40 dholland *scrollp = *posp;
275 1.40 dholland }
276 1.40 dholland }
277 1.40 dholland }
278 1.40 dholland
279 1.40 dholland /*
280 1.40 dholland * Move down by 1, scrolling if needed. MAX is the total number of
281 1.40 dholland * items; VISIBLE is the number that can be visible at once.
282 1.40 dholland */
283 1.40 dholland static void
284 1.40 dholland down(int *posp, int *scrollp, int max, int visible)
285 1.40 dholland {
286 1.40 dholland if (max > 0 && *posp < max - 1) {
287 1.40 dholland (*posp)++;
288 1.40 dholland }
289 1.40 dholland if (scrollp != NULL) {
290 1.40 dholland if (*posp > *scrollp + visible - 1) {
291 1.40 dholland *scrollp = *posp - visible + 1;
292 1.40 dholland }
293 1.40 dholland }
294 1.40 dholland }
295 1.40 dholland
296 1.40 dholland /*
297 1.40 dholland * Complain briefly.
298 1.40 dholland */
299 1.40 dholland static void
300 1.40 dholland oops(int y, int x, const char *fmt, ...)
301 1.40 dholland {
302 1.40 dholland int oy, ox;
303 1.40 dholland va_list ap;
304 1.40 dholland
305 1.40 dholland oy = getcury(stdscr);
306 1.40 dholland ox = getcurx(stdscr);
307 1.40 dholland move(y, x);
308 1.40 dholland va_start(ap, fmt);
309 1.40 dholland vwprintw(stdscr, fmt, ap);
310 1.40 dholland va_end(ap);
311 1.40 dholland move(oy, ox);
312 1.40 dholland wrefresh(stdscr);
313 1.40 dholland sleep(1);
314 1.40 dholland }
315 1.40 dholland
316 1.40 dholland ////////////////////////////////////////////////////////////
317 1.35 dholland // scrolling message area
318 1.35 dholland
319 1.35 dholland static void
320 1.35 dholland scrollarea_add(const char *text)
321 1.35 dholland {
322 1.35 dholland char *copy;
323 1.35 dholland int errsave;
324 1.35 dholland
325 1.35 dholland copy = strdup(text);
326 1.35 dholland if (copy == NULL) {
327 1.35 dholland goto nomem;
328 1.35 dholland }
329 1.35 dholland if (stringarray_add(sc_lines, copy, NULL)) {
330 1.35 dholland goto nomem;
331 1.35 dholland }
332 1.35 dholland return;
333 1.35 dholland
334 1.35 dholland nomem:
335 1.35 dholland /*
336 1.35 dholland * XXX this should use leave(), but that won't
337 1.35 dholland * currently work right.
338 1.35 dholland */
339 1.35 dholland errsave = errno;
340 1.35 dholland #if 0
341 1.35 dholland leave(LEAVE_MALLOC);
342 1.35 dholland #else
343 1.35 dholland cleanupscreen();
344 1.35 dholland sync_close(!hasdriver);
345 1.35 dholland errno = errsave;
346 1.35 dholland err(1, "malloc");
347 1.35 dholland #endif
348 1.35 dholland }
349 1.35 dholland
350 1.35 dholland static void
351 1.35 dholland draw_scroll(void)
352 1.35 dholland {
353 1.35 dholland unsigned total_lines;
354 1.35 dholland unsigned visible_lines;
355 1.35 dholland unsigned index_of_top;
356 1.35 dholland unsigned index_of_y;
357 1.35 dholland unsigned y;
358 1.35 dholland unsigned cursorx;
359 1.35 dholland
360 1.35 dholland werase(scroll_w);
361 1.35 dholland
362 1.37 dholland /* XXX: SCROLL_Y and whatnot should be unsigned too */
363 1.35 dholland visible_lines = SCROLL_Y - 1;
364 1.35 dholland
365 1.35 dholland total_lines = stringarray_num(sc_lines);
366 1.35 dholland if (total_lines > visible_lines) {
367 1.35 dholland index_of_top = total_lines - visible_lines;
368 1.35 dholland } else {
369 1.35 dholland index_of_top = 0;
370 1.35 dholland }
371 1.35 dholland if (index_of_top < sc_scrollup) {
372 1.35 dholland index_of_top = 0;
373 1.35 dholland } else {
374 1.35 dholland index_of_top -= sc_scrollup;
375 1.35 dholland }
376 1.35 dholland
377 1.37 dholland for (y = 0; y < visible_lines; y++) {
378 1.35 dholland index_of_y = index_of_top + y;
379 1.35 dholland if (index_of_y >= total_lines) {
380 1.35 dholland break;
381 1.35 dholland }
382 1.35 dholland wmove(scroll_w, y, 0);
383 1.35 dholland waddstr(scroll_w, stringarray_get(sc_lines, index_of_y));
384 1.35 dholland }
385 1.35 dholland if (sc_hasprompt && !sc_hideprompt) {
386 1.35 dholland wmove(scroll_w, SCROLL_Y-1, 0);
387 1.35 dholland waddstr(scroll_w, sc_prompt);
388 1.35 dholland waddstr(scroll_w, sc_buf);
389 1.35 dholland cursorx = strlen(sc_prompt) + strlen(sc_buf);
390 1.35 dholland wmove(scroll_w, SCROLL_Y-1, cursorx);
391 1.35 dholland }
392 1.35 dholland else {
393 1.35 dholland wmove(scroll_w, SCROLL_Y-1, 0);
394 1.35 dholland }
395 1.35 dholland }
396 1.35 dholland
397 1.1 cgd /*VARARGS2*/
398 1.7 christos void
399 1.7 christos Signal(const char *fmt, struct ship *ship, ...)
400 1.1 cgd {
401 1.7 christos va_list ap;
402 1.7 christos char format[BUFSIZ];
403 1.35 dholland char buf[BUFSIZ];
404 1.7 christos
405 1.1 cgd if (!done_curses)
406 1.1 cgd return;
407 1.25 wiz va_start(ap, ship);
408 1.35 dholland if (*fmt == '\a') {
409 1.35 dholland beep();
410 1.35 dholland fmt++;
411 1.35 dholland }
412 1.7 christos fmtship(format, sizeof(format), fmt, ship);
413 1.35 dholland vsnprintf(buf, sizeof(buf), format, ap);
414 1.7 christos va_end(ap);
415 1.35 dholland scrollarea_add(buf);
416 1.7 christos }
417 1.7 christos
418 1.7 christos /*VARARGS2*/
419 1.7 christos void
420 1.7 christos Msg(const char *fmt, ...)
421 1.7 christos {
422 1.7 christos va_list ap;
423 1.35 dholland char buf[BUFSIZ];
424 1.7 christos
425 1.7 christos if (!done_curses)
426 1.7 christos return;
427 1.25 wiz va_start(ap, fmt);
428 1.35 dholland if (*fmt == '\a') {
429 1.35 dholland beep();
430 1.35 dholland fmt++;
431 1.35 dholland }
432 1.35 dholland vsnprintf(buf, sizeof(buf), fmt, ap);
433 1.7 christos va_end(ap);
434 1.35 dholland scrollarea_add(buf);
435 1.1 cgd }
436 1.1 cgd
437 1.38 dholland static void
438 1.17 jwise prompt(const char *p, struct ship *ship)
439 1.1 cgd {
440 1.8 christos static char buf[BUFSIZ];
441 1.1 cgd
442 1.8 christos fmtship(buf, sizeof(buf), p, ship);
443 1.8 christos sc_prompt = buf;
444 1.1 cgd sc_buf = "";
445 1.35 dholland sc_hasprompt = true;
446 1.1 cgd }
447 1.1 cgd
448 1.17 jwise static void
449 1.35 dholland endprompt(void)
450 1.1 cgd {
451 1.35 dholland sc_prompt = NULL;
452 1.35 dholland sc_buf = NULL;
453 1.35 dholland sc_hasprompt = false;
454 1.1 cgd }
455 1.1 cgd
456 1.34 dholland /*
457 1.34 dholland * Next two functions called from newturn() to poke display. Shouldn't
458 1.34 dholland * exist... XXX
459 1.34 dholland */
460 1.34 dholland
461 1.34 dholland void
462 1.34 dholland display_hide_prompt(void)
463 1.34 dholland {
464 1.35 dholland sc_hideprompt = true;
465 1.35 dholland draw_scroll();
466 1.35 dholland wrefresh(scroll_w);
467 1.34 dholland }
468 1.34 dholland
469 1.34 dholland void
470 1.34 dholland display_reshow_prompt(void)
471 1.34 dholland {
472 1.35 dholland sc_hideprompt = false;
473 1.35 dholland draw_scroll();
474 1.35 dholland wrefresh(scroll_w);
475 1.34 dholland }
476 1.34 dholland
477 1.34 dholland
478 1.7 christos int
479 1.16 jwise sgetch(const char *p, struct ship *ship, int flag)
480 1.1 cgd {
481 1.7 christos int c;
482 1.35 dholland char input[2];
483 1.35 dholland
484 1.1 cgd prompt(p, ship);
485 1.35 dholland input[0] = '\0';
486 1.35 dholland input[1] = '\0';
487 1.35 dholland sc_buf = input;
488 1.1 cgd blockalarm();
489 1.35 dholland draw_scroll();
490 1.16 jwise wrefresh(scroll_w);
491 1.35 dholland fflush(stdout);
492 1.1 cgd unblockalarm();
493 1.1 cgd while ((c = wgetch(scroll_w)) == EOF)
494 1.1 cgd ;
495 1.35 dholland if (flag && c >= ' ' && c < 0x7f) {
496 1.35 dholland blockalarm();
497 1.35 dholland input[0] = c;
498 1.35 dholland draw_scroll();
499 1.35 dholland wrefresh(scroll_w);
500 1.35 dholland fflush(stdout);
501 1.35 dholland unblockalarm();
502 1.35 dholland }
503 1.35 dholland endprompt();
504 1.1 cgd return c;
505 1.1 cgd }
506 1.1 cgd
507 1.7 christos void
508 1.16 jwise sgetstr(const char *pr, char *buf, int n)
509 1.1 cgd {
510 1.7 christos int c;
511 1.7 christos char *p = buf;
512 1.1 cgd
513 1.1 cgd prompt(pr, (struct ship *)0);
514 1.1 cgd sc_buf = buf;
515 1.1 cgd for (;;) {
516 1.1 cgd *p = 0;
517 1.1 cgd blockalarm();
518 1.35 dholland draw_scroll();
519 1.16 jwise wrefresh(scroll_w);
520 1.35 dholland fflush(stdout);
521 1.1 cgd unblockalarm();
522 1.1 cgd while ((c = wgetch(scroll_w)) == EOF)
523 1.1 cgd ;
524 1.1 cgd switch (c) {
525 1.1 cgd case '\n':
526 1.1 cgd case '\r':
527 1.35 dholland endprompt();
528 1.1 cgd return;
529 1.1 cgd case '\b':
530 1.1 cgd if (p > buf) {
531 1.35 dholland /*waddstr(scroll_w, "\b \b");*/
532 1.1 cgd p--;
533 1.1 cgd }
534 1.1 cgd break;
535 1.1 cgd default:
536 1.1 cgd if (c >= ' ' && c < 0x7f && p < buf + n - 1) {
537 1.1 cgd *p++ = c;
538 1.35 dholland /*waddch(scroll_w, c);*/
539 1.1 cgd } else
540 1.35 dholland beep();
541 1.1 cgd }
542 1.1 cgd }
543 1.1 cgd }
544 1.1 cgd
545 1.35 dholland ////////////////////////////////////////////////////////////
546 1.35 dholland // drawing of other panes
547 1.35 dholland
548 1.35 dholland void
549 1.35 dholland display_force_full_redraw(void)
550 1.35 dholland {
551 1.35 dholland clear();
552 1.35 dholland }
553 1.35 dholland
554 1.7 christos void
555 1.35 dholland display_redraw(void)
556 1.1 cgd {
557 1.35 dholland draw_board();
558 1.1 cgd draw_view();
559 1.1 cgd draw_turn();
560 1.1 cgd draw_stat();
561 1.1 cgd draw_slot();
562 1.35 dholland draw_scroll();
563 1.35 dholland /* move the cursor */
564 1.35 dholland wrefresh(scroll_w);
565 1.35 dholland /* paranoia */
566 1.35 dholland fflush(stdout);
567 1.1 cgd }
568 1.1 cgd
569 1.35 dholland static void
570 1.16 jwise draw_view(void)
571 1.1 cgd {
572 1.7 christos struct ship *sp;
573 1.1 cgd
574 1.16 jwise werase(view_w);
575 1.1 cgd foreachship(sp) {
576 1.1 cgd if (sp->file->dir
577 1.1 cgd && sp->file->row > viewrow
578 1.1 cgd && sp->file->row < viewrow + VIEW_Y
579 1.1 cgd && sp->file->col > viewcol
580 1.1 cgd && sp->file->col < viewcol + VIEW_X) {
581 1.16 jwise wmove(view_w, sp->file->row - viewrow,
582 1.1 cgd sp->file->col - viewcol);
583 1.16 jwise waddch(view_w, colours(sp));
584 1.16 jwise wmove(view_w,
585 1.1 cgd sternrow(sp) - viewrow,
586 1.1 cgd sterncol(sp) - viewcol);
587 1.16 jwise waddch(view_w, sterncolour(sp));
588 1.1 cgd }
589 1.1 cgd }
590 1.16 jwise wrefresh(view_w);
591 1.1 cgd }
592 1.1 cgd
593 1.35 dholland static void
594 1.16 jwise draw_turn(void)
595 1.1 cgd {
596 1.16 jwise wmove(turn_w, 0, 0);
597 1.16 jwise wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn);
598 1.16 jwise wrefresh(turn_w);
599 1.1 cgd }
600 1.1 cgd
601 1.35 dholland static void
602 1.16 jwise draw_stat(void)
603 1.1 cgd {
604 1.16 jwise wmove(stat_w, STAT_1, 0);
605 1.16 jwise wprintw(stat_w, "Points %3d\n", mf->points);
606 1.16 jwise wprintw(stat_w, "Fouls %2d\n", fouled(ms));
607 1.16 jwise wprintw(stat_w, "Grapples %2d\n", grappled(ms));
608 1.1 cgd
609 1.16 jwise wmove(stat_w, STAT_2, 0);
610 1.16 jwise wprintw(stat_w, " 0 %c(%c)\n",
611 1.1 cgd maxmove(ms, winddir + 3, -1) + '0',
612 1.1 cgd maxmove(ms, winddir + 3, 1) + '0');
613 1.16 jwise waddstr(stat_w, " \\|/\n");
614 1.16 jwise wprintw(stat_w, " -^-%c(%c)\n",
615 1.1 cgd maxmove(ms, winddir + 2, -1) + '0',
616 1.1 cgd maxmove(ms, winddir + 2, 1) + '0');
617 1.16 jwise waddstr(stat_w, " /|\\\n");
618 1.16 jwise wprintw(stat_w, " | %c(%c)\n",
619 1.1 cgd maxmove(ms, winddir + 1, -1) + '0',
620 1.1 cgd maxmove(ms, winddir + 1, 1) + '0');
621 1.16 jwise wprintw(stat_w, " %c(%c)\n",
622 1.1 cgd maxmove(ms, winddir, -1) + '0',
623 1.1 cgd maxmove(ms, winddir, 1) + '0');
624 1.1 cgd
625 1.16 jwise wmove(stat_w, STAT_3, 0);
626 1.16 jwise wprintw(stat_w, "Load %c%c %c%c\n",
627 1.1 cgd loadname[mf->loadL], readyname(mf->readyL),
628 1.1 cgd loadname[mf->loadR], readyname(mf->readyR));
629 1.16 jwise wprintw(stat_w, "Hull %2d\n", mc->hull);
630 1.16 jwise wprintw(stat_w, "Crew %2d %2d %2d\n",
631 1.1 cgd mc->crew1, mc->crew2, mc->crew3);
632 1.16 jwise wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR);
633 1.16 jwise wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR);
634 1.16 jwise wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3);
635 1.1 cgd if (mc->rig4 < 0)
636 1.16 jwise waddch(stat_w, '-');
637 1.1 cgd else
638 1.16 jwise wprintw(stat_w, "%d", mc->rig4);
639 1.16 jwise wrefresh(stat_w);
640 1.1 cgd }
641 1.1 cgd
642 1.7 christos void
643 1.16 jwise draw_slot(void)
644 1.1 cgd {
645 1.35 dholland int i;
646 1.35 dholland
647 1.1 cgd if (!boarding(ms, 0)) {
648 1.16 jwise mvwaddstr(slot_w, 0, 0, " ");
649 1.16 jwise mvwaddstr(slot_w, 1, 0, " ");
650 1.35 dholland } else {
651 1.35 dholland wmove(slot_w, 0, 0);
652 1.35 dholland for (i = 0; i < 3; i++) {
653 1.35 dholland waddch(slot_w, obp[i] ? '1'+i : ' ');
654 1.35 dholland }
655 1.16 jwise mvwaddstr(slot_w, 1, 0, "OBP");
656 1.35 dholland }
657 1.1 cgd if (!boarding(ms, 1)) {
658 1.16 jwise mvwaddstr(slot_w, 2, 0, " ");
659 1.16 jwise mvwaddstr(slot_w, 3, 0, " ");
660 1.35 dholland } else {
661 1.35 dholland wmove(slot_w, 2, 0);
662 1.35 dholland for (i = 0; i < 3; i++) {
663 1.35 dholland waddch(slot_w, dbp[i] ? '1'+i : ' ');
664 1.35 dholland }
665 1.16 jwise mvwaddstr(slot_w, 3, 0, "DBP");
666 1.35 dholland }
667 1.1 cgd
668 1.16 jwise wmove(slot_w, SLOT_Y-4, 0);
669 1.1 cgd if (mf->RH)
670 1.16 jwise wprintw(slot_w, "%dRH", mf->RH);
671 1.1 cgd else
672 1.16 jwise waddstr(slot_w, " ");
673 1.16 jwise wmove(slot_w, SLOT_Y-3, 0);
674 1.1 cgd if (mf->RG)
675 1.16 jwise wprintw(slot_w, "%dRG", mf->RG);
676 1.1 cgd else
677 1.16 jwise waddstr(slot_w, " ");
678 1.16 jwise wmove(slot_w, SLOT_Y-2, 0);
679 1.1 cgd if (mf->RR)
680 1.16 jwise wprintw(slot_w, "%dRR", mf->RR);
681 1.1 cgd else
682 1.16 jwise waddstr(slot_w, " ");
683 1.1 cgd
684 1.1 cgd #define Y (SLOT_Y/2)
685 1.16 jwise wmove(slot_w, 7, 1);
686 1.16 jwise wprintw(slot_w,"%d", windspeed);
687 1.16 jwise mvwaddch(slot_w, Y, 0, ' ');
688 1.16 jwise mvwaddch(slot_w, Y, 2, ' ');
689 1.16 jwise mvwaddch(slot_w, Y-1, 0, ' ');
690 1.16 jwise mvwaddch(slot_w, Y-1, 1, ' ');
691 1.16 jwise mvwaddch(slot_w, Y-1, 2, ' ');
692 1.16 jwise mvwaddch(slot_w, Y+1, 0, ' ');
693 1.16 jwise mvwaddch(slot_w, Y+1, 1, ' ');
694 1.16 jwise mvwaddch(slot_w, Y+1, 2, ' ');
695 1.16 jwise wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]);
696 1.1 cgd switch (winddir) {
697 1.1 cgd case 1:
698 1.1 cgd case 5:
699 1.16 jwise waddch(slot_w, '|');
700 1.1 cgd break;
701 1.1 cgd case 2:
702 1.1 cgd case 6:
703 1.16 jwise waddch(slot_w, '/');
704 1.1 cgd break;
705 1.1 cgd case 3:
706 1.1 cgd case 7:
707 1.16 jwise waddch(slot_w, '-');
708 1.1 cgd break;
709 1.1 cgd case 4:
710 1.1 cgd case 8:
711 1.16 jwise waddch(slot_w, '\\');
712 1.1 cgd break;
713 1.1 cgd }
714 1.16 jwise mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+');
715 1.16 jwise wrefresh(slot_w);
716 1.1 cgd }
717 1.1 cgd
718 1.7 christos void
719 1.16 jwise draw_board(void)
720 1.1 cgd {
721 1.7 christos int n;
722 1.1 cgd
723 1.35 dholland erase();
724 1.16 jwise werase(view_w);
725 1.16 jwise werase(slot_w);
726 1.16 jwise werase(scroll_w);
727 1.16 jwise werase(stat_w);
728 1.16 jwise werase(turn_w);
729 1.1 cgd
730 1.16 jwise move(BOX_T, BOX_L);
731 1.1 cgd for (n = 0; n < BOX_X; n++)
732 1.16 jwise addch('-');
733 1.16 jwise move(BOX_B, BOX_L);
734 1.1 cgd for (n = 0; n < BOX_X; n++)
735 1.16 jwise addch('-');
736 1.1 cgd for (n = BOX_T+1; n < BOX_B; n++) {
737 1.16 jwise mvaddch(n, BOX_L, '|');
738 1.16 jwise mvaddch(n, BOX_R, '|');
739 1.1 cgd }
740 1.16 jwise mvaddch(BOX_T, BOX_L, '+');
741 1.16 jwise mvaddch(BOX_T, BOX_R, '+');
742 1.16 jwise mvaddch(BOX_B, BOX_L, '+');
743 1.16 jwise mvaddch(BOX_B, BOX_R, '+');
744 1.16 jwise refresh();
745 1.1 cgd
746 1.35 dholland #if 0
747 1.1 cgd #define WSaIM "Wooden Ships & Iron Men"
748 1.16 jwise wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2);
749 1.16 jwise waddstr(view_w, WSaIM);
750 1.16 jwise wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2);
751 1.16 jwise waddstr(view_w, cc->name);
752 1.16 jwise wrefresh(view_w);
753 1.35 dholland #endif
754 1.1 cgd
755 1.16 jwise move(LINE_T, LINE_L);
756 1.16 jwise printw("Class %d %s (%d guns) '%s' (%c%c)",
757 1.1 cgd mc->class,
758 1.1 cgd classname[mc->class],
759 1.1 cgd mc->guns,
760 1.1 cgd ms->shipname,
761 1.1 cgd colours(ms),
762 1.1 cgd sterncolour(ms));
763 1.16 jwise refresh();
764 1.1 cgd }
765 1.1 cgd
766 1.33 dholland void
767 1.35 dholland display_set_obp(int which, bool show)
768 1.35 dholland {
769 1.35 dholland obp[which] = show;
770 1.35 dholland }
771 1.35 dholland
772 1.35 dholland void
773 1.35 dholland display_set_dbp(int which, bool show)
774 1.33 dholland {
775 1.35 dholland dbp[which] = show;
776 1.33 dholland }
777 1.33 dholland
778 1.35 dholland ////////////////////////////////////////////////////////////
779 1.35 dholland // external actions on the display
780 1.35 dholland
781 1.33 dholland void
782 1.35 dholland display_scroll_pageup(void)
783 1.33 dholland {
784 1.35 dholland unsigned total_lines, visible_lines, limit;
785 1.35 dholland unsigned pagesize = SCROLL_Y - 2;
786 1.35 dholland
787 1.35 dholland total_lines = stringarray_num(sc_lines);
788 1.35 dholland visible_lines = SCROLL_Y - 1;
789 1.35 dholland limit = total_lines - visible_lines;
790 1.35 dholland
791 1.35 dholland sc_scrollup += pagesize;
792 1.35 dholland if (sc_scrollup > limit) {
793 1.35 dholland sc_scrollup = limit;
794 1.35 dholland }
795 1.33 dholland }
796 1.33 dholland
797 1.33 dholland void
798 1.35 dholland display_scroll_pagedown(void)
799 1.33 dholland {
800 1.35 dholland unsigned pagesize = SCROLL_Y - 2;
801 1.35 dholland
802 1.35 dholland if (sc_scrollup < pagesize) {
803 1.35 dholland sc_scrollup = 0;
804 1.35 dholland } else {
805 1.35 dholland sc_scrollup -= pagesize;
806 1.35 dholland }
807 1.33 dholland }
808 1.33 dholland
809 1.7 christos void
810 1.16 jwise centerview(void)
811 1.1 cgd {
812 1.1 cgd viewrow = mf->row - VIEW_Y / 2;
813 1.1 cgd viewcol = mf->col - VIEW_X / 2;
814 1.1 cgd }
815 1.1 cgd
816 1.7 christos void
817 1.16 jwise upview(void)
818 1.1 cgd {
819 1.1 cgd viewrow -= VIEW_Y / 3;
820 1.1 cgd }
821 1.1 cgd
822 1.7 christos void
823 1.16 jwise downview(void)
824 1.1 cgd {
825 1.1 cgd viewrow += VIEW_Y / 3;
826 1.1 cgd }
827 1.1 cgd
828 1.7 christos void
829 1.16 jwise leftview(void)
830 1.1 cgd {
831 1.1 cgd viewcol -= VIEW_X / 5;
832 1.1 cgd }
833 1.1 cgd
834 1.7 christos void
835 1.16 jwise rightview(void)
836 1.1 cgd {
837 1.1 cgd viewcol += VIEW_X / 5;
838 1.1 cgd }
839 1.1 cgd
840 1.34 dholland /* Called from newturn()... rename? */
841 1.34 dholland void
842 1.34 dholland display_adjust_view(void)
843 1.1 cgd {
844 1.1 cgd if (dont_adjust)
845 1.1 cgd return;
846 1.1 cgd if (mf->row < viewrow + VIEW_Y/4)
847 1.1 cgd viewrow = mf->row - (VIEW_Y - VIEW_Y/4);
848 1.1 cgd else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4))
849 1.1 cgd viewrow = mf->row - VIEW_Y/4;
850 1.1 cgd if (mf->col < viewcol + VIEW_X/8)
851 1.1 cgd viewcol = mf->col - (VIEW_X - VIEW_X/8);
852 1.1 cgd else if (mf->col > viewcol + (VIEW_X - VIEW_X/8))
853 1.1 cgd viewcol = mf->col - VIEW_X/8;
854 1.1 cgd }
855 1.40 dholland
856 1.40 dholland ////////////////////////////////////////////////////////////
857 1.40 dholland // starting game
858 1.40 dholland
859 1.40 dholland static bool shipselected;
860 1.40 dholland static int loadpos;
861 1.40 dholland
862 1.40 dholland static int
863 1.40 dholland nextload(int load)
864 1.40 dholland {
865 1.40 dholland switch (load) {
866 1.40 dholland case L_ROUND: return L_GRAPE;
867 1.40 dholland case L_GRAPE: return L_CHAIN;
868 1.40 dholland case L_CHAIN: return L_DOUBLE;
869 1.40 dholland case L_DOUBLE: return L_ROUND;
870 1.40 dholland }
871 1.40 dholland return L_ROUND;
872 1.40 dholland }
873 1.40 dholland
874 1.40 dholland static int
875 1.40 dholland loadbychar(int ch)
876 1.40 dholland {
877 1.40 dholland switch (ch) {
878 1.40 dholland case 'r': return L_ROUND;
879 1.40 dholland case 'g': return L_GRAPE;
880 1.40 dholland case 'c': return L_CHAIN;
881 1.40 dholland case 'd': return L_DOUBLE;
882 1.40 dholland }
883 1.40 dholland return L_ROUND;
884 1.40 dholland }
885 1.40 dholland
886 1.40 dholland static const char *
887 1.40 dholland loadstr(int load)
888 1.40 dholland {
889 1.40 dholland switch (load) {
890 1.40 dholland case L_ROUND: return "round";
891 1.40 dholland case L_GRAPE: return "grape";
892 1.40 dholland case L_CHAIN: return "chain";
893 1.40 dholland case L_DOUBLE: return "double";
894 1.40 dholland }
895 1.40 dholland return "???";
896 1.40 dholland }
897 1.40 dholland
898 1.40 dholland static void
899 1.40 dholland displayshiplist(void)
900 1.40 dholland {
901 1.40 dholland struct ship *sp;
902 1.40 dholland int which;
903 1.40 dholland
904 1.40 dholland erase();
905 1.40 dholland
906 1.40 dholland attron(A_BOLD);
907 1.40 dholland mvaddstr(1, 4, cc->name);
908 1.40 dholland attroff(A_BOLD);
909 1.40 dholland
910 1.40 dholland which = 0;
911 1.40 dholland foreachship(sp) {
912 1.40 dholland mvselprintw(which + 3, 4, which, player, 60,
913 1.40 dholland " %2d: %-10s %-15s (%-2d pts) %s",
914 1.40 dholland sp->file->index,
915 1.40 dholland countryname[sp->nationality],
916 1.40 dholland sp->shipname,
917 1.40 dholland sp->specs->pts,
918 1.40 dholland saywhat(sp, 1));
919 1.40 dholland which++;
920 1.40 dholland }
921 1.40 dholland
922 1.40 dholland if (!shipselected) {
923 1.40 dholland mvaddstr(15, 4, "Choose your ship");
924 1.40 dholland move(player + 3, 63);
925 1.40 dholland } else {
926 1.40 dholland mvselprintw(15, 4, 0, loadpos, 32,
927 1.40 dholland "Initial left broadside: %s", loadstr(mf->loadL));
928 1.40 dholland mvselprintw(16, 4, 1, loadpos, 32,
929 1.40 dholland "Initial right broadside: %s", loadstr(mf->loadR));
930 1.40 dholland mvselprintw(17, 4, 2, loadpos, 32, "Set sail");
931 1.40 dholland move(loadpos+15, 35);
932 1.40 dholland }
933 1.40 dholland
934 1.40 dholland wrefresh(stdscr);
935 1.40 dholland }
936 1.40 dholland
937 1.40 dholland static int
938 1.40 dholland pickship(void)
939 1.40 dholland {
940 1.40 dholland struct File *fp;
941 1.40 dholland struct ship *sp;
942 1.40 dholland bool done;
943 1.40 dholland int ch;
944 1.40 dholland
945 1.40 dholland for (;;) {
946 1.40 dholland foreachship(sp)
947 1.40 dholland if (sp->file->captain[0] == 0 && !sp->file->struck
948 1.40 dholland && sp->file->captured == 0)
949 1.40 dholland break;
950 1.40 dholland if (sp >= ls) {
951 1.40 dholland return -1;
952 1.40 dholland }
953 1.40 dholland player = sp - SHIP(0);
954 1.40 dholland if (randomize) {
955 1.40 dholland /* nothing */
956 1.40 dholland } else {
957 1.40 dholland done = false;
958 1.40 dholland while (!done) {
959 1.40 dholland displayshiplist();
960 1.40 dholland
961 1.40 dholland ch = getch();
962 1.40 dholland switch (ch) {
963 1.40 dholland case 12 /*^L*/:
964 1.40 dholland clear();
965 1.40 dholland break;
966 1.40 dholland case '\r':
967 1.40 dholland case '\n':
968 1.40 dholland done = true;
969 1.40 dholland break;
970 1.40 dholland case 7 /*^G*/:
971 1.40 dholland case 8 /*^H*/:
972 1.40 dholland case 27 /*ESC*/:
973 1.40 dholland case 127 /*^?*/:
974 1.40 dholland beep();
975 1.40 dholland break;
976 1.40 dholland case 16 /*^P*/:
977 1.40 dholland case KEY_UP:
978 1.40 dholland up(&player, NULL);
979 1.40 dholland break;
980 1.40 dholland case 14 /*^N*/:
981 1.40 dholland case KEY_DOWN:
982 1.40 dholland down(&player, NULL, cc->vessels,
983 1.40 dholland cc->vessels);
984 1.40 dholland break;
985 1.40 dholland default:
986 1.40 dholland beep();
987 1.40 dholland break;
988 1.40 dholland }
989 1.40 dholland }
990 1.40 dholland }
991 1.40 dholland if (player < 0)
992 1.40 dholland continue;
993 1.40 dholland if (Sync() < 0)
994 1.40 dholland leave(LEAVE_SYNC);
995 1.40 dholland fp = SHIP(player)->file;
996 1.40 dholland if (fp->captain[0] || fp->struck || fp->captured != 0)
997 1.40 dholland oops(16, 4, "That ship is taken.");
998 1.40 dholland else
999 1.40 dholland break;
1000 1.40 dholland }
1001 1.40 dholland return 0;
1002 1.40 dholland }
1003 1.40 dholland
1004 1.40 dholland static void
1005 1.40 dholland pickload(void)
1006 1.40 dholland {
1007 1.40 dholland bool done;
1008 1.40 dholland int ch;
1009 1.40 dholland
1010 1.40 dholland mf->loadL = L_ROUND;
1011 1.40 dholland mf->loadR = L_ROUND;
1012 1.40 dholland
1013 1.40 dholland loadpos = 0;
1014 1.40 dholland done = false;
1015 1.40 dholland while (!done) {
1016 1.40 dholland displayshiplist();
1017 1.40 dholland
1018 1.40 dholland ch = getch();
1019 1.40 dholland switch (ch) {
1020 1.40 dholland case 12 /*^L*/:
1021 1.40 dholland clear();
1022 1.40 dholland break;
1023 1.40 dholland case 'r':
1024 1.40 dholland case 'g':
1025 1.40 dholland case 'c':
1026 1.40 dholland case 'd':
1027 1.40 dholland switch (loadpos) {
1028 1.40 dholland case 0: mf->loadL = loadbychar(ch); break;
1029 1.40 dholland case 1: mf->loadR = loadbychar(ch); break;
1030 1.40 dholland case 2: beep(); break;
1031 1.40 dholland }
1032 1.40 dholland break;
1033 1.40 dholland case '\r':
1034 1.40 dholland case '\n':
1035 1.40 dholland switch (loadpos) {
1036 1.40 dholland case 0: mf->loadL = nextload(mf->loadL); break;
1037 1.40 dholland case 1: mf->loadR = nextload(mf->loadR); break;
1038 1.40 dholland case 2: done = true; break;
1039 1.40 dholland }
1040 1.40 dholland break;
1041 1.40 dholland case 7 /*^G*/:
1042 1.40 dholland case 8 /*^H*/:
1043 1.40 dholland case 27 /*ESC*/:
1044 1.40 dholland case 127 /*^?*/:
1045 1.40 dholland beep();
1046 1.40 dholland break;
1047 1.40 dholland case 16 /*^P*/:
1048 1.40 dholland case KEY_UP:
1049 1.40 dholland up(&loadpos, NULL);
1050 1.40 dholland break;
1051 1.40 dholland case 14 /*^N*/:
1052 1.40 dholland case KEY_DOWN:
1053 1.40 dholland down(&loadpos, NULL, 3, 3);
1054 1.40 dholland break;
1055 1.40 dholland default:
1056 1.40 dholland beep();
1057 1.40 dholland break;
1058 1.40 dholland }
1059 1.40 dholland }
1060 1.40 dholland mf->readyR = R_LOADED|R_INITIAL;
1061 1.40 dholland mf->readyL = R_LOADED|R_INITIAL;
1062 1.40 dholland }
1063 1.40 dholland
1064 1.40 dholland static void
1065 1.40 dholland startgame(void)
1066 1.40 dholland {
1067 1.40 dholland
1068 1.40 dholland ingame = true;
1069 1.40 dholland shipselected = false;
1070 1.40 dholland
1071 1.40 dholland pl_main_init();
1072 1.40 dholland
1073 1.40 dholland hasdriver = sync_exists(game);
1074 1.40 dholland if (sync_open() < 0) {
1075 1.40 dholland oops(21, 10, "syncfile: %s", strerror(errno));
1076 1.40 dholland pl_main_uninit();
1077 1.40 dholland ingame = false;
1078 1.40 dholland return;
1079 1.40 dholland }
1080 1.40 dholland
1081 1.40 dholland if (hasdriver) {
1082 1.40 dholland mvaddstr(21, 10, "Synchronizing with the other players...");
1083 1.40 dholland wrefresh(stdscr);
1084 1.40 dholland fflush(stdout);
1085 1.40 dholland if (Sync() < 0)
1086 1.40 dholland leave(LEAVE_SYNC);
1087 1.40 dholland } else {
1088 1.40 dholland mvaddstr(21, 10, "Starting driver...");
1089 1.40 dholland wrefresh(stdscr);
1090 1.40 dholland fflush(stdout);
1091 1.40 dholland startdriver();
1092 1.40 dholland }
1093 1.40 dholland
1094 1.40 dholland if (pickship() < 0) {
1095 1.40 dholland oops(21, 10, "All ships taken in that scenario.");
1096 1.40 dholland sync_close(0);
1097 1.40 dholland people = 0;
1098 1.40 dholland pl_main_uninit();
1099 1.40 dholland ingame = false;
1100 1.40 dholland return;
1101 1.40 dholland }
1102 1.40 dholland shipselected = true;
1103 1.40 dholland
1104 1.40 dholland ms = SHIP(player);
1105 1.40 dholland mf = ms->file;
1106 1.40 dholland mc = ms->specs;
1107 1.40 dholland
1108 1.40 dholland pickload();
1109 1.40 dholland
1110 1.40 dholland pl_main();
1111 1.40 dholland ingame = false;
1112 1.40 dholland }
1113 1.40 dholland
1114 1.40 dholland ////////////////////////////////////////////////////////////
1115 1.40 dholland // scenario picker
1116 1.40 dholland
1117 1.40 dholland static int pickerpos;
1118 1.40 dholland static int pickerscroll;
1119 1.40 dholland
1120 1.40 dholland static const char *
1121 1.40 dholland absdirectionname(int dir)
1122 1.40 dholland {
1123 1.40 dholland switch (dir) {
1124 1.40 dholland case 1: return "South";
1125 1.40 dholland case 2: return "Southwest";
1126 1.40 dholland case 3: return "West";
1127 1.40 dholland case 4: return "Northwest";
1128 1.40 dholland case 5: return "North";
1129 1.40 dholland case 6: return "Northeast";
1130 1.40 dholland case 7: return "East";
1131 1.40 dholland case 8: return "Southeast";
1132 1.40 dholland }
1133 1.40 dholland return "?";
1134 1.40 dholland }
1135 1.40 dholland
1136 1.40 dholland static const char *
1137 1.40 dholland windname(int wind)
1138 1.40 dholland {
1139 1.40 dholland switch (wind) {
1140 1.40 dholland case 0: return "calm";
1141 1.40 dholland case 1: return "light breeze";
1142 1.40 dholland case 2: return "moderate breeze";
1143 1.40 dholland case 3: return "fresh breeze";
1144 1.40 dholland case 4: return "strong breeze";
1145 1.40 dholland case 5: return "gale";
1146 1.40 dholland case 6: return "full gale";
1147 1.40 dholland case 7: return "hurricane";
1148 1.40 dholland }
1149 1.40 dholland return "???";
1150 1.40 dholland }
1151 1.40 dholland
1152 1.40 dholland static const char *
1153 1.40 dholland nationalityname(int nationality)
1154 1.40 dholland {
1155 1.40 dholland switch (nationality) {
1156 1.40 dholland case N_A: return "a";
1157 1.40 dholland case N_B: return "b";
1158 1.40 dholland case N_S: return "s";
1159 1.40 dholland case N_F: return "f";
1160 1.40 dholland case N_J: return "j";
1161 1.40 dholland case N_D: return "d";
1162 1.40 dholland case N_K: return "k";
1163 1.40 dholland case N_O: return "o";
1164 1.40 dholland }
1165 1.40 dholland return "?";
1166 1.40 dholland }
1167 1.40 dholland
1168 1.40 dholland static void
1169 1.40 dholland drawpicker(void)
1170 1.40 dholland {
1171 1.40 dholland int y, sc, i;
1172 1.40 dholland struct ship *ship;
1173 1.40 dholland
1174 1.40 dholland erase();
1175 1.40 dholland
1176 1.40 dholland mvaddstr(0, 0, "## SHIPS TITLE");
1177 1.40 dholland for (y=1; y<LINES-11; y++) {
1178 1.40 dholland sc = (y-1) + pickerscroll;
1179 1.40 dholland if (sc < NSCENE) {
1180 1.40 dholland mvselprintw(y, 0, sc, pickerpos, 56,
1181 1.40 dholland "%-2d %-5d %s",
1182 1.40 dholland sc, scene[sc].vessels, scene[sc].name);
1183 1.40 dholland }
1184 1.40 dholland }
1185 1.40 dholland
1186 1.40 dholland mvprintw(2, 60 + 2, "%s wind",
1187 1.40 dholland absdirectionname(scene[pickerpos].winddir));
1188 1.40 dholland mvprintw(3, 60 + 2, "(%s)",
1189 1.40 dholland windname(scene[pickerpos].windspeed));
1190 1.40 dholland
1191 1.40 dholland for (i=0; i<scene[pickerpos].vessels; i++) {
1192 1.40 dholland ship = &scene[pickerpos].ship[i];
1193 1.40 dholland mvprintw(LINES-10 + i, 0,
1194 1.40 dholland "(%s) %-16s %3d gun %s (%s crew) (%d pts)",
1195 1.40 dholland nationalityname(ship->nationality),
1196 1.40 dholland ship->shipname,
1197 1.40 dholland ship->specs->guns,
1198 1.40 dholland shortclassname[ship->specs->class],
1199 1.40 dholland qualname[ship->specs->qual],
1200 1.40 dholland ship->specs->pts);
1201 1.40 dholland }
1202 1.40 dholland
1203 1.40 dholland move(1 + pickerpos - pickerscroll, 55);
1204 1.40 dholland wrefresh(stdscr);
1205 1.40 dholland }
1206 1.40 dholland
1207 1.40 dholland static int
1208 1.40 dholland pickscenario(int initpos)
1209 1.40 dholland {
1210 1.40 dholland int ch;
1211 1.40 dholland
1212 1.40 dholland pickerpos = initpos;
1213 1.40 dholland if (pickerpos < 0) {
1214 1.40 dholland pickerpos = 0;
1215 1.40 dholland }
1216 1.40 dholland
1217 1.40 dholland while (1) {
1218 1.40 dholland drawpicker();
1219 1.40 dholland ch = getch();
1220 1.40 dholland switch (ch) {
1221 1.40 dholland case 12 /*^L*/:
1222 1.40 dholland clear();
1223 1.40 dholland break;
1224 1.40 dholland case '\r':
1225 1.40 dholland case '\n':
1226 1.40 dholland return pickerpos;
1227 1.40 dholland case 7 /*^G*/:
1228 1.40 dholland case 8 /*^H*/:
1229 1.40 dholland case 27 /*ESC*/:
1230 1.40 dholland case 127 /*^?*/:
1231 1.40 dholland return initpos;
1232 1.40 dholland case 16 /*^P*/:
1233 1.40 dholland case KEY_UP:
1234 1.40 dholland up(&pickerpos, &pickerscroll);
1235 1.40 dholland break;
1236 1.40 dholland case 14 /*^N*/:
1237 1.40 dholland case KEY_DOWN:
1238 1.40 dholland down(&pickerpos, &pickerscroll, NSCENE, LINES-12);
1239 1.40 dholland break;
1240 1.40 dholland default:
1241 1.40 dholland beep();
1242 1.40 dholland break;
1243 1.40 dholland }
1244 1.40 dholland }
1245 1.40 dholland return pickerpos;
1246 1.40 dholland }
1247 1.40 dholland
1248 1.40 dholland ////////////////////////////////////////////////////////////
1249 1.40 dholland // setup menus
1250 1.40 dholland
1251 1.40 dholland #define MAINITEMS_NUM 5
1252 1.40 dholland #define STARTITEMS_NUM 4
1253 1.40 dholland #define OPTIONSITEMS_NUM 5
1254 1.40 dholland
1255 1.40 dholland static int mainpos;
1256 1.40 dholland static bool connected;
1257 1.40 dholland
1258 1.40 dholland static bool joinactive;
1259 1.40 dholland static int joinpos;
1260 1.40 dholland static int joinscroll;
1261 1.40 dholland static int joinable[NSCENE];
1262 1.40 dholland static int numjoinable;
1263 1.40 dholland
1264 1.40 dholland static bool startactive;
1265 1.40 dholland static int startpos;
1266 1.40 dholland static int startscenario;
1267 1.40 dholland
1268 1.40 dholland static bool optionsactive;
1269 1.40 dholland static int optionspos;
1270 1.40 dholland static char o_myname[MAXNAMESIZE];
1271 1.40 dholland static bool o_randomize;
1272 1.40 dholland static bool o_longfmt;
1273 1.40 dholland static bool o_nobells;
1274 1.40 dholland
1275 1.40 dholland
1276 1.40 dholland /*
1277 1.40 dholland * this and sgetstr() should share code
1278 1.40 dholland */
1279 1.40 dholland static void
1280 1.40 dholland startup_getstr(int y, int x, char *buf, size_t max)
1281 1.40 dholland {
1282 1.40 dholland size_t pos = 0;
1283 1.40 dholland int ch;
1284 1.40 dholland
1285 1.40 dholland for (;;) {
1286 1.40 dholland buf[pos] = 0;
1287 1.40 dholland move(y, x);
1288 1.40 dholland addstr(buf);
1289 1.40 dholland clrtoeol();
1290 1.40 dholland wrefresh(stdscr);
1291 1.40 dholland fflush(stdout);
1292 1.40 dholland
1293 1.40 dholland ch = getch();
1294 1.40 dholland switch (ch) {
1295 1.40 dholland case '\n':
1296 1.40 dholland case '\r':
1297 1.40 dholland return;
1298 1.40 dholland case '\b':
1299 1.40 dholland if (pos > 0) {
1300 1.40 dholland /*waddstr(scroll_w, "\b \b");*/
1301 1.40 dholland pos--;
1302 1.40 dholland }
1303 1.40 dholland break;
1304 1.40 dholland default:
1305 1.40 dholland if (ch >= ' ' && ch < 0x7f && pos < max - 1) {
1306 1.40 dholland buf[pos++] = ch;
1307 1.40 dholland } else {
1308 1.40 dholland beep();
1309 1.40 dholland }
1310 1.40 dholland }
1311 1.40 dholland }
1312 1.40 dholland }
1313 1.40 dholland
1314 1.40 dholland static void
1315 1.40 dholland changename(void)
1316 1.40 dholland {
1317 1.40 dholland mvaddstr(LINES-2, COLS/2, "Enter your name:");
1318 1.40 dholland startup_getstr(LINES-1, COLS/2, o_myname, sizeof(o_myname));
1319 1.40 dholland }
1320 1.40 dholland
1321 1.40 dholland static void
1322 1.40 dholland checkforgames(void)
1323 1.40 dholland {
1324 1.40 dholland int i;
1325 1.40 dholland int prev;
1326 1.40 dholland
1327 1.40 dholland if (numjoinable > 0) {
1328 1.40 dholland prev = joinable[joinpos];
1329 1.40 dholland } else {
1330 1.40 dholland prev = 0;
1331 1.40 dholland }
1332 1.40 dholland
1333 1.40 dholland numjoinable = 0;
1334 1.40 dholland for (i = 0; i < NSCENE; i++) {
1335 1.40 dholland if (!sync_exists(i)) {
1336 1.40 dholland continue;
1337 1.40 dholland }
1338 1.40 dholland if (i < prev) {
1339 1.40 dholland joinpos = numjoinable;
1340 1.40 dholland }
1341 1.40 dholland joinable[numjoinable++] = i;
1342 1.40 dholland }
1343 1.40 dholland if (joinpos > numjoinable) {
1344 1.40 dholland joinpos = (numjoinable > 0) ? numjoinable - 1 : 0;
1345 1.40 dholland }
1346 1.40 dholland if (joinscroll > joinpos) {
1347 1.40 dholland joinscroll = (joinpos > 0) ? joinpos - 1 : 0;
1348 1.40 dholland }
1349 1.40 dholland }
1350 1.40 dholland
1351 1.40 dholland static void
1352 1.40 dholland drawstartmenus(void)
1353 1.40 dholland {
1354 1.40 dholland const int mainy0 = 8;
1355 1.40 dholland const int mainx0 = 12;
1356 1.40 dholland
1357 1.40 dholland erase();
1358 1.40 dholland
1359 1.40 dholland mvaddstr(5, 10, "Wooden Ships & Iron Men");
1360 1.40 dholland
1361 1.40 dholland mvaddselstr(mainy0+0, mainx0, 0, mainpos, 17, "Join a game");
1362 1.40 dholland mvaddselstr(mainy0+1, mainx0, 1, mainpos, 17, "Start a game");
1363 1.40 dholland mvaddselstr(mainy0+2, mainx0, 2, mainpos, 17, "Options");
1364 1.40 dholland mvaddselstr(mainy0+3, mainx0, 3, mainpos, 17, "Show high scores");
1365 1.40 dholland mvaddselstr(mainy0+4, mainx0, 4, mainpos, 17, "Quit");
1366 1.40 dholland
1367 1.40 dholland mvprintw(15, 10, "Captain %s", myname);
1368 1.40 dholland if (connected) {
1369 1.40 dholland mvaddstr(16, 10, "Connected via scratch files.");
1370 1.40 dholland } else {
1371 1.40 dholland mvaddstr(16, 10, "Not connected.");
1372 1.40 dholland }
1373 1.40 dholland
1374 1.40 dholland if (joinactive) {
1375 1.40 dholland int y0, leavey = 0, i, sc;
1376 1.40 dholland
1377 1.40 dholland mvaddstr(0, COLS/2, "## SHIPS TITLE");
1378 1.40 dholland y0 = 1;
1379 1.40 dholland for (i = 0; i < numjoinable; i++) {
1380 1.40 dholland if (i >= joinscroll && i < joinscroll + LINES-1) {
1381 1.40 dholland move(y0 + i - joinscroll, COLS/2);
1382 1.40 dholland if (i == joinpos) {
1383 1.40 dholland attron(A_REVERSE);
1384 1.40 dholland }
1385 1.40 dholland sc = joinable[i];
1386 1.40 dholland printw("%-2d %-5d %s",
1387 1.40 dholland sc, scene[sc].vessels, scene[sc].name);
1388 1.40 dholland if (i == joinpos) {
1389 1.40 dholland filltoeol();
1390 1.40 dholland attroff(A_REVERSE);
1391 1.40 dholland leavey = y0 + i - joinscroll;
1392 1.40 dholland }
1393 1.40 dholland }
1394 1.40 dholland }
1395 1.40 dholland mvaddstr(19, 10, "(Esc to abort)");
1396 1.40 dholland if (numjoinable > 0) {
1397 1.40 dholland mvaddstr(18, 10, "Choose a game to join.");
1398 1.40 dholland move(leavey, COLS-1);
1399 1.40 dholland } else {
1400 1.40 dholland mvaddstr(2, COLS/2, "No games.");
1401 1.40 dholland mvaddstr(18, 10, "Press return to refresh.");
1402 1.40 dholland }
1403 1.40 dholland
1404 1.40 dholland } else if (startactive) {
1405 1.40 dholland const char *name;
1406 1.40 dholland
1407 1.40 dholland mvaddstr(18, 10, "Start a new game");
1408 1.40 dholland mvaddstr(19, 10, "(Esc to abort)");
1409 1.40 dholland mvaddstr(2, COLS/2, "New game");
1410 1.40 dholland
1411 1.40 dholland name = (startscenario < 0) ?
1412 1.40 dholland "not selected" : scene[startscenario].name;
1413 1.40 dholland
1414 1.40 dholland mvselprintw(4, COLS/2, 0, startpos, COLS/2 - 1,
1415 1.40 dholland "Scenario: %s", name);
1416 1.40 dholland mvaddselstr(5, COLS/2, 1, startpos, COLS/2 - 1,
1417 1.40 dholland "Visibility: local");
1418 1.40 dholland mvaddselstr(6, COLS/2, 2, startpos, COLS/2 - 1,
1419 1.40 dholland "Password: unset");
1420 1.40 dholland mvaddselstr(7, COLS/2, 3, startpos, COLS/2 - 1,
1421 1.40 dholland "Start game");
1422 1.40 dholland move(4+startpos, COLS - 2);
1423 1.40 dholland
1424 1.40 dholland } else if (optionsactive) {
1425 1.40 dholland mvaddstr(18, 10, "Adjust options");
1426 1.40 dholland mvaddstr(19, 10, "(Esc to abort)");
1427 1.40 dholland mvaddstr(2, COLS/2, "Adjust options");
1428 1.40 dholland
1429 1.40 dholland mvselprintw(4, COLS/2, 0, optionspos, COLS/2-1,
1430 1.40 dholland "Your name: %s", o_myname);
1431 1.40 dholland mvselprintw(5, COLS/2, 1, optionspos, COLS/2-1,
1432 1.40 dholland "Auto-pick ships: %s", o_randomize ? "ON" : "off");
1433 1.40 dholland mvselprintw(6, COLS/2, 2, optionspos, COLS/2-1,
1434 1.40 dholland "Usernames in scores: %s",
1435 1.40 dholland o_longfmt ? "ON" : "off");
1436 1.40 dholland mvselprintw(7, COLS/2, 3, optionspos, COLS/2-1,
1437 1.40 dholland "Beeping: %s", o_nobells ? "OFF" : "on");
1438 1.40 dholland mvselprintw(8, COLS/2, 4, optionspos, COLS/2-1,
1439 1.40 dholland "Apply changes");
1440 1.40 dholland move(4+optionspos, COLS - 2);
1441 1.40 dholland
1442 1.40 dholland } else {
1443 1.40 dholland move(mainy0 + mainpos, mainx0 + 16);
1444 1.40 dholland }
1445 1.40 dholland
1446 1.40 dholland wrefresh(stdscr);
1447 1.40 dholland fflush(stdout);
1448 1.40 dholland }
1449 1.40 dholland
1450 1.40 dholland void
1451 1.40 dholland startup(void)
1452 1.40 dholland {
1453 1.40 dholland int ch;
1454 1.40 dholland
1455 1.40 dholland connected = false;
1456 1.40 dholland mainpos = 0;
1457 1.40 dholland
1458 1.40 dholland joinactive = false;
1459 1.40 dholland joinpos = 0;
1460 1.40 dholland joinscroll = 0;
1461 1.40 dholland numjoinable = 0;
1462 1.40 dholland
1463 1.40 dholland startactive = false;
1464 1.40 dholland startpos = 0;
1465 1.40 dholland startscenario = -1;
1466 1.40 dholland
1467 1.40 dholland optionsactive = false;
1468 1.40 dholland optionspos = 0;
1469 1.40 dholland
1470 1.40 dholland while (1) {
1471 1.40 dholland if (joinactive) {
1472 1.40 dholland checkforgames();
1473 1.40 dholland }
1474 1.40 dholland drawstartmenus();
1475 1.40 dholland ch = getch();
1476 1.40 dholland switch (ch) {
1477 1.40 dholland case 12 /*^L*/:
1478 1.40 dholland clear();
1479 1.40 dholland break;
1480 1.40 dholland case '\r':
1481 1.40 dholland case '\n':
1482 1.40 dholland if (joinactive && numjoinable > 0) {
1483 1.40 dholland game = joinable[joinpos];
1484 1.40 dholland startgame();
1485 1.40 dholland joinactive = false;
1486 1.40 dholland } else if (startactive) {
1487 1.40 dholland switch (startpos) {
1488 1.40 dholland case 0:
1489 1.40 dholland startscenario = pickscenario(startscenario);
1490 1.40 dholland startpos = 3;
1491 1.40 dholland break;
1492 1.40 dholland case 1:
1493 1.40 dholland case 2:
1494 1.40 dholland oops(21, 10, "That doesn't work yet.");
1495 1.40 dholland break;
1496 1.40 dholland case 3:
1497 1.40 dholland if (startscenario >= 0) {
1498 1.40 dholland game = startscenario;
1499 1.40 dholland /* can't do this here yet */
1500 1.40 dholland /*startdriver();*/
1501 1.40 dholland startgame();
1502 1.40 dholland startactive = false;
1503 1.40 dholland startscenario = -1;
1504 1.40 dholland } else {
1505 1.40 dholland oops(21, 10,
1506 1.40 dholland "Pick a scenario.");
1507 1.40 dholland }
1508 1.40 dholland break;
1509 1.40 dholland }
1510 1.40 dholland } else if (optionsactive) {
1511 1.40 dholland switch (optionspos) {
1512 1.40 dholland case 0: changename(); break;
1513 1.40 dholland case 1: o_randomize = !o_randomize; break;
1514 1.40 dholland case 2: o_longfmt = !o_longfmt; break;
1515 1.40 dholland case 3: o_nobells = !o_nobells; break;
1516 1.40 dholland case 4:
1517 1.40 dholland strlcpy(myname, o_myname,
1518 1.40 dholland sizeof(myname));
1519 1.40 dholland randomize = o_randomize;
1520 1.40 dholland longfmt = o_longfmt;
1521 1.40 dholland nobells = o_nobells;
1522 1.40 dholland optionsactive = false;
1523 1.40 dholland break;
1524 1.40 dholland }
1525 1.40 dholland } else {
1526 1.40 dholland switch (mainpos) {
1527 1.40 dholland case 0: joinactive = true; break;
1528 1.40 dholland case 1: startactive = true; break;
1529 1.40 dholland case 2:
1530 1.40 dholland strlcpy(o_myname, myname,
1531 1.40 dholland sizeof(o_myname));
1532 1.40 dholland o_randomize = randomize;
1533 1.40 dholland o_longfmt = longfmt;
1534 1.40 dholland o_nobells = nobells;
1535 1.40 dholland optionsactive = true;
1536 1.40 dholland break;
1537 1.40 dholland case 3: lo_curses(); break;
1538 1.40 dholland case 4: return;
1539 1.40 dholland }
1540 1.40 dholland }
1541 1.40 dholland break;
1542 1.40 dholland case 7 /*^G*/:
1543 1.40 dholland case 8 /*^H*/:
1544 1.40 dholland case 27 /*ESC*/:
1545 1.40 dholland case 127 /*^?*/:
1546 1.40 dholland if (joinactive) {
1547 1.40 dholland joinactive = false;
1548 1.40 dholland } else if (startactive) {
1549 1.40 dholland startactive = false;
1550 1.40 dholland } else if (optionsactive) {
1551 1.40 dholland optionsactive = false;
1552 1.40 dholland } else {
1553 1.40 dholland /* nothing */
1554 1.40 dholland }
1555 1.40 dholland break;
1556 1.40 dholland case 16 /*^P*/:
1557 1.40 dholland case KEY_UP:
1558 1.40 dholland if (joinactive) {
1559 1.40 dholland up(&joinpos, &joinscroll);
1560 1.40 dholland } else if (startactive) {
1561 1.40 dholland up(&startpos, NULL);
1562 1.40 dholland } else if (optionsactive) {
1563 1.40 dholland up(&optionspos, NULL);
1564 1.40 dholland } else {
1565 1.40 dholland up(&mainpos, NULL);
1566 1.40 dholland }
1567 1.40 dholland break;
1568 1.40 dholland case 14 /*^N*/:
1569 1.40 dholland case KEY_DOWN:
1570 1.40 dholland if (joinactive) {
1571 1.40 dholland down(&joinpos, &joinscroll,
1572 1.40 dholland numjoinable, LINES-1);
1573 1.40 dholland } else if (startactive) {
1574 1.40 dholland down(&startpos, NULL,
1575 1.40 dholland STARTITEMS_NUM, STARTITEMS_NUM);
1576 1.40 dholland } else if (optionsactive) {
1577 1.40 dholland down(&optionspos, NULL,
1578 1.40 dholland OPTIONSITEMS_NUM, OPTIONSITEMS_NUM);
1579 1.40 dholland } else {
1580 1.40 dholland down(&mainpos, NULL,
1581 1.40 dholland MAINITEMS_NUM, MAINITEMS_NUM);
1582 1.40 dholland }
1583 1.40 dholland break;
1584 1.40 dholland default:
1585 1.40 dholland beep();
1586 1.40 dholland break;
1587 1.40 dholland }
1588 1.40 dholland }
1589 1.40 dholland }
1590