Annotation of 43BSDReno/games/larn/io.c, revision 1.1.1.1

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:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.