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