home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
archiver
/
peek_221.arj
/
ANSI.C
next >
Wrap
C/C++ Source or Header
|
1992-03-30
|
18KB
|
752 lines
#include <stdlib.h>
#include <stdio.h>
#include <string.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";
#ifdef __TURBOC__
#define _fastcall pascal
#endif
#define MAXARGLEN 128
#define NOTHING 0
#define WASESCAPE 1
#define WASBRKT 2
/* set maxx,maxy as desired */
void _fastcall set_screensize (int reservedlines);
/* put character c at x,y using attr as attribute */
void _fastcall put_char (char c,char attr,int x,int y);
/* position hardware cursor at x,y */
void _fastcall pos_hardcursor (int x,int y);
/* turn hardware cursor off */
void _fastcall hardcursor_off (void);
/* turn hardware cursor on at x,y */
void _fastcall hardcursor_on (int x,int y);
/* scroll window tx,ty - bx,by up one line; fill with blank+attr */
void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr);
/* clear the window from tx,ty - bx,by; fill with blank+attr */
void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr);
/* clear line y from col x to eol (ex); fill with blank+attr */
void _fastcall cleartoeol (int x,int y,int ex,char attr);
/* validate cursor position after external routines may have changed it */
void _fastcall validate_cursor (void);
/* the ansi string interpreter */
int _fastcall ansi_out (char *buf);
/* "generic" support functions closely related to ansi_out */
void _fastcall 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 _fastcall 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 _fastcall 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 _fastcall 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 _fastcall 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 _fastcall report (char *argbuf,int arglen,char cmd) {
/* you figure out how to implement it ... */
}
void _fastcall save_pos (char *argbuf,int arglen,char cmd) {
savx = curx;
savy = cury;
issaved = 1;
}
void _fastcall restore_pos (char *argbuf,int arglen,char cmd) {
if(issaved) {
curx = savx;
cury = savy;
issaved = 0;
}
}
void _fastcall clear_screen (char *argbuf,int arglen,char cmd) {
/* needs error checking */
clearwindow(0,0,maxx - 1,maxy - 1,curattr);
curx = cury = 0;
}
void _fastcall kill_line (char *argbuf,int arglen,char cmd) {
cleartoeol(curx,cury,maxx - 1,curattr);
}
void _fastcall 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 _fastcall 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);
}
/* OS specific functions -- this can be moved to a separate module */
#ifdef OS2
#define INCL_DOS
#define INCL_VIO
#include <os2.h>
int vidhandle = 0; /* can be changed for AVIO */
void _fastcall set_screensize (int reservedlines) {
VIOMODEINFO vm;
vm.cb = sizeof(VIOMODEINFO);
VioGetMode(&vm, vidhandle);
maxx = vm.col;
maxy = vm.row - reservedlines;
realmaxx = maxx;
realmaxy = vm.row;
}
void _fastcall pos_hardcursor (int x,int y) {
VioSetCurPos(y,x,vidhandle);
}
void _fastcall hardcursor_off (void) {
VIOCURSORINFO vc;
VioGetCurType(&vc,vidhandle);
vc.attr = -1;
VioSetCurType(&vc,vidhandle);
}
void _fastcall hardcursor_on (int x,int y) {
VIOCURSORINFO vc;
VioGetCurType(&vc,vidhandle);
vc.attr = 0;
VioSetCurType(&vc,vidhandle);
VioSetCurPos(y,x,vidhandle);
}
void _fastcall put_char (char c, char attr, int x, int y) {
VioWrtCharStrAtt(&c,1,y,x,&attr,vidhandle);
}
void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
int attrib = ' ' | (attr << 8);
VioScrollUp(ty,tx,by,bx,1,(char *)&attrib,vidhandle);
}
void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
int attrib = ' ' | (attr << 8);
VioScrollUp(ty,tx,by,bx,-1,(char *)&attrib,vidhandle);
}
void _fastcall cleartoeol (int x,int y,int ex,char attr) {
int attrib = ' ' | (attr << 8);
VioScrollUp(y,x,y,ex,-1,(char *)&attrib,vidhandle);
}
void _fastcall validate_cursor (void) {
int x,y;
VioGetCurPos(&y,&x,vidhandle);
if(y > maxy - 1) {
cury = maxy - 1;
}
else cury = y;
curx = x;
}
#else
/* MS-DOS -- this stuff has _not_ been tested */
#include <dos.h>
#if !defined(MK_FP)
#define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off)))
#endif
static int far *vseg;
int realmaxy,realmaxx;
char usebios = 0; /* if true, output through BIOS */
int _fastcall vmode (void) {
union REGS r;
r.h.ah = 15;
r.x.bx = 0;
int86(0x10,&r,&r);
return r.h.al;
}
void _fastcall set_screensize (int reservedlines) {
union REGS r;
unsigned int vbase;
r.h.ah = 0x0f;
r.x.bx = 0;
int86 (0x10, &r, &r);
maxx = (int) r.h.ah;
if(maxx < 80) { /* gimme a break! */
r.x.ax = 0x0003;
int86(0x10,&r,&r);
maxx = 80;
}
realmaxx = maxx;
r.x.ax = 0x1130;
r.x.dx = maxy;
int86 (0x10, &r, &r);
realmaxy = maxy = (r.x.dx == 0) ? 25 : (r.x.dx + 1);
maxy -= reservedlines;
vbase = (vmode () == 7 ? 0xb000 : 0xb800);
vseg = MK_FP(vbase,0); /* address of video ram as pointer */
}
void _fastcall pos_hardcursor (int x,int y) {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((y << 8) & 0xff00) + x;
int86(0x10,&r,&r);
}
void _fastcall hardcursor_off (void) {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((realmaxy << 8) & 0xff00);
int86(0x10,&r,&r);
}
void _fastcall hardcursor_on (int x,int y) {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((y << 8) & 0xff00) + x;
int86(0x10,&r,&r);
}
void _fastcall put_char (char c, char attr, int x, int y) {
if(!usebios) {
register int far *v;
v = vseg + ((y * realmaxx) + x); /* point v to right spot in vid RAM */
*v = (c | (attr << 8)); /* display */
}
else {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((y << 8) & 0xff00) + x;
int86(0x10,&r,&r);
r.h.ah = 0x09;
r.h.bh = 0;
r.h.bl = attr;
r.x.cx = 1;
r.h.al = c;
int86(0x10,&r,&r);
}
}
void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
union REGS r;
r.h.ah = 6;
r.h.al = 1;
r.h.bh = attr;
r.h.cl = tx;
r.h.ch = ty;
r.h.dl = bx;
r.h.dh = by;
int86(0x10,&r,&r);
}
void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
union REGS r;
r.h.ah = 6;
r.h.al = 0;
r.h.bh = attr;
r.h.cl = tx;
r.h.ch = ty;
r.h.dl = bx;
r.h.dh = by;
int86(0x10,&r,&r);
}
void _fastcall cleartoeol (int x,int y,int ex,char attr) {
union REGS r;
r.h.ah = 6;
r.h.al = 0;
r.h.bh = attr;
r.h.cl = x;
r.h.ch = y;
r.h.dl = ex;
r.h.dh = y;
int86(0x10,&r,&r);
}
void _fastcall validate_cursor (void) {
union REGS r;
r.x.ax = 0x0300;
r.x.bx = 0;
int86(0x10,&r,&r);
if(r.h.dh > maxy - 1) {
cury = maxy - 1;
}
else cury = (int)r.h.dh;
curx = (int)r.h.dl;
}
#endif