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