1 /* $NetBSD: bdisp.c,v 1.17 2014/03/22 18:58:57 dholland Exp $ */
2
3 /*
4 * Copyright (c) 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Ralph Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)bdisp.c 8.2 (Berkeley) 5/3/95
35 */
36
37 #include <curses.h>
38 #include <string.h>
39 #include <stdlib.h>
40 #include <err.h>
41 #include "gomoku.h"
42
43 #define SCRNH 24 /* assume 24 lines for the moment */
44 #define SCRNW 80 /* assume 80 chars for the moment */
45
46 static int lastline;
47 static char pcolor[] = "*O.?";
48
49 /*
50 * Initialize screen display.
51 */
52 void
cursinit(void)53 cursinit(void)
54 {
55
56 if (!initscr()) {
57 errx(EXIT_FAILURE, "Couldn't initialize screen");
58 }
59 if ((LINES < SCRNH) || (COLS < SCRNW)) {
60 errx(EXIT_FAILURE, "Screen too small (need %d%xd)",
61 SCRNW, SCRNH);
62 }
63 keypad(stdscr, TRUE);
64 nonl();
65 noecho();
66 cbreak();
67 leaveok(stdscr, FALSE);
68
69 #if 0 /* no mouse support in netbsd curses yet */
70 mousemask(BUTTON1_CLICKED, NULL);
71 #endif
72 }
73
74 /*
75 * Restore screen display.
76 */
77 void
cursfini(void)78 cursfini(void)
79 {
80
81 move(BSZ4, 0);
82 clrtoeol();
83 refresh();
84 echo();
85 endwin();
86 }
87
88 /*
89 * Initialize board display.
90 */
91 void
bdisp_init(void)92 bdisp_init(void)
93 {
94 int i, j;
95
96 /* top border */
97 for (i = 1; i < BSZ1; i++) {
98 move(0, 2 * i + 1);
99 addch(letters[i]);
100 }
101 /* left and right edges */
102 for (j = BSZ1; --j > 0; ) {
103 move(20 - j, 0);
104 printw("%2d ", j);
105 move(20 - j, 2 * BSZ1 + 1);
106 printw("%d ", j);
107 }
108 /* bottom border */
109 for (i = 1; i < BSZ1; i++) {
110 move(20, 2 * i + 1);
111 addch(letters[i]);
112 }
113 bdwho(0);
114 move(0, 47);
115 addstr("# black white");
116 lastline = 0;
117 bdisp();
118 }
119
120 /*
121 * Update who is playing whom.
122 */
123 void
bdwho(int update)124 bdwho(int update)
125 {
126 int i, j;
127
128 move(21, 0);
129 printw(" ");
130 i = strlen(plyr[BLACK]);
131 j = strlen(plyr[WHITE]);
132 if (i + j <= 20) {
133 move(21, 10 - (i+j)/2);
134 printw("BLACK/%s (*) vs. WHITE/%s (O)",
135 plyr[BLACK], plyr[WHITE]);
136 } else {
137 move(21, 0);
138 if (i <= 10) {
139 j = 20 - i;
140 } else if (j <= 10) {
141 i = 20 - j;
142 } else {
143 i = j = 10;
144 }
145 printw("BLACK/%.*s (*) vs. WHITE/%.*s (O)",
146 i, plyr[BLACK], j, plyr[WHITE]);
147 }
148 if (update)
149 refresh();
150 }
151
152 /*
153 * Update the board display after a move.
154 */
155 void
bdisp(void)156 bdisp(void)
157 {
158 int i, j, c;
159 struct spotstr *sp;
160
161 for (j = BSZ1; --j > 0; ) {
162 for (i = 1; i < BSZ1; i++) {
163 move(BSZ1 - j, 2 * i + 1);
164 sp = &board[i + j * BSZ1];
165 if (debug > 1 && sp->s_occ == EMPTY) {
166 if (sp->s_flags & IFLAGALL)
167 c = '+';
168 else if (sp->s_flags & CFLAGALL)
169 c = '-';
170 else
171 c = '.';
172 } else
173 c = pcolor[sp->s_occ];
174 addch(c);
175 }
176 }
177 refresh();
178 }
179
180 #ifdef DEBUG
181 /*
182 * Dump board display to a file.
183 */
184 void
bdump(FILE * fp)185 bdump(FILE *fp)
186 {
187 int i, j, c;
188 struct spotstr *sp;
189
190 /* top border */
191 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
192
193 for (j = BSZ1; --j > 0; ) {
194 /* left edge */
195 fprintf(fp, "%2d ", j);
196 for (i = 1; i < BSZ1; i++) {
197 sp = &board[i + j * BSZ1];
198 if (debug > 1 && sp->s_occ == EMPTY) {
199 if (sp->s_flags & IFLAGALL)
200 c = '+';
201 else if (sp->s_flags & CFLAGALL)
202 c = '-';
203 else
204 c = '.';
205 } else
206 c = pcolor[sp->s_occ];
207 putc(c, fp);
208 putc(' ', fp);
209 }
210 /* right edge */
211 fprintf(fp, "%d\n", j);
212 }
213
214 /* bottom border */
215 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
216 }
217 #endif /* DEBUG */
218
219 /*
220 * Display a transcript entry
221 */
222 void
dislog(const char * str)223 dislog(const char *str)
224 {
225
226 if (++lastline >= SCRNH - 1) {
227 /* move 'em up */
228 lastline = 1;
229 }
230 move(lastline, TRANSCRIPT_COL);
231 addnstr(str, SCRNW - TRANSCRIPT_COL - 1);
232 clrtoeol();
233 move(lastline + 1, TRANSCRIPT_COL);
234 clrtoeol();
235 }
236
237 /*
238 * Display a question.
239 */
240
241 void
ask(const char * str)242 ask(const char *str)
243 {
244 int len = strlen(str);
245
246 move(BSZ4, 0);
247 addstr(str);
248 clrtoeol();
249 move(BSZ4, len);
250 refresh();
251 }
252
253 int
get_key(const char * allowed)254 get_key(const char *allowed)
255 {
256 int ch;
257
258 while (1) {
259 ch = getch();
260 if (allowed != NULL &&
261 ch != '\0' && strchr(allowed, ch) == NULL) {
262 beep();
263 refresh();
264 continue;
265 }
266 break;
267 }
268 return ch;
269 }
270
271 int
get_line(char * buf,int size)272 get_line(char *buf, int size)
273 {
274 char *cp, *end;
275 int c;
276
277 c = 0;
278 cp = buf;
279 end = buf + size - 1; /* save room for the '\0' */
280 while (cp < end && (c = getchar()) != EOF && c != '\n' && c != '\r') {
281 *cp++ = c;
282 if (interactive) {
283 switch (c) {
284 case 0x0c: /* ^L */
285 wrefresh(curscr);
286 cp--;
287 continue;
288 case 0x15: /* ^U */
289 case 0x18: /* ^X */
290 while (cp > buf) {
291 cp--;
292 addch('\b');
293 }
294 clrtoeol();
295 break;
296 case '\b':
297 case 0x7f: /* DEL */
298 if (cp == buf + 1) {
299 cp--;
300 continue;
301 }
302 cp -= 2;
303 addch('\b');
304 c = ' ';
305 /* FALLTHROUGH */
306 default:
307 addch(c);
308 }
309 refresh();
310 }
311 }
312 *cp = '\0';
313 return(c != EOF);
314 }
315
316 /*
317 * Decent (n)curses interface for the game, based on Eric S. Raymond's
318 * modifications to the battleship (bs) user interface.
319 */
320 int
get_coord(void)321 get_coord(void)
322 {
323 static int curx = BSZ / 2;
324 static int cury = BSZ / 2;
325 int ny, nx, ch;
326
327 BGOTO(cury, curx);
328 refresh();
329 nx = curx;
330 ny = cury;
331 for (;;) {
332 mvprintw(BSZ3, (BSZ -6)/2, "(%c %d) ",
333 'A'+ ((curx > 7) ? (curx+1) : curx), cury + 1);
334 BGOTO(cury, curx);
335
336 ch = getch();
337 switch (ch) {
338 case 'k':
339 case '8':
340 case KEY_UP:
341 nx = curx;
342 ny = cury + 1;
343 break;
344 case 'j':
345 case '2':
346 case KEY_DOWN:
347 nx = curx;
348 ny = BSZ + cury - 1;
349 break;
350 case 'h':
351 case '4':
352 case KEY_LEFT:
353 nx = BSZ + curx - 1;
354 ny = cury;
355 break;
356 case 'l':
357 case '6':
358 case KEY_RIGHT:
359 nx = curx + 1;
360 ny = cury;
361 break;
362 case 'y':
363 case '7':
364 case KEY_A1:
365 nx = BSZ + curx - 1;
366 ny = cury + 1;
367 break;
368 case 'b':
369 case '1':
370 case KEY_C1:
371 nx = BSZ + curx - 1;
372 ny = BSZ + cury - 1;
373 break;
374 case 'u':
375 case '9':
376 case KEY_A3:
377 nx = curx + 1;
378 ny = cury + 1;
379 break;
380 case 'n':
381 case '3':
382 case KEY_C3:
383 nx = curx + 1;
384 ny = BSZ + cury - 1;
385 break;
386 case 'K':
387 nx = curx;
388 ny = cury + 5;
389 break;
390 case 'J':
391 nx = curx;
392 ny = BSZ + cury - 5;
393 break;
394 case 'H':
395 nx = BSZ + curx - 5;
396 ny = cury;
397 break;
398 case 'L':
399 nx = curx + 5;
400 ny = cury;
401 break;
402 case 'Y':
403 nx = BSZ + curx - 5;
404 ny = cury + 5;
405 break;
406 case 'B':
407 nx = BSZ + curx - 5;
408 ny = BSZ + cury - 5;
409 break;
410 case 'U':
411 nx = curx + 5;
412 ny = cury + 5;
413 break;
414 case 'N':
415 nx = curx + 5;
416 ny = BSZ + cury - 5;
417 break;
418 case '\f':
419 nx = curx;
420 ny = cury;
421 (void)clearok(stdscr, TRUE);
422 (void)refresh();
423 break;
424 #if 0 /* notyet */
425 case KEY_MOUSE:
426 {
427 MEVENT myevent;
428
429 getmouse(&myevent);
430 if (myevent.y >= 1 && myevent.y <= BSZ1 &&
431 myevent.x >= 3 && myevent.x <= (2 * BSZ + 1)) {
432 curx = (myevent.x - 3) / 2;
433 cury = BSZ - myevent.y;
434 return PT(curx,cury);
435 } else {
436 beep();
437 }
438 }
439 break;
440 #endif /* 0 */
441 case 'Q':
442 case 'q':
443 return RESIGN;
444 break;
445 case 'S':
446 case 's':
447 return SAVE;
448 break;
449 case ' ':
450 case '\r':
451 (void) mvaddstr(BSZ3, (BSZ -6)/2, " ");
452 return PT(curx+1,cury+1);
453 break;
454 }
455
456 curx = nx % BSZ;
457 cury = ny % BSZ;
458 }
459 }
460