|
|
1.1 ! root 1: /* io.c Larn is copyrighted 1986 by Noah Morgan. ! 2: * ! 3: * Below are the functions in this file: ! 4: * ! 5: * setupvt100() Subroutine to set up terminal in correct mode for game ! 6: * clearvt100() Subroutine to clean up terminal when the game is over ! 7: * getchar() Routine to read in one character from the terminal ! 8: * scbr() Function to set cbreak -echo for the terminal ! 9: * sncbr() Function to set -cbreak echo for the terminal ! 10: * newgame() Subroutine to save the initial time and seed rnd() ! 11: * ! 12: * FILE OUTPUT ROUTINES ! 13: * ! 14: * lprintf(format,args . . .) printf to the output buffer ! 15: * lprint(integer) send binary integer to output buffer ! 16: * lwrite(buf,len) write a buffer to the output buffer ! 17: * lprcat(str) sent string to output buffer ! 18: * ! 19: * FILE OUTPUT MACROS (in header.h) ! 20: * ! 21: * lprc(character) put the character into the output buffer ! 22: * ! 23: * FILE INPUT ROUTINES ! 24: * ! 25: * long lgetc() read one character from input buffer ! 26: * long lrint() read one integer from input buffer ! 27: * lrfill(address,number) put input bytes into a buffer ! 28: * char *lgetw() get a whitespace ended word from input ! 29: * char *lgetl() get a \n or EOF ended line from input ! 30: * ! 31: * FILE OPEN / CLOSE ROUTINES ! 32: * ! 33: * lcreat(filename) create a new file for write ! 34: * lopen(filename) open a file for read ! 35: * lappend(filename) open for append to an existing file ! 36: * lrclose() close the input file ! 37: * lwclose() close output file ! 38: * lflush() flush the output buffer ! 39: * ! 40: * Other Routines ! 41: * ! 42: * cursor(x,y) position cursor at [x,y] ! 43: * cursors() position cursor at [1,24] (saves memory) ! 44: * cl_line(x,y) Clear line at [1,y] and leave cursor at [x,y] ! 45: * cl_up(x,y) Clear screen from [x,1] to current line. ! 46: * cl_dn(x,y) Clear screen from [1,y] to end of display. ! 47: * standout(str) Print the string in standout mode. ! 48: * set_score_output() Called when output should be literally printed. ! 49: ** putchar(ch) Print one character in decoded output buffer. ! 50: ** flush_buf() Flush buffer with decoded output. ! 51: ** init_term() Terminal initialization -- setup termcap info ! 52: ** char *tmcapcnv(sd,ss) Routine to convert VT100 \33's to termcap format ! 53: * beep() Routine to emit a beep if enabled (see no-beep in .larnopts) ! 54: * ! 55: * Note: ** entries are available only in termcap mode. ! 56: */ ! 57: ! 58: #include "header.h" ! 59: ! 60: #ifdef SYSV /* system III or system V */ ! 61: #include <termio.h> ! 62: #define sgttyb termio ! 63: #define stty(_a,_b) ioctl(_a,TCSETA,_b) ! 64: #define gtty(_a,_b) ioctl(_a,TCGETA,_b) ! 65: static int rawflg = 0; ! 66: static char saveeof,saveeol; ! 67: #define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\ ! 68: _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL) ! 69: #define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL ! 70: ! 71: #else not SYSV ! 72: ! 73: #ifndef BSD ! 74: #define CBREAK RAW /* V7 has no CBREAK */ ! 75: #endif ! 76: ! 77: #define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO) ! 78: #define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO) ! 79: #include <sgtty.h> ! 80: #endif not SYSV ! 81: ! 82: #ifndef NOVARARGS /* if we have varargs */ ! 83: #include <varargs.h> ! 84: #else NOVARARGS /* if we don't have varargs */ ! 85: typedef char *va_list; ! 86: #define va_dcl int va_alist; ! 87: #define va_start(plist) plist = (char *) &va_alist ! 88: #define va_end(plist) ! 89: #define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1] ! 90: #endif NOVARARGS ! 91: ! 92: #define LINBUFSIZE 128 /* size of the lgetw() and lgetl() buffer */ ! 93: int lfd; /* output file numbers */ ! 94: int fd; /* input file numbers */ ! 95: static struct sgttyb ttx; /* storage for the tty modes */ ! 96: static int ipoint=MAXIBUF,iepoint=MAXIBUF; /* input buffering pointers */ ! 97: static char lgetwbuf[LINBUFSIZE]; /* get line (word) buffer */ ! 98: ! 99: /* ! 100: * setupvt100() Subroutine to set up terminal in correct mode for game ! 101: * ! 102: * Attributes off, clear screen, set scrolling region, set tty mode ! 103: */ ! 104: setupvt100() ! 105: { ! 106: clear(); setscroll(); scbr(); /* system("stty cbreak -echo"); */ ! 107: } ! 108: ! 109: /* ! 110: * clearvt100() Subroutine to clean up terminal when the game is over ! 111: * ! 112: * Attributes off, clear screen, unset scrolling region, restore tty mode ! 113: */ ! 114: clearvt100() ! 115: { ! 116: resetscroll(); clear(); sncbr(); /* system("stty -cbreak echo"); */ ! 117: } ! 118: ! 119: /* ! 120: * getchar() Routine to read in one character from the terminal ! 121: */ ! 122: getchar() ! 123: { ! 124: char byt; ! 125: #ifdef EXTRA ! 126: c[BYTESIN]++; ! 127: #endif ! 128: lflush(); /* be sure output buffer is flushed */ ! 129: read(0,&byt,1); /* get byte from terminal */ ! 130: return(byt); ! 131: } ! 132: ! 133: /* ! 134: * scbr() Function to set cbreak -echo for the terminal ! 135: * ! 136: * like: system("stty cbreak -echo") ! 137: */ ! 138: scbr() ! 139: { ! 140: gtty(0,&ttx); doraw(ttx); stty(0,&ttx); ! 141: } ! 142: ! 143: /* ! 144: * sncbr() Function to set -cbreak echo for the terminal ! 145: * ! 146: * like: system("stty -cbreak echo") ! 147: */ ! 148: sncbr() ! 149: { ! 150: gtty(0,&ttx); unraw(ttx); stty(0,&ttx); ! 151: } ! 152: ! 153: /* ! 154: * newgame() Subroutine to save the initial time and seed rnd() ! 155: */ ! 156: newgame() ! 157: { ! 158: register long *p,*pe; ! 159: for (p=c,pe=c+100; p<pe; *p++ =0); ! 160: time(&initialtime); srand(initialtime); ! 161: lcreat((char*)0); /* open buffering for output to terminal */ ! 162: } ! 163: ! 164: /* ! 165: * lprintf(format,args . . .) printf to the output buffer ! 166: * char *format; ! 167: * ??? args . . . ! 168: * ! 169: * Enter with the format string in "format", as per printf() usage ! 170: * and any needed arguments following it ! 171: * Note: lprintf() only supports %s, %c and %d, with width modifier and left ! 172: * or right justification. ! 173: * No correct checking for output buffer overflow is done, but flushes ! 174: * are done beforehand if needed. ! 175: * Returns nothing of value. ! 176: */ ! 177: #ifdef lint ! 178: /*VARARGS*/ ! 179: lprintf(str) ! 180: char *str; ! 181: { ! 182: char *str2; ! 183: str2 = str; ! 184: str = str2; /* to make lint happy */ ! 185: } ! 186: /*VARARGS*/ ! 187: sprintf(str) ! 188: char *str; ! 189: { ! 190: char *str2; ! 191: str2 = str; ! 192: str = str2; /* to make lint happy */ ! 193: } ! 194: #else lint ! 195: /*VARARGS*/ ! 196: lprintf(va_alist) ! 197: va_dcl ! 198: { ! 199: va_list ap; /* pointer for variable argument list */ ! 200: register char *fmt; ! 201: register char *outb,*tmpb; ! 202: register long wide,left,cont,n; /* data for lprintf */ ! 203: char db[12]; /* %d buffer in lprintf */ ! 204: ! 205: va_start(ap); /* initialize the var args pointer */ ! 206: fmt = va_arg(ap, char *); /* pointer to format string */ ! 207: if (lpnt >= lpend) lflush(); ! 208: outb = lpnt; ! 209: for ( ; ; ) ! 210: { ! 211: while (*fmt != '%') ! 212: if (*fmt) *outb++ = *fmt++; else { lpnt=outb; return; } ! 213: wide = 0; left = 1; cont=1; ! 214: while (cont) ! 215: switch(*(++fmt)) ! 216: { ! 217: case 'd': n = va_arg(ap, long); ! 218: if (n<0) { n = -n; *outb++ = '-'; if (wide) --wide; } ! 219: tmpb = db+11; *tmpb = (char)(n % 10 + '0'); ! 220: while (n>9) *(--tmpb) = (char)((n /= 10) % 10 + '0'); ! 221: if (wide==0) while (tmpb < db+12) *outb++ = *tmpb++; ! 222: else ! 223: { ! 224: wide -= db-tmpb+12; ! 225: if (left) while (wide-- > 0) *outb++ = ' '; ! 226: while (tmpb < db+12) *outb++ = *tmpb++; ! 227: if (left==0) while (wide-- > 0) *outb++ = ' '; ! 228: } ! 229: cont=0; break; ! 230: ! 231: case 's': tmpb = va_arg(ap, char *); ! 232: if (wide==0) { while (*outb++ = *tmpb++); --outb; } ! 233: else ! 234: { ! 235: n = wide - strlen(tmpb); ! 236: if (left) while (n-- > 0) *outb++ = ' '; ! 237: while (*outb++ = *tmpb++); --outb; ! 238: if (left==0) while (n-- > 0) *outb++ = ' '; ! 239: } ! 240: cont=0; break; ! 241: ! 242: case 'c': *outb++ = va_arg(ap, int); cont=0; break; ! 243: ! 244: case '0': ! 245: case '1': ! 246: case '2': ! 247: case '3': ! 248: case '4': ! 249: case '5': ! 250: case '6': ! 251: case '7': ! 252: case '8': ! 253: case '9': wide = 10*wide + *fmt - '0'; break; ! 254: ! 255: case '-': left = 0; break; ! 256: ! 257: default: *outb++ = *fmt; cont=0; break; ! 258: }; ! 259: fmt++; ! 260: } ! 261: va_end(ap); ! 262: } ! 263: #endif lint ! 264: ! 265: /* ! 266: * lprint(long-integer) send binary integer to output buffer ! 267: * long integer; ! 268: * ! 269: * +---------+---------+---------+---------+ ! 270: * | high | | | low | ! 271: * | order | | | order | ! 272: * | byte | | | byte | ! 273: * +---------+---------+---------+---------+ ! 274: * 31 --- 24 23 --- 16 15 --- 8 7 --- 0 ! 275: * ! 276: * The save order is low order first, to high order (4 bytes total) ! 277: * and is written to be system independent. ! 278: * No checking for output buffer overflow is done, but flushes if needed! ! 279: * Returns nothing of value. ! 280: */ ! 281: lprint(x) ! 282: register long x; ! 283: { ! 284: if (lpnt >= lpend) lflush(); ! 285: *lpnt++ = 255 & x; *lpnt++ = 255 & (x>>8); ! 286: *lpnt++ = 255 & (x>>16); *lpnt++ = 255 & (x>>24); ! 287: } ! 288: ! 289: /* ! 290: * lwrite(buf,len) write a buffer to the output buffer ! 291: * char *buf; ! 292: * int len; ! 293: * ! 294: * Enter with the address and number of bytes to write out ! 295: * Returns nothing of value ! 296: */ ! 297: lwrite(buf,len) ! 298: register char *buf; ! 299: int len; ! 300: { ! 301: register char *str; ! 302: register int num2; ! 303: if (len > 399) /* don't copy data if can just write it */ ! 304: { ! 305: #ifdef EXTRA ! 306: c[BYTESOUT] += len; ! 307: #endif ! 308: ! 309: #ifndef VT100 ! 310: for (str=buf; len>0; --len) ! 311: lprc(*str++); ! 312: #else VT100 ! 313: lflush(); ! 314: write(lfd,buf,len); ! 315: #endif VT100 ! 316: } ! 317: else while (len) ! 318: { ! 319: if (lpnt >= lpend) lflush(); /* if buffer is full flush it */ ! 320: num2 = lpbuf+BUFBIG-lpnt; /* # bytes left in output buffer */ ! 321: if (num2 > len) num2=len; ! 322: str = lpnt; len -= num2; ! 323: while (num2--) *str++ = *buf++; /* copy in the bytes */ ! 324: lpnt = str; ! 325: } ! 326: } ! 327: ! 328: /* ! 329: * long lgetc() Read one character from input buffer ! 330: * ! 331: * Returns 0 if EOF, otherwise the character ! 332: */ ! 333: long lgetc() ! 334: { ! 335: register int i; ! 336: if (ipoint != iepoint) return(inbuffer[ipoint++]); ! 337: if (iepoint!=MAXIBUF) return(0); ! 338: if ((i=read(fd,inbuffer,MAXIBUF))<=0) ! 339: { ! 340: if (i!=0) write(1,"error reading from input file\n",30); ! 341: iepoint = ipoint = 0; return(0); ! 342: } ! 343: ipoint=1; iepoint=i; return(*inbuffer); ! 344: } ! 345: ! 346: /* ! 347: * long lrint() Read one integer from input buffer ! 348: * ! 349: * +---------+---------+---------+---------+ ! 350: * | high | | | low | ! 351: * | order | | | order | ! 352: * | byte | | | byte | ! 353: * +---------+---------+---------+---------+ ! 354: * 31 --- 24 23 --- 16 15 --- 8 7 --- 0 ! 355: * ! 356: * The save order is low order first, to high order (4 bytes total) ! 357: * Returns the int read ! 358: */ ! 359: long lrint() ! 360: { ! 361: register unsigned long i; ! 362: i = 255 & lgetc(); i |= (255 & lgetc()) << 8; ! 363: i |= (255 & lgetc()) << 16; i |= (255 & lgetc()) << 24; ! 364: return(i); ! 365: } ! 366: ! 367: /* ! 368: * lrfill(address,number) put input bytes into a buffer ! 369: * char *address; ! 370: * int number; ! 371: * ! 372: * Reads "number" bytes into the buffer pointed to by "address". ! 373: * Returns nothing of value ! 374: */ ! 375: lrfill(adr,num) ! 376: register char *adr; ! 377: int num; ! 378: { ! 379: register char *pnt; ! 380: register int num2; ! 381: while (num) ! 382: { ! 383: if (iepoint == ipoint) ! 384: { ! 385: if (num>5) /* fast way */ ! 386: { ! 387: if (read(fd,adr,num) != num) ! 388: write(2,"error reading from input file\n",30); ! 389: num=0; ! 390: } ! 391: else { *adr++ = lgetc(); --num; } ! 392: } ! 393: else ! 394: { ! 395: num2 = iepoint-ipoint; /* # of bytes left in the buffer */ ! 396: if (num2 > num) num2=num; ! 397: pnt = inbuffer+ipoint; num -= num2; ipoint += num2; ! 398: while (num2--) *adr++ = *pnt++; ! 399: } ! 400: } ! 401: } ! 402: ! 403: /* ! 404: * char *lgetw() Get a whitespace ended word from input ! 405: * ! 406: * Returns pointer to a buffer that contains word. If EOF, returns a NULL ! 407: */ ! 408: char *lgetw() ! 409: { ! 410: register char *lgp,cc; ! 411: register int n=LINBUFSIZE,quote=0; ! 412: lgp = lgetwbuf; ! 413: do cc=lgetc(); while ((cc <= 32) && (cc > NULL)); /* eat whitespace */ ! 414: for ( ; ; --n,cc=lgetc()) ! 415: { ! 416: if ((cc==NULL) && (lgp==lgetwbuf)) return(NULL); /* EOF */ ! 417: if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); } ! 418: if (cc != '"') *lgp++ = cc; else quote ^= 1; ! 419: } ! 420: } ! 421: ! 422: /* ! 423: * char *lgetl() Function to read in a line ended by newline or EOF ! 424: * ! 425: * Returns pointer to a buffer that contains the line. If EOF, returns NULL ! 426: */ ! 427: char *lgetl() ! 428: { ! 429: register int i=LINBUFSIZE,ch; ! 430: register char *str=lgetwbuf; ! 431: for ( ; ; --i) ! 432: { ! 433: if ((*str++ = ch = lgetc()) == NULL) ! 434: { ! 435: if (str == lgetwbuf+1) return(NULL); /* EOF */ ! 436: ot: *str = NULL; return(lgetwbuf); /* line ended by EOF */ ! 437: } ! 438: if ((ch=='\n') || (i<=1)) goto ot; /* line ended by \n */ ! 439: } ! 440: } ! 441: ! 442: /* ! 443: * lcreat(filename) Create a new file for write ! 444: * char *filename; ! 445: * ! 446: * lcreat((char*)0); means to the terminal ! 447: * Returns -1 if error, otherwise the file descriptor opened. ! 448: */ ! 449: lcreat(str) ! 450: char *str; ! 451: { ! 452: lpnt = lpbuf; lpend = lpbuf+BUFBIG; ! 453: if (str==NULL) return(lfd=1); ! 454: if ((lfd=creat(str,0644)) < 0) ! 455: { ! 456: lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1); ! 457: } ! 458: return(lfd); ! 459: } ! 460: ! 461: /* ! 462: * lopen(filename) Open a file for read ! 463: * char *filename; ! 464: * ! 465: * lopen(0) means from the terminal ! 466: * Returns -1 if error, otherwise the file descriptor opened. ! 467: */ ! 468: lopen(str) ! 469: char *str; ! 470: { ! 471: ipoint = iepoint = MAXIBUF; ! 472: if (str==NULL) return(fd=0); ! 473: if ((fd=open(str,0)) < 0) ! 474: { ! 475: lwclose(); lfd=1; lpnt=lpbuf; return(-1); ! 476: } ! 477: return(fd); ! 478: } ! 479: ! 480: /* ! 481: * lappend(filename) Open for append to an existing file ! 482: * char *filename; ! 483: * ! 484: * lappend(0) means to the terminal ! 485: * Returns -1 if error, otherwise the file descriptor opened. ! 486: */ ! 487: lappend(str) ! 488: char *str; ! 489: { ! 490: lpnt = lpbuf; lpend = lpbuf+BUFBIG; ! 491: if (str==NULL) return(lfd=1); ! 492: if ((lfd=open(str,2)) < 0) ! 493: { ! 494: lfd=1; return(-1); ! 495: } ! 496: lseek(lfd,0,2); /* seek to end of file */ ! 497: return(lfd); ! 498: } ! 499: ! 500: /* ! 501: * lrclose() close the input file ! 502: * ! 503: * Returns nothing of value. ! 504: */ ! 505: lrclose() ! 506: { ! 507: if (fd > 0) close(fd); ! 508: } ! 509: ! 510: /* ! 511: * lwclose() close output file flushing if needed ! 512: * ! 513: * Returns nothing of value. ! 514: */ ! 515: lwclose() ! 516: { ! 517: lflush(); if (lfd > 2) close(lfd); ! 518: } ! 519: ! 520: /* ! 521: * lprcat(string) append a string to the output buffer ! 522: * avoids calls to lprintf (time consuming) ! 523: */ ! 524: lprcat(str) ! 525: register char *str; ! 526: { ! 527: register char *str2; ! 528: if (lpnt >= lpend) lflush(); ! 529: str2 = lpnt; ! 530: while (*str2++ = *str++); ! 531: lpnt = str2 - 1; ! 532: } ! 533: ! 534: #ifdef VT100 ! 535: /* ! 536: * cursor(x,y) Subroutine to set the cursor position ! 537: * ! 538: * x and y are the cursor coordinates, and lpbuff is the output buffer where ! 539: * escape sequence will be placed. ! 540: */ ! 541: static char *y_num[]= { "\33[","\33[","\33[2","\33[3","\33[4","\33[5","\33[6", ! 542: "\33[7","\33[8","\33[9","\33[10","\33[11","\33[12","\33[13","\33[14", ! 543: "\33[15","\33[16","\33[17","\33[18","\33[19","\33[20","\33[21","\33[22", ! 544: "\33[23","\33[24" }; ! 545: ! 546: static char *x_num[]= { "H","H",";2H",";3H",";4H",";5H",";6H",";7H",";8H",";9H", ! 547: ";10H",";11H",";12H",";13H",";14H",";15H",";16H",";17H",";18H",";19H", ! 548: ";20H",";21H",";22H",";23H",";24H",";25H",";26H",";27H",";28H",";29H", ! 549: ";30H",";31H",";32H",";33H",";34H",";35H",";36H",";37H",";38H",";39H", ! 550: ";40H",";41H",";42H",";43H",";44H",";45H",";46H",";47H",";48H",";49H", ! 551: ";50H",";51H",";52H",";53H",";54H",";55H",";56H",";57H",";58H",";59H", ! 552: ";60H",";61H",";62H",";63H",";64H",";65H",";66H",";67H",";68H",";69H", ! 553: ";70H",";71H",";72H",";73H",";74H",";75H",";76H",";77H",";78H",";79H", ! 554: ";80H" }; ! 555: ! 556: cursor(x,y) ! 557: int x,y; ! 558: { ! 559: register char *p; ! 560: if (lpnt >= lpend) lflush(); ! 561: ! 562: p = y_num[y]; /* get the string to print */ ! 563: while (*p) *lpnt++ = *p++; /* print the string */ ! 564: ! 565: p = x_num[x]; /* get the string to print */ ! 566: while (*p) *lpnt++ = *p++; /* print the string */ ! 567: } ! 568: #else VT100 ! 569: /* ! 570: * cursor(x,y) Put cursor at specified coordinates staring at [1,1] (termcap) ! 571: */ ! 572: cursor (x,y) ! 573: int x,y; ! 574: { ! 575: if (lpnt >= lpend) lflush (); ! 576: ! 577: *lpnt++ = CURSOR; *lpnt++ = x; *lpnt++ = y; ! 578: } ! 579: #endif VT100 ! 580: ! 581: /* ! 582: * Routine to position cursor at beginning of 24th line ! 583: */ ! 584: cursors() ! 585: { ! 586: cursor(1,24); ! 587: } ! 588: ! 589: #ifndef VT100 ! 590: /* ! 591: * Warning: ringing the bell is control code 7. Don't use in defines. ! 592: * Don't change the order of these defines. ! 593: * Also used in helpfiles. Codes used in helpfiles should be \E[1 to \E[7 with ! 594: * obvious meanings. ! 595: */ ! 596: ! 597: static char cap[256]; ! 598: char *CM, *CE, *CD, *CL, *SO, *SE, *AL, *DL;/* Termcap capabilities */ ! 599: static char *outbuf=0; /* translated output buffer */ ! 600: ! 601: int putchar (); ! 602: ! 603: /* ! 604: * init_term() Terminal initialization -- setup termcap info ! 605: */ ! 606: init_term() ! 607: { ! 608: char termbuf[1024]; ! 609: char *capptr = cap+10; ! 610: char *term; ! 611: ! 612: switch (tgetent(termbuf, term = getenv("TERM"))) ! 613: { ! 614: case -1: ! 615: write(2, "Cannot open termcap file.\n", 26); exit(); ! 616: case 0: ! 617: write(2, "Cannot find entry of ", 21); ! 618: write(2, term, strlen (term)); ! 619: write(2, " in termcap\n", 12); ! 620: exit(); ! 621: }; ! 622: ! 623: CM = tgetstr("cm", &capptr); /* Cursor motion */ ! 624: CE = tgetstr("ce", &capptr); /* Clear to eoln */ ! 625: CL = tgetstr("cl", &capptr); /* Clear screen */ ! 626: ! 627: /* OPTIONAL */ ! 628: AL = tgetstr("al", &capptr); /* Insert line */ ! 629: DL = tgetstr("dl", &capptr); /* Delete line */ ! 630: SO = tgetstr("so", &capptr); /* Begin standout mode */ ! 631: SE = tgetstr("se", &capptr); /* End standout mode */ ! 632: CD = tgetstr("cd", &capptr); /* Clear to end of display */ ! 633: ! 634: if (!CM) /* can't find cursor motion entry */ ! 635: { ! 636: write(2, "Sorry, for a ",13); write(2, term, strlen(term)); ! 637: write(2, ", I can't find the cursor motion entry in termcap\n",50); ! 638: exit(); ! 639: } ! 640: if (!CE) /* can't find clear to end of line entry */ ! 641: { ! 642: write(2, "Sorry, for a ",13); write(2, term, strlen(term)); ! 643: write(2,", I can't find the clear to end of line entry in termcap\n",57); ! 644: exit(); ! 645: } ! 646: if (!CL) /* can't find clear entire screen entry */ ! 647: { ! 648: write(2, "Sorry, for a ",13); write(2, term, strlen(term)); ! 649: write(2, ", I can't find the clear entire screen entry in termcap\n",56); ! 650: exit(); ! 651: } ! 652: if ((outbuf=malloc(BUFBIG+16))==0) /* get memory for decoded output buffer*/ ! 653: { ! 654: write(2,"Error malloc'ing memory for decoded output buffer\n",50); ! 655: died(-285); /* malloc() failure */ ! 656: } ! 657: } ! 658: #endif VT100 ! 659: ! 660: /* ! 661: * cl_line(x,y) Clear the whole line indicated by 'y' and leave cursor at [x,y] ! 662: */ ! 663: cl_line(x,y) ! 664: int x,y; ! 665: { ! 666: #ifdef VT100 ! 667: cursor(x,y); lprcat("\33[2K"); ! 668: #else VT100 ! 669: cursor(1,y); *lpnt++ = CL_LINE; cursor(x,y); ! 670: #endif VT100 ! 671: } ! 672: ! 673: /* ! 674: * cl_up(x,y) Clear screen from [x,1] to current position. Leave cursor at [x,y] ! 675: */ ! 676: cl_up(x,y) ! 677: register int x,y; ! 678: { ! 679: #ifdef VT100 ! 680: cursor(x,y); lprcat("\33[1J\33[2K"); ! 681: #else VT100 ! 682: register int i; ! 683: cursor(1,1); ! 684: for (i=1; i<=y; i++) { *lpnt++ = CL_LINE; *lpnt++ = '\n'; } ! 685: cursor(x,y); ! 686: #endif VT100 ! 687: } ! 688: ! 689: /* ! 690: * cl_dn(x,y) Clear screen from [1,y] to end of display. Leave cursor at [x,y] ! 691: */ ! 692: cl_dn(x,y) ! 693: register int x,y; ! 694: { ! 695: #ifdef VT100 ! 696: cursor(x,y); lprcat("\33[J\33[2K"); ! 697: #else VT100 ! 698: register int i; ! 699: cursor(1,y); ! 700: if (!CD) ! 701: { ! 702: *lpnt++ = CL_LINE; ! 703: for (i=y; i<=24; i++) { *lpnt++ = CL_LINE; if (i!=24) *lpnt++ = '\n'; } ! 704: cursor(x,y); ! 705: } ! 706: else ! 707: *lpnt++ = CL_DOWN; ! 708: cursor(x,y); ! 709: #endif VT100 ! 710: } ! 711: ! 712: /* ! 713: * standout(str) Print the argument string in inverse video (standout mode). ! 714: */ ! 715: standout(str) ! 716: register char *str; ! 717: { ! 718: #ifdef VT100 ! 719: setbold(); ! 720: while (*str) ! 721: *lpnt++ = *str++; ! 722: resetbold(); ! 723: #else VT100 ! 724: *lpnt++ = ST_START; ! 725: while (*str) ! 726: *lpnt++ = *str++; ! 727: *lpnt++ = ST_END; ! 728: #endif VT100 ! 729: } ! 730: ! 731: /* ! 732: * set_score_output() Called when output should be literally printed. ! 733: */ ! 734: set_score_output() ! 735: { ! 736: enable_scroll = -1; ! 737: } ! 738: ! 739: /* ! 740: * lflush() Flush the output buffer ! 741: * ! 742: * Returns nothing of value. ! 743: * for termcap version: Flush output in output buffer according to output ! 744: * status as indicated by `enable_scroll' ! 745: */ ! 746: #ifndef VT100 ! 747: static int scrline=18; /* line # for wraparound instead of scrolling if no DL */ ! 748: lflush () ! 749: { ! 750: register int lpoint; ! 751: register char *str; ! 752: static int curx = 0; ! 753: static int cury = 0; ! 754: ! 755: if ((lpoint = lpnt - lpbuf) > 0) ! 756: { ! 757: #ifdef EXTRA ! 758: c[BYTESOUT] += lpoint; ! 759: #endif ! 760: if (enable_scroll <= -1) ! 761: { ! 762: flush_buf(); ! 763: if (write(lfd,lpbuf,lpoint) != lpoint) ! 764: write(2,"error writing to output file\n",29); ! 765: lpnt = lpbuf; /* point back to beginning of buffer */ ! 766: return; ! 767: } ! 768: for (str = lpbuf; str < lpnt; str++) ! 769: { ! 770: if (*str>=32) { putchar (*str); curx++; } ! 771: else switch (*str) ! 772: { ! 773: case CLEAR: tputs (CL, 0, putchar); curx = cury = 0; ! 774: break; ! 775: ! 776: case CL_LINE: tputs (CE, 0, putchar); ! 777: break; ! 778: ! 779: case CL_DOWN: tputs (CD, 0, putchar); ! 780: break; ! 781: ! 782: case ST_START: tputs (SO, 0, putchar); ! 783: break; ! 784: ! 785: case ST_END: tputs (SE, 0, putchar); ! 786: break; ! 787: ! 788: case CURSOR: curx = *++str - 1; cury = *++str - 1; ! 789: tputs (tgoto (CM, curx, cury), 0, putchar); ! 790: break; ! 791: ! 792: case '\n': if ((cury == 23) && enable_scroll) ! 793: { ! 794: if (!DL || !AL) /* wraparound or scroll? */ ! 795: { ! 796: if (++scrline > 23) scrline=19; ! 797: ! 798: if (++scrline > 23) scrline=19; ! 799: tputs (tgoto (CM, 0, scrline), 0, putchar); ! 800: tputs (CE, 0, putchar); ! 801: ! 802: if (--scrline < 19) scrline=23; ! 803: tputs (tgoto (CM, 0, scrline), 0, putchar); ! 804: tputs (CE, 0, putchar); ! 805: } ! 806: else ! 807: { ! 808: tputs (tgoto (CM, 0, 19), 0, putchar); ! 809: tputs (DL, 0, putchar); ! 810: tputs (tgoto (CM, 0, 23), 0, putchar); ! 811: /* tputs (AL, 0, putchar); */ ! 812: } ! 813: } ! 814: else ! 815: { ! 816: putchar ('\n'); cury++; ! 817: } ! 818: curx = 0; ! 819: break; ! 820: ! 821: default: putchar (*str); curx++; ! 822: }; ! 823: } ! 824: } ! 825: lpnt = lpbuf; ! 826: flush_buf(); /* flush real output buffer now */ ! 827: } ! 828: #else VT100 ! 829: /* ! 830: * lflush() flush the output buffer ! 831: * ! 832: * Returns nothing of value. ! 833: */ ! 834: lflush() ! 835: { ! 836: register int lpoint; ! 837: if ((lpoint = lpnt - lpbuf) > 0) ! 838: { ! 839: #ifdef EXTRA ! 840: c[BYTESOUT] += lpoint; ! 841: #endif ! 842: if (write(lfd,lpbuf,lpoint) != lpoint) ! 843: write(2,"error writing to output file\n",29); ! 844: } ! 845: lpnt = lpbuf; /* point back to beginning of buffer */ ! 846: } ! 847: #endif VT100 ! 848: ! 849: #ifndef VT100 ! 850: static int index=0; ! 851: /* ! 852: * putchar(ch) Print one character in decoded output buffer. ! 853: */ ! 854: int putchar(c) ! 855: int c; ! 856: { ! 857: outbuf[index++] = c; ! 858: if (index >= BUFBIG) flush_buf(); ! 859: } ! 860: ! 861: /* ! 862: * flush_buf() Flush buffer with decoded output. ! 863: */ ! 864: flush_buf() ! 865: { ! 866: if (index) write(lfd, outbuf, index); ! 867: index = 0; ! 868: } ! 869: ! 870: /* ! 871: * char *tmcapcnv(sd,ss) Routine to convert VT100 escapes to termcap format ! 872: * ! 873: * Processes only the \33[#m sequence (converts . files for termcap use ! 874: */ ! 875: char *tmcapcnv(sd,ss) ! 876: register char *sd,*ss; ! 877: { ! 878: register int tmstate=0; /* 0=normal, 1=\33 2=[ 3=# */ ! 879: char tmdigit=0; /* the # in \33[#m */ ! 880: while (*ss) ! 881: { ! 882: switch(tmstate) ! 883: { ! 884: case 0: if (*ss=='\33') { tmstate++; break; } ! 885: ign: *sd++ = *ss; ! 886: ign2: tmstate = 0; ! 887: break; ! 888: case 1: if (*ss!='[') goto ign; ! 889: tmstate++; ! 890: break; ! 891: case 2: if (isdigit(*ss)) { tmdigit= *ss-'0'; tmstate++; break; } ! 892: if (*ss == 'm') { *sd++ = ST_END; goto ign2; } ! 893: goto ign; ! 894: case 3: if (*ss == 'm') ! 895: { ! 896: if (tmdigit) *sd++ = ST_START; ! 897: else *sd++ = ST_END; ! 898: goto ign2; ! 899: } ! 900: default: goto ign; ! 901: }; ! 902: ss++; ! 903: } ! 904: *sd=0; /* NULL terminator */ ! 905: return(sd); ! 906: } ! 907: #endif VT100 ! 908: ! 909: /* ! 910: * beep() Routine to emit a beep if enabled (see no-beep in .larnopts) ! 911: */ ! 912: beep() ! 913: { ! 914: if (!nobeep) *lpnt++ = '\7'; ! 915: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.