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