home *** CD-ROM | disk | FTP | other *** search
- /*
- ** DOANSI_1.C - Portable ANSI screen code interpreter
- **
- ** From DRSK_105.LZH (ansi.c), hereby declared free for use for whatever
- ** purposes by author: Mark Kimes
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "doansi.h"
-
- /*
- * to initialize:
- * call set_screensize(<# lines to reserve>);
- * to print through ansi interpreter:
- * call ansi_out(<string>);
- */
-
- char curattr = 7;
- int curx = 0,cury = 0;
- int maxx = 80, maxy = 25; /* size of ansi output window */
- int realmaxy,realmaxx; /* real screen size */
- char useansi = 1; /* while true, interp ansi seqs */
- int tabspaces = 8;
- static int savx,savy,issaved = 0;
- static char ansi_terminators[] = "HFABCDnsuJKmp";
-
- #define MAXARGLEN 128
-
- #define NOTHING 0
- #define WASESCAPE 1
- #define WASBRKT 2
-
- /* "generic" support functions closely related to ansi_out */
-
- void set_pos (char *argbuf,int arglen,char cmd)
- {
- int y,x;
- char *p;
-
- if (!*argbuf || !arglen)
- {
- curx = cury = 0;
- }
- y = atoi(argbuf) - 1;
- p = strchr(argbuf,';');
- if (y >= 0 && p)
- {
- x = atoi(p + 1) - 1;
- if(x >= 0)
- {
- curx = x;
- cury = y;
- }
- }
- }
-
- void go_up (char *argbuf,int arglen,char cmd)
- {
- int x;
-
- x = atoi(argbuf);
- if (!x)
- x = 1;
- for ( ; x ; x--)
- {
- if (!cury)
- break;
- cury--;
- }
- }
-
- void go_down (char *argbuf,int arglen,char cmd)
- {
- int x;
-
- x = atoi(argbuf);
- if (!x)
- x = 1;
- for ( ; x ; x--)
- {
- if (cury == maxy - 1)
- break;
- cury++;
- }
- }
-
- void go_left (char *argbuf,int arglen,char cmd)
- {
- int x;
-
- x = atoi(argbuf);
- if (!x)
- x = 1;
- for ( ; x ; x--)
- {
- if(!curx)
- break;
- curx--;
- }
- }
-
- void go_right (char *argbuf,int arglen,char cmd)
- {
- int x;
-
- x = atoi(argbuf);
- if (!x)
- x = 1;
- for ( ; x ; x--)
- {
- if (curx == maxx - 1)
- break;
- curx++;
- }
- }
-
- void report (char *argbuf,int arglen,char cmd)
- {
- /* you figure out how to implement it ... */
- }
-
- void save_pos (char *argbuf,int arglen,char cmd)
- {
- savx = curx;
- savy = cury;
- issaved = 1;
- }
-
- void restore_pos (char *argbuf,int arglen,char cmd)
- {
- if(issaved)
- {
- curx = savx;
- cury = savy;
- issaved = 0;
- }
- }
-
- void clear_screen (char *argbuf,int arglen,char cmd)
- {
- /* needs error checking */
-
- clearwindow(0,0,maxx - 1,maxy - 1,curattr);
- curx = cury = 0;
- }
-
- void kill_line (char *argbuf,int arglen,char cmd)
- {
- cleartoeol(curx,cury,maxx - 1,curattr);
- }
-
-
- void set_colors (char *argbuf,int arglen,char cmd)
- {
- char *p,*pp;
-
- if (*argbuf && arglen)
- {
- pp = argbuf;
- do
- {
- p = strchr(pp,';');
- if (p && *p)
- {
- *p = 0;
- p++;
- }
- switch (atoi(pp))
- {
- case 0: /* all attributes off */
- curattr = 7;
- break;
-
- case 1: /* bright on */
- curattr |= 8;
- break;
-
- case 2: /* faint on */
- curattr &= (~8);
- break;
-
- case 3: /* italic on */
- break;
-
- case 5: /* blink on */
- curattr |= 128;
- break;
-
- case 6: /* rapid blink on */
- break;
-
- case 7: /* reverse video on */
- curattr = 112;
- break;
-
- case 8: /* concealed on */
- curattr = 0;
- break;
-
- case 30: /* black fg */
- curattr &= (~7);
- break;
-
- case 31: /* red fg */
- curattr &= (~7);
- curattr |= 4;
- break;
-
- case 32: /* green fg */
- curattr &= (~7);
- curattr |= 2;
- break;
-
- case 33: /* yellow fg */
- curattr &= (~7);
- curattr |= 6;
- break;
-
- case 34: /* blue fg */
- curattr &= (~7);
- curattr |= 1;
- break;
-
- case 35: /* magenta fg */
- curattr &= (~7);
- curattr |= 5;
- break;
-
- case 36: /* cyan fg */
- curattr &= (~7);
- curattr |= 3;
- break;
-
- case 37: /* white fg */
- curattr |= 7;
- break;
-
- case 40: /* black bg */
- curattr &= (~112);
- break;
-
- case 41: /* red bg */
- curattr &= (~112);
- curattr |= (4 << 4);
- break;
-
- case 42: /* green bg */
- curattr &= (~112);
- curattr |= (2 << 4);
- break;
-
- case 43: /* yellow bg */
- curattr &= (~112);
- curattr |= (6 << 4);
- break;
-
- case 44: /* blue bg */
- curattr &= (~112);
- curattr |= (1 << 4);
- break;
-
- case 45: /* magenta bg */
- curattr &= (~112);
- curattr |= (5 << 4);
- break;
-
- case 46: /* cyan bg */
- curattr &= (~112);
- curattr |= (3 << 4);
- break;
-
- case 47: /* white bg */
- curattr |= 112;
- break;
-
- case 48: /* subscript bg */
- break;
-
- case 49: /* superscript bg */
- break;
-
- default: /* unsupported */
- break;
- }
- pp = p;
- } while (p);
- }
- }
-
- int ansi_out (char *buf)
- {
- int arglen = 0, ansistate = NOTHING, x;
- char *b = buf, argbuf[MAXARGLEN] = "";
-
- /* cursor is off while string is being displayed so we don't have
- to keep updating it. works to our detriment only if using
- BIOS writes under MS-DOS
- */
-
- hardcursor_off();
-
- if (!useansi) /* is ANSI interp on? */
- {
- ansistate = NOTHING;
- arglen = 0;
- *argbuf = 0;
- }
-
- while (*b)
- {
- switch (ansistate)
- {
- case NOTHING:
- switch (*b)
- {
- case '\x1b':
- if (useansi)
- {
- ansistate = WASESCAPE;
- break;
- }
-
- case '\r':
- curx = 0;
- break;
-
- case '\n':
- cury++;
- if (cury > maxy - 1)
- {
- scroll_up(0,0,maxx - 1,maxy - 1,curattr);
- cury--;
- }
- break;
-
- case '\t': /* so _you_ figure out what to do... */
- for (x = 0; x < tabspaces; x++)
- {
- put_char(' ',curattr,curx,cury);
- curx++;
- if (curx > maxx - 1)
- {
- curx = 0;
- cury++;
- if (cury > maxy - 1)
- {
- scroll_up(0, 0, maxx - 1, maxy - 1,
- curattr);
- cury--;
- }
- }
- }
- break;
-
- case '\b':
- if (curx)
- {
- curx--;
- }
- break;
-
- case '\07': /* usually a console bell */
- putchar('\07');
- break;
-
- default:
- put_char(*b,curattr,curx,cury);
- curx++;
- if (curx > maxx - 1)
- {
- curx = 0;
- cury++;
- if (cury > maxy - 1)
- {
- scroll_up(0,0,maxx - 1,maxy - 1,curattr);
- cury--;
- }
- }
- break;
- }
- break;
-
- case WASESCAPE:
- if (*b == '[')
- {
- ansistate = WASBRKT;
- arglen = 0;
- *argbuf = 0;
- break;
- }
- ansistate = NOTHING;
- break;
-
- case WASBRKT:
- if (strchr(ansi_terminators, (int)*b))
- {
- switch ((int)*b)
- {
- case 'H': /* set cursor position */
- case 'F':
- set_pos(argbuf,arglen,*b);
- break;
-
- case 'A': /* up */
- go_up(argbuf,arglen,*b);
- break;
-
- case 'B': /* down */
- go_down(argbuf,arglen,*b);
- break;
-
- case 'C': /* right */
- go_right(argbuf,arglen,*b);
- break;
-
- case 'D': /* left */
- go_left(argbuf,arglen,*b);
- break;
-
- case 'n': /* report pos */
- report(argbuf,arglen,*b);
- break;
-
- case 's': /* save pos */
- save_pos(argbuf,arglen,*b);
- break;
-
- case 'u': /* restore pos */
- restore_pos(argbuf,arglen,*b);
- break;
-
- case 'J': /* clear screen */
- clear_screen(argbuf,arglen,*b);
- break;
-
- case 'K': /* delete to eol */
- kill_line(argbuf,arglen,*b);
- break;
-
- case 'm': /* set video attribs */
- set_colors(argbuf,arglen,*b);
- break;
-
- case 'p': /* keyboard redef -- disallowed */
- break;
-
- default: /* unsupported */
- break;
- }
- ansistate = NOTHING;
- arglen = 0;
- *argbuf = 0;
- }
- else
- {
- if (arglen < MAXARGLEN)
- {
- argbuf[arglen] = *b;
- argbuf[arglen + 1] = 0;
- arglen++;
- }
- }
- break;
-
- default:
- pos_hardcursor(curx,cury);
- fputs("\n **Error in ANSI state machine.\n",stderr);
- break;
- }
- b++;
- }
- pos_hardcursor(curx,cury);
- hardcursor_on(curx,cury);
-
- return ((int)b - (int)buf);
- }
-