home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / archiver / peek_221.arj / ANSI.C next >
C/C++ Source or Header  |  1992-03-30  |  18KB  |  752 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. /*
  6.  * to initialize:
  7.  *   call set_screensize(<# lines to reserve>);
  8.  * to print through ansi interpreter:
  9.  *   call ansi_out(<string>);
  10.  */
  11.  
  12. char               curattr = 7;
  13. int                curx = 0,cury = 0;
  14. int                maxx = 80, maxy = 25;  /* size of ansi output window */
  15. int                realmaxy,realmaxx;     /* real screen size */
  16. char               useansi = 1;           /* while true, interp ansi seqs */
  17. int                tabspaces = 8;
  18. static int         savx,savy,issaved = 0;
  19. static char        ansi_terminators[] = "HFABCDnsuJKmp";
  20.  
  21. #ifdef __TURBOC__
  22.     #define _fastcall pascal
  23. #endif
  24.  
  25. #define MAXARGLEN       128
  26.  
  27. #define NOTHING         0
  28. #define WASESCAPE       1
  29. #define WASBRKT         2
  30.  
  31.  
  32. /* set maxx,maxy as desired */
  33. void _fastcall set_screensize (int reservedlines);
  34.  
  35. /* put character c at x,y using attr as attribute */
  36. void _fastcall put_char (char c,char attr,int x,int y);
  37.  
  38. /* position hardware cursor at x,y */
  39. void _fastcall pos_hardcursor (int x,int y);
  40.  
  41. /* turn hardware cursor off */
  42. void _fastcall hardcursor_off (void);
  43.  
  44. /* turn hardware cursor on at x,y */
  45. void _fastcall hardcursor_on (int x,int y);
  46.  
  47. /* scroll window tx,ty - bx,by up one line; fill with blank+attr */
  48. void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr);
  49.  
  50. /* clear the window from tx,ty - bx,by; fill with blank+attr */
  51. void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr);
  52.  
  53. /* clear line y from col x to eol (ex); fill with blank+attr */
  54. void _fastcall cleartoeol (int x,int y,int ex,char attr);
  55.  
  56. /* validate cursor position after external routines may have changed it */
  57. void _fastcall validate_cursor (void);
  58.  
  59.  
  60. /* the ansi string interpreter */
  61. int _fastcall ansi_out (char *buf);
  62.  
  63.  
  64.  
  65. /* "generic" support functions closely related to ansi_out */
  66.  
  67. void _fastcall set_pos (char *argbuf,int arglen,char cmd) {
  68.  
  69.     int   y,x;
  70.     char *p;
  71.  
  72.  
  73.     if(!*argbuf || !arglen) {
  74.         curx = cury = 0;
  75.     }
  76.     y = atoi(argbuf) - 1;
  77.     p = strchr(argbuf,';');
  78.     if(y >= 0 && p) {
  79.         x = atoi(p + 1) - 1;
  80.         if(x >= 0) {
  81.             curx = x;
  82.             cury = y;
  83.         }
  84.     }
  85. }
  86.  
  87.  
  88. void _fastcall go_up (char *argbuf,int arglen,char cmd) {
  89.  
  90.     int x;
  91.  
  92.     x = atoi(argbuf);
  93.     if(!x) x = 1;
  94.     for(;x;x--) {
  95.         if(!cury) break;
  96.         cury--;
  97.     }
  98. }
  99.  
  100.  
  101. void _fastcall go_down (char *argbuf,int arglen,char cmd) {
  102.  
  103.     int x;
  104.  
  105.     x = atoi(argbuf);
  106.     if(!x) x = 1;
  107.     for(;x;x--) {
  108.         if(cury == maxy - 1) break;
  109.         cury++;
  110.     }
  111. }
  112.  
  113.  
  114. void _fastcall go_left (char *argbuf,int arglen,char cmd) {
  115.  
  116.     int x;
  117.  
  118.     x = atoi(argbuf);
  119.     if(!x) x = 1;
  120.     for(;x;x--) {
  121.         if(!curx) break;
  122.         curx--;
  123.     }
  124. }
  125.  
  126.  
  127. void _fastcall go_right (char *argbuf,int arglen,char cmd) {
  128.  
  129.     int x;
  130.  
  131.     x = atoi(argbuf);
  132.     if(!x) x = 1;
  133.     for(;x;x--) {
  134.         if(curx == maxx - 1) break;
  135.         curx++;
  136.     }
  137. }
  138.  
  139.  
  140. void _fastcall report (char *argbuf,int arglen,char cmd) {
  141.  
  142.     /* you figure out how to implement it ... */
  143. }
  144.  
  145.  
  146. void _fastcall save_pos (char *argbuf,int arglen,char cmd) {
  147.  
  148.     savx = curx;
  149.     savy = cury;
  150.     issaved = 1;
  151. }
  152.  
  153.  
  154. void _fastcall restore_pos (char *argbuf,int arglen,char cmd) {
  155.  
  156.     if(issaved) {
  157.         curx = savx;
  158.         cury = savy;
  159.         issaved = 0;
  160.     }
  161. }
  162.  
  163.  
  164. void _fastcall clear_screen (char *argbuf,int arglen,char cmd) {
  165.  
  166.     /* needs error checking */
  167.  
  168.     clearwindow(0,0,maxx - 1,maxy - 1,curattr);
  169.     curx = cury = 0;
  170. }
  171.  
  172.  
  173. void _fastcall kill_line (char *argbuf,int arglen,char cmd) {
  174.  
  175.     cleartoeol(curx,cury,maxx - 1,curattr);
  176. }
  177.  
  178.  
  179. void _fastcall set_colors (char *argbuf,int arglen,char cmd) {
  180.  
  181.     char *p,*pp;
  182.  
  183.  
  184.     if(*argbuf && arglen) {
  185.         pp = argbuf;
  186.         do {
  187.             p = strchr(pp,';');
  188.             if(p && *p) {
  189.                 *p = 0;
  190.                 p++;
  191.             }
  192.             switch(atoi(pp)) {
  193.                 case 0: /* all attributes off */
  194.                     curattr = 7;
  195.                     break;
  196.  
  197.                 case 1: /* bright on */
  198.                     curattr |= 8;
  199.                     break;
  200.  
  201.                 case 2: /* faint on */
  202.                     curattr &= (~8);
  203.                     break;
  204.  
  205.                 case 3: /* italic on */
  206.                     break;
  207.  
  208.                 case 5: /* blink on */
  209.                     curattr |= 128;
  210.                     break;
  211.  
  212.                 case 6: /* rapid blink on */
  213.                     break;
  214.  
  215.                 case 7: /* reverse video on */
  216.                     curattr = 112;
  217.                     break;
  218.  
  219.                 case 8: /* concealed on */
  220.                     curattr = 0;
  221.                     break;
  222.  
  223.                 case 30: /* black fg */
  224.                     curattr &= (~7);
  225.                     break;
  226.  
  227.                 case 31: /* red fg */
  228.                     curattr &= (~7);
  229.                     curattr |= 4;
  230.                     break;
  231.  
  232.                 case 32: /* green fg */
  233.                     curattr &= (~7);
  234.                     curattr |= 2;
  235.                     break;
  236.  
  237.                 case 33: /* yellow fg */
  238.                     curattr &= (~7);
  239.                     curattr |= 6;
  240.                     break;
  241.  
  242.                 case 34: /* blue fg */
  243.                     curattr &= (~7);
  244.                     curattr |= 1;
  245.                     break;
  246.  
  247.                 case 35: /* magenta fg */
  248.                     curattr &= (~7);
  249.                     curattr |= 5;
  250.                     break;
  251.  
  252.                 case 36: /* cyan fg */
  253.                     curattr &= (~7);
  254.                     curattr |= 3;
  255.                     break;
  256.  
  257.                 case 37: /* white fg */
  258.                     curattr |= 7;
  259.                     break;
  260.  
  261.                 case 40: /* black bg */
  262.                     curattr &= (~112);
  263.                     break;
  264.  
  265.                 case 41: /* red bg */
  266.                     curattr &= (~112);
  267.                     curattr |= (4 << 4);
  268.                     break;
  269.  
  270.                 case 42: /* green bg */
  271.                     curattr &= (~112);
  272.                     curattr |= (2 << 4);
  273.                     break;
  274.  
  275.                 case 43: /* yellow bg */
  276.                     curattr &= (~112);
  277.                     curattr |= (6 << 4);
  278.                     break;
  279.  
  280.                 case 44: /* blue bg */
  281.                     curattr &= (~112);
  282.                     curattr |= (1 << 4);
  283.                     break;
  284.  
  285.                 case 45: /* magenta bg */
  286.                     curattr &= (~112);
  287.                     curattr |= (5 << 4);
  288.                     break;
  289.  
  290.                 case 46: /* cyan bg */
  291.                     curattr &= (~112);
  292.                     curattr |= (3 << 4);
  293.                     break;
  294.  
  295.                 case 47: /* white bg */
  296.                     curattr |= 112;
  297.                     break;
  298.  
  299.                 case 48: /* subscript bg */
  300.                     break;
  301.  
  302.                 case 49: /* superscript bg */
  303.                     break;
  304.  
  305.                 default: /* unsupported */
  306.                     break;
  307.             }
  308.             pp = p;
  309.         } while(p);
  310.     }
  311. }
  312.  
  313.  
  314. int _fastcall ansi_out (char *buf) {
  315.  
  316.     int  arglen = 0,ansistate = NOTHING,x;
  317.     char *b = buf,argbuf[MAXARGLEN] = "";
  318.  
  319.  
  320.     /* cursor is off while string is being displayed so we don't have
  321.        to keep updating it.  works to our detriment only if using
  322.        BIOS writes under MS-DOS */
  323.  
  324.     hardcursor_off();
  325.  
  326.     if(!useansi) {          /* is ANSI interp on? */
  327.       ansistate = NOTHING;
  328.       arglen = 0;
  329.       *argbuf = 0;
  330.     }
  331.  
  332.     while(*b) {
  333.         switch(ansistate) {
  334.           case NOTHING:
  335.                 switch(*b) {
  336.                     case '\x1b':
  337.                         if(useansi) {
  338.                           ansistate = WASESCAPE;
  339.                           break;
  340.                         }
  341.  
  342.                     case '\r':
  343.                         curx = 0;
  344.                         break;
  345.  
  346.                     case '\n':
  347.                         cury++;
  348.                         if(cury > maxy - 1) {
  349.                             scroll_up(0,0,maxx - 1,maxy - 1,curattr);
  350.                             cury--;
  351.                         }
  352.                         break;
  353.  
  354.                     case '\t':     /* so _you_ figure out what to do... */
  355.                         for(x = 0;x < tabspaces;x++) {
  356.                             put_char(' ',curattr,curx,cury);
  357.                             curx++;
  358.                             if(curx > maxx - 1) {
  359.                                 curx = 0;
  360.                                 cury++;
  361.                                 if(cury > maxy - 1) {
  362.                                     scroll_up(0,0,maxx - 1,maxy - 1,curattr);
  363.                                     cury--;
  364.                                 }
  365.                             }
  366.                         }
  367.                         break;
  368.  
  369.                     case '\b':
  370.                         if(curx) {
  371.                             curx--;
  372.                         }
  373.                         break;
  374.  
  375.                     case '\07':     /* usually a console bell */
  376.                         putchar('\07');
  377.                         break;
  378.  
  379.                     default:
  380.                         put_char(*b,curattr,curx,cury);
  381.                         curx++;
  382.                         if(curx > maxx - 1) {
  383.                             curx = 0;
  384.                             cury++;
  385.                             if(cury > maxy - 1) {
  386.                                 scroll_up(0,0,maxx - 1,maxy - 1,curattr);
  387.                                 cury--;
  388.                             }
  389.                         }
  390.                         break;
  391.                 }
  392.                 break;
  393.  
  394.           case WASESCAPE:
  395.             if(*b == '[') {
  396.                 ansistate = WASBRKT;
  397.                 arglen = 0;
  398.                 *argbuf = 0;
  399.                 break;
  400.             }
  401.             ansistate = NOTHING;
  402.             break;
  403.  
  404.           case WASBRKT:
  405.             if(strchr(ansi_terminators,(int)*b)) {
  406.                 switch((int)*b) {
  407.                     case 'H':   /* set cursor position */
  408.                     case 'F':
  409.                         set_pos(argbuf,arglen,*b);
  410.                         break;
  411.  
  412.                     case 'A':   /* up */
  413.                         go_up(argbuf,arglen,*b);
  414.                         break;
  415.  
  416.                     case 'B':   /* down */
  417.                         go_down(argbuf,arglen,*b);
  418.                         break;
  419.  
  420.                     case 'C':   /* right */
  421.                         go_right(argbuf,arglen,*b);
  422.                         break;
  423.  
  424.                     case 'D':   /* left */
  425.                         go_left(argbuf,arglen,*b);
  426.                         break;
  427.  
  428.                     case 'n':   /* report pos */
  429.                         report(argbuf,arglen,*b);
  430.                         break;
  431.  
  432.                     case 's':   /* save pos */
  433.                         save_pos(argbuf,arglen,*b);
  434.                         break;
  435.  
  436.                     case 'u':   /* restore pos */
  437.                         restore_pos(argbuf,arglen,*b);
  438.                         break;
  439.  
  440.                     case 'J':   /* clear screen */
  441.                         clear_screen(argbuf,arglen,*b);
  442.                         break;
  443.  
  444.                     case 'K':   /* delete to eol */
  445.                         kill_line(argbuf,arglen,*b);
  446.                         break;
  447.  
  448.                     case 'm':   /* set video attribs */
  449.                         set_colors(argbuf,arglen,*b);
  450.                         break;
  451.  
  452.                     case 'p':   /* keyboard redef -- disallowed */
  453.                         break;
  454.  
  455.                     default:    /* unsupported */
  456.                         break;
  457.                 }
  458.                 ansistate = NOTHING;
  459.                 arglen = 0;
  460.                 *argbuf = 0;
  461.             }
  462.             else {
  463.                 if(arglen < MAXARGLEN) {
  464.                     argbuf[arglen] = *b;
  465.                     argbuf[arglen + 1] = 0;
  466.                     arglen++;
  467.                 }
  468.             }
  469.             break;
  470.  
  471.           default:
  472.             pos_hardcursor(curx,cury);
  473.             fputs("\n **Error in ANSI state machine.\n",stderr);
  474.             break;
  475.         }
  476.  
  477.         b++;
  478.     }
  479.  
  480.     pos_hardcursor(curx,cury);
  481.     hardcursor_on(curx,cury);
  482.  
  483.     return ((int)b - (int)buf);
  484. }
  485.  
  486.  
  487.  
  488. /* OS specific functions -- this can be moved to a separate module */
  489.  
  490. #ifdef OS2
  491.  
  492. #define INCL_DOS
  493. #define INCL_VIO
  494.  
  495. #include <os2.h>
  496.  
  497. int vidhandle = 0;  /* can be changed for AVIO */
  498.  
  499.  
  500. void _fastcall set_screensize (int reservedlines) {
  501.  
  502.     VIOMODEINFO vm;
  503.  
  504.     vm.cb = sizeof(VIOMODEINFO);
  505.     VioGetMode(&vm, vidhandle);
  506.     maxx = vm.col;
  507.     maxy = vm.row - reservedlines;
  508.     realmaxx = maxx;
  509.     realmaxy = vm.row;
  510. }
  511.  
  512.  
  513. void _fastcall pos_hardcursor (int x,int y) {
  514.  
  515.     VioSetCurPos(y,x,vidhandle);
  516. }
  517.  
  518.  
  519. void _fastcall hardcursor_off (void) {
  520.  
  521.     VIOCURSORINFO vc;
  522.  
  523.     VioGetCurType(&vc,vidhandle);
  524.     vc.attr = -1;
  525.     VioSetCurType(&vc,vidhandle);
  526. }
  527.  
  528.  
  529. void _fastcall hardcursor_on (int x,int y) {
  530.  
  531.     VIOCURSORINFO vc;
  532.  
  533.     VioGetCurType(&vc,vidhandle);
  534.     vc.attr = 0;
  535.     VioSetCurType(&vc,vidhandle);
  536.     VioSetCurPos(y,x,vidhandle);
  537. }
  538.  
  539.  
  540. void _fastcall put_char (char c, char attr, int x, int y) {
  541.  
  542.     VioWrtCharStrAtt(&c,1,y,x,&attr,vidhandle);
  543. }
  544.  
  545.  
  546. void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
  547.  
  548.     int attrib = ' ' | (attr << 8);
  549.  
  550.     VioScrollUp(ty,tx,by,bx,1,(char *)&attrib,vidhandle);
  551. }
  552.  
  553.  
  554. void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
  555.  
  556.     int attrib = ' ' | (attr << 8);
  557.  
  558.     VioScrollUp(ty,tx,by,bx,-1,(char *)&attrib,vidhandle);
  559. }
  560.  
  561.  
  562. void _fastcall cleartoeol (int x,int y,int ex,char attr) {
  563.  
  564.     int attrib = ' ' | (attr << 8);
  565.  
  566.     VioScrollUp(y,x,y,ex,-1,(char *)&attrib,vidhandle);
  567. }
  568.  
  569. void _fastcall validate_cursor (void) {
  570.  
  571.   int x,y;
  572.  
  573.   VioGetCurPos(&y,&x,vidhandle);
  574.   if(y > maxy - 1) {
  575.     cury = maxy - 1;
  576.   }
  577.   else cury = y;
  578.   curx = x;
  579. }
  580.  
  581. #else
  582.  
  583. /* MS-DOS -- this stuff has _not_ been tested */
  584.  
  585. #include <dos.h>
  586.  
  587. #if !defined(MK_FP)
  588.  #define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off)))
  589. #endif
  590.  
  591. static int far *vseg;
  592. int            realmaxy,realmaxx;
  593. char           usebios = 0; /* if true, output through BIOS */
  594.  
  595.  
  596. int _fastcall vmode (void) {
  597.  
  598.     union REGS r;
  599.  
  600.     r.h.ah = 15;
  601.     r.x.bx = 0;
  602.     int86(0x10,&r,&r);
  603.     return r.h.al;
  604. }
  605.  
  606.  
  607. void _fastcall set_screensize (int reservedlines) {
  608.  
  609.     union REGS   r;
  610.     unsigned int vbase;
  611.  
  612.     r.h.ah = 0x0f;
  613.     r.x.bx = 0;
  614.     int86 (0x10, &r, &r);
  615.     maxx = (int) r.h.ah;
  616.     if(maxx < 80) {               /* gimme a break! */
  617.         r.x.ax = 0x0003;
  618.         int86(0x10,&r,&r);
  619.         maxx = 80;
  620.     }
  621.     realmaxx = maxx;
  622.     r.x.ax = 0x1130;
  623.     r.x.dx = maxy;
  624.     int86 (0x10, &r, &r);
  625.     realmaxy = maxy = (r.x.dx == 0) ? 25 : (r.x.dx + 1);
  626.     maxy -= reservedlines;
  627.     vbase = (vmode () == 7 ? 0xb000 : 0xb800);
  628.     vseg = MK_FP(vbase,0);       /* address of video ram as pointer */
  629. }
  630.  
  631.  
  632. void _fastcall pos_hardcursor (int x,int y) {
  633.  
  634.     union REGS r;
  635.  
  636.     r.x.ax = 0x0200;
  637.     r.x.bx = 0;
  638.     r.x.dx = ((y << 8) & 0xff00) + x;
  639.     int86(0x10,&r,&r);
  640. }
  641.  
  642.  
  643. void _fastcall hardcursor_off (void) {
  644.  
  645.     union REGS r;
  646.  
  647.     r.x.ax = 0x0200;
  648.     r.x.bx = 0;
  649.     r.x.dx = ((realmaxy << 8) & 0xff00);
  650.     int86(0x10,&r,&r);
  651. }
  652.  
  653.  
  654. void _fastcall hardcursor_on (int x,int y) {
  655.  
  656.     union REGS r;
  657.  
  658.     r.x.ax = 0x0200;
  659.     r.x.bx = 0;
  660.     r.x.dx = ((y << 8) & 0xff00) + x;
  661.     int86(0x10,&r,&r);
  662. }
  663.  
  664.  
  665. void _fastcall put_char (char c, char attr, int x, int y) {
  666.  
  667.   if(!usebios) {
  668.  
  669.     register int far *v;
  670.  
  671.     v = vseg + ((y * realmaxx) + x); /* point v to right spot in vid RAM */
  672.     *v = (c | (attr << 8));          /* display */
  673.   }
  674.   else {
  675.  
  676.     union REGS r;
  677.  
  678.     r.x.ax = 0x0200;
  679.     r.x.bx = 0;
  680.     r.x.dx = ((y << 8) & 0xff00) + x;
  681.     int86(0x10,&r,&r);
  682.     r.h.ah = 0x09;
  683.     r.h.bh = 0;
  684.     r.h.bl = attr;
  685.     r.x.cx = 1;
  686.     r.h.al = c;
  687.     int86(0x10,&r,&r);
  688.   }
  689. }
  690.  
  691.  
  692. void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
  693.  
  694.     union REGS r;
  695.  
  696.     r.h.ah = 6;
  697.     r.h.al = 1;
  698.     r.h.bh = attr;
  699.     r.h.cl = tx;
  700.     r.h.ch = ty;
  701.     r.h.dl = bx;
  702.     r.h.dh = by;
  703.     int86(0x10,&r,&r);
  704. }
  705.  
  706.  
  707. void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
  708.  
  709.     union REGS r;
  710.  
  711.     r.h.ah = 6;
  712.     r.h.al = 0;
  713.     r.h.bh = attr;
  714.     r.h.cl = tx;
  715.     r.h.ch = ty;
  716.     r.h.dl = bx;
  717.     r.h.dh = by;
  718.     int86(0x10,&r,&r);
  719. }
  720.  
  721.  
  722. void _fastcall cleartoeol (int x,int y,int ex,char attr) {
  723.  
  724.     union REGS r;
  725.  
  726.     r.h.ah = 6;
  727.     r.h.al = 0;
  728.     r.h.bh = attr;
  729.     r.h.cl = x;
  730.     r.h.ch = y;
  731.     r.h.dl = ex;
  732.     r.h.dh = y;
  733.     int86(0x10,&r,&r);
  734. }
  735.  
  736.  
  737. void _fastcall validate_cursor (void) {
  738.  
  739.   union REGS r;
  740.  
  741.   r.x.ax = 0x0300;
  742.   r.x.bx = 0;
  743.   int86(0x10,&r,&r);
  744.   if(r.h.dh > maxy - 1) {
  745.     cury = maxy - 1;
  746.   }
  747.   else cury = (int)r.h.dh;
  748.   curx = (int)r.h.dl;
  749. }
  750.  
  751. #endif
  752.