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