xref: /dflybsd-src/games/hack/hack.topl.c (revision 0402ebbc7d4b6f34d02791995169d25c4aec3b15)
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.2 2003/06/17 04:25:24 dillon Exp $ */
5 
6 #include "hack.h"
7 #include <stdio.h>
8 extern char *eos();
9 extern int CO;
10 
11 char toplines[BUFSZ];
12 xchar tlx, tly;			/* set by pline; used by addtopl */
13 
14 struct topl {
15 	struct topl *next_topl;
16 	char *topl_text;
17 } *old_toplines, *last_redone_topl;
18 #define	OTLMAX	20		/* max nr of old toplines remembered */
19 
20 doredotopl(){
21 	if(last_redone_topl)
22 		last_redone_topl = last_redone_topl->next_topl;
23 	if(!last_redone_topl)
24 		last_redone_topl = old_toplines;
25 	if(last_redone_topl){
26 		(void) strcpy(toplines, last_redone_topl->topl_text);
27 	}
28 	redotoplin();
29 	return(0);
30 }
31 
32 redotoplin() {
33 	home();
34 	if(index(toplines, '\n')) cl_end();
35 	putstr(toplines);
36 	cl_end();
37 	tlx = curx;
38 	tly = cury;
39 	flags.toplin = 1;
40 	if(tly > 1)
41 		more();
42 }
43 
44 remember_topl() {
45 struct topl *tl;
46 int cnt = OTLMAX;
47 	if(last_redone_topl &&
48 	   !strcmp(toplines, last_redone_topl->topl_text)) return;
49 	if(old_toplines &&
50 	   !strcmp(toplines, old_toplines->topl_text)) return;
51 	last_redone_topl = 0;
52 	tl = (struct topl *)
53 		alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 1));
54 	tl->next_topl = old_toplines;
55 	tl->topl_text = (char *)(tl + 1);
56 	(void) strcpy(tl->topl_text, toplines);
57 	old_toplines = tl;
58 	while(cnt && tl){
59 		cnt--;
60 		tl = tl->next_topl;
61 	}
62 	if(tl && tl->next_topl){
63 		free((char *) tl->next_topl);
64 		tl->next_topl = 0;
65 	}
66 }
67 
68 addtopl(s) char *s; {
69 	curs(tlx,tly);
70 	if(tlx + strlen(s) > CO) putsym('\n');
71 	putstr(s);
72 	tlx = curx;
73 	tly = cury;
74 	flags.toplin = 1;
75 }
76 
77 xmore(s)
78 char *s;	/* allowed chars besides space/return */
79 {
80 	if(flags.toplin) {
81 		curs(tlx, tly);
82 		if(tlx + 8 > CO) putsym('\n'), tly++;
83 	}
84 
85 	if(flags.standout)
86 		standoutbeg();
87 	putstr("--More--");
88 	if(flags.standout)
89 		standoutend();
90 
91 	xwaitforspace(s);
92 	if(flags.toplin && tly > 1) {
93 		home();
94 		cl_end();
95 		docorner(1, tly-1);
96 	}
97 	flags.toplin = 0;
98 }
99 
100 more(){
101 	xmore("");
102 }
103 
104 cmore(s)
105 char *s;
106 {
107 	xmore(s);
108 }
109 
110 clrlin(){
111 	if(flags.toplin) {
112 		home();
113 		cl_end();
114 		if(tly > 1) docorner(1, tly-1);
115 		remember_topl();
116 	}
117 	flags.toplin = 0;
118 }
119 
120 /*VARARGS1*/
121 pline(line,arg1,arg2,arg3,arg4,arg5,arg6)
122 char *line,*arg1,*arg2,*arg3,*arg4,*arg5,*arg6;
123 {
124 	char pbuf[BUFSZ];
125 	char *bp = pbuf, *tl;
126 	int n,n0;
127 
128 	if(!line || !*line) return;
129 	if(!index(line, '%')) (void) strcpy(pbuf,line); else
130 	(void) sprintf(pbuf,line,arg1,arg2,arg3,arg4,arg5,arg6);
131 	if(flags.toplin == 1 && !strcmp(pbuf, toplines)) return;
132 	nscr();		/* %% */
133 
134 	/* If there is room on the line, print message on same line */
135 	/* But messages like "You die..." deserve their own line */
136 	n0 = strlen(bp);
137 	if(flags.toplin == 1 && tly == 1 &&
138 	    n0 + strlen(toplines) + 3 < CO-8 &&  /* leave room for --More-- */
139 	    strncmp(bp, "You ", 4)) {
140 		(void) strcat(toplines, "  ");
141 		(void) strcat(toplines, bp);
142 		tlx += 2;
143 		addtopl(bp);
144 		return;
145 	}
146 	if(flags.toplin == 1) more();
147 	remember_topl();
148 	toplines[0] = 0;
149 	while(n0){
150 		if(n0 >= CO){
151 			/* look for appropriate cut point */
152 			n0 = 0;
153 			for(n = 0; n < CO; n++) if(bp[n] == ' ')
154 				n0 = n;
155 			if(!n0) for(n = 0; n < CO-1; n++)
156 				if(!letter(bp[n])) n0 = n;
157 			if(!n0) n0 = CO-2;
158 		}
159 		(void) strncpy((tl = eos(toplines)), bp, n0);
160 		tl[n0] = 0;
161 		bp += n0;
162 
163 		/* remove trailing spaces, but leave one */
164 		while(n0 > 1 && tl[n0-1] == ' ' && tl[n0-2] == ' ')
165 			tl[--n0] = 0;
166 
167 		n0 = strlen(bp);
168 		if(n0 && tl[0]) (void) strcat(tl, "\n");
169 	}
170 	redotoplin();
171 }
172 
173 putsym(c) char c; {
174 	switch(c) {
175 	case '\b':
176 		backsp();
177 		return;
178 	case '\n':
179 		curx = 1;
180 		cury++;
181 		if(cury > tly) tly = cury;
182 		break;
183 	default:
184 		if(curx == CO)
185 			putsym('\n');	/* 1 <= curx <= CO; avoid CO */
186 		else
187 			curx++;
188 	}
189 	(void) putchar(c);
190 }
191 
192 putstr(s) char *s; {
193 	while(*s) putsym(*s++);
194 }
195