home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 14 / CD_ASCQ_14_0694.iso / maj / 653 / doansi_1.c < prev    next >
C/C++ Source or Header  |  1994-04-03  |  14KB  |  479 lines

  1. /*
  2. **  DOANSI_1.C - Portable ANSI screen code interpreter
  3. **
  4. **  From DRSK_105.LZH (ansi.c), hereby declared free for use for whatever
  5. **  purposes by author: Mark Kimes
  6. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "doansi.h"
  12.  
  13. /*
  14.  * to initialize:
  15.  *   call set_screensize(<# lines to reserve>);
  16.  * to print through ansi interpreter:
  17.  *   call ansi_out(<string>);
  18.  */
  19.  
  20. char               curattr = 7;
  21. int                curx = 0,cury = 0;
  22. int                maxx = 80, maxy = 25;  /* size of ansi output window */
  23. int                realmaxy,realmaxx;     /* real screen size */
  24. char               useansi = 1;           /* while true, interp ansi seqs */
  25. int                tabspaces = 8;
  26. static int         savx,savy,issaved = 0;
  27. static char        ansi_terminators[] = "HFABCDnsuJKmp";
  28.  
  29. #define MAXARGLEN       128
  30.  
  31. #define NOTHING         0
  32. #define WASESCAPE       1
  33. #define WASBRKT         2
  34.  
  35. /* "generic" support functions closely related to ansi_out */
  36.  
  37. void set_pos (char *argbuf,int arglen,char cmd)
  38. {
  39.       int   y,x;
  40.       char *p;
  41.  
  42.       if (!*argbuf || !arglen)
  43.       {
  44.             curx = cury = 0;
  45.       }
  46.       y = atoi(argbuf) - 1;
  47.       p = strchr(argbuf,';');
  48.       if (y >= 0 && p)
  49.       {
  50.             x = atoi(p + 1) - 1;
  51.             if(x >= 0)
  52.             {
  53.                   curx = x;
  54.                   cury = y;
  55.             }
  56.       }
  57. }
  58.  
  59. void go_up (char *argbuf,int arglen,char cmd)
  60. {
  61.       int x;
  62.  
  63.       x = atoi(argbuf);
  64.       if (!x)
  65.             x = 1;
  66.       for ( ; x ; x--)
  67.       {
  68.             if (!cury)
  69.                   break;
  70.             cury--;
  71.       }
  72. }
  73.  
  74. void go_down (char *argbuf,int arglen,char cmd)
  75. {
  76.       int x;
  77.  
  78.       x = atoi(argbuf);
  79.       if (!x)
  80.             x = 1;
  81.       for ( ; x ; x--)
  82.       {
  83.             if (cury == maxy - 1)
  84.                   break;
  85.             cury++;
  86.       }
  87. }
  88.  
  89. void go_left (char *argbuf,int arglen,char cmd)
  90. {
  91.       int x;
  92.  
  93.       x = atoi(argbuf);
  94.       if (!x)
  95.             x = 1;
  96.       for ( ; x ; x--)
  97.       {
  98.             if(!curx)
  99.                   break;
  100.             curx--;
  101.       }
  102. }
  103.  
  104. void go_right (char *argbuf,int arglen,char cmd)
  105. {
  106.       int x;
  107.  
  108.       x = atoi(argbuf);
  109.       if (!x)
  110.             x = 1;
  111.       for ( ; x ; x--)
  112.       {
  113.             if (curx == maxx - 1)
  114.                   break;
  115.             curx++;
  116.       }
  117. }
  118.  
  119. void report (char *argbuf,int arglen,char cmd)
  120. {
  121.       /* you figure out how to implement it ... */
  122. }
  123.  
  124. void save_pos (char *argbuf,int arglen,char cmd)
  125. {
  126.       savx = curx;
  127.       savy = cury;
  128.       issaved = 1;
  129. }
  130.  
  131. void restore_pos (char *argbuf,int arglen,char cmd)
  132. {
  133.       if(issaved)
  134.       {
  135.             curx = savx;
  136.             cury = savy;
  137.             issaved = 0;
  138.       }
  139. }
  140.  
  141. void clear_screen (char *argbuf,int arglen,char cmd)
  142. {
  143.       /* needs error checking */
  144.  
  145.       clearwindow(0,0,maxx - 1,maxy - 1,curattr);
  146.       curx = cury = 0;
  147. }
  148.  
  149. void kill_line (char *argbuf,int arglen,char cmd)
  150. {
  151.       cleartoeol(curx,cury,maxx - 1,curattr);
  152. }
  153.  
  154.  
  155. void set_colors (char *argbuf,int arglen,char cmd)
  156. {
  157.       char *p,*pp;
  158.  
  159.       if (*argbuf && arglen)
  160.       {
  161.             pp = argbuf;
  162.             do
  163.             {
  164.                   p = strchr(pp,';');
  165.                   if (p && *p)
  166.                   {
  167.                         *p = 0;
  168.                         p++;
  169.                   }
  170.                   switch (atoi(pp))
  171.                   {
  172.                   case 0: /* all attributes off */
  173.                         curattr = 7;
  174.                         break;
  175.  
  176.                   case 1: /* bright on */
  177.                         curattr |= 8;
  178.                         break;
  179.  
  180.                   case 2: /* faint on */
  181.                         curattr &= (~8);
  182.                         break;
  183.  
  184.                   case 3: /* italic on */
  185.                         break;
  186.  
  187.                   case 5: /* blink on */
  188.                         curattr |= 128;
  189.                         break;
  190.  
  191.                   case 6: /* rapid blink on */
  192.                         break;
  193.  
  194.                   case 7: /* reverse video on */
  195.                         curattr = 112;
  196.                         break;
  197.  
  198.                   case 8: /* concealed on */
  199.                         curattr = 0;
  200.                         break;
  201.  
  202.                   case 30: /* black fg */
  203.                         curattr &= (~7);
  204.                         break;
  205.  
  206.                   case 31: /* red fg */
  207.                         curattr &= (~7);
  208.                         curattr |= 4;
  209.                         break;
  210.  
  211.                   case 32: /* green fg */
  212.                         curattr &= (~7);
  213.                         curattr |= 2;
  214.                         break;
  215.  
  216.                   case 33: /* yellow fg */
  217.                         curattr &= (~7);
  218.                         curattr |= 6;
  219.                         break;
  220.  
  221.                   case 34: /* blue fg */
  222.                         curattr &= (~7);
  223.                         curattr |= 1;
  224.                         break;
  225.  
  226.                   case 35: /* magenta fg */
  227.                         curattr &= (~7);
  228.                         curattr |= 5;
  229.                         break;
  230.  
  231.                   case 36: /* cyan fg */
  232.                         curattr &= (~7);
  233.                         curattr |= 3;
  234.                         break;
  235.  
  236.                   case 37: /* white fg */
  237.                         curattr |= 7;
  238.                         break;
  239.  
  240.                   case 40: /* black bg */
  241.                         curattr &= (~112);
  242.                         break;
  243.  
  244.                   case 41: /* red bg */
  245.                         curattr &= (~112);
  246.                         curattr |= (4 << 4);
  247.                         break;
  248.  
  249.                   case 42: /* green bg */
  250.                         curattr &= (~112);
  251.                         curattr |= (2 << 4);
  252.                         break;
  253.  
  254.                   case 43: /* yellow bg */
  255.                         curattr &= (~112);
  256.                         curattr |= (6 << 4);
  257.                         break;
  258.  
  259.                   case 44: /* blue bg */
  260.                         curattr &= (~112);
  261.                         curattr |= (1 << 4);
  262.                         break;
  263.  
  264.                   case 45: /* magenta bg */
  265.                         curattr &= (~112);
  266.                         curattr |= (5 << 4);
  267.                         break;
  268.  
  269.                   case 46: /* cyan bg */
  270.                         curattr &= (~112);
  271.                         curattr |= (3 << 4);
  272.                         break;
  273.  
  274.                   case 47: /* white bg */
  275.                         curattr |= 112;
  276.                         break;
  277.  
  278.                   case 48: /* subscript bg */
  279.                         break;
  280.  
  281.                   case 49: /* superscript bg */
  282.                         break;
  283.  
  284.                   default: /* unsupported */
  285.                         break;
  286.                   }
  287.                   pp = p;
  288.             } while (p);
  289.       }
  290. }
  291.  
  292. int ansi_out (char *buf)
  293. {
  294.       int  arglen = 0, ansistate = NOTHING, x;
  295.       char *b = buf, argbuf[MAXARGLEN] = "";
  296.  
  297.       /* cursor is off while string is being displayed so we don't have
  298.          to keep updating it.  works to our detriment only if using
  299.          BIOS writes under MS-DOS
  300.       */
  301.  
  302.       hardcursor_off();
  303.  
  304.       if (!useansi)                       /* is ANSI interp on? */
  305.       {
  306.             ansistate = NOTHING;
  307.             arglen = 0;
  308.             *argbuf = 0;
  309.       }
  310.  
  311.       while (*b)
  312.       {
  313.             switch (ansistate)
  314.             {
  315.             case NOTHING:
  316.                   switch (*b)
  317.                   {
  318.                   case '\x1b':
  319.                         if (useansi)
  320.                         {
  321.                               ansistate = WASESCAPE;
  322.                               break;
  323.                         }
  324.  
  325.                   case '\r':
  326.                         curx = 0;
  327.                         break;
  328.  
  329.                   case '\n':
  330.                         cury++;
  331.                         if (cury > maxy - 1)
  332.                         {
  333.                               scroll_up(0,0,maxx - 1,maxy - 1,curattr);
  334.                               cury--;
  335.                         }
  336.                         break;
  337.  
  338.                   case '\t':     /* so _you_ figure out what to do... */
  339.                         for (x = 0; x < tabspaces; x++)
  340.                         {
  341.                               put_char(' ',curattr,curx,cury);
  342.                               curx++;
  343.                               if (curx > maxx - 1)
  344.                               {
  345.                                     curx = 0;
  346.                                     cury++;
  347.                                     if (cury > maxy - 1)
  348.                                     {
  349.                                           scroll_up(0, 0, maxx - 1, maxy - 1,
  350.                                                 curattr);
  351.                                           cury--;
  352.                                     }
  353.                               }
  354.                         }
  355.                         break;
  356.  
  357.                   case '\b':
  358.                         if (curx)
  359.                         {
  360.                               curx--;
  361.                         }
  362.                         break;
  363.  
  364.                   case '\07':     /* usually a console bell */
  365.                         putchar('\07');
  366.                         break;
  367.  
  368.                   default:
  369.                         put_char(*b,curattr,curx,cury);
  370.                         curx++;
  371.                         if (curx > maxx - 1)
  372.                         {
  373.                               curx = 0;
  374.                               cury++;
  375.                               if (cury > maxy - 1)
  376.                               {
  377.                                     scroll_up(0,0,maxx - 1,maxy - 1,curattr);
  378.                                     cury--;
  379.                               }
  380.                         }
  381.                         break;
  382.                   }
  383.                   break;
  384.  
  385.             case WASESCAPE:
  386.                   if (*b == '[')
  387.                   {
  388.                         ansistate = WASBRKT;
  389.                         arglen = 0;
  390.                         *argbuf = 0;
  391.                         break;
  392.                   }
  393.                   ansistate = NOTHING;
  394.                   break;
  395.  
  396.             case WASBRKT:
  397.                   if (strchr(ansi_terminators, (int)*b))
  398.                   {
  399.                         switch ((int)*b)
  400.                         {
  401.                         case 'H':   /* set cursor position */
  402.                         case 'F':
  403.                               set_pos(argbuf,arglen,*b);
  404.                               break;
  405.  
  406.                         case 'A':   /* up */
  407.                               go_up(argbuf,arglen,*b);
  408.                               break;
  409.  
  410.                         case 'B':   /* down */
  411.                               go_down(argbuf,arglen,*b);
  412.                               break;
  413.  
  414.                         case 'C':   /* right */
  415.                               go_right(argbuf,arglen,*b);
  416.                               break;
  417.  
  418.                         case 'D':   /* left */
  419.                               go_left(argbuf,arglen,*b);
  420.                               break;
  421.  
  422.                         case 'n':   /* report pos */
  423.                               report(argbuf,arglen,*b);
  424.                               break;
  425.  
  426.                         case 's':   /* save pos */
  427.                               save_pos(argbuf,arglen,*b);
  428.                               break;
  429.  
  430.                         case 'u':   /* restore pos */
  431.                               restore_pos(argbuf,arglen,*b);
  432.                               break;
  433.  
  434.                         case 'J':   /* clear screen */
  435.                               clear_screen(argbuf,arglen,*b);
  436.                               break;
  437.  
  438.                         case 'K':   /* delete to eol */
  439.                               kill_line(argbuf,arglen,*b);
  440.                               break;
  441.  
  442.                         case 'm':   /* set video attribs */
  443.                               set_colors(argbuf,arglen,*b);
  444.                               break;
  445.  
  446.                         case 'p':   /* keyboard redef -- disallowed */
  447.                               break;
  448.  
  449.                         default:    /* unsupported */
  450.                               break;
  451.                         }
  452.                         ansistate = NOTHING;
  453.                         arglen = 0;
  454.                         *argbuf = 0;
  455.                   }
  456.                   else
  457.                   {
  458.                         if (arglen < MAXARGLEN)
  459.                         {
  460.                               argbuf[arglen] = *b;
  461.                               argbuf[arglen + 1] = 0;
  462.                               arglen++;
  463.                         }
  464.                   }
  465.                   break;
  466.  
  467.             default:
  468.                   pos_hardcursor(curx,cury);
  469.                   fputs("\n **Error in ANSI state machine.\n",stderr);
  470.                   break;
  471.             }
  472.             b++;
  473.       }
  474.       pos_hardcursor(curx,cury);
  475.       hardcursor_on(curx,cury);
  476.  
  477.       return ((int)b - (int)buf);
  478. }
  479.