1/*	$NetBSD: table.c,v 1.10 2009/08/12 05:17:57 dholland Exp $	*/
2
3/*
4 * Copyright (c) 1980, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33#ifndef lint
34#if 0
35static char sccsid[] = "@(#)table.c	8.1 (Berkeley) 5/31/93";
36#else
37__RCSID("$NetBSD: table.c,v 1.10 2009/08/12 05:17:57 dholland Exp $");
38#endif
39#endif /* not lint */
40
41#include "back.h"
42
43static const char *const help2[] = {
44	"   Enter moves as <s>-<f> or <s>/<r> where <s> is the starting",
45	"position, <f> is the finishing position, and <r> is the roll.",
46	"Remember, each die roll must be moved separately.",
47	0
48};
49
50struct state {
51	char    ch;
52	int     fcode;
53	int     newst;
54};
55
56static const struct state atmata[] = {
57
58	{'R', 1, 0},	{'?', 7, 0},	{'Q', 0, -3},	{'B', 8, 25},
59	{'9', 2, 25},	{'8', 2, 25},	{'7', 2, 25},	{'6', 2, 25},
60	{'5', 2, 25},	{'4', 2, 25},	{'3', 2, 25},	{'2', 2, 19},
61	{'1', 2, 15},	{'0', 2, 25},	{'.', 0, 0},	{'9', 2, 25},
62	{'8', 2, 25},	{'7', 2, 25},	{'6', 2, 25},	{'5', 2, 25},
63
64	{'4', 2, 25},	{'3', 2, 25},	{'2', 2, 25},	{'1', 2, 25},
65	{'0', 2, 25},	{'/', 0, 32},	{'-', 0, 39},	{'.', 0, 0},
66	{'/', 5, 32},	{' ', 6, 3},	{',', 6, 3},	{'\n', 0, -1},
67	{'6', 3, 28},	{'5', 3, 28},	{'4', 3, 28},	{'3', 3, 28},
68	{'2', 3, 28},	{'1', 3, 28},	{'.', 0, 0},	{'H', 9, 61},
69
70	{'9', 4, 61},	{'8', 4, 61},	{'7', 4, 61},	{'6', 4, 61},
71	{'5', 4, 61},	{'4', 4, 61},	{'3', 4, 61},	{'2', 4, 53},
72	{'1', 4, 51},	{'0', 4, 61},	{'.', 0, 0},	{'9', 4, 61},
73	{'8', 4, 61},	{'7', 4, 61},	{'6', 4, 61},	{'5', 4, 61},
74	{'4', 4, 61},	{'3', 4, 61},	{'2', 4, 61},	{'1', 4, 61},
75
76	{'0', 4, 61},	{' ', 6, 3},	{',', 6, 3},	{'-', 5, 39},
77	{'\n', 0, -1},	{'.', 0, 0}
78};
79
80static int dotable(int, int);
81static int rsetbrd(void);
82
83int
84checkmove(int ist)
85{
86	int     j, n;
87	char    c;
88
89domove:
90	if (ist == 0) {
91		if (tflag)
92			curmove(curr, 32);
93		else
94			writel("\t\t");
95		writel("Move:  ");
96	}
97	ist = mvl = ncin = 0;
98	for (j = 0; j < 5; j++)
99		p[j] = g[j] = -1;
100
101dochar:
102	c = readc();
103
104	if (c == 'S') {
105		raflag = 0;
106		save(1);
107		if (tflag) {
108			curmove(cturn == -1 ? 18 : 19, 39);
109			ist = -1;
110			goto domove;
111		} else {
112			proll();
113			ist = 0;
114			goto domove;
115		}
116	}
117	if (c == old.c_cc[VERASE] && ncin > 0) {
118		if (tflag)
119			curmove(curr, curc - 1);
120		else {
121			if (old.c_cc[VERASE] == '\010')
122				writel("\010 \010");
123			else
124				writec(cin[ncin - 1]);
125		}
126		ncin--;
127		n = rsetbrd();
128		if (n == 0) {
129			n = -1;
130			if (tflag)
131				refresh();
132		}
133		if ((ist = n) > 0)
134			goto dochar;
135		goto domove;
136	}
137	if (c == old.c_cc[VKILL] && ncin > 0) {
138		if (tflag) {
139			refresh();
140			curmove(curr, 39);
141			ist = -1;
142			goto domove;
143		} else
144			if (old.c_cc[VERASE] == '\010') {
145				for (j = 0; j < ncin; j++)
146					writel("\010 \010");
147				ist = -1;
148				goto domove;
149			} else {
150				writec('\\');
151				writec('\n');
152				proll();
153				ist = 0;
154				goto domove;
155			}
156	}
157	n = dotable(c, ist);
158	if (n >= 0) {
159		cin[ncin++] = c;
160		if (n > 2)
161			if ((!tflag) || c != '\n')
162				writec(c);
163		ist = n;
164		if (n)
165			goto dochar;
166		else
167			goto domove;
168	}
169	if (n == -1 && mvl >= mvlim)
170		return (0);
171	if (n == -1 && mvl < mvlim - 1)
172		return (-4);
173
174	if (n == -6) {
175		if (!tflag) {
176			if (movokay(mvl + 1)) {
177				wrboard();
178				movback(mvl + 1);
179			}
180			proll();
181			writel("\t\tMove:  ");
182			for (j = 0; j < ncin;)
183				writec(cin[j++]);
184		} else {
185			if (movokay(mvl + 1)) {
186				refresh();
187				movback(mvl + 1);
188			} else
189				curmove(cturn == -1 ? 18 : 19, ncin + 39);
190		}
191		ist = n = rsetbrd();
192		goto dochar;
193	}
194	if (n != -5)
195		return (n);
196	writec('\007');
197	goto dochar;
198}
199
200static int
201dotable(int c, int i)
202{
203	int     a;
204	int     test;
205
206	test = (c == 'R');
207
208	while ((a = atmata[i].ch) != '.') {
209		if (a == c || (test && a == '\n')) {
210			switch (atmata[i].fcode) {
211
212			case 1:
213				wrboard();
214				if (tflag) {
215					curmove(cturn == -1 ? 18 : 19, 0);
216					proll();
217					writel("\t\t");
218				} else
219					proll();
220				break;
221
222			case 2:
223				if (p[mvl] == -1)
224					p[mvl] = c - '0';
225				else
226					p[mvl] = p[mvl] * 10 + c - '0';
227				break;
228
229			case 3:
230				if (g[mvl] != -1) {
231					if (mvl < mvlim)
232						mvl++;
233					p[mvl] = p[mvl - 1];
234				}
235				g[mvl] = p[mvl] + cturn * (c - '0');
236				if (g[mvl] < 0)
237					g[mvl] = 0;
238				if (g[mvl] > 25)
239					g[mvl] = 25;
240				break;
241
242			case 4:
243				if (g[mvl] == -1)
244					g[mvl] = c - '0';
245				else
246					g[mvl] = g[mvl] * 10 + c - '0';
247				break;
248
249			case 5:
250				if (mvl < mvlim)
251					mvl++;
252				p[mvl] = g[mvl - 1];
253				break;
254
255			case 6:
256				if (mvl < mvlim)
257					mvl++;
258				break;
259
260			case 7:
261				if (tflag)
262					curmove(20, 0);
263				else
264					writec('\n');
265				(void) wrtext(help2);
266				if (tflag) {
267					curmove(cturn == -1 ? 18 : 19, 39);
268				} else {
269					writec('\n');
270					proll();
271					writel("\t\tMove:  ");
272				}
273				break;
274
275			case 8:
276				p[mvl] = bar;
277				break;
278
279			case 9:
280				g[mvl] = home;
281			}
282
283			if (!test || a != '\n')
284				return (atmata[i].newst);
285			else
286				return (-6);
287		}
288		i++;
289	}
290
291	return (-5);
292}
293
294static int
295rsetbrd(void)
296{
297	int     i, j, n;
298
299	n = 0;
300	mvl = 0;
301	for (i = 0; i < 4; i++)
302		p[i] = g[i] = -1;
303	for (j = 0; j < ncin; j++)
304		if ((n = dotable(cin[j], n)) < 0)
305			return n;
306	return (n);
307}
308