bdisp.c revision 1.14
1/*	$NetBSD: bdisp.c,v 1.14 2010/03/29 03:51:55 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
35#include <sys/cdefs.h>
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)bdisp.c	8.2 (Berkeley) 5/3/95";
39#else
40__RCSID("$NetBSD: bdisp.c,v 1.14 2010/03/29 03:51:55 dholland Exp $");
41#endif
42#endif /* not lint */
43
44#include <curses.h>
45#include <string.h>
46#include <stdlib.h>
47#include <err.h>
48#include "gomoku.h"
49
50#define	SCRNH		24		/* assume 24 lines for the moment */
51#define	SCRNW		80		/* assume 80 chars for the moment */
52
53static	int	lastline;
54static	char	pcolor[] = "*O.?";
55
56extern int interactive;
57extern char *plyr[];
58
59/*
60 * Initialize screen display.
61 */
62void
63cursinit(void)
64{
65
66	if (!initscr()) {
67		errx(EXIT_FAILURE, "Couldn't initialize screen");
68	}
69	if ((LINES < SCRNH) || (COLS < SCRNW)) {
70		errx(EXIT_FAILURE, "Screen too small (need %d%xd)",
71		    SCRNW, SCRNH);
72	}
73	keypad(stdscr, TRUE);
74	nonl();
75	noecho();
76	cbreak();
77	leaveok(stdscr, FALSE);
78
79#if 0 /* no mouse support in netbsd curses yet */
80	mousemask(BUTTON1_CLICKED, NULL);
81#endif
82}
83
84/*
85 * Restore screen display.
86 */
87void
88cursfini(void)
89{
90
91	move(BSZ4, 0);
92	clrtoeol();
93	refresh();
94	echo();
95	endwin();
96}
97
98/*
99 * Initialize board display.
100 */
101void
102bdisp_init(void)
103{
104	int i, j;
105
106	/* top border */
107	for (i = 1; i < BSZ1; i++) {
108		move(0, 2 * i + 1);
109		addch(letters[i]);
110	}
111	/* left and right edges */
112	for (j = BSZ1; --j > 0; ) {
113		move(20 - j, 0);
114		printw("%2d ", j);
115		move(20 - j, 2 * BSZ1 + 1);
116		printw("%d ", j);
117	}
118	/* bottom border */
119	for (i = 1; i < BSZ1; i++) {
120		move(20, 2 * i + 1);
121		addch(letters[i]);
122	}
123	bdwho(0);
124	move(0, 47);
125	addstr("#  black  white");
126	lastline = 0;
127	bdisp();
128}
129
130/*
131 * Update who is playing whom.
132 */
133void
134bdwho(int update)
135{
136	int i, j;
137
138	move(21, 0);
139        printw("                                              ");
140	i = strlen(plyr[BLACK]);
141	j = strlen(plyr[WHITE]);
142	if (i + j <= 20) {
143		move(21, 10 - (i+j)/2);
144		printw("BLACK/%s (*) vs. WHITE/%s (O)",
145		    plyr[BLACK], plyr[WHITE]);
146	} else {
147		move(21, 0);
148		if (i <= 10) {
149			j = 20 - i;
150		} else if (j <= 10) {
151			i = 20 - j;
152		} else {
153			i = j = 10;
154		}
155		printw("BLACK/%.*s (*) vs. WHITE/%.*s (O)",
156		    i, plyr[BLACK], j, plyr[WHITE]);
157	}
158	if (update)
159		refresh();
160}
161
162/*
163 * Update the board display after a move.
164 */
165void
166bdisp(void)
167{
168	int i, j, c;
169	struct spotstr *sp;
170
171	for (j = BSZ1; --j > 0; ) {
172		for (i = 1; i < BSZ1; i++) {
173			move(BSZ1 - j, 2 * i + 1);
174			sp = &board[i + j * BSZ1];
175			if (debug > 1 && sp->s_occ == EMPTY) {
176				if (sp->s_flags & IFLAGALL)
177					c = '+';
178				else if (sp->s_flags & CFLAGALL)
179					c = '-';
180				else
181					c = '.';
182			} else
183				c = pcolor[sp->s_occ];
184			addch(c);
185		}
186	}
187	refresh();
188}
189
190#ifdef DEBUG
191/*
192 * Dump board display to a file.
193 */
194void
195bdump(FILE *fp)
196{
197	int i, j, c;
198	struct spotstr *sp;
199
200	/* top border */
201	fprintf(fp, "   A B C D E F G H J K L M N O P Q R S T\n");
202
203	for (j = BSZ1; --j > 0; ) {
204		/* left edge */
205		fprintf(fp, "%2d ", j);
206		for (i = 1; i < BSZ1; i++) {
207			sp = &board[i + j * BSZ1];
208			if (debug > 1 && sp->s_occ == EMPTY) {
209				if (sp->s_flags & IFLAGALL)
210					c = '+';
211				else if (sp->s_flags & CFLAGALL)
212					c = '-';
213				else
214					c = '.';
215			} else
216				c = pcolor[sp->s_occ];
217			putc(c, fp);
218			putc(' ', fp);
219		}
220		/* right edge */
221		fprintf(fp, "%d\n", j);
222	}
223
224	/* bottom border */
225	fprintf(fp, "   A B C D E F G H J K L M N O P Q R S T\n");
226}
227#endif /* DEBUG */
228
229/*
230 * Display a transcript entry
231 */
232void
233dislog(const char *str)
234{
235
236	if (++lastline >= SCRNH - 1) {
237		/* move 'em up */
238		lastline = 1;
239	}
240	move(lastline, TRANSCRIPT_COL);
241	addnstr(str, SCRNW - TRANSCRIPT_COL - 1);
242	clrtoeol();
243	move(lastline + 1, TRANSCRIPT_COL);
244	clrtoeol();
245}
246
247/*
248 * Display a question.
249 */
250
251void
252ask(const char *str)
253{
254	int len = strlen(str);
255
256	move(BSZ4, 0);
257	addstr(str);
258	clrtoeol();
259	move(BSZ4, len);
260	refresh();
261}
262
263int
264get_line(char *buf, int size)
265{
266	char *cp, *end;
267	int c;
268
269	c = 0;
270	cp = buf;
271	end = buf + size - 1;	/* save room for the '\0' */
272	while (cp < end && (c = getchar()) != EOF && c != '\n' && c != '\r') {
273		*cp++ = c;
274		if (interactive) {
275			switch (c) {
276			case 0x0c: /* ^L */
277				wrefresh(curscr);
278				cp--;
279				continue;
280			case 0x15: /* ^U */
281			case 0x18: /* ^X */
282				while (cp > buf) {
283					cp--;
284					addch('\b');
285				}
286				clrtoeol();
287				break;
288			case '\b':
289			case 0x7f: /* DEL */
290				if (cp == buf + 1) {
291					cp--;
292					continue;
293				}
294				cp -= 2;
295				addch('\b');
296				c = ' ';
297				/* FALLTHROUGH */
298			default:
299				addch(c);
300			}
301			refresh();
302		}
303	}
304	*cp = '\0';
305	return(c != EOF);
306}
307
308/*
309 * Decent (n)curses interface for the game, based on Eric S. Raymond's
310 * modifications to the battleship (bs) user interface.
311 */
312int
313get_coord(void)
314{
315	static int curx = BSZ / 2;
316	static int cury = BSZ / 2;
317	int ny, nx, ch;
318
319	BGOTO(cury, curx);
320	refresh();
321	nx = curx;
322	ny = cury;
323	for (;;) {
324		mvprintw(BSZ3, (BSZ -6)/2, "(%c %d)",
325				'A'+ ((curx > 7) ? (curx+1) : curx), cury + 1);
326		BGOTO(cury, curx);
327
328		ch = getch();
329		switch (ch) {
330		case 'k':
331		case '8':
332		case KEY_UP:
333			nx = curx;
334			ny = cury + 1;
335			break;
336		case 'j':
337		case '2':
338		case KEY_DOWN:
339			nx = curx;
340			ny = BSZ + cury - 1;
341			break;
342		case 'h':
343		case '4':
344		case KEY_LEFT:
345			nx = BSZ + curx - 1;
346			ny = cury;
347			break;
348		case 'l':
349		case '6':
350		case KEY_RIGHT:
351			nx = curx + 1;
352			ny = cury;
353			break;
354		case 'y':
355		case '7':
356		case KEY_A1:
357			nx = BSZ + curx - 1;
358			ny = cury + 1;
359			break;
360		case 'b':
361		case '1':
362		case KEY_C1:
363			nx = BSZ + curx - 1;
364			ny = BSZ + cury - 1;
365			break;
366		case 'u':
367		case '9':
368		case KEY_A3:
369			nx = curx + 1;
370			ny = cury + 1;
371			break;
372		case 'n':
373		case '3':
374		case KEY_C3:
375			nx = curx + 1;
376			ny = BSZ + cury - 1;
377			break;
378		case 'K':
379			nx = curx;
380			ny = cury + 5;
381			break;
382		case 'J':
383			nx = curx;
384			ny = BSZ + cury - 5;
385			break;
386		case 'H':
387			nx = BSZ + curx - 5;
388			ny = cury;
389			break;
390		case 'L':
391			nx = curx + 5;
392			ny = cury;
393			break;
394		case 'Y':
395		        nx = BSZ + curx - 5;
396			ny = cury + 5;
397			break;
398		case 'B':
399			nx = BSZ + curx - 5;
400			ny = BSZ + cury - 5;
401			break;
402		case 'U':
403			nx = curx + 5;
404			ny = cury + 5;
405			break;
406		case 'N':
407			nx = curx + 5;
408			ny = BSZ + cury - 5;
409			break;
410		case '\f':
411			nx = curx;
412			ny = cury;
413			(void)clearok(stdscr, TRUE);
414			(void)refresh();
415			break;
416#if 0 /* notyet */
417		case KEY_MOUSE:
418		{
419			MEVENT	myevent;
420
421			getmouse(&myevent);
422			if (myevent.y >= 1 && myevent.y <= BSZ1 &&
423			    myevent.x >= 3 && myevent.x <= (2 * BSZ + 1)) {
424				curx = (myevent.x - 3) / 2;
425				cury = BSZ - myevent.y;
426				return PT(curx,cury);
427			} else {
428				beep();
429			}
430		}
431		break;
432#endif /* 0 */
433		case 'Q':
434			return RESIGN;
435			break;
436		case 'S':
437			return SAVE;
438			break;
439		case ' ':
440		case '\r':
441			(void) mvaddstr(BSZ3, (BSZ -6)/2, "      ");
442			return PT(curx+1,cury+1);
443			break;
444	}
445
446	curx = nx % BSZ;
447	cury = ny % BSZ;
448    }
449}
450