sys/vfs/hammer: Fix and add comments on btree boundaries
[dragonfly.git] / games / hack / hack.topl.c
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
5 #include "hack.h"
6 extern int CO;
7
8 char toplines[BUFSZ];
9 xchar tlx, tly;                 /* set by pline; used by addtopl */
10
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 */
16
17 static void redotoplin(void);
18 static void xmore(const char *);
19
20 int
21 doredotopl(void)
22 {
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);
31 }
32
33 static void
34 redotoplin(void)
35 {
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();
46 }
47
48 void
49 remember_topl(void)
50 {
51         struct topl *tl;
52         int cnt = OTLMAX;
53
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;
69         }
70         if (tl && tl->next_topl) {
71                 free(tl->next_topl);
72                 tl->next_topl = NULL;
73         }
74 }
75
76 void
77 addtopl(const char *s)
78 {
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;
86 }
87
88 static void
89 xmore(const char *s)    /* allowed chars besides space/return */
90 {
91         if (flags.toplin) {
92                 curs(tlx, tly);
93                 if (tlx + 8 > CO)
94                         putsym('\n'), tly++;
95         }
96
97         if (flags.standout)
98                 standoutbeg();
99         putstr("--More--");
100         if (flags.standout)
101                 standoutend();
102
103         xwaitforspace(s);
104         if (flags.toplin && tly > 1) {
105                 home();
106                 cl_end();
107                 docorner(1, tly - 1);
108         }
109         flags.toplin = 0;
110 }
111
112 void
113 more(void)
114 {
115         xmore("");
116 }
117
118 void
119 cmore(const char *s)
120 {
121         xmore(s);
122 }
123
124 void
125 clrlin(void)
126 {
127         if (flags.toplin) {
128                 home();
129                 cl_end();
130                 if (tly > 1)
131                         docorner(1, tly - 1);
132                 remember_topl();
133         }
134         flags.toplin = 0;
135 }
136
137 void
138 pline(const char *line, ...)
139 {
140         va_list ap;
141         va_start(ap, line);
142         vpline(line, ap);
143         va_end(ap);
144 }
145
146 /*VARARGS1*/
147 void
148 vpline(const char *line, va_list ap)
149 {
150         char pbuf[BUFSZ];
151         char *bp = pbuf, *tl;
152         int n, n0;
153
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();         /* %% */
163
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;
175         }
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;
193                 }
194                 strncpy((tl = eos(toplines)), bp, n0);
195                 tl[n0] = 0;
196                 bp += n0;
197
198                 /* remove trailing spaces, but leave one */
199                 while (n0 > 1 && tl[n0 - 1] == ' ' && tl[n0 - 2] == ' ')
200                         tl[--n0] = 0;
201
202                 n0 = strlen(bp);
203                 if (n0 && tl[0])
204                         strcat(tl, "\n");
205         }
206         redotoplin();
207 }
208
209 void
210 putsym(char c)
211 {
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++;
227         }
228         putchar(c);
229 }
230
231 void
232 putstr(const char *s)
233 {
234         while (*s)
235                 putsym(*s++);
236 }