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