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