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