kernel - support dummy reallocblks in devfs
[dragonfly.git] / games / hack / hack.topl.c
blob75d612adf4d5f010bc9c623bd6794aa2c8c07103
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 $ */
5 #include "hack.h"
6 extern int CO;
8 char toplines[BUFSZ];
9 xchar tlx, tly; /* set by pline; used by addtopl */
11 struct topl {
12 struct topl *next_topl;
13 char *topl_text;
14 } *old_toplines, *last_redone_topl;
15 #define OTLMAX 20 /* max nr of old toplines remembered */
17 static void redotoplin(void);
18 static void xmore(const char *);
20 int
21 doredotopl(void)
23 if (last_redone_topl)
24 last_redone_topl = last_redone_topl->next_topl;
25 if (!last_redone_topl)
26 last_redone_topl = old_toplines;
27 if (last_redone_topl)
28 strcpy(toplines, last_redone_topl->topl_text);
29 redotoplin();
30 return (0);
33 static void
34 redotoplin(void)
36 home();
37 if (strchr(toplines, '\n'))
38 cl_end();
39 putstr(toplines);
40 cl_end();
41 tlx = curx;
42 tly = cury;
43 flags.toplin = 1;
44 if (tly > 1)
45 more();
48 void
49 remember_topl(void)
51 struct topl *tl;
52 int cnt = OTLMAX;
54 if (last_redone_topl &&
55 !strcmp(toplines, last_redone_topl->topl_text))
56 return;
57 if (old_toplines &&
58 !strcmp(toplines, old_toplines->topl_text))
59 return;
60 last_redone_topl = NULL;
61 tl = alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 1));
62 tl->next_topl = old_toplines;
63 tl->topl_text = (char *)(tl + 1);
64 strcpy(tl->topl_text, toplines);
65 old_toplines = tl;
66 while (cnt && tl) {
67 cnt--;
68 tl = tl->next_topl;
70 if (tl && tl->next_topl) {
71 free(tl->next_topl);
72 tl->next_topl = NULL;
76 void
77 addtopl(const char *s)
79 curs(tlx, tly);
80 if (tlx + (int)strlen(s) > CO)
81 putsym('\n');
82 putstr(s);
83 tlx = curx;
84 tly = cury;
85 flags.toplin = 1;
88 static void
89 xmore(const char *s) /* allowed chars besides space/return */
91 if (flags.toplin) {
92 curs(tlx, tly);
93 if (tlx + 8 > CO)
94 putsym('\n'), tly++;
97 if (flags.standout)
98 standoutbeg();
99 putstr("--More--");
100 if (flags.standout)
101 standoutend();
103 xwaitforspace(s);
104 if (flags.toplin && tly > 1) {
105 home();
106 cl_end();
107 docorner(1, tly - 1);
109 flags.toplin = 0;
112 void
113 more(void)
115 xmore("");
118 void
119 cmore(const char *s)
121 xmore(s);
124 void
125 clrlin(void)
127 if (flags.toplin) {
128 home();
129 cl_end();
130 if (tly > 1)
131 docorner(1, tly - 1);
132 remember_topl();
134 flags.toplin = 0;
137 void
138 pline(const char *line, ...)
140 va_list ap;
141 va_start(ap, line);
142 vpline(line, ap);
143 va_end(ap);
146 /*VARARGS1*/
147 void
148 vpline(const char *line, va_list ap)
150 char pbuf[BUFSZ];
151 char *bp = pbuf, *tl;
152 int n, n0;
154 if (!line || !*line)
155 return;
156 if (!strchr(line, '%'))
157 strcpy(pbuf, line);
158 else
159 vsprintf(pbuf, line, ap);
160 if (flags.toplin == 1 && !strcmp(pbuf, toplines))
161 return;
162 nscr(); /* %% */
164 /* If there is room on the line, print message on same line */
165 /* But messages like "You die..." deserve their own line */
166 n0 = strlen(bp);
167 if (flags.toplin == 1 && tly == 1 &&
168 n0 + (int)strlen(toplines) + 3 < CO - 8 && /* room for --More-- */
169 strncmp(bp, "You ", 4)) {
170 strcat(toplines, " ");
171 strcat(toplines, bp);
172 tlx += 2;
173 addtopl(bp);
174 return;
176 if (flags.toplin == 1)
177 more();
178 remember_topl();
179 toplines[0] = 0;
180 while (n0) {
181 if (n0 >= CO) {
182 /* look for appropriate cut point */
183 n0 = 0;
184 for (n = 0; n < CO; n++)
185 if (bp[n] == ' ')
186 n0 = n;
187 if (!n0)
188 for (n = 0; n < CO - 1; n++)
189 if (!letter(bp[n]))
190 n0 = n;
191 if (!n0)
192 n0 = CO - 2;
194 strncpy((tl = eos(toplines)), bp, n0);
195 tl[n0] = 0;
196 bp += n0;
198 /* remove trailing spaces, but leave one */
199 while (n0 > 1 && tl[n0 - 1] == ' ' && tl[n0 - 2] == ' ')
200 tl[--n0] = 0;
202 n0 = strlen(bp);
203 if (n0 && tl[0])
204 strcat(tl, "\n");
206 redotoplin();
209 void
210 putsym(char c)
212 switch (c) {
213 case '\b':
214 backsp();
215 return;
216 case '\n':
217 curx = 1;
218 cury++;
219 if (cury > tly)
220 tly = cury;
221 break;
222 default:
223 if (curx == CO)
224 putsym('\n'); /* 1 <= curx <= CO; avoid CO */
225 else
226 curx++;
228 putchar(c);
231 void
232 putstr(const char *s)
234 while (*s)
235 putsym(*s++);