This is topl.c in view mode; [Download] [Up]
/* SCCS Id: @(#)topl.c 3.0 89/01/09 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ /* Changed for graphical version of NetHack on NextStep */ /* by Christoph Marquardt 9/4/93 */ #define NEED_VARARGS /* Uses ... */ /* comment line for pre-compiled headers */ #include "hack.h" VSTATIC char toplines[BUFSIZ]; #ifndef OVLB OSTATIC boolean no_repeat; #else /* OVLB */ XSTATIC boolean no_repeat = FALSE; #endif /* OVLB */ extern xchar tlx, tly; #ifdef OVLB xchar tlx, tly; /* set by pline; used by addtopl */ #endif /* OVLB */ OSTATIC void NDECL(redotoplin); OSTATIC void FDECL(xmore,(const char *)); VSTATIC struct topl { struct topl *next_topl; char *topl_text; } *old_toplines, *last_redone_topl; #define OTLMAX 20 /* max nr of old toplines remembered */ #ifdef OVL1 XSTATIC void redotoplin() { home(); if(index(toplines, '\n')) cl_end(); if((*toplines & 0x80) && AS) { /* kludge for the / command, the only time we ever want a */ /* graphics character on the top line */ putstr(AS); xputc(*toplines); putstr(AE); putstr(toplines+1); } else putstr(toplines); cl_end(); tlx = curx; tly = cury; flags.toplin = 1; if(tly > 1) more(); } #endif /* OVL1 */ #ifdef OVLB int doredotopl(){ if(last_redone_topl) last_redone_topl = last_redone_topl->next_topl; if(!last_redone_topl) last_redone_topl = old_toplines; if(last_redone_topl){ Strcpy(toplines, last_redone_topl->topl_text); } redotoplin(); return 0; } #endif /* OVLB */ #ifdef OVL1 void remember_topl() { register struct topl *tl; register int cnt = OTLMAX; if(last_redone_topl && !strcmp(toplines, last_redone_topl->topl_text)) return; if(old_toplines && !strcmp(toplines, old_toplines->topl_text)) return; last_redone_topl = 0; tl = (struct topl *) alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 1)); tl->next_topl = old_toplines; tl->topl_text = (char *)(tl + 1); Strcpy(tl->topl_text, toplines); old_toplines = tl; while(cnt && tl){ cnt--; tl = tl->next_topl; } if(tl && tl->next_topl){ free((genericptr_t) tl->next_topl); tl->next_topl = 0; } } void addtopl(s) const char *s; { curs(tlx,tly); if(tlx + strlen(s) > CO) putsym('\n'); putstr(s); tlx = curx; tly = cury; flags.toplin = 1; } #endif /* OVL1 */ #ifdef OVL2 XSTATIC void xmore(s) const char *s; /* allowed chars besides space/return */ { if(flags.toplin) { curs(tlx, tly); if(tlx + 8 > CO) putsym('\n'), tly++; } if(flags.standout) standoutbeg(); putstr("--More--"); if(flags.standout) standoutend(); xwaitforspace(s); if(flags.toplin && tly > 1) { home(); cl_end(); docorner(1, tly-1); tlx = tly = 1; curs(tlx, tly); } flags.toplin = 0; } void more(){ xmore(""); } #endif /* OVL2 */ #ifdef OVLB void cmore(s) register const char *s; { xmore(s); } #endif /* OVLB */ #ifdef OVL1 void clrlin(){ if(flags.toplin) { home(); cl_end(); if(tly > 1) { docorner(1, tly-1); tlx = tly = 1; } remember_topl(); } flags.toplin = 0; } #endif /* OVL1 */ #ifdef OVLB /*VARARGS1*/ /* Note that these declarations rely on knowledge of the internals * of the variable argument handling stuff in "tradstdc.h" */ #if defined(USE_STDARG) || defined(USE_VARARGS) void pline VA_DECL(const char *, line) VA_START(line); VA_INIT(line, char *); vpline(line, VA_ARGS); VA_END(); } # ifdef USE_STDARG void vpline(const char *line, va_list the_args) { # else void vpline(line, the_args) const char *line; va_list the_args; { # endif #else /* USE_STDARG | USE_VARARG */ void pline VA_DECL(const char *, line) #endif char pbuf[BUFSZ]; register char *bp = pbuf, *tl; register int n,n0; /* Do NOT use VA_START and VA_END in here... see above */ if(!line || !*line) return; if(!index(line, '%')) Strcpy(pbuf,line); else Vsprintf(pbuf,line,VA_ARGS); if(no_repeat && flags.toplin == 1 && !strcmp(pbuf, toplines)) return; nscr(); /* %% */ /* If there is room on the line, print message on same line */ /* But messages like "You die..." deserve their own line */ n0 = strlen(bp); if(flags.toplin == 1 && tly == 1 && n0 + strlen(toplines) + 3 < CO-8 && /* leave room for --More-- */ strncmp(bp, "You die", 7)) { Strcat(toplines, " "); Strcat(toplines, bp); tlx += 2; addtopl(bp); return; } if(flags.toplin == 1 && !strcmp(pbuf, toplines) && (n0 + strlen(toplines) + 3 >= CO-8)) { more(); home(); putstr(""); cl_end(); goto again; } if(flags.toplin == 1) more(); else if(tly > 1) { /* for when flags.toplin == 2 && tly > 1 */ docorner(1, tly-1); /* reset tly = 1 if redraw screen */ tlx = tly = 1; /* from home--cls() and docorner(1,n) */ } again: remember_topl(); toplines[0] = 0; while(n0){ if(n0 >= CO){ /* look for appropriate cut point */ n0 = 0; for(n = 0; n < CO; n++) if(bp[n] == ' ') n0 = n; if(!n0) for(n = 0; n < CO-1; n++) if(!letter(bp[n])) n0 = n; if(!n0) n0 = CO-2; } (void) strncpy((tl = eos(toplines)), bp, n0); tl[n0] = 0; bp += n0; /* remove trailing spaces, but leave one */ while(n0 > 1 && tl[n0-1] == ' ' && tl[n0-2] == ' ') tl[--n0] = 0; n0 = strlen(bp); if(n0 && tl[0]) Strcat(tl, "\n"); } redotoplin(); } /*VARARGS1*/ void Norep VA_DECL(const char *, line) VA_START(line); VA_INIT(line, const char *); no_repeat = TRUE; vpline(line, VA_ARGS); no_repeat = FALSE; VA_END(); return; } /*VARARGS1*/ void You VA_DECL(const char *, line) char *tmp; VA_START(line); VA_INIT(line, const char *); tmp = (char *)alloc((unsigned int)(strlen(line) + 5)); Strcpy(tmp, "You "); Strcat(tmp, line); vpline(tmp, VA_ARGS); free(tmp); VA_END(); return; } /*VARARGS1*/ void Your VA_DECL(const char *,line) char *tmp; VA_START(line); VA_INIT(line, const char *); tmp = (char *)alloc((unsigned int)(strlen(line) + 6)); Strcpy(tmp, "Your "); Strcat(tmp, line); vpline(tmp, VA_ARGS); free(tmp); VA_END(); return; } /*ARGSUSED*/ /*VARARGS2*/ void kludge VA_DECL2(const char *, str, const char *, arg) #ifdef VA_NEXT char *other1, *other2, *other3; #endif VA_START(arg); VA_INIT(str, const char *); VA_INIT(arg, const char *); #ifdef VA_NEXT VA_NEXT(other1, char *); VA_NEXT(other2, char *); VA_NEXT(other3, char *); # define OTHER_ARGS other1,other2,other3 #else # define OTHER_ARGS arg1,arg2,arg3 #endif if(Blind || !flags.verbose) { if(*str == '%') pline(str,"It",OTHER_ARGS); else pline(str,"it",OTHER_ARGS); } else pline(str,arg,OTHER_ARGS); VA_END(); } #endif /* OVLB */ #ifdef OVL0 void putsym(c) char c; { switch(c) { case '\b': backsp(); curx--; if(curx == 1 && cury > 1) curs(CO, cury-1); return; case '\n': curx = 1; cury++; if(cury > tly) tly = cury; break; default: if(curx == CO) putsym('\n'); /* 1 <= curx <= CO; avoid CO */ curx++; } (void) putchar(c); } #ifdef NEXT void putstr(s) register const char *s; { WindowPutstr(s); } #else void putstr(s) register const char *s; { while(*s) putsym(*s++); } #endif /* NEXT */ #endif /* OVL0 */ #ifdef OVL2 char yn_function(resp, def) const char *resp; char def; /* * Generic yes/no function */ { register char q; char rtmp[8]; Sprintf(rtmp, "[%s] ", resp); addtopl(rtmp); do { q = lowc(readchar()); if (index(quitchars, q)) q = def; else if (!index(resp, q)) { bell(); q = (char)0; } } while(!q); Sprintf(rtmp, "%c", q); addtopl(rtmp); flags.toplin = 2; return q; } #endif /* OVL2 */ #ifdef OVLB /*VARARGS1*/ void impossible VA_DECL(const char *, s) VA_START(s); VA_INIT(s, const char *); vpline(s,VA_ARGS); pline("Program in disorder - perhaps you'd better Quit."); VA_END(); } #endif /* OVLB */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.