home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / ANSISYS.CPP < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  218 lines

  1. // +++Date last modified: 05-Jul-1997
  2.  
  3. // Implements ansi.sys display class
  4. // public domain
  5. // by David Nugent <davidn@unique.blaze.net.au>
  6. // 3:632/348@fidonet
  7.  
  8. #include <iostream.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11.  
  12. #include "ansisys.hpp"
  13.  
  14.  
  15. ansisys::ansisys(video & v)
  16.   : scrinterp(v),
  17.     dispfunc(0),
  18.     savx(0),
  19.     savy(0)
  20. {}
  21.  
  22. void
  23. ansisys::reset()
  24. {
  25.   dispfunc = 0;
  26.   savx = savy = 0;
  27.   scrinterp::reset();
  28. }
  29.  
  30.   // This is the top level dispatcher. It really only
  31.   // Looks for special control characters
  32.  
  33. void
  34. ansisys::putch(int ch)
  35. {
  36.   if (dispfunc)
  37.     (this->*dispfunc)(ch);
  38.   else if (ch == '\x1b')
  39.   {
  40.     flushbuf();
  41.     dispfunc = &ansisys::esc; // Hand over to ESC routine
  42.   }
  43.   else
  44.     scrinterp::putch(ch);
  45. }
  46.  
  47.   // This parses for the leadin for an escape sequence
  48.  
  49. void
  50. ansisys::esc(int ch)
  51. {
  52.   switch (ch)
  53.   {
  54.   case '[':                   // ANSI lead-in
  55.     dispfunc = &ansisys::seq; // Now parse the sequences
  56.     break;
  57.  
  58.   default:                    // Huh?
  59.     putbuf('?');
  60.     dispfunc = 0;
  61.     break;
  62.   }
  63. }
  64.  
  65. int
  66. ansisys::evalargs(cell_t * plist)
  67. {
  68.   chrbuf[chridx] = '\0';
  69.  
  70.   char const * s = chrbuf;
  71.   int idx = 0;
  72.   while (idx < 32)
  73.   {
  74.     cell_t res = 0;
  75.     while (*s && isdigit(*s))   // Evaluate numeric
  76.       res = cell_t((res * 10) + (*s++ - '0'));
  77.     plist[idx++] = res;
  78.     if (*s == ';')              // Skip over
  79.       ++s;
  80.     else break;                 // Not a valid delimiter, quit
  81.   }
  82.  
  83.   return idx;
  84. }
  85.  
  86.  
  87.   // Parses esc sequences
  88.  
  89. void
  90. ansisys::seq(int ch)
  91. {
  92.   if (ch == ';' || isdigit(ch))   // Accumulate parameters
  93.   {
  94.     if (chridx < CBUFSZ)
  95.       chrbuf[chridx++] = char(ch);
  96.   }
  97.   else
  98.   {
  99.     cell_t  plist[32];
  100.     cell_t  x,
  101.             y,
  102.             mx,
  103.             my;
  104.     int     nx =0,
  105.             ny =0;
  106.  
  107.     int args = evalargs(plist);
  108.  
  109.     switch (ch)
  110.     {
  111.     default:    // Unknown sequences
  112.       reset();
  113.       break;
  114.  
  115.     case 'A':                 // Cursor up
  116.       ny = -((args < 1 || plist[0] == 0) ? 1 : plist[0]);
  117.       goto mvxy;
  118.  
  119.     case 'B':                 // Cursor down
  120.       ny =  ((args < 1 || plist[0] == 0) ? 1 : plist[0]);
  121.       goto mvxy;
  122.  
  123.     case 'C':                 // Cursor right
  124.       nx =  ((args < 1 || plist[0] == 0) ? 1 : plist[0]);
  125.       goto mvxy;
  126.  
  127.     case 'D':                 // Cursor left
  128.       nx = -((args < 1 || plist[0] == 0) ? 1 : plist[0]);
  129.     mvxy:
  130.       vs.wherexy(x, y);
  131.       x = cell_t(x + nx);
  132.       y = cell_t(y + ny);
  133.       goto goxy;
  134.  
  135.     case 'H':                 // Cursor position
  136.       y = cell_t(((args < 1 || plist[0] == 0) ? 1 : plist[0]) - 1);
  137.       x = cell_t(((args < 2 || plist[1] == 0) ? 1 : plist[1]) - 1);
  138.     goxy:
  139.       vs.maxxy(mx, my);
  140.       if (x < mx && y < my)
  141.         vs.gotoxy(x, y);
  142.       break;
  143.  
  144.     case 'J':                 // Erase display
  145.       if (args && plist[0] == 2)
  146.         vs.gotoxy(0, 0);
  147.       vs.cls();
  148.       break;
  149.  
  150.     case 'K':                 // Erase line
  151.       vs.wherexy(x, y);
  152.       vs.maxxy(mx, my);
  153.       vs.repchr(' ', mx - x);
  154.       vs.gotoxy(x, y);
  155.       break;
  156.  
  157.     case 'n':                 // Device status report
  158.       // Not supported here
  159.       // Need to send back ESC [ x+1 ; y+1 R
  160.       break;
  161.  
  162.     case 's':                 // Save cursor position
  163.       vs.wherexy(savx, savy);
  164.       break;
  165.  
  166.     case 'u':                 // Restore cursor position
  167.       vs.gotoxy(savx, savy);
  168.       break;
  169.  
  170.     case 'm':                 // Set graphics rendition (colour)
  171.       if (!args)
  172.         plist[args++] = 0;
  173.       for (int idx = 0 ; idx < args ; ++idx)
  174.       {
  175.         cell_t val = plist[idx];
  176.         static cell_t colmap[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
  177.  
  178.         switch (val)
  179.         {
  180.         case 0:
  181.           vs.setattr(7);
  182.           break;
  183.         case 1:
  184.           vs.setfg(cell_t(vs.getfg() | 0x8));
  185.           break;
  186.         case 2:
  187.           vs.setfg(cell_t(vs.getbg() | 0x8));
  188.           break;
  189.         case 3:
  190.           vs.setfg(cell_t((vs.getbg() & ~0x8) | 1));
  191.           break;
  192.         case 5:
  193.           vs.setbg(cell_t(vs.getbg() | 0x8));
  194.           break;
  195.         case 7:
  196.           vs.setfg(0);
  197.           vs.setbg(cell_t(7 + (vs.getbg() & 0x8)));
  198.           break;
  199.         case 8:
  200.           vs.setfg(cell_t(vs.getbg() & ~0x8));
  201.           break;
  202.         default:
  203.           if (val >= 30 && val <= 37)
  204.             vs.setfg(cell_t(colmap[val-30] | (vs.getfg() & 0x8)));
  205.           else if (val >= 40 && val <= 47)
  206.             vs.setbg(cell_t(colmap[val-40] | (vs.getbg() & 0x8)));
  207.           break;
  208.         }
  209.       }
  210.       break;
  211.  
  212.     }
  213.     chridx = 0;
  214.     dispfunc = 0;
  215.   }
  216. }
  217.  
  218.