home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
bbs_ra
/
msgq160s.arj
/
SCREEN.C
< prev
next >
Wrap
Text File
|
1991-07-28
|
14KB
|
688 lines
/*
* SCREEN.C - Display functions
*
* Msged/Q message editor for QuickBBS Copyright 1990 by P.J. Muller
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <dos.h>
#include <ctype.h>
#include "msged.h"
#include "screen.h"
#if !defined(MK_FP)
#define MK_FP(seg,ofs) ((void far *) (((unsigned long)(seg) << 16) | \
(unsigned)(ofs)))
#endif
#if USEFOSSIL
#include "vfossil.h"
static void vfossil_init (void);
static void vfossil_open (void);
static void vfossil_close (void);
static void vfossil_cursor (int st);
static int (pascal *vfossil_funcs[20]) () = {
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL
};
#endif
#define FALSE 0
#define TRUE !FALSE
#define TEXTLEN 200
int int86(int intnum,union REGS *i, union REGS *o);
int int86x(int intnum,union REGS *i, union REGS *o,struct SREGS *s);
unsigned int *macros[40]; /* function key macros */
int maxx; /* maximum screen columns */
int maxy; /* maximum screen rows */
int videomethod; /* (extern in msged.h) how to write to the screen */
unsigned int vbase; /* where screen memory is located */
static unsigned int far *screen = NULL;
static unsigned int cx = 1;
static unsigned int cy = 1;
static int desqview = 0;
#if USEFOSSIL
static struct FOSSIL_DATA {
int length;
char mode;
char maxcolors;
int maxx;
int maxy;
int fill1;
int fill2;
long fill3;
} fossil_data;
static unsigned char scroll_fill [2];
#endif
static unsigned char current_color;
void video_init()
{
union REGS r;
struct SREGS sr;
int vmode = 0;
if (videomethod == FOSSIL) {
#if !USEFOSSIL
fputs("Fossil video not supported by this version\n",stderr);
halt(255);
#else
vfossil_init (); /* Start Video FOSSIL */
/**/ fossil_data.length = /* 2 * */ sizeof (fossil_data);
VioGetMode (&fossil_data,0);
/* Get mode info */
maxx = fossil_data.maxx; /* Maximum 'X' value */
maxy = fossil_data.maxy; /* Maximum 'Y' value */
#endif
}
else {
r.h.ah = 0x0f;
int86(0x10,&r,&r);
vmode = r.h.al;
if (maxx == 0)
maxx = (int) r.h.ah;
if (maxy == 0) {
r.x.ax = 0x1130;
r.x.dx = maxy;
int86(0x10,&r,&r);
maxy = (r.x.dx == 0) ? 25 : (r.x.dx + 1);
}
if ((videomethod == DIRECT) || (videomethod == NOSNOW)) {
if (vbase == 0)
if (vmode == 0x07)
vbase = 0xb000;
else
vbase = 0xb800;
r.h.ah = 0xfe;
sr.es = vbase;
r.x.di = 0;
int86x(0x10,&r,&r,&sr);
desqview = (vbase != sr.es);
vbase = sr.es;
screen = (unsigned int far *) MK_FP(vbase,r.x.di);
}
}
}
void video_end()
{
#if USEFOSSIL
if (videomethod == FOSSIL) {
vfossil_close ();
}
#endif
}
void video_update()
{
#if USEFOSSIL
if (videomethod == FOSSIL) {
VioSetCurPos (cy - 1, cx - 1, 0);
} else
#endif
{
union REGS r;
r.h.ah = 2;
r.h.bh = 0;
r.h.dh = (char) cy - 1;
r.h.dl = (char) cx - 1;
int86(0x10, &r, &r);
}
}
void scrollup(x1, y1, x2, y2, lines)
int x1, y1, x2, y2, lines;
{
y2 = min(y2,maxy) - 1;
y1 = min(y1,maxy) - 1;
x1 = min(x1,maxx) - 1;
x2 = min(x2,maxx) - 1;
#if USEFOSSIL
if (videomethod == FOSSIL) {
scroll_fill [0] = ' ';
scroll_fill [1] = current_color;
if (lines == 0)
lines = -1;
VioScrollUp (y1,x1,y2,x2,lines,scroll_fill,0);
} else
#endif
{
union REGS r;
r.h.ah = 6;
r.h.al = (char) lines;
r.h.ch = (char) y1;
r.h.cl = (char) x1;
r.h.dh = (char) y2;
r.h.dl = (char) x2;
r.h.bh = current_color;
int86(0x10, &r, &r);
}
}
void scrolldown(x1, y1, x2, y2, lines)
int x1, y1, x2, y2, lines;
{
y2 = min(y2,maxy) - 1;
y1 = min(y1,maxy) - 1;
x1 = min(x1,maxx) - 1;
x2 = min(x2,maxx) - 1;
#if USEFOSSIL
if (videomethod == FOSSIL) {
scroll_fill [0] = ' ';
scroll_fill [1] = current_color;
VioScrollDn (y1,x1,y2,x2,lines,scroll_fill,0);
} else
#endif
{
union REGS r;
r.h.ah = 7;
r.h.al = (char) lines;
r.h.ch = (char) y1;
r.h.cl = (char) x1;
r.h.dh = (char) y2;
r.h.dl = (char) x2;
r.h.bh = current_color;
int86(0x10, &r, &r);
}
}
extern void wrscrch(unsigned int far *addr, unsigned int chattr);
void bputc(unsigned char c)
{
union REGS r;
unsigned int d = 0;
d = (c & 0xff) | (current_color << 8);
switch (videomethod) {
case DIRECT:
*(screen + ((((cy - 1) * maxx) + (cx - 1)))) = d;
break;
case NOSNOW:
wrscrch(screen + ((((cy - 1) * maxx) + (cx - 1))), d);
break;
#if USEFOSSIL
case FOSSIL: {
unsigned int far *cell_ptr = &d;
VioWrtCellStr (cell_ptr, 2, cy - 1, cx - 1, 0);
break;
}
#endif
default:
video_update();
r.h.ah = 0x9;
r.h.bh = 0;
r.h.al = c;
r.h.bl = current_color;
r.x.cx = 1;
int86(0x10,&r,&r);
break;
} /* switch */
if (++cx > maxx) {
cx = 1;
if (++cy > maxy)
cy = 1;
} /* if */
} /* bputc */
void gotoxy(int x, int y)
{
cx = min(x,maxx);
cy = min(y,maxy);
}
int wherex()
{
return (cx);
}
int wherey()
{
return(cy);
}
int getkey()
{
union REGS r;
static unsigned int *macro;
if (macro) {
if (*(++macro))
return(*macro);
macro = NULL;
}
#if USEFOSSIL
if (videomethod == FOSSIL) {
r.h.ah = 0x0e;
int86 (0x14,&r,&r);
}
else
#endif
{
r.h.ah = 0;
int86(0x16,&r,&r);
}
if (r.h.al) { /* Must use FOSSIL keymap, */
r.h.ah = 0; /* No scan code if have char */
return(r.x.ax);
}
if ((r.h.ah >= 0x3b) && (r.h.ah <= 0x44))
macro = macros[r.h.ah - 0x3b];
else if ((r.h.ah >= 0x54) && (r.h.ah <= 0x71))
macro = macros[r.h.ah - 0x4a];
if (macro) {
if (*macro)
return(*macro);
macro = NULL;
}
return(r.x.ax);
} /* getkey */
int keypressed()
{
union REGS r;
#if USEFOSSIL
if (videomethod == FOSSIL) {
r.h.ah = 0x0d;
int86 (0x14,&r,&r);
return (r.x.ax != 0xffff);
}
#endif
r.h.ah = 1;
int86(0x16,&r,&r);
return !(r.x.flags & 0x40);
} /* keypressed */
extern void wrscrstr(unsigned int far *addr, char far *str, int len, BYTE attr);
void bputs(char *s)
{
if (s == NULL)
return;
switch (videomethod) {
default:
case DIRECT:
case BIOS:
while ((*s) && (wherex() < maxx))
if (*s != '\n')
bputc(*s++);
else
break;
break;
#if USEFOSSIL
case FOSSIL: {
char *e;
int l;
int a = current_color;
if ((e = strchr(s,'\n')) == NULL)
e = strchr(s,'\0');
if ((l = e - s) < 1)
return;
VioWrtCharStrAtt(s,l,cy - 1,cx - 1,&a,0);
cx += l;
break;
}
#endif
case NOSNOW: {
int l;
char *e;
if ((e = strchr(s,'\n')) != NULL)
l = e - s;
else
l = strlen(s);
if (l < 1)
break;
wrscrstr(screen + ((((cy - 1) * maxx) + (cx - 1))), (char far *) s,
l, current_color);
cx += l;
break;
}
} /* switch */
} /* bputs */
void cls()
{
scrollup(1, 1, maxx, maxy, 0);
gotoxy(1, 1);
}
void clrwnd(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
scrollup(x1, y1, x2, y2, 0);
gotoxy(x1,y1);
}
void clreol()
{
clrwnd(cx,cy,maxx,cy);
}
int bgets(char *s1, int c)
{
int ch;
int x1;
char *t;
static BOOLEAN insert = ON;
static char s[TEXTLEN];
int y = wherey();
int x = wherex();
strncpy(s, s1, sizeof s);
t = s + strlen(s);
*t = '\0';
bputs(s);
while (TRUE) { /* endless loop */
video_update();
switch (ch = getkey()) {
case UP:
case DOWN:
case PGUP:
case PGDN:
case ENTER:
strcpy(s1, s);
return (ch);
case WORDRT:
while ((*t != EOS) && (!isspace(*t)))
++t;
while ((*t != EOS) && (isspace(*t)))
++t;
gotoxy(x + (t-s), y);
break;
case WORDLT:
if (t == s)
break;
while ((t > s) && (isspace(*(t-1))))
--t;
while ((t > s) && (!isspace(*(t-1))))
--t;
gotoxy(x + (t-s), y);
break;
case ABORT: /* Esc */
return ABORT;
case DELMSG: /* Alt-D */
case 'Y'-'@': /* Ctrl-Y */
memset(s, 0, sizeof s);
t = s;
gotoxy(x, y);
clreol();
break;
case GOBOL:
t = s;
gotoxy(x, y);
break;
case GOEOL:
t = s + strlen(s);
gotoxy(x + strlen(s), y);
break;
case RUBOUT:
case BKSPC:
if (x == wherex())
break;
t--;
memmove(t, (t + 1), strlen(t) + 1);
gotoxy(wherex() - 1, y);
x1 = wherex();
bputs(t);
bputc(' ');
gotoxy(x1, y);
break;
case LEFT:
if (t == s)
break;
t--;
gotoxy(wherex() - 1, y);
break;
case RIGHT:
if (t >= (s + strlen(s)))
break;
t++;
gotoxy(wherex() + 1, y);
break;
case DELCHR:
memmove(t, t + 1, strlen(t) + 1);
x1 = wherex();
bputs(t);
bputc(' ');
gotoxy(x1, y);
break;
case INSERT:
insert = !insert;
break;
default:
if ((strlen(s) == c) || ((ch & 0xff) == 0))
break;
if (insert) {
x1 = wherex();
t++;
strins(s, (char) (ch & 0xff), (x1 - x + 1));
gotoxy(x, y);
bputs(s);
gotoxy(x1 + 1, y);
}
else {
*t++ = (char) (ch & 0xFF);
bputc((char) (ch & 0xff));
}
video_update();
break;
}
}
return(ABORT); /* never reached */
}
int getnum(int l, int h, int value)
{
int i, x;
char s[TEXTLEN];
i = value;
x = wherex();
do {
clreol();
memset(s, 0, sizeof(s));
itoa(i, s, 10);
gotoxy(x, wherey());
(void)bgets(s, TEXTLEN/2);
i = atoi(s);
} while ((i < l) || (i > h));
return (i);
}
void set_color(unsigned char attr)
{
current_color = attr;
}
unsigned get_color()
{
return(current_color);
}
int bprintf(char *f,...)
{
va_list params;
int i;
char s[TEXTLEN];
va_start(params, f);
i = vsprintf(s, f, params);
bputs(s);
return (i);
}
void strins(char *l, char c, int x)
{
int i = strlen(l);
x--;
if (i-x < 0) return;
memmove((l + x + 1), (l + x), (i - x));
*(l + x) = c;
}
void strdel(char *l, int x)
{
int i = strlen(l);
x--;
if (i-x+1 < 0) return;
memmove((l + x), (l + x + 1), (i - x + 1));
*(l + i) = 0;
}
#if USEFOSSIL
VFOSSIL v;
static void vfossil_init ()
{
char far *q;
union REGS r;
struct SREGS s;
v.vfossil_size = sizeof (VFOSSIL);
q = (char far *) &v;
r.h.ah = 0x81;
r.h.al = 0;
segread (&s);
s.es = FP_SEG (q);
r.x.di = FP_OFF (q);
int86x (0x14, &r, &r, &s);
if (r.x.ax == 0x1954)
{
/* There is a VFOSSIL out there, so set it up for use */
vfossil_open ();
}
else
{
fputs ("No Video FOSSIL installed, aborting....\n\n",stderr);
halt(255);
}
}
CURSOR _cursor;
static void vfossil_cursor (int st)
{
CURSOR far *q;
if (vfossil_funcs[9])
{
q = (CURSOR far *) &_cursor;
/* We can make the cursor go away */
VioGetCurType (q, 0);
_cursor.cur_attr = st ? 0 : -1;
VioSetCurType (q, 0);
}
}
static void vfossil_open ()
{
char far *q;
union REGS r;
struct SREGS s;
segread (&s);
r.h.ah = 0x81;
r.h.al = 1;
r.x.cx = 80;
q = (char far *) vfossil_funcs;
r.x.di = FP_OFF (q);
s.es = FP_SEG (q);
int86x (0x14, &r, &r, &s);
if ((r.x.ax != 0x1954) || (r.x.bx < 14))
{
fputs ("Unable to initialize Video FOSSIL, aborting....\n\n",stderr);
halt(255);
}
}
static void vfossil_close ()
{
union REGS r;
vfossil_cursor (1);
r.h.ah = 0x81;
r.h.al = 2;
int86 (0x14, &r, &r);
}
#endif