games - misc - clean up compiler warnings
[games.git] / games / hack / hack.termcap.c
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.termcap.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.termcap.c,v 1.10 1999/11/16 10:26:38 marcel Exp $ */
4 /* $DragonFly: src/games/hack/hack.termcap.c,v 1.5 2006/08/21 19:45:32 pavalos Exp $ */
5
6 #include <termcap.h>
7 #include "hack.h"
8
9 static char tbuf[512];
10 static char *HO, *CL, *CE, *tcUP, *CM, *ND, *XD, *tcBC, *SO, *SE, *TI, *TE;
11 static char *VS, *VE;
12 static int SG;
13 static char tcPC = '\0';
14 char *CD;               /* tested in pri.c: docorner() */
15 int CO, LI;             /* used in pri.c and whatis.c */
16
17 static void     nocmov(int, int);
18 static void     cmov(int, int);
19 static int      xputc(int);
20 static int      xputs(char *);
21
22 void
23 startup(void)
24 {
25         char *term;
26         char *tptr;
27         char *tbufptr, *pc;
28
29         tptr = (char *) alloc(1024);
30
31         tbufptr = tbuf;
32         if(!(term = getenv("TERM")))
33                 error("Can't get TERM.");
34         if(tgetent(tptr, term) < 1)
35                 error("Unknown terminal type: %s.", term);
36         if (tgetflag(__DECONST(char *, "NP")) ||
37             tgetflag(__DECONST(char *, "nx")))
38                 flags.nonull = 1;
39         if((pc = tgetstr(__DECONST(char *, "pc"), &tbufptr)))
40                 tcPC = *pc;
41         if(!(tcBC = tgetstr(__DECONST(char *, "bc"), &tbufptr))
42             &&!(tcBC = tgetstr(__DECONST(char *, "le"), &tbufptr))) {
43                 if(!tgetflag(__DECONST(char *, "bs")))
44                         error("Terminal must backspace.");
45                 tcBC = tbufptr;
46                 tbufptr += 2;
47                 *tcBC = '\b';
48         }
49         HO = tgetstr(__DECONST(char *, "ho"), &tbufptr);
50         CO = tgetnum(__DECONST(char *, "co"));
51         LI = tgetnum(__DECONST(char *, "li"));
52         if(CO < COLNO || LI < ROWNO+2)
53                 setclipped();
54         if(!(CL = tgetstr(__DECONST(char *, "cl"), &tbufptr)))
55                 error("Hack needs CL.");
56         ND = tgetstr(__DECONST(char *, "nd"), &tbufptr);
57         if(tgetflag(__DECONST(char *, "os")))
58                 error("Hack can't have OS.");
59         CE = tgetstr(__DECONST(char *, "ce"), &tbufptr);
60         tcUP = tgetstr(__DECONST(char *, "up"), &tbufptr);
61         /* It seems that xd is no longer supported, and we should use
62            a linefeed instead; unfortunately this requires resetting
63            CRMOD, and many output routines will have to be modified
64            slightly. Let's leave that till the next release. */
65         XD = tgetstr(__DECONST(char *, "xd"), &tbufptr);
66 /* not:                 XD = tgetstr("do", &tbufptr); */
67         if(!(CM = tgetstr(__DECONST(char *, "cm"), &tbufptr))) {
68                 if(!tcUP && !HO)
69                         error("Hack needs CM or UP or HO.");
70                 printf("Playing hack on terminals without cm is suspect...\n");
71                 getret();
72         }
73         SO = tgetstr(__DECONST(char *, "so"), &tbufptr);
74         SE = tgetstr(__DECONST(char *, "se"), &tbufptr);
75         SG = tgetnum(__DECONST(char *, "sg"));
76         if(!SO || !SE || (SG > 0)) SO = SE = 0;
77         CD = tgetstr(__DECONST(char *, "cd"), &tbufptr);
78         set_whole_screen();             /* uses LI and CD */
79         if(tbufptr-tbuf > (int)sizeof(tbuf)) error("TERMCAP entry too big...\n");
80         free(tptr);
81 }
82
83 void
84 start_screen(void)
85 {
86         xputs(TI);
87         xputs(VS);
88 }
89
90 void
91 end_screen(void)
92 {
93         xputs(VE);
94         xputs(TE);
95 }
96
97 /* not xchar: perhaps xchar is unsigned and curx-x would be unsigned as well */
98 void
99 curs(int x, int y)
100 {
101
102         if (y == cury && x == curx)
103                 return;
104         if(!ND && (curx != x || x <= 3)) {      /* Extremely primitive */
105                 cmov(x, y);                     /* bunker!wtm */
106                 return;
107         }
108         if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
109                 nocmov(x, y);
110         else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
111                 putchar('\r');
112                 curx = 1;
113                 nocmov(x, y);
114         } else if(!CM) {
115                 nocmov(x, y);
116         } else
117                 cmov(x, y);
118 }
119
120 static void
121 nocmov(int x, int y)
122 {
123         if (cury > y) {
124                 if(tcUP) {
125                         while (cury > y) {      /* Go up. */
126                                 xputs(tcUP);
127                                 cury--;
128                         }
129                 } else if(CM) {
130                         cmov(x, y);
131                 } else if(HO) {
132                         home();
133                         curs(x, y);
134                 } /* else impossible("..."); */
135         } else if (cury < y) {
136                 if(XD) {
137                         while(cury < y) {
138                                 xputs(XD);
139                                 cury++;
140                         }
141                 } else if(CM) {
142                         cmov(x, y);
143                 } else {
144                         while(cury < y) {
145                                 xputc('\n');
146                                 curx = 1;
147                                 cury++;
148                         }
149                 }
150         }
151         if (curx < x) {         /* Go to the right. */
152                 if(!ND) cmov(x, y); else        /* bah */
153                         /* should instead print what is there already */
154                 while (curx < x) {
155                         xputs(ND);
156                         curx++;
157                 }
158         } else if (curx > x) {
159                 while (curx > x) {      /* Go to the left. */
160                         xputs(tcBC);
161                         curx--;
162                 }
163         }
164 }
165
166 static void
167 cmov(int x, int y)
168 {
169         xputs(tgoto(CM, x-1, y-1));
170         cury = y;
171         curx = x;
172 }
173
174 static int
175 xputc(int c)
176 {
177         return(fputc(c, stdout));
178 }
179
180 static int
181 xputs(char *s)
182 {
183         return(tputs(s, 1, xputc));
184 }
185
186 void
187 cl_end(void)
188 {
189         if(CE)
190                 xputs(CE);
191         else {  /* no-CE fix - free after Harold Rynes */
192                 /* this looks terrible, especially on a slow terminal
193                    but is better than nothing */
194                 int cx = curx, cy = cury;
195
196                 while(curx < COLNO) {
197                         xputc(' ');
198                         curx++;
199                 }
200                 curs(cx, cy);
201         }
202 }
203
204 void
205 clear_screen(void)
206 {
207         xputs(CL);
208         curx = cury = 1;
209 }
210
211 void
212 home(void)
213 {
214         if(HO)
215                 xputs(HO);
216         else if(CM)
217                 xputs(tgoto(CM, 0, 0));
218         else
219                 curs(1, 1);     /* using tcUP ... */
220         curx = cury = 1;
221 }
222
223 void
224 standoutbeg(void)
225 {
226         if(SO) xputs(SO);
227 }
228
229 void
230 standoutend(void)
231 {
232         if(SE) xputs(SE);
233 }
234
235 void
236 backsp(void)
237 {
238         xputs(tcBC);
239         curx--;
240 }
241
242 void
243 bell(void)
244 {
245         putchar('\007');                /* curx does not change */
246         fflush(stdout);
247 }
248
249 void
250 cl_eos(void)                    /* free after Robert Viduya */
251 {                               /* must only be called with curx = 1 */
252
253         if(CD)
254                 xputs(CD);
255         else {
256                 int cx = curx, cy = cury;
257                 while(cury <= LI-2) {
258                         cl_end();
259                         xputc('\n');
260                         curx = 1;
261                         cury++;
262                 }
263                 cl_end();
264                 curs(cx, cy);
265         }
266 }