Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / games / hack / hack.termcap.c
CommitLineData
984263bc
MD
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 $ */
c7106d58 4/* $DragonFly: src/games/hack/hack.termcap.c,v 1.5 2006/08/21 19:45:32 pavalos Exp $ */
984263bc 5
984263bc 6#include <termcap.h>
c7106d58 7#include "hack.h"
984263bc
MD
8
9static char tbuf[512];
2f052168 10static char *HO, *CL, *CE, *tcUP, *CM, *ND, *XD, *tcBC, *SO, *SE, *TI, *TE;
984263bc
MD
11static char *VS, *VE;
12static int SG;
2f052168 13static char tcPC = '\0';
984263bc
MD
14char *CD; /* tested in pri.c: docorner() */
15int CO, LI; /* used in pri.c and whatis.c */
16
c7106d58
PA
17static void nocmov(int, int);
18static void cmov(int, int);
19static int xputc(int);
20static int xputs(char *);
21
22void
23startup(void)
984263bc
MD
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);
fd2d026f
YT
36 if (tgetflag(__DECONST(char *, "NP")) ||
37 tgetflag(__DECONST(char *, "nx")))
984263bc 38 flags.nonull = 1;
c7106d58 39 if((pc = tgetstr(__DECONST(char *, "pc"), &tbufptr)))
2f052168 40 tcPC = *pc;
fd2d026f
YT
41 if(!(tcBC = tgetstr(__DECONST(char *, "bc"), &tbufptr))) {
42 if(!tgetflag(__DECONST(char *, "bs")))
984263bc 43 error("Terminal must backspace.");
2f052168 44 tcBC = tbufptr;
984263bc 45 tbufptr += 2;
2f052168 46 *tcBC = '\b';
984263bc 47 }
fd2d026f
YT
48 HO = tgetstr(__DECONST(char *, "ho"), &tbufptr);
49 CO = tgetnum(__DECONST(char *, "co"));
50 LI = tgetnum(__DECONST(char *, "li"));
984263bc
MD
51 if(CO < COLNO || LI < ROWNO+2)
52 setclipped();
fd2d026f 53 if(!(CL = tgetstr(__DECONST(char *, "cl"), &tbufptr)))
984263bc 54 error("Hack needs CL.");
fd2d026f
YT
55 ND = tgetstr(__DECONST(char *, "nd"), &tbufptr);
56 if(tgetflag(__DECONST(char *, "os")))
984263bc 57 error("Hack can't have OS.");
fd2d026f
YT
58 CE = tgetstr(__DECONST(char *, "ce"), &tbufptr);
59 tcUP = tgetstr(__DECONST(char *, "up"), &tbufptr);
984263bc
MD
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. */
fd2d026f 64 XD = tgetstr(__DECONST(char *, "xd"), &tbufptr);
984263bc 65/* not: XD = tgetstr("do", &tbufptr); */
fd2d026f 66 if(!(CM = tgetstr(__DECONST(char *, "cm"), &tbufptr))) {
2f052168 67 if(!tcUP && !HO)
984263bc
MD
68 error("Hack needs CM or UP or HO.");
69 printf("Playing hack on terminals without cm is suspect...\n");
70 getret();
71 }
fd2d026f
YT
72 SO = tgetstr(__DECONST(char *, "so"), &tbufptr);
73 SE = tgetstr(__DECONST(char *, "se"), &tbufptr);
74 SG = tgetnum(__DECONST(char *, "sg"));
984263bc 75 if(!SO || !SE || (SG > 0)) SO = SE = 0;
fd2d026f 76 CD = tgetstr(__DECONST(char *, "cd"), &tbufptr);
984263bc 77 set_whole_screen(); /* uses LI and CD */
c7106d58 78 if(tbufptr-tbuf > (int)sizeof(tbuf)) error("TERMCAP entry too big...\n");
984263bc
MD
79 free(tptr);
80}
81
c7106d58
PA
82void
83start_screen(void)
984263bc
MD
84{
85 xputs(TI);
86 xputs(VS);
87}
88
c7106d58
PA
89void
90end_screen(void)
984263bc
MD
91{
92 xputs(VE);
93 xputs(TE);
94}
95
c7106d58
PA
96/* not xchar: perhaps xchar is unsigned and curx-x would be unsigned as well */
97void
98curs(int x, int y)
984263bc
MD
99{
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))) {
c7106d58 110 putchar('\r');
984263bc
MD
111 curx = 1;
112 nocmov(x, y);
113 } else if(!CM) {
114 nocmov(x, y);
115 } else
116 cmov(x, y);
117}
118
c7106d58
PA
119static void
120nocmov(int x, int y)
984263bc
MD
121{
122 if (cury > y) {
2f052168 123 if(tcUP) {
984263bc 124 while (cury > y) { /* Go up. */
2f052168 125 xputs(tcUP);
984263bc
MD
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) cmov(x, y); else /* bah */
152 /* should instead print what is there already */
153 while (curx < x) {
154 xputs(ND);
155 curx++;
156 }
157 } else if (curx > x) {
158 while (curx > x) { /* Go to the left. */
2f052168 159 xputs(tcBC);
984263bc
MD
160 curx--;
161 }
162 }
163}
164
c7106d58
PA
165static void
166cmov(int x, int y)
984263bc
MD
167{
168 xputs(tgoto(CM, x-1, y-1));
169 cury = y;
170 curx = x;
171}
172
c7106d58
PA
173static int
174xputc(int c)
175{
176 return(fputc(c, stdout));
984263bc
MD
177}
178
c7106d58
PA
179static int
180xputs(char *s)
181{
182 return(tputs(s, 1, xputc));
984263bc
MD
183}
184
c7106d58
PA
185void
186cl_end(void)
187{
984263bc
MD
188 if(CE)
189 xputs(CE);
190 else { /* no-CE fix - free after Harold Rynes */
191 /* this looks terrible, especially on a slow terminal
192 but is better than nothing */
193 int cx = curx, cy = cury;
194
195 while(curx < COLNO) {
196 xputc(' ');
197 curx++;
198 }
199 curs(cx, cy);
200 }
201}
202
c7106d58
PA
203void
204clear_screen(void)
205{
984263bc
MD
206 xputs(CL);
207 curx = cury = 1;
208}
209
c7106d58
PA
210void
211home(void)
984263bc
MD
212{
213 if(HO)
214 xputs(HO);
215 else if(CM)
216 xputs(tgoto(CM, 0, 0));
217 else
2f052168 218 curs(1, 1); /* using tcUP ... */
984263bc
MD
219 curx = cury = 1;
220}
221
c7106d58
PA
222void
223standoutbeg(void)
984263bc
MD
224{
225 if(SO) xputs(SO);
226}
227
c7106d58
PA
228void
229standoutend(void)
984263bc
MD
230{
231 if(SE) xputs(SE);
232}
233
c7106d58
PA
234void
235backsp(void)
984263bc 236{
2f052168 237 xputs(tcBC);
984263bc
MD
238 curx--;
239}
240
c7106d58
PA
241void
242bell(void)
984263bc 243{
c7106d58
PA
244 putchar('\007'); /* curx does not change */
245 fflush(stdout);
984263bc 246}
984263bc 247
c7106d58
PA
248void
249cl_eos(void) /* free after Robert Viduya */
984263bc
MD
250{ /* must only be called with curx = 1 */
251
252 if(CD)
253 xputs(CD);
254 else {
255 int cx = curx, cy = cury;
256 while(cury <= LI-2) {
257 cl_end();
258 xputc('\n');
259 curx = 1;
260 cury++;
261 }
262 cl_end();
263 curs(cx, cy);
264 }
265}