get mxge to build, stage 6/many
[dragonfly.git] / games / hack / hack.topl.c
blob6b3d8016f02d00816aa4e3171ca919cd7c72a272
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.topl.c - version 1.0.2 */
3 /* $FreeBSD: src/games/hack/hack.topl.c,v 1.3 1999/11/16 02:57:12 billf Exp $ */
4 /* $DragonFly: src/games/hack/hack.topl.c,v 1.3 2006/08/21 19:45:32 pavalos Exp $ */
6 #include "hack.h"
7 extern int CO;
9 char toplines[BUFSZ];
10 xchar tlx, tly; /* set by pline; used by addtopl */
12 struct topl {
13 struct topl *next_topl;
14 char *topl_text;
15 } *old_toplines, *last_redone_topl;
16 #define OTLMAX 20 /* max nr of old toplines remembered */
18 static void redotoplin(void);
19 static void xmore(const char *);
21 int
22 doredotopl(void)
24 if(last_redone_topl)
25 last_redone_topl = last_redone_topl->next_topl;
26 if(!last_redone_topl)
27 last_redone_topl = old_toplines;
28 if(last_redone_topl){
29 strcpy(toplines, last_redone_topl->topl_text);
31 redotoplin();
32 return(0);
35 static void
36 redotoplin(void)
38 home();
39 if(index(toplines, '\n')) cl_end();
40 putstr(toplines);
41 cl_end();
42 tlx = curx;
43 tly = cury;
44 flags.toplin = 1;
45 if(tly > 1)
46 more();
49 void
50 remember_topl(void)
52 struct topl *tl;
53 int cnt = OTLMAX;
54 if(last_redone_topl &&
55 !strcmp(toplines, last_redone_topl->topl_text)) return;
56 if(old_toplines &&
57 !strcmp(toplines, old_toplines->topl_text)) return;
58 last_redone_topl = 0;
59 tl = (struct topl *)
60 alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 1));
61 tl->next_topl = old_toplines;
62 tl->topl_text = (char *)(tl + 1);
63 strcpy(tl->topl_text, toplines);
64 old_toplines = tl;
65 while(cnt && tl){
66 cnt--;
67 tl = tl->next_topl;
69 if(tl && tl->next_topl){
70 free((char *) tl->next_topl);
71 tl->next_topl = 0;
75 void
76 addtopl(const char *s)
78 curs(tlx,tly);
79 if(tlx + (int)strlen(s) > CO) putsym('\n');
80 putstr(s);
81 tlx = curx;
82 tly = cury;
83 flags.toplin = 1;
86 static void
87 xmore(const char *s) /* allowed chars besides space/return */
89 if(flags.toplin) {
90 curs(tlx, tly);
91 if(tlx + 8 > CO) putsym('\n'), tly++;
94 if(flags.standout)
95 standoutbeg();
96 putstr("--More--");
97 if(flags.standout)
98 standoutend();
100 xwaitforspace(s);
101 if(flags.toplin && tly > 1) {
102 home();
103 cl_end();
104 docorner(1, tly-1);
106 flags.toplin = 0;
109 void
110 more(void)
112 xmore("");
115 void
116 cmore(const char *s)
118 xmore(s);
121 void
122 clrlin(void)
124 if(flags.toplin) {
125 home();
126 cl_end();
127 if(tly > 1) docorner(1, tly-1);
128 remember_topl();
130 flags.toplin = 0;
133 void
134 pline(const char *line, ...)
136 va_list ap;
137 va_start(ap, line);
138 vpline(line, ap);
139 va_end(ap);
142 /*VARARGS1*/
143 void
144 vpline(const char *line, va_list ap)
146 char pbuf[BUFSZ];
147 char *bp = pbuf, *tl;
148 int n,n0;
150 if(!line || !*line) return;
151 if(!index(line, '%')) strcpy(pbuf,line); else
152 vsprintf(pbuf, line, ap);
153 if(flags.toplin == 1 && !strcmp(pbuf, toplines)) return;
154 nscr(); /* %% */
156 /* If there is room on the line, print message on same line */
157 /* But messages like "You die..." deserve their own line */
158 n0 = strlen(bp);
159 if(flags.toplin == 1 && tly == 1 &&
160 n0 + (int)strlen(toplines) + 3 < CO-8 && /* room for --More-- */
161 strncmp(bp, "You ", 4)) {
162 strcat(toplines, " ");
163 strcat(toplines, bp);
164 tlx += 2;
165 addtopl(bp);
166 return;
168 if(flags.toplin == 1) more();
169 remember_topl();
170 toplines[0] = 0;
171 while(n0){
172 if(n0 >= CO){
173 /* look for appropriate cut point */
174 n0 = 0;
175 for(n = 0; n < CO; n++) if(bp[n] == ' ')
176 n0 = n;
177 if(!n0) for(n = 0; n < CO-1; n++)
178 if(!letter(bp[n])) n0 = n;
179 if(!n0) n0 = CO-2;
181 strncpy((tl = eos(toplines)), bp, n0);
182 tl[n0] = 0;
183 bp += n0;
185 /* remove trailing spaces, but leave one */
186 while(n0 > 1 && tl[n0-1] == ' ' && tl[n0-2] == ' ')
187 tl[--n0] = 0;
189 n0 = strlen(bp);
190 if(n0 && tl[0]) strcat(tl, "\n");
192 redotoplin();
195 void
196 putsym(char c)
198 switch(c) {
199 case '\b':
200 backsp();
201 return;
202 case '\n':
203 curx = 1;
204 cury++;
205 if(cury > tly) tly = cury;
206 break;
207 default:
208 if(curx == CO)
209 putsym('\n'); /* 1 <= curx <= CO; avoid CO */
210 else
211 curx++;
213 putchar(c);
216 void
217 putstr(const char *s)
219 while(*s) putsym(*s++);