Source:NetHack 3.0.0/topl.c

Below is the full text to topl.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/topl.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)topl.c	3.0	89/01/09 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   char toplines[BUFSIZ]; 8.   xchar tlx, tly;			/* set by pline; used by addtopl */ 9.    10.   struct topl { 11.  	struct topl *next_topl; 12.  	char *topl_text; 13.  } *old_toplines, *last_redone_topl; 14.  #define	OTLMAX	20		/* max nr of old toplines remembered */ 15.   16.   static void 17.  redotoplin { 18.  	home; 19.  	if(index(toplines, '\n')) cl_end; 20.  	if((*toplines & 0x80) && AS) { 21.  		/* kludge for the / command, the only time we ever want a */ 22.  		/* graphics character on the top line */ 23.  		putstr(AS); 24.  		xputc(*toplines); 25.  		putstr(AE); 26.  		putstr(toplines+1); 27.  	} else putstr(toplines); 28.  	cl_end; 29.  	tlx = curx; 30.  	tly = cury; 31.  	flags.toplin = 1; 32.  	if(tly > 1) 33.  		more; 34.  }  35.    36.   int 37.  doredotopl{ 38.  	if(last_redone_topl) 39.  		last_redone_topl = last_redone_topl->next_topl; 40.  	if(!last_redone_topl) 41.  		last_redone_topl = old_toplines; 42.  	if(last_redone_topl){ 43.  		Strcpy(toplines, last_redone_topl->topl_text); 44.  	}  45.   	redotoplin; 46.  	return 0; 47.  }  48.    49.   void 50.  remember_topl { 51.  	register struct topl *tl; 52.  	register int cnt = OTLMAX; 53.  	if(last_redone_topl &&  54.   	   !strcmp(toplines, last_redone_topl->topl_text)) return; 55.  	if(old_toplines &&  56.   	   !strcmp(toplines, old_toplines->topl_text)) return; 57.  	last_redone_topl = 0; 58.  	tl = (struct topl *) 59.  		alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 1)); 60.  	tl->next_topl = old_toplines; 61.  	tl->topl_text = (char *)(tl + 1); 62.  	Strcpy(tl->topl_text, toplines); 63.  	old_toplines = tl; 64.  	while(cnt && tl){ 65.  		cnt--; 66.  		tl = tl->next_topl; 67.  	}  68.   	if(tl && tl->next_topl){ 69.  		free((genericptr_t) tl->next_topl); 70.  		tl->next_topl = 0; 71.  	}  72.   }  73.    74.   void 75.  addtopl(s) char *s; { 76.  	curs(tlx,tly); 77.  	if(tlx + strlen(s) > CO) putsym('\n'); 78.  	putstr(s); 79.  	tlx = curx; 80.  	tly = cury; 81.  	flags.toplin = 1; 82.  }  83.    84.   static void 85.  xmore(s) 86.  char *s;	/* allowed chars besides space/return */ 87.  {  88.   	if(flags.toplin) { 89.  		curs(tlx, tly); 90.  		if(tlx + 8 > CO) putsym('\n'), tly++; 91.  	}  92.    93.   	if(flags.standout) 94.  		standoutbeg; 95.  	putstr("--More--"); 96.  	if(flags.standout) 97.  		standoutend; 98.   99.   	xwaitforspace(s); 100. 	if(flags.toplin && tly > 1) { 101. 		home; 102. 		cl_end; 103. 		docorner(1, tly-1); 104. 		tlx = tly = 1; 105. 	}  106.  	flags.toplin = 0; 107. }  108.   109.  void 110. more{ 111. 	xmore(""); 112. }  113.   114.  void 115. cmore(s) 116. register char *s; 117. {  118.  	xmore(s); 119. }  120.   121.  void 122. clrlin{ 123. 	if(flags.toplin) { 124. 		home; 125. 		cl_end; 126. 		if(tly > 1) { 127. 			docorner(1, tly-1); 128. 			tlx = tly = 1; 129. 		}  130.  		remember_topl; 131. 	}  132.  	flags.toplin = 0; 133. }  134.   135.  /*VARARGS1*/ 136. /* Because the modified mstatusline has 9 arguments KAA */ 137. void 138. pline(line,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) 139. #ifndef TOS 140. register 141. #endif 142. const char *line,*arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9; 143. {  144.  	char pbuf[BUFSZ]; 145. 	register char *bp = pbuf, *tl; 146. 	register int n,n0; 147.  148.  	if(!line || !*line) return; 149. 	if(!index(line, '%')) Strcpy(pbuf,line); else 150. 	Sprintf(pbuf,line,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9); 151. /*	if(flags.toplin == 1 && !strcmp(pbuf, toplines)) return;*/ 152. 	nscr;		/* %% */ 153.  154.  	/* If there is room on the line, print message on same line */ 155. 	/* But messages like "You die..." deserve their own line */ 156. 	n0 = strlen(bp); 157. 	if(flags.toplin == 1 && tly == 1 &&  158.  	    n0 + strlen(toplines) + 3 < CO-8 &&  /* leave room for --More-- */  159.  	    strncmp(bp, "You die", 7)) { 160. 		Strcat(toplines, "  "); 161. 		Strcat(toplines, bp); 162. 		tlx += 2; 163. 		addtopl(bp); 164. 		return; 165. 	}  166.  	if(flags.toplin == 1 && !strcmp(pbuf, toplines) &&  167.  	    (n0 + strlen(toplines) + 3 >= CO-8)) { 168. 		more; 169. 		home; 170. 		putstr(""); 171. 		cl_end; 172. 		goto again; 173. 	}  174.  	if(flags.toplin == 1) more; 175. 	else if(tly > 1) {	/* for when flags.toplin == 2 && tly > 1 */ 176. 		docorner(1, tly-1);	/* reset tly = 1 if redraw screen */ 177. 		tlx = tly = 1;	/* from home--cls and docorner(1,n) */ 178. 	}  179.  again: 180. 	remember_topl; 181. 	toplines[0] = 0; 182. 	while(n0){ 183. 		if(n0 >= CO){ 184. 			/* look for appropriate cut point */ 185. 			n0 = 0; 186. 			for(n = 0; n < CO; n++) if(bp[n] == ' ') 187. 				n0 = n;  188. if(!n0) for(n = 0; n < CO-1; n++) 189. 				if(!letter(bp[n])) n0 = n;  190. if(!n0) n0 = CO-2; 191. 		}  192.  		(void) strncpy((tl = eos(toplines)), bp, n0); 193. 		tl[n0] = 0; 194. 		bp += n0; 195.  196.  		/* remove trailing spaces, but leave one */ 197. 		while(n0 > 1 && tl[n0-1] == ' ' && tl[n0-2] == ' ') 198. 			tl[--n0] = 0; 199.  200.  		n0 = strlen(bp); 201. 		if(n0 && tl[0]) Strcat(tl, "\n"); 202. 	}  203.  	redotoplin; 204. }  205.   206.  /*VARARGS1*/ 207. void 208. You(line,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) 209. #ifndef TOS 210. register 211. #endif 212. const char *line,*arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9; 213. {  214.  	char *tmp; 215. 	tmp = (char *)alloc((unsigned int)(strlen(line) + 5)); 216. 	Strcpy(tmp, "You "); 217. 	Strcat(tmp, line); 218. 	pline(tmp, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); 219. 	free(tmp); 220. 	return; 221. }  222.   223.  /*VARARGS1*/ 224. void 225. Your(line,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) 226. #ifndef TOS 227. register 228. #endif 229. const char *line,*arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9; 230. {  231.  	char *tmp; 232. 	tmp = (char *)alloc((unsigned int)(strlen(line) + 6)); 233. 	Strcpy(tmp, "Your "); 234. 	Strcat(tmp, line); 235. 	pline(tmp, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); 236. 	free(tmp); 237. 	return; 238. }  239.   240.  void 241. putsym(c) 242. char c;  243. { 244.  	switch(c) { 245. 	case '\b': 246. 		backsp; 247. 		curx--; 248. 		if(curx == 1 && cury > 1) 249. 			curs(CO, cury-1); 250. 		return; 251. 	case '\n': 252. 		curx = 1; 253. 		cury++; 254. 		if(cury > tly) tly = cury; 255. 		break; 256. 	default: 257. 		if(curx == CO) 258. 			putsym('\n');	/* 1 <= curx <= CO; avoid CO */ 259. 		curx++; 260. 	}  261.  	(void) putchar(c); 262. }  263.   264.  void 265. putstr(s) 266. register char *s; 267. {  268.  	while(*s) putsym(*s++); 269. }  270.   271.  char 272. yn_function(resp, def) 273. char *resp, def; 274. /*  275.   *   Generic yes/no function 276.  */  277.  {  278.  	register char q;  279. char rtmp[8]; 280.  281.  	Sprintf(rtmp, "[%s] ", resp); 282. 	addtopl(rtmp); 283.  284.  	do { 285. 		q = lowc(readchar); 286.  287.  		if (index(quitchars, q)) q = def; 288. 		else if (!index(resp, q)) { 289. 			bell; 290. 			q = (char)0; 291. 		}  292.  	} while(!q); 293.  294.  	Sprintf(rtmp, "%c", q); 295. 	addtopl(rtmp); 296. 	flags.toplin = 2; 297.  298.  	return q;  299. }