summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/doansi_1.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/doansi_1.c')
-rwxr-xr-xreference/C/CONTRIB/SNIP/doansi_1.c478
1 files changed, 478 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/doansi_1.c b/reference/C/CONTRIB/SNIP/doansi_1.c
new file mode 100755
index 0000000..f328cb1
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/doansi_1.c
@@ -0,0 +1,478 @@
+/*
+** 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);
+}