1 /*	@(#)subs.c	8.1 (Berkeley) 5/31/93			*/
2 /*	$NetBSD: subs.c,v 1.20 2013/09/13 20:46:50 joerg Exp $	*/
3 
4 /*
5  * Copyright (c) 1980, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include "back.h"
34 
35 int     buffnum;
36 static char outbuff[BUFSIZ];
37 
38 static const char plred[] = "Player is red, computer is white.";
39 static const char plwhite[] = "Player is white, computer is red.";
40 static const char nocomp[] = "(No computer play.)";
41 
42 void
43 errexit(const char *s)
44 {
45 	write(2, "\n", 1);
46 	perror(s);
47 	getout(0);
48 }
49 
50 int
51 addbuf(int c)
52 {
53 	buffnum++;
54 	if (buffnum == BUFSIZ) {
55 		if (write(1, outbuff, BUFSIZ) != BUFSIZ)
56 			errexit("addbuf (write):");
57 		buffnum = 0;
58 	}
59 	outbuff[buffnum] = c;
60 	return (0);
61 }
62 
63 void
64 buflush(void)
65 {
66 	if (buffnum < 0)
67 		return;
68 	buffnum++;
69 	if (write(1, outbuff, buffnum) != buffnum)
70 		errexit("buflush (write):");
71 	buffnum = -1;
72 }
73 
74 int
75 readc(void)
76 {
77 	char    c;
78 
79 	if (tflag) {
80 		cline();
81 		newpos();
82 	}
83 	buflush();
84 	if (read(0, &c, 1) != 1)
85 		errexit("readc");
86 #ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
87 	if (c == '\177')
88 		getout(0);
89 #endif
90 	if (c == '\033' || c == '\015')
91 		return ('\n');
92 	if (cflag)
93 		return (c);
94 	if (c == '\014')
95 		return ('R');
96 	if (c >= 'a' && c <= 'z')
97 		return (c & 0137);
98 	return (c);
99 }
100 
101 void
102 writec(int c)
103 {
104 	if (tflag)
105 		fancyc(c);
106 	else
107 		addbuf(c);
108 }
109 
110 void
111 writel(const char *l)
112 {
113 #ifdef DEBUG
114 	const char   *s;
115 
116 	if (trace == NULL)
117 		trace = fopen("bgtrace", "w");
118 
119 	fprintf(trace, "writel: \"");
120 	for (s = l; *s; s++) {
121 		if (*s < ' ' || *s == '\177')
122 			fprintf(trace, "^%c", (*s) ^ 0100);
123 		else
124 			putc(*s, trace);
125 	}
126 	fprintf(trace, "\"\n");
127 	fflush(trace);
128 #endif
129 
130 	while (*l)
131 		writec(*l++);
132 }
133 
134 void
135 proll(struct move *mm)
136 {
137 	if (mm->d0)
138 		mswap(mm);
139 	if (cturn == 1)
140 		writel("Red's roll:  ");
141 	else
142 		writel("White's roll:  ");
143 	writec(mm->D0 + '0');
144 	writec('\040');
145 	writec(mm->D1 + '0');
146 	if (tflag)
147 		cline();
148 }
149 
150 void
151 wrint(int n)
152 {
153 	int     i, j, t;
154 
155 	for (i = 4; i > 0; i--) {
156 		t = 1;
157 		for (j = 0; j < i; j++)
158 			t *= 10;
159 		if (n > t - 1)
160 			writec((n / t) % 10 + '0');
161 	}
162 	writec(n % 10 + '0');
163 }
164 
165 void
166 gwrite(void)
167 {
168 	int     r, c;
169 
170 	r = c = 0;
171 	if (tflag) {
172 		r = curr;
173 		c = curc;
174 		curmove(16, 0);
175 	}
176 	if (gvalue > 1) {
177 		writel("Game value:  ");
178 		wrint(gvalue);
179 		writel(".  ");
180 		if (dlast == -1)
181 			writel(color[0]);
182 		else
183 			writel(color[1]);
184 		writel(" doubled last.");
185 	} else {
186 		switch (pnum) {
187 		case -1:	/* player is red */
188 			writel(plred);
189 			break;
190 		case 0:	/* player is both colors */
191 			writel(nocomp);
192 			break;
193 		case 1:	/* player is white */
194 			writel(plwhite);
195 		}
196 	}
197 
198 	if (rscore || wscore) {
199 		writel("  ");
200 		wrscore();
201 	}
202 	if (tflag) {
203 		cline();
204 		curmove(r, c);
205 	}
206 }
207 
208 int
209 quit(struct move *mm)
210 {
211 
212 	if (tflag) {
213 		curmove(20, 0);
214 		clend();
215 	} else
216 		writec('\n');
217 	writel("Are you sure you want to quit?");
218 	if (yorn(0)) {
219 		if (rfl) {
220 			writel("Would you like to save this game?");
221 			if (yorn(0))
222 				save(mm, 0);
223 		}
224 		cturn = 0;
225 		return (1);
226 	}
227 	return (0);
228 }
229 
230 int
231 yorn(int special)
232 {
233 	char    c;
234 	int     i;
235 
236 	i = 1;
237 	while ((c = readc()) != 'Y' && c != 'N') {
238 		if (special && c == special)
239 			return (2);
240 		if (i) {
241 			if (special) {
242 				writel("  (Y, N, or ");
243 				writec(special);
244 				writec(')');
245 			} else
246 				writel("  (Y or N)");
247 			i = 0;
248 		} else
249 			writec('\007');
250 	}
251 	if (c == 'Y')
252 		writel("  Yes.\n");
253 	else
254 		writel("  No.\n");
255 	if (tflag)
256 		buflush();
257 	return (c == 'Y');
258 }
259 
260 void
261 wrhit(int i)
262 {
263 	writel("Blot hit on ");
264 	wrint(i);
265 	writec('.');
266 	writec('\n');
267 }
268 
269 void
270 nexturn(void)
271 {
272 	int     c;
273 
274 	cturn = -cturn;
275 	c = cturn / abs(cturn);
276 	home = bar;
277 	bar = 25 - bar;
278 	offptr += c;
279 	offopp -= c;
280 	inptr += c;
281 	inopp -= c;
282 	Colorptr += c;
283 	colorptr += c;
284 }
285 
286 void
287 getarg(struct move *mm, char ***arg)
288 {
289 	char  **s;
290 
291 	/* process arguments here.  dashes are ignored, nbrw are ignored if
292 	 * the game is being recovered */
293 
294 	s = *arg;
295 	while (*s && s[0][0] == '-') {
296 		switch (s[0][1]) {
297 
298 			/* don't ask if rules or instructions needed */
299 		case 'n':
300 			if (rflag)
301 				break;
302 			aflag = 0;
303 			args[acnt++] = 'n';
304 			break;
305 
306 			/* player is both red and white */
307 		case 'b':
308 			if (rflag)
309 				break;
310 			pnum = 0;
311 			aflag = 0;
312 			args[acnt++] = 'b';
313 			break;
314 
315 			/* player is red */
316 		case 'r':
317 			if (rflag)
318 				break;
319 			pnum = -1;
320 			aflag = 0;
321 			args[acnt++] = 'r';
322 			break;
323 
324 			/* player is white */
325 		case 'w':
326 			if (rflag)
327 				break;
328 			pnum = 1;
329 			aflag = 0;
330 			args[acnt++] = 'w';
331 			break;
332 
333 			/* print board after move according to following
334 			 * character */
335 		case 'p':
336 			if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
337 				break;
338 			args[acnt++] = 'p';
339 			args[acnt++] = s[0][2];
340 			if (s[0][2] == 'r')
341 				bflag = 1;
342 			if (s[0][2] == 'w')
343 				bflag = -1;
344 			if (s[0][2] == 'b')
345 				bflag = 0;
346 			break;
347 
348 		case 't':
349 			if (s[0][2] == '\0') {	/* get terminal caps */
350 				s++;
351 				tflag = getcaps(*s);
352 			} else
353 				tflag = getcaps(&s[0][2]);
354 			break;
355 
356 		case 's':
357 			s++;
358 			/* recover file */
359 			if (s[0] == NULL) {
360 				writel("No save file named\n");
361 				getout(0);
362 			} else
363 				recover(mm, s[0]);
364 			break;
365 		}
366 		s++;
367 	}
368 	if (s[0] != 0)
369 		recover(mm, s[0]);
370 }
371 
372 void
373 init(void)
374 {
375 	int     i;
376 
377 	for (i = 0; i < 26;)
378 		board[i++] = 0;
379 	board[1] = 2;
380 	board[6] = board[13] = -5;
381 	board[8] = -3;
382 	board[12] = board[19] = 5;
383 	board[17] = 3;
384 	board[24] = -2;
385 	off[0] = off[1] = -15;
386 	in[0] = in[1] = 5;
387 	gvalue = 1;
388 	dlast = 0;
389 }
390 
391 void
392 wrscore(void)
393 {
394 	writel("Score:  ");
395 	writel(color[1]);
396 	writec(' ');
397 	wrint(rscore);
398 	writel(", ");
399 	writel(color[0]);
400 	writec(' ');
401 	wrint(wscore);
402 }
403 
404 void
405 fixtty(struct termios *t)
406 {
407 	if (tflag)
408 		newpos();
409 	buflush();
410 	if (tcsetattr(0, TCSADRAIN, t) < 0)
411 		errexit("fixtty");
412 }
413 
414 void
415 getout(int dummy __unused)
416 {
417 	/* go to bottom of screen */
418 	if (tflag) {
419 		curmove(23, 0);
420 		cline();
421 	} else
422 		writec('\n');
423 
424 	/* fix terminal status */
425 	fixtty(&old);
426 	exit(0);
427 }
428 
429 void
430 roll(struct move *mm)
431 {
432 	char    c;
433 	int     row;
434 	int     col;
435 
436 	row = col = 0;
437 	if (iroll) {
438 		if (tflag) {
439 			row = curr;
440 			col = curc;
441 			curmove(17, 0);
442 		} else
443 			writec('\n');
444 		writel("ROLL: ");
445 		c = readc();
446 		if (c != '\n') {
447 			while (c < '1' || c > '6')
448 				c = readc();
449 			mm->D0 = c - '0';
450 			writec(' ');
451 			writec(c);
452 			c = readc();
453 			while (c < '1' || c > '6')
454 				c = readc();
455 			mm->D1 = c - '0';
456 			writec(' ');
457 			writec(c);
458 			if (tflag) {
459 				curmove(17, 0);
460 				cline();
461 				curmove(row, col);
462 			} else
463 				writec('\n');
464 			return;
465 		}
466 		if (tflag) {
467 			curmove(17, 0);
468 			cline();
469 			curmove(row, col);
470 		} else
471 			writec('\n');
472 	}
473 	mm->D0 = rnum(6) + 1;
474 	mm->D1 = rnum(6) + 1;
475 	mm->d0 = 0;
476 }
477