tcsh: fix warning to keep compiling with WARNS=2
[dragonfly.git] / games / hack / hack.termcap.c
blobbaf06a5bfa713803520c69656830998b0189b1f9
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 /* $DragonFly: src/games/hack/hack.termcap.c,v 1.5 2006/08/21 19:45:32 pavalos Exp $ */
6 #include <termcap.h>
7 #include "hack.h"
9 static char tbuf[512];
10 static char *HO, *CL, *CE, *tcUP, *CM, *ND, *XD, *tcBC, *SO, *SE, *TI, *TE;
11 static char *VS, *VE;
12 static int SG;
13 static char tcPC = '\0';
14 char *CD; /* tested in pri.c: docorner() */
15 int CO, LI; /* used in pri.c and whatis.c */
17 static void nocmov(int, int);
18 static void cmov(int, int);
19 static int xputc(int);
20 static int xputs(char *);
22 void
23 startup(void)
25 char *term;
26 char *tptr;
27 char *tbufptr, *pc;
29 tptr = (char *) alloc(1024);
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);
36 if (tgetflag(__DECONST(char *, "NP")) ||
37 tgetflag(__DECONST(char *, "nx")))
38 flags.nonull = 1;
39 if((pc = tgetstr(__DECONST(char *, "pc"), &tbufptr)))
40 tcPC = *pc;
41 if(!(tcBC = tgetstr(__DECONST(char *, "bc"), &tbufptr))
42 &&!(tcBC = tgetstr(__DECONST(char *, "le"), &tbufptr))) {
43 if(!tgetflag(__DECONST(char *, "bs")))
44 error("Terminal must backspace.");
45 tcBC = tbufptr;
46 tbufptr += 2;
47 *tcBC = '\b';
49 HO = tgetstr(__DECONST(char *, "ho"), &tbufptr);
50 CO = tgetnum(__DECONST(char *, "co"));
51 LI = tgetnum(__DECONST(char *, "li"));
52 if(CO < COLNO || LI < ROWNO+2)
53 setclipped();
54 if(!(CL = tgetstr(__DECONST(char *, "cl"), &tbufptr)))
55 error("Hack needs CL.");
56 ND = tgetstr(__DECONST(char *, "nd"), &tbufptr);
57 if(tgetflag(__DECONST(char *, "os")))
58 error("Hack can't have OS.");
59 CE = tgetstr(__DECONST(char *, "ce"), &tbufptr);
60 tcUP = tgetstr(__DECONST(char *, "up"), &tbufptr);
61 /* It seems that xd is no longer supported, and we should use
62 a linefeed instead; unfortunately this requires resetting
63 CRMOD, and many output routines will have to be modified
64 slightly. Let's leave that till the next release. */
65 XD = tgetstr(__DECONST(char *, "xd"), &tbufptr);
66 /* not: XD = tgetstr("do", &tbufptr); */
67 if(!(CM = tgetstr(__DECONST(char *, "cm"), &tbufptr))) {
68 if(!tcUP && !HO)
69 error("Hack needs CM or UP or HO.");
70 printf("Playing hack on terminals without cm is suspect...\n");
71 getret();
73 SO = tgetstr(__DECONST(char *, "so"), &tbufptr);
74 SE = tgetstr(__DECONST(char *, "se"), &tbufptr);
75 SG = tgetnum(__DECONST(char *, "sg"));
76 if(!SO || !SE || (SG > 0)) SO = SE = 0;
77 CD = tgetstr(__DECONST(char *, "cd"), &tbufptr);
78 set_whole_screen(); /* uses LI and CD */
79 if(tbufptr-tbuf > (int)sizeof(tbuf)) error("TERMCAP entry too big...\n");
80 free(tptr);
83 void
84 start_screen(void)
86 xputs(TI);
87 xputs(VS);
90 void
91 end_screen(void)
93 xputs(VE);
94 xputs(TE);
97 /* not xchar: perhaps xchar is unsigned and curx-x would be unsigned as well */
98 void
99 curs(int x, int y)
102 if (y == cury && x == curx)
103 return;
104 if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */
105 cmov(x, y); /* bunker!wtm */
106 return;
108 if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
109 nocmov(x, y);
110 else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
111 putchar('\r');
112 curx = 1;
113 nocmov(x, y);
114 } else if(!CM) {
115 nocmov(x, y);
116 } else
117 cmov(x, y);
120 static void
121 nocmov(int x, int y)
123 if (cury > y) {
124 if(tcUP) {
125 while (cury > y) { /* Go up. */
126 xputs(tcUP);
127 cury--;
129 } else if(CM) {
130 cmov(x, y);
131 } else if(HO) {
132 home();
133 curs(x, y);
134 } /* else impossible("..."); */
135 } else if (cury < y) {
136 if(XD) {
137 while(cury < y) {
138 xputs(XD);
139 cury++;
141 } else if(CM) {
142 cmov(x, y);
143 } else {
144 while(cury < y) {
145 xputc('\n');
146 curx = 1;
147 cury++;
151 if (curx < x) { /* Go to the right. */
152 if(!ND) cmov(x, y); else /* bah */
153 /* should instead print what is there already */
154 while (curx < x) {
155 xputs(ND);
156 curx++;
158 } else if (curx > x) {
159 while (curx > x) { /* Go to the left. */
160 xputs(tcBC);
161 curx--;
166 static void
167 cmov(int x, int y)
169 xputs(tgoto(CM, x-1, y-1));
170 cury = y;
171 curx = x;
174 static int
175 xputc(int c)
177 return(fputc(c, stdout));
180 static int
181 xputs(char *s)
183 return(tputs(s, 1, xputc));
186 void
187 cl_end(void)
189 if(CE)
190 xputs(CE);
191 else { /* no-CE fix - free after Harold Rynes */
192 /* this looks terrible, especially on a slow terminal
193 but is better than nothing */
194 int cx = curx, cy = cury;
196 while(curx < COLNO) {
197 xputc(' ');
198 curx++;
200 curs(cx, cy);
204 void
205 clear_screen(void)
207 xputs(CL);
208 curx = cury = 1;
211 void
212 home(void)
214 if(HO)
215 xputs(HO);
216 else if(CM)
217 xputs(tgoto(CM, 0, 0));
218 else
219 curs(1, 1); /* using tcUP ... */
220 curx = cury = 1;
223 void
224 standoutbeg(void)
226 if(SO) xputs(SO);
229 void
230 standoutend(void)
232 if(SE) xputs(SE);
235 void
236 backsp(void)
238 xputs(tcBC);
239 curx--;
242 void
243 bell(void)
245 putchar('\007'); /* curx does not change */
246 fflush(stdout);
249 void
250 cl_eos(void) /* free after Robert Viduya */
251 { /* must only be called with curx = 1 */
253 if(CD)
254 xputs(CD);
255 else {
256 int cx = curx, cy = cury;
257 while(cury <= LI-2) {
258 cl_end();
259 xputc('\n');
260 curx = 1;
261 cury++;
263 cl_end();
264 curs(cx, cy);