pc-hack

PC HACK 3.61 source code (archival)
git clone http://frotz.net/git/pc-hack.git
Log | Files | Refs

topl.c (3798B)


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