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