1/* $NetBSD: table.c,v 1.12 2012/10/13 18:44:15 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.12 2012/10/13 18:44:15 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 int mvl; /* working copy of move->mvlim */ 57 58static const struct state atmata[] = { 59 60 {'R', 1, 0}, {'?', 7, 0}, {'Q', 0, -3}, {'B', 8, 25}, 61 {'9', 2, 25}, {'8', 2, 25}, {'7', 2, 25}, {'6', 2, 25}, 62 {'5', 2, 25}, {'4', 2, 25}, {'3', 2, 25}, {'2', 2, 19}, 63 {'1', 2, 15}, {'0', 2, 25}, {'.', 0, 0}, {'9', 2, 25}, 64 {'8', 2, 25}, {'7', 2, 25}, {'6', 2, 25}, {'5', 2, 25}, 65 66 {'4', 2, 25}, {'3', 2, 25}, {'2', 2, 25}, {'1', 2, 25}, 67 {'0', 2, 25}, {'/', 0, 32}, {'-', 0, 39}, {'.', 0, 0}, 68 {'/', 5, 32}, {' ', 6, 3}, {',', 6, 3}, {'\n', 0, -1}, 69 {'6', 3, 28}, {'5', 3, 28}, {'4', 3, 28}, {'3', 3, 28}, 70 {'2', 3, 28}, {'1', 3, 28}, {'.', 0, 0}, {'H', 9, 61}, 71 72 {'9', 4, 61}, {'8', 4, 61}, {'7', 4, 61}, {'6', 4, 61}, 73 {'5', 4, 61}, {'4', 4, 61}, {'3', 4, 61}, {'2', 4, 53}, 74 {'1', 4, 51}, {'0', 4, 61}, {'.', 0, 0}, {'9', 4, 61}, 75 {'8', 4, 61}, {'7', 4, 61}, {'6', 4, 61}, {'5', 4, 61}, 76 {'4', 4, 61}, {'3', 4, 61}, {'2', 4, 61}, {'1', 4, 61}, 77 78 {'0', 4, 61}, {' ', 6, 3}, {',', 6, 3}, {'-', 5, 39}, 79 {'\n', 0, -1}, {'.', 0, 0} 80}; 81 82static int dotable(struct move *, int, int); 83static int rsetbrd(struct move *); 84 85int 86checkmove(struct move *mm, int ist) 87{ 88 int j, n; 89 char c; 90 91domove: 92 if (ist == 0) { 93 if (tflag) 94 curmove(curr, 32); 95 else 96 writel("\t\t"); 97 writel("Move: "); 98 } 99 ist = mvl = ncin = 0; 100 for (j = 0; j < 5; j++) 101 mm->p[j] = mm->g[j] = -1; 102 103dochar: 104 c = readc(); 105 106 if (c == 'S') { 107 raflag = 0; 108 save(mm, 1); 109 if (tflag) { 110 curmove(cturn == -1 ? 18 : 19, 39); 111 ist = -1; 112 goto domove; 113 } else { 114 proll(mm); 115 ist = 0; 116 goto domove; 117 } 118 } 119 if (c == old.c_cc[VERASE] && ncin > 0) { 120 if (tflag) 121 curmove(curr, curc - 1); 122 else { 123 if (old.c_cc[VERASE] == '\010') 124 writel("\010 \010"); 125 else 126 writec(cin[ncin - 1]); 127 } 128 ncin--; 129 n = rsetbrd(mm); 130 if (n == 0) { 131 n = -1; 132 if (tflag) 133 refresh(); 134 } 135 if ((ist = n) > 0) 136 goto dochar; 137 goto domove; 138 } 139 if (c == old.c_cc[VKILL] && ncin > 0) { 140 if (tflag) { 141 refresh(); 142 curmove(curr, 39); 143 ist = -1; 144 goto domove; 145 } else 146 if (old.c_cc[VERASE] == '\010') { 147 for (j = 0; j < ncin; j++) 148 writel("\010 \010"); 149 ist = -1; 150 goto domove; 151 } else { 152 writec('\\'); 153 writec('\n'); 154 proll(mm); 155 ist = 0; 156 goto domove; 157 } 158 } 159 n = dotable(mm, c, ist); 160 if (n >= 0) { 161 cin[ncin++] = c; 162 if (n > 2) 163 if ((!tflag) || c != '\n') 164 writec(c); 165 ist = n; 166 if (n) 167 goto dochar; 168 else 169 goto domove; 170 } 171 if (n == -1 && mvl >= mm->mvlim) 172 return (0); 173 if (n == -1 && mvl < mm->mvlim - 1) 174 return (-4); 175 176 if (n == -6) { 177 if (!tflag) { 178 if (movokay(mm, mvl + 1)) { 179 wrboard(); 180 movback(mm, mvl + 1); 181 } 182 proll(mm); 183 writel("\t\tMove: "); 184 for (j = 0; j < ncin;) 185 writec(cin[j++]); 186 } else { 187 if (movokay(mm, mvl + 1)) { 188 refresh(); 189 movback(mm, mvl + 1); 190 } else 191 curmove(cturn == -1 ? 18 : 19, ncin + 39); 192 } 193 ist = n = rsetbrd(mm); 194 goto dochar; 195 } 196 if (n != -5) 197 return (n); 198 writec('\007'); 199 goto dochar; 200} 201 202static int 203dotable(struct move *mm, int c, int i) 204{ 205 int a; 206 int test; 207 208 test = (c == 'R'); 209 210 while ((a = atmata[i].ch) != '.') { 211 if (a == c || (test && a == '\n')) { 212 switch (atmata[i].fcode) { 213 214 case 1: 215 wrboard(); 216 if (tflag) { 217 curmove(cturn == -1 ? 18 : 19, 0); 218 proll(mm); 219 writel("\t\t"); 220 } else 221 proll(mm); 222 break; 223 224 case 2: 225 if (mm->p[mvl] == -1) 226 mm->p[mvl] = c - '0'; 227 else 228 mm->p[mvl] = mm->p[mvl] * 10 + c - '0'; 229 break; 230 231 case 3: 232 if (mm->g[mvl] != -1) { 233 if (mvl < mm->mvlim) 234 mvl++; 235 mm->p[mvl] = mm->p[mvl - 1]; 236 } 237 mm->g[mvl] = mm->p[mvl] + cturn * (c - '0'); 238 if (mm->g[mvl] < 0) 239 mm->g[mvl] = 0; 240 if (mm->g[mvl] > 25) 241 mm->g[mvl] = 25; 242 break; 243 244 case 4: 245 if (mm->g[mvl] == -1) 246 mm->g[mvl] = c - '0'; 247 else 248 mm->g[mvl] = mm->g[mvl] * 10 + c - '0'; 249 break; 250 251 case 5: 252 if (mvl < mm->mvlim) 253 mvl++; 254 mm->p[mvl] = mm->g[mvl - 1]; 255 break; 256 257 case 6: 258 if (mvl < mm->mvlim) 259 mvl++; 260 break; 261 262 case 7: 263 if (tflag) 264 curmove(20, 0); 265 else 266 writec('\n'); 267 (void) wrtext(help2); 268 if (tflag) { 269 curmove(cturn == -1 ? 18 : 19, 39); 270 } else { 271 writec('\n'); 272 proll(mm); 273 writel("\t\tMove: "); 274 } 275 break; 276 277 case 8: 278 mm->p[mvl] = bar; 279 break; 280 281 case 9: 282 mm->g[mvl] = home; 283 } 284 285 if (!test || a != '\n') 286 return (atmata[i].newst); 287 else 288 return (-6); 289 } 290 i++; 291 } 292 293 return (-5); 294} 295 296static int 297rsetbrd(struct move *mm) 298{ 299 int i, j, n; 300 301 n = 0; 302 mvl = 0; 303 for (i = 0; i < 4; i++) 304 mm->p[i] = mm->g[i] = -1; 305 for (j = 0; j < ncin; j++) 306 if ((n = dotable(mm, cin[j], n)) < 0) 307 return n; 308 return (n); 309} 310