]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.termcap.c
Spell "privilege" correctly (correct spelling from Jonathan Stone).
[bsdgames-darwin.git] / hack / hack.termcap.c
1 /* $NetBSD: hack.termcap.c,v 1.8 1999/08/14 16:36:42 tron Exp $ */
2
3 /*
4 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5 */
6
7 #include <sys/cdefs.h>
8 #ifndef lint
9 __RCSID("$NetBSD: hack.termcap.c,v 1.8 1999/08/14 16:36:42 tron Exp $");
10 #endif /* not lint */
11
12 #include <string.h>
13 #include <termios.h>
14 #include <termcap.h>
15 #include <stdlib.h>
16 #include "hack.h"
17 #include "extern.h"
18 #include "def.flag.h" /* for flags.nonull */
19
20 static char tbuf[512];
21 static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
22 static char *VS, *VE;
23 static int SG;
24 static char PC = '\0';
25 char *CD; /* tested in pri.c: docorner() */
26 int CO, LI; /* used in pri.c and whatis.c */
27
28 void
29 startup()
30 {
31 char *term;
32 char *tptr;
33 char *tbufptr, *pc;
34
35 tptr = (char *) alloc(1024);
36
37 tbufptr = tbuf;
38 if (!(term = getenv("TERM")))
39 error("Can't get TERM.");
40 if (!strncmp(term, "5620", 4))
41 flags.nonull = 1; /* this should be a termcap flag */
42 if (tgetent(tptr, term) < 1)
43 error("Unknown terminal type: %s.", term);
44 if ((pc = tgetstr("pc", &tbufptr)) != NULL)
45 PC = *pc;
46 if (!(BC = tgetstr("bc", &tbufptr))) {
47 if (!tgetflag("bs"))
48 error("Terminal must backspace.");
49 BC = tbufptr;
50 tbufptr += 2;
51 *BC = '\b';
52 }
53 HO = tgetstr("ho", &tbufptr);
54 CO = tgetnum("co");
55 LI = tgetnum("li");
56 if (CO < COLNO || LI < ROWNO + 2)
57 setclipped();
58 if (!(CL = tgetstr("cl", &tbufptr)))
59 error("Hack needs CL.");
60 ND = tgetstr("nd", &tbufptr);
61 if (tgetflag("os"))
62 error("Hack can't have OS.");
63 CE = tgetstr("ce", &tbufptr);
64 UP = tgetstr("up", &tbufptr);
65 /*
66 * It seems that xd is no longer supported, and we should use a
67 * linefeed instead; unfortunately this requires resetting CRMOD, and
68 * many output routines will have to be modified slightly. Let's
69 * leave that till the next release.
70 */
71 XD = tgetstr("xd", &tbufptr);
72 /* not: XD = tgetstr("do", &tbufptr); */
73 if (!(CM = tgetstr("cm", &tbufptr))) {
74 if (!UP && !HO)
75 error("Hack needs CM or UP or HO.");
76 printf("Playing hack on terminals without cm is suspect...\n");
77 getret();
78 }
79 SO = tgetstr("so", &tbufptr);
80 SE = tgetstr("se", &tbufptr);
81 SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */
82 if (!SO || !SE || (SG > 0))
83 SO = SE = 0;
84 CD = tgetstr("cd", &tbufptr);
85 set_whole_screen(); /* uses LI and CD */
86 if (tbufptr - tbuf > sizeof(tbuf))
87 error("TERMCAP entry too big...\n");
88 free(tptr);
89 }
90
91 void
92 start_screen()
93 {
94 xputs(TI);
95 xputs(VS);
96 }
97
98 void
99 end_screen()
100 {
101 xputs(VE);
102 xputs(TE);
103 }
104
105 /* Cursor movements */
106 void
107 curs(x, y)
108 int x, y; /* not xchar: perhaps xchar is unsigned and
109 * curx-x would be unsigned as well */
110 {
111
112 if (y == cury && x == curx)
113 return;
114 if (!ND && (curx != x || x <= 3)) { /* Extremely primitive */
115 cmov(x, y); /* bunker!wtm */
116 return;
117 }
118 if (abs(cury - y) <= 3 && abs(curx - x) <= 3)
119 nocmov(x, y);
120 else if ((x <= 3 && abs(cury - y) <= 3) || (!CM && x < abs(curx - x))) {
121 (void) putchar('\r');
122 curx = 1;
123 nocmov(x, y);
124 } else if (!CM) {
125 nocmov(x, y);
126 } else
127 cmov(x, y);
128 }
129
130 void
131 nocmov(x, y)
132 int x, y;
133 {
134 if (cury > y) {
135 if (UP) {
136 while (cury > y) { /* Go up. */
137 xputs(UP);
138 cury--;
139 }
140 } else if (CM) {
141 cmov(x, y);
142 } else if (HO) {
143 home();
144 curs(x, y);
145 } /* else impossible("..."); */
146 } else if (cury < y) {
147 if (XD) {
148 while (cury < y) {
149 xputs(XD);
150 cury++;
151 }
152 } else if (CM) {
153 cmov(x, y);
154 } else {
155 while (cury < y) {
156 xputc('\n');
157 curx = 1;
158 cury++;
159 }
160 }
161 }
162 if (curx < x) { /* Go to the right. */
163 if (!ND)
164 cmov(x, y);
165 else /* bah */
166 /* should instead print what is there already */
167 while (curx < x) {
168 xputs(ND);
169 curx++;
170 }
171 } else if (curx > x) {
172 while (curx > x) { /* Go to the left. */
173 xputs(BC);
174 curx--;
175 }
176 }
177 }
178
179 void
180 cmov(x, y)
181 int x, y;
182 {
183 xputs(tgoto(CM, x - 1, y - 1));
184 cury = y;
185 curx = x;
186 }
187
188 void
189 xputc(c)
190 char c;
191 {
192 (void) fputc(c, stdout);
193 }
194
195 void
196 xputs(s)
197 char *s;
198 {
199 tputs(s, 1, xputc);
200 }
201
202 void
203 cl_end()
204 {
205 if (CE)
206 xputs(CE);
207 else { /* no-CE fix - free after Harold Rynes */
208 /*
209 * this looks terrible, especially on a slow terminal but is
210 * better than nothing
211 */
212 int cx = curx, cy = cury;
213
214 while (curx < COLNO) {
215 xputc(' ');
216 curx++;
217 }
218 curs(cx, cy);
219 }
220 }
221
222 void
223 clear_screen()
224 {
225 xputs(CL);
226 curx = cury = 1;
227 }
228
229 void
230 home()
231 {
232 if (HO)
233 xputs(HO);
234 else if (CM)
235 xputs(tgoto(CM, 0, 0));
236 else
237 curs(1, 1); /* using UP ... */
238 curx = cury = 1;
239 }
240
241 void
242 standoutbeg()
243 {
244 if (SO)
245 xputs(SO);
246 }
247
248 void
249 standoutend()
250 {
251 if (SE)
252 xputs(SE);
253 }
254
255 void
256 backsp()
257 {
258 xputs(BC);
259 curx--;
260 }
261
262 void
263 bell()
264 {
265 (void) putchar('\007'); /* curx does not change */
266 (void) fflush(stdout);
267 }
268
269 void
270 delay_output()
271 {
272 /* delay 50 ms - could also use a 'nap'-system call */
273 /*
274 * BUG: if the padding character is visible, as it is on the 5620
275 * then this looks terrible.
276 */
277 if (!flags.nonull)
278 tputs("50", 1, xputc);
279
280 /* cbosgd!cbcephus!pds for SYS V R2 */
281 /* is this terminfo, or what? */
282 /* tputs("$<50>", 1, xputc); */
283
284 else if (ospeed > 0)
285 if (CM) {
286 /*
287 * delay by sending cm(here) an appropriate number of
288 * times
289 */
290 int cmlen = strlen(tgoto(CM, curx - 1, cury - 1));
291 int i = (ospeed + (100 * cmlen)) / (200 * cmlen);
292
293 while (i > 0) {
294 cmov(curx, cury);
295 }
296 }
297 }
298
299 void
300 cl_eos()
301 { /* free after Robert Viduya *//* must only be
302 * called with curx = 1 */
303
304 if (CD)
305 xputs(CD);
306 else {
307 int cx = curx, cy = cury;
308 while (cury <= LI - 2) {
309 cl_end();
310 xputc('\n');
311 curx = 1;
312 cury++;
313 }
314 cl_end();
315 curs(cx, cy);
316 }
317 }