Category : C Source Code
Archive   : PDW1231.ZIP
Filename : QWIK.C

 
Output of file : QWIK.C contained in archive : PDW1231.ZIP

/***************************************************************************
* This file contains the functions for the directory handler and all the *
* window support routines. See WINDOW.DOC for documentation on how to use *
* the various functions. *
* *
* Modification History: 061787 - original release DLM. *
* 081387 - added additional storage in window *
* array. Also added qwrited/qwritef *
* functions to write double/float numbers *
* 092487 - Field width added to qwritef() & qwrited()*
* Border types implemented. DLM *
* 102587 - Ported to Turbo C. Added clones for most *
* scr_ functions from AZTEC. Rewrote *
* get_ansi_sequence to correctly handle *
* blink and high intensity colors. *
* Same source now compiles under Aztec or *
* Turbo via defines. All screen writes *
* now approx 10 times faster. *
* 123087 - Bug fix in scr_printf(). Float args now *
* handled correctly. DLM. *
* Bug fix in scr_getc(). Was trashing ax *
* register resulting in high order byte of *
* return value being non-zero. DLM. *
***************************************************************************/

#define TURBO

#ifdef TURBO
#include
#include
#include
#endif

#include "stdio.h"
#include "color.h"
#include "gchars.h" /* defs for graphics chars */
#include "ctype.h" /* contains macros isalpha, toupper , etc */

#define FALSE 0 /* falsehood */
#define TRUE 1 /* truth */
#define MAYBE 1/2 /* life */


#define TOP 0 /* flags for where to place window titles top/bottom */
#define BOT 1
#define OFF 0 /* flags for cursor routines */
#define ON 1

/* direction types for use with shadowing, etc. */


#define nodir 0
#define up 2
#define down 3
#define top 5
#define left 6
#define right 1
#define center 12

#define maxwndw 30 /* max number of windows allowed */

/* 12 possible border types */

typedef enum { doubl,blank,singl,mixed,solid,
evensolid,thinsolid,lhatch,mhatch,
hhatch,user,nobrdr} borders;

#define TLC 0 /* offsets for borders */
#define THC 1
#define TRC 2
#define LVC 3
#define RVC 4
#define BLC 5
#define BHC 6
#define BRC 7


char brdr[12][8]={201,205,187,186,186,200,205,188, /* double */
32, 32, 32, 32, 32, 32, 32, 32, /* blank */
218,196,191,179,179,192,196,217, /* single */
213,205,184,179,179,212,205,190, /* mixed */
219,219,219,219,219,219,219,219, /* solid */
219,223,219,219,219,219,220,219, /* even solid */
219,223,219,221,222,219,220,219, /* thin solid */
176,176,176,176,176,176,176,176, /* Light hatch */
177,177,177,177,177,177,177,177, /* Medium hatch */
178,178,178,178,178,178,178,178, /* Heavy hatch */
42, 42, 42, 42, 42, 42, 42, 42, /* user */
32, 32, 32, 32, 32, 32, 32, 32}; /* none */
/*

example of the types of borders possible with the above table

( ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' { none }
( ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' { Blank }
( 'Ú' 'Ä' '¿' '³' '³' 'À' 'Ä' 'Ù' { Single }
( 'É' 'Í' '»' 'º' 'º' 'È' 'Í' '¼' { Double }
( 'Õ' 'Í' '¸' '³' '³' 'Ô' 'Í' '¾' { Mixed }
( 'Û' 'Û' 'Û' 'Û' 'Û' 'Û' 'Û' 'Û' { Solid }
( 'Û' 'ß' 'Û' 'Û' 'Û' 'Û' 'Ü' 'Û' { EvenSolid }
( 'Û' 'ß' 'Û' 'Ý' 'Þ' 'Û' 'Ü' 'Û' { ThinSolid }
( '°' '°' '°' '°' '°' '°' '°' '°' { Lhatch }
( '±' '±' '±' '±' '±' '±' '±' '±' { Mhatch }
( '²' '²' '²' '²' '²' '²' '²' '²' { Hhatch }
( '*' '*' '*' '*' '*' '*' '*' '*' { User }

*/

/* constants for use in floating point evaluations */

double round[] = { 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3,
0.5e-4, 0.5e-5, 0.5e-6, 0.5e-7, 0.5e-8,
0.5e-9, 0.5e-10, 0.5e-11, 0.5e-12, 0.5e-13,
0.5e-14, 0.5e-15, 0.5e-16, 0.5e-17, 0.5e-18 };

/*****************************************************************************
* the following are the variables that are modifiable from your application *
* i.e., they are defined as external in WINDOW.H *
****************************************************************************/

int shadow_effect=right; /* direction of shadow use nodir if no shadow*/
char zoom_effect =TRUE; /* zoom on/off flag use FALSE if no zoom wanted */
int zoom_delay =11; /* delay when zooming - adjust to taste */
int shadow_attr =BLACK; /* color of shadow - whatever looks good to you */
int dir_border =white*16;
int dir_window =white;
char clear_char =32; /* char to clear windows with - alterable */

unsigned char *wndwptr[maxwndw]; /* pointers to windows on heap */
int li, licurrent; /* level index, level index for
swapping windows */

/* this array defines the various stuff for each of 1 - maxwndw possible
windows. */

struct { int wsrow, /* top left row of window */
wscol, /* top left column */
wsrows, /* number of rows in this window */
wscols, /* number of columns */
wswattr, /* window attribute */
wsbattr; /* border attribute */
borders wsbrdr; /* border type */
int wsshadow; /* direction of shadow if employed */
int wslastx, /* last row and */
wslasty; /* and column position of cursor in this window *
int x2,x3,x4; /* some additional storage - use as you see fit *
int y2,y3,y4; /* same - ideal for addtional cursor coords */
int orig_row, /* row where window was first opened */
orig_col; /* col " " " " " */

} w[maxwndw];


char ansi_seq[17]=" [0m [3x;4xm\0"; /* for gening ansi escape sequences */

struct {
char key; /* holds last key pressed in directory handler */
int indx; /* index into dir_list[] of selected filename */
} dir; /* i.e., index of name selected. */


/** end of variables global to your code */

/*****************************************************************************/

/* local cursor key definitions */

#define cursor_up 0xc8
#define cursor_dn 0xd0
#define cursor_rt 0xcd
#define cursor_lf 0xcb
#define home 0xc7
#define end 0xcf
#define page_up 0xc9
#define page_dn 0xd1
#define cr 0xd
#define HELP 0xbb

unsigned char *qsave();

#ifndef TURBO
unsigned char *malloc();
unsigned char *scdir(); /* Aztecs directory func. */
#endif

char *gets();
void get_addr();

unsigned int page_seg; /* segment of video matrix */
int vmode,card_wait,
max_page,qseg; /* work vars for window routines */
int qwait;
unsigned char *kill_flag;
unsigned char *ptr;
int cur_lin,cur_col; /* cursor tracking storage */
char buf[80]; /* buffer for screen title
strings */
int tattr=7; /* attribute */

/* help screen legend */
/* NOTE: some code in qinit() writes to the "[1234]" area of line 6 */

char *help_line[6]={" [HOME] - 1st homes page, 2nd homes list. ",
" [END] - Go to end of directory list. ",
" [PgUp] - Scroll backwards 1 page. ",
" [PgDn] - Scroll forwards 1 page. ",
" [CR] - Selects highlighted name and exits. ",
" [1234] - Move highlight bar to next/previous."};

char count_title[]=" xxx entries "; /* title in directory handler */
unsigned char *dir_ptr; /* dir stuff */

/* misc usage */

unsigned char *killflag,*orig;

int hl,lasthl,first_hl,last_hl,last_indx;
int help_flag=0;
int mcolor[4];
char confirm[37]=" OK to delete xxxxxxxx.xxx (Y/N)? \0";
char new_name[45]=" New name: xxxxxxxx.xxx or CR to cancel.\0";
int start_row;
int end_row;
int start_col;
int end_col;
int culor;
int hcolor;
int max;
int width;
int num_cols;
int indx;
char *vid_ram; /* points at screen ram */

#ifdef TURBO
union REGS regs;
int _attrib=7,_echo;
#endif

/* end of definitions necessary for window pkg. */

#ifdef TURBO /* all the following compiles only under Turbo C */

/*
* delete the char. at the cursor and put blank at end of line
*/

#define max_width 80
#define max_y 25

scr_cdelete()
{
register unsigned ch, x;
int lin, col;

scr_loc(&lin, &col);

for(x = col ; x < max_width-1 ; ++x) {
scr_curs(lin, x+1);
ch = scr_call(0x0800,0,0,0); /* read out current char */
scr_curs(lin, x);
scr_call(0x0900 | (ch&255), ch>>8, 1, 0); /* and shift over */
}

scr_curs(lin, max_width-1);
scr_call(0x920, _attrib, 1, 0); /* put a blank at end of line */
scr_curs(lin, col);
return(0);

} /* end of scr_cdelete() */

/*
* insert a space at the cursor and delete the char. at end of line
*/

scr_cinsert()
{
register unsigned ch, z;
int lin, col;

scr_loc(&lin, &col);

for(z = max_width - 1 ; z > col ; --z) {
scr_curs(lin, z-1);
ch = scr_call(0x0800,0,0,0); /* read out current char */
scr_curs(lin, z);
scr_call(0x0900 | (ch&255), ch>>8, 1, 0); /* and move it right */
}

scr_curs(lin, col);
scr_call(0x920,_attrib,1,0);
return(0);

} /* end of scr_cinsert() */

/*
* Clear to the end of line
*/

scr_eol()
{
int lin, col;

scr_loc(&lin, &col);
scr_call(0x920, _attrib, 80-col, 0);
return(0);

} /* end of scr_eol() */

/*
* clear to end of screen
*/

scr_eos()
{
int lin, col;

scr_loc(&lin, &col);
scr_call(0x920, _attrib, (80-col)+((24-lin)*80), 0);
return(0);

} /* end of scr_eos() */

/*
* if flg is zero turn on inverse
*/

scr_invers(flg)
int flg;
{
_attrib = flg ? 0x70 : 0x07;
return(0);

} /* end of scr_invers() */

/*
* Deletes line at lin, blank lines at bottom
*/

scr_ldelete()
{
int lin, col;

scr_loc(&lin, &col);
scr_call(0x600 | 1, _attrib<<8, lin<<8, (24<<8) | 79);
scr_curs(lin, 0);
return(0);

} /* end of scr_ldelete() */

/*
* Inserts blank lines at lin, pushing rest down
*/

scr_linsert()
{
int lin, col;

scr_loc(&lin, &col);
scr_call(0x700 | 1, _attrib<<8, lin<<8, (24<<8) | 79);
scr_curs(lin, 0);
return(0);

} /* end of scr_linsert() */


scr_poll()
{
regs.h.ah=0x01;
regs.x.flags=0;
int86(0x016,®s,®s);

if(!(regs.x.flags & 64)) {
mapchar();
return(regs.x.ax);
}
else
return(-1);

} /* end of scr_poll() */

scr_getc()
{
int ax; /* 123087 - DLM */

regs.h.ah=0;
int86(0x016,®s,®s);
mapchar();

if(_echo == 0)
return(regs.x.ax);
else
if(regs.x.ax > 127)
return(regs.x.ax);
else {
ax=regs.x.ax; /* 123087 DLM */
scr_putc(regs.x.ax);
return(ax); /* 123087 DLM */
}

} /* end of scr_getc() */

mapchar()
{
if(regs.h.al=='\0') {
special();
return;
}
else
regs.h.ah='\0';

} /* end of map_char() */

special()
{
char h,l;

h=regs.h.ah;
l=regs.h.al;
regs.h.al=h;
regs.h.ah=l;

if(regs.h.al=='\0')
regs.x.ax= -2;
else

if(regs.h.al==(char)(3)) {
regs.x.ax=0;
return;
}
else
regs.h.al = regs.h.al | (char)(0x80);

} /* end of special() */

/*
* if flg is zero disable echoing of characters
*/

scr_echo(flg)
int flg;
{
_echo = flg;
return(0);

} /* end of scr_echo() */

scr_call(ax,bx,cx,dx)
int ax,bx,cx,dx;
{

regs.x.ax=ax;
regs.x.bx=bx;
regs.x.cx=cx;
regs.x.dx=dx;
int86(0x010,®s,®s);

} /* end of scr_call() */

scr_putc(c)
register int c;
{
c &= 255;

if(c >= 0x20)
scr_call(0x0900 | c, _attrib,1,0);

scr_call(0x0e00 | c, _attrib,1,0);
return c;

} /* end of scr_putc() */

scr_loc(lin,col)
int *lin,*col;
{

scr_call(0x300,0,0,0);
*lin=regs.h.dh;
*col=regs.h.dl;

} /* end of scr_loc() */

/*
* Moves cursor to line lin, position pos
*/

scr_curs(lin, col)
register int lin, col;
{
if(col >= max_width)
col = max_width - 1;

if(lin >= 25)
lin = 24;

scr_call(0x200, 0, 0, (lin << 8) | col);
return(0);

} /* end of scr_curs() */

/*
* Clears the screen and homes the cursor
*/

scr_clear()
{
scr_home();
scr_call(0x920,_attrib,(max_width * max_y),0);
return(0);

} /* end of scr_clear() */

/*
* Homes the cursor (0, 0)
*/

scr_home()
{
scr_curs(0, 0);
return(0);

} /* end of scr_home() */

static cputc(chr)
register int chr;
{
scr_putc(chr);

if(chr == '\n')
scr_putc('\r');

} /* end of cputc() (local use only!) */

scr_puts(str)
register char *str;
{
while(*str)
cputc(*str++);

cputc('\n');

} /* end of scr_puts() */

scr_printf(fmt,args)
register char *fmt;
unsigned args;
{
format(cputc,fmt,&args);

} /* end of scr_printf() */

scr_setatr(back,frg,intens,xblink)
int back, frg;
int intens, xblink;
{
register char tmp;

tmp = _attrib;
_attrib = (back << 4) | frg;

if(xblink)
_attrib |= 128;
else
_attrib &= 127;

if(intens)
_attrib |= 8;
else
_attrib &= 247;

_attrib &= 255;
return(tmp);

} /* end of scr_setatr() */

scr_getatr()
{
return(_attrib);

} /* end of scr_getatr() */

scr_resatr(atr)
register int atr;
{
register char tmp;

tmp = _attrib;
_attrib = atr;
return(tmp);

} /* end of scr_resatr() */


static char * _fmtcvt(ap, base, cp, len)
int *ap; register char *cp;
{
register unsigned long val;
static char digits[]="0123456789abcdef";

if(len == sizeof(long))
val = *(long *)ap;
else
if(base > 0)
val = *(unsigned *)ap;
else
val = *ap;

len = 0;

if(base < 0) {
base = -base;
if((long)val < 0) {
val = -val;
len = 1;
}
}

do { *--cp = digits[(int)(val%base)];
} while((val /= base) != 0);

if(len)
*--cp = '-';

return cp;

} /* end of _fmtcvt() (local use only!) */

/******************************************************
* handles all formating for scr_printf() *
* Modified 123087 to properly handle float args - DLM*
*****************************************************/

format(putsub, fmt, argp)
int (*putsub)();
char *fmt, *argp;
{
int c;
union { int *ip;
char *cp;
char **cpp;
double *dp;
} args;

int charcount;
int rj, fillc;
int maxwidth, width;
int i, k;
char *cp;
auto char s[200];

charcount = 0;
args.cp = argp;

while( c = *fmt++ ) {

if( c == '%' ) {
s[14] = 0;
rj = 1;
fillc = ' ';
maxwidth = 10000;

if((c = *fmt++) == '-') {
rj = 0;
c = *fmt++;
}

if(c == '0') {
fillc = '0';
c = *fmt++;
}

if(c == '*') {
width = *args.ip++;
c = *fmt++;
}

else {
for(width = 0 ; isdigit(c) ; c = *fmt++)
width = width*10 + c - '0';
}
if( c == '.' ) {
if((c = *fmt++) == '*') {
maxwidth = *args.ip++;
c = *fmt++;
}
else {
for(maxwidth = 0 ; isdigit(c) ; c = *fmt++)
maxwidth = maxwidth*10 + c - '0';
}
}
i = sizeof(int);

if(c == 'l') {
c = *fmt++;
i = sizeof(long);
}
else
if(c == 'h')
c = *fmt++;

switch(c) {

case 'o':
k = 8;
goto do_conversion;
case 'u':
k = 10;
goto do_conversion;
case 'x':
k = 16;
goto do_conversion;

case 'd':
k = -10;
do_conversion:
cp = _fmtcvt(args.cp, k, s+14, i);
args.cp += i;
break;

case 's':
i = strlen(cp = *args.cpp++);
goto havelen;

case 'e':
case 'f':
case 'g': ftoa(*args.dp++, s, maxwidth==10000?6:maxwidth, c-'e');
i = strlen(cp = s);
maxwidth = 200;
goto havelen;


case 'c':
c = *args.ip++;
default:
*(cp = s+13) = c;
break;

} /* end switch */

i = (s+14) - cp;
havelen:
if( i > maxwidth )
i = maxwidth;

if( rj ) { /* if not right justify */

if((*cp == '-' || *cp == '+') && fillc == '0') {
--width;
if((*putsub)(*cp++) == -1)
return -1;
}
for(; width-- > i ; ++charcount)
if((*putsub)(fillc) == -1)
return -1;
}

for( k = 0 ; *cp && k < maxwidth ; ++k )
if((*putsub)(*cp++) == -1)
return -1;

charcount += k;

if( !rj ) {
for(; width-- > i ; ++charcount)
if((*putsub)(' ') == -1)
return -1;
}
}
else {
if((*putsub)(c) == -1)
return -1;

++charcount;
}

} /* end while */

return(charcount);

} /* end of format() */

/**************************************
* float to ASCII conversion routine *
* for use by scr_printf(). *
* Added 123087 - DLM *
*************************************/

ftoa(number, buffer, maxwidth, flag)
double number;
char *buffer;
int maxwidth,flag;
{
register int i;
int exp, digit, decpos, ndig;

ndig = maxwidth+1;
exp = 0;
if(number < 0.0) {
number = -number;
*buffer++ = '-';
}
if(number > 0.0) {
while(number < 1.0) {
number *= 10.0;
--exp;
}
while(number >= 10.0) {
number /= 10.0;
++exp;
}
}
if(flag == 2) { /* 'g' format */
ndig = maxwidth;
if(exp < -4 || exp >= maxwidth)
flag = 0; /* switch to 'e' format */
}
else
if(flag == 1) /* 'f' format */
ndig += exp;

if(ndig >= 0) {
if((number += round[ndig>16?16:ndig]) >= 10.0) {
number = 1.0;
++exp;
if(flag)
++ndig;
}
}

if(flag) {
if(exp < 0) {
*buffer++ = '0';
*buffer++ = '.';
i = -exp - 1;

if(ndig <= 0)
i = maxwidth;

while (i--)
*buffer++ = '0';

decpos = 0;
}
else {
decpos = exp+1;
}
}
else {
decpos = 1;
}

if(ndig > 0) {
for(i = 0;;++i) {
if(i < 16) {
digit = (int)number;
*buffer++ = digit+'0';
number = (number - digit) * 10.0;
}
else
*buffer++ = '0';

if(--ndig == 0)
break;

if(decpos && --decpos == 0)
*buffer++ = '.';
}
}

if(!flag) {
*buffer++ = 'e';
if(exp < 0) {
exp = -exp;
*buffer++ = '-';
}
else
*buffer++ = '+';

if(exp >= 100) {
*buffer++ = exp/100 + '0';;
exp %= 100;
}
*buffer++ = exp/10 + '0';
*buffer++ = exp%10 + '0';
}
*buffer = 0;

} /* end of ftoa() */


#endif /* ifdef TURBO */

/*****************************************************************************
* my_itoa() is a special version of itoa(). Used by the directory lister *
* to generate the number of entries string. DO NOT use as a general purpose *
* integer-->ascii convertion routine. *
****************************************************************************/

my_itoa(num,buf_ptr)
int num;
char *buf_ptr;
{
register int i,sign;
register char *work_ptr;

i=num;
work_ptr=buf_ptr;
if((sign=i)<0)
i= -i;

do {
*work_ptr++ = i%10+'0';
}
while((i/=10)>0);

if(sign<0)
*work_ptr++='-';

revers(buf_ptr);

} /* end of itoa() */

/*****************************************************************************
* low level prim used by my_itoa() to reverse the digits at buf_ptr. *
****************************************************************************/

revers(buf_ptr)
char *buf_ptr;
{
char c;

c=*buf_ptr;
*buf_ptr=*(buf_ptr+2);
*(buf_ptr+2)=c;

} /* end of reverse() */

/****************************************************************************
* cursor() turns the cursor on/off by altering its size. *
***************************************************************************/

cursor(x) /* sets cursor size */
register int x;
{
register int cx;

if(vmode==7) /* mono card */
switch (x) {
case OFF: cx=0x0f0f;
break;
case ON: cx=0x0c0d;
break;
default: return;

} /* end switch */
else /* else was CGA/EGA card */
switch (x) {
case OFF: cx=0x0f0f;
break;
case ON: cx=0x0607;
break;
default: return;

} /* end switch */

scr_call(0x0100,0,cx,0);

} /* end cursor() */

/*****************************************************************************
* get_ansi_color() takes a packed foreground/background attribute and *
* generates the full ansi escape sequence necessary to change the system *
* for/background colors. *
****************************************************************************/

get_ansi_color(x)
register int x;
{
register int i;

i=x&0x0f; /* get foreground nibble */

if(i>8) { /* high color ? */
i -= 8;
ansi_seq[2]='1'; /* yep, set bold on */
}
else
ansi_seq[2]='2'; /* else set faint on */

/* gen foreground sequence */

ansi_seq[7]=(char)(get_ansi_equiv(i)|0x30); /* fg */

i=(x&0x70)>>4; /* get background nibble stripping any
accidental intensity bit */

/* gen background sequence */

ansi_seq[10]=(char)(get_ansi_equiv(i)|0x30); /* bg */

} /* end of get_ansi_color() */

/****************************************************************************
* get_ansi_equiv() translates the AZTEC colors into the ansi equivalents. *
* COLOR.H should/could be modified so that this wouldn't be necessary. *
***************************************************************************/

get_ansi_equiv(x)
register int x;
{
switch(x) {
case 1: return(RED);
case 2: return(GREEN);
case 3: return(YELLOW);
case 4: return(BLUE);
case 5: return(MAGENTA);
case 6: return(CYAN);
case 7: return(WHITE);
default: return(x);
}

} /* end of get_ansi_equiv() */

/*************************************************
* convert float to ascii for qwritef/d functions *
*************************************************/

my_ftoa(number, buffer,maxwidth)
double number;
register char *buffer;
int maxwidth;
{
register int i,exp,ndig;
int digit, decpos;

ndig = maxwidth+1;
exp = 0;
if(number < 0.0) {
number = -number;
*buffer++ = '-';
}
if(number > 0.0) {
while(number < 1.0) {
number *= 10.0;
--exp;
}
while(number >= 10.0) {
number /= 10.0;
++exp;
}
}

ndig += exp;

if(ndig >= 0) {
if((number += round[ndig>16?16:ndig]) >= 10.0) {
number = 1.0;
++exp;
++ndig;
}
}

if(exp < 0) {
*buffer++ = '0';
*buffer++ = '.';
i = -exp - 1;

if(ndig <= 0)
i = maxwidth;

while(i--)
*buffer++ = '0';

decpos = 0;
}
else
decpos = exp+1;

if(ndig > 0) {
for(i = 0 ; ; ++i) {

if(i < 16) {
digit = (int)number;
*buffer++ = digit+'0';
number = (number - digit) * 10.0;
}
else
*buffer++ = '0';

if(--ndig == 0)
break;

if(decpos && --decpos == 0)
*buffer++ = '.';
}
}
*buffer = 0;

} /* end of my_ftoa() */

/*****************************************************************************
* swap() swap the high and low bytes of an int. *
* I use this to generate an inverse video color using the current fg/bg *
****************************************************************************/

swap(x)
int x;
{
return(( ( (x&0x0f)<<4) | ( (x&0xf0)>>4) ));
}

/****************************************************************************
* rings console bell. *
***************************************************************************/

beep()
{
scr_putc(7);

} /* end of beep() */

/*****************************************************************************
* attr() converts a foreground/background color combination into a single *
* color attribute. *
*****************************************************************************/

attr(fg,bg)
int fg,bg;
{
return((bg<<4) + (fg));

} /* end of attr() */


/****************************************************************************
* delay() provides a short delay for zoom effects. *
***************************************************************************/

delay(x)
int x;
{
long i;

for(i=130*x;i>0;i--)
; /* waste some time ... */

} /* end of delay() */


/***********************************************************************
* ega_check() returns the value of graphics adapter card installed *
* as found in 0040:0049 on the systems var page. *
**********************************************************************/

ega_check()
{

#ifdef TURBO
return((int)peekb(0x0040,0x0049));
#else
return((int)peekb(0x0049,0x0040));
#endif

} /* end of ega_check() */


/**********************************************************************
* qinit() initializes some system variables in preparation for the *
* menu routines. *
*********************************************************************/


qinit()
{

vmode=ega_check(); /* get video adapter type */

if(vmode==7) {
page_seg=0xb000; /* mono adapter installed */
card_wait=FALSE; /* no retrace wait needed */
max_page=0; /* only 1 page available */
}
else {
page_seg=0xb800; /* else it was cga/ega adapter */
card_wait=TRUE; /* set vertical retrace flag on */

if(vmode==0 || vmode==1)
max_page=7; /* if standard text mode 8 pages are available */
else
max_page=3; /* else only 4 pages available */
}
qseg=page_seg;
qwait=card_wait;
ansi_seq[0]=ansi_seq[4]=27; /* init ansi sequence string */


} /* end of qinit() */

/********************************************************************
* qwritelv() writes referenced strings direct to screen memory *
* using length. String need not be null terminated. Use this to *
* write partial strings. *
*******************************************************************/

qwritelv(row,col,attr,length,str)
int row,col,attr,length;
char *str;
{
register int i,l;
char attrib;

attrib=(char)attr;
get_addr(row,col); /* generate offset into screen */

for(i=length,l=1;(i !=0 && *str!='\0');l++,i--) {
*vid_ram++ = *str++;
*vid_ram++ = attrib;
}
return(l); /* return length written */

} /* end of qwritelv() */

/**************************************************************************
* qwritef() writes a floating point number directly to screen memory. *
* Places specifies the number of digits to the left of the decimal point*
*************************************************************************/

qwritef(row,col,attr,places,decimals,fnum)
int row,col,attr,places,decimals;
float fnum;
{
qwrited(row,col,attr,places,decimals,(double)fnum);

} /* end of qwritef() */

/******************************************************************************
* qwrited() writes a double directly to screen memory. Places specifies the *
* number of digits to the left of the decimal point. *
*****************************************************************************/

qwrited(row,col,attr,places,decimals,dnum)
int row,col,attr,places,decimals;
double dnum;
{
register int offset;
register char *buf2,*temp,x;
char attrib;
char work[32],dbuf[32];
int start,s,ss;

s=decimals+places+1;
temp=buf2=&dbuf[0];
for(offset=0;offset work[offset] = ' ';

buf2=temp;
my_ftoa(dnum,buf2,decimals,1); /* convert double to string */
ss=strlen(buf2);
start=s-ss;

if(s > -1)
strcpy(&work[start],buf2);
else {
for(offset=0;offset work[offset]='*';

work[offset]='.';

for(x= ++offset,offset=0;offset work[x]='*';

work[x]='\0';
}

attrib=(char)attr;
get_addr(row,col); /* generate abs screen start addr */

buf2=&work[0];
while(*buf2!='\0') { /* till end of string */
*vid_ram++ = *buf2++;
*vid_ram++ = attrib;
}

} /* end of qwrited() */

/**********************************************************************
* qwrite() writes a string passed by value directly to screen memory *
* String MUST be null terminated. *
*********************************************************************/

qwrite(row,col,attr,qbuf)
int row,col,attr;
char *qbuf;
{
char attrib;

attrib=(char)attr;
get_addr(row,col); /* generate abs screen start addr */

while(*qbuf!='\0') { /* till end of string */
*vid_ram++ = *qbuf++;
*vid_ram++ = attrib;
}

} /* end of qwrite() */

/*************************************************************************
* qwritev writes a single character plus attribute directly to the video*
* ram. *
************************************************************************/


qwritev(row,col,attr,ch)
int row,col,attr;
char ch;
{
char attrib;

attrib=(char)attr;
get_addr(row,col);
*vid_ram++ = ch;
*vid_ram = attrib;

} /* end of qwritev() */


/*************************************************************************
* qwritecv() writes a string directly to screen memory. String is auto- *
* matically centered on the line. Boundries for left and right cols *
* must be supplied. String MUST be null terminated. *
************************************************************************/

qwritecv(row,coll,colr,attr,str)
int row,coll,colr,attr;
char *str;
{
register int i,y;
char attrib;

i=strlen(str);
y=colr-coll; /* total column width of window */

if(i>y)
return(-1); /* string too long for stated boundries */

y=((y-i)>>1)+1; /* that - length of (str / 2) is pad */
attrib=(char)(attr);
get_addr(row,y+coll);

while(*str!='\0') {
*vid_ram++ = *str++;
*vid_ram++ = attrib;
}
return(0);

} /* end of qwritecv() */


/**************************************************************************
* qfillc repetitive filling with same character and attribute. Self- *
* centering. *
*************************************************************************/

qfillc(row,coll,colr,rows,cols,attr,ch)
int row,coll,colr,rows,cols,attr;
char ch;
{
register int t1,t2,t3,t4;
char attrib;

if(coll<1 || colr>79 || row<0 || row>24)
return(-1);

attrib=(char)attr;
t1=t3=((colr-coll)>>1)+1 ; /* get actual start column */
get_addr(row,t1); /* gen offset into screen */
t2=rows; /* serve as indexes ... */
t1=cols;
t4=row;

while(t2>0) { /* while still rows to do */

while(t1>0) { /* while still columns to do in this row */
*vid_ram++ = ch;
*vid_ram++ = attrib;
t1--; /* column count within this line */
}
t2--; /* total line count to fill */
t4++;
get_addr(t4,t3); /* offset of next line into screen */
}
return(0);

} /* end of qfillc() */

/***********************************************************************
* qfill does repetitive filling with the same character and attribute *
**********************************************************************/

qfill(row,col,rows,cols,attr,ch)
int row,col,rows,cols,attr;
char ch;
{
register int t1,t2,t3;
char attrib;

t3=row;
t1=rows;
t2=cols;
attrib=(char)(attr);
get_addr(row,col);

while(t1>0) {

while(t2>0) {
*vid_ram++ = ch;
*vid_ram++ = attrib;
t2--;
}
t2=cols;
t1--;
t3++;
get_addr(t3,col);

}

} /* end of qfill() */

/*************************************************************************
* qattr() does repetitive filling of an attribute *
************************************************************************/

qattr(row,col,rows,cols,attr)
int row,col,rows,cols,attr;
{
register int t1,t3,t4;
char attrib;

attrib=(char)attr;
get_addr(row,col);
vid_ram++;
t1=row;
t3=rows;
t4=cols;

while(t3>0) {

while(t4>0) {
*vid_ram++ = attrib;
++vid_ram;
t4--;
}
t4=cols;
t3--;
t1++;
get_addr(t1,col);
vid_ram++;
}

} /* end of qattr() */

/***************************************************************************
* qsave() snapshots the screen and saves it on the heap. *
* row & col define the upper left hand coord of the area to be saved. *
* rows & cols define the size of the area in rows deep by cols wide. *
**************************************************************************/

unsigned char *qsave(row,col,rows,cols)
int row,col,rows,cols;
{
register int t1,t3,t4;
int needed_size;
unsigned char *h,*h2;

needed_size=(rows*cols)<<1; /* saved size must include attributes */
h=malloc(needed_size); /* try to get that much heap */

if(h==(unsigned char *)0 || h==(unsigned char *)0xffff0000){ /* out of
return((unsigned char *)0); /* pass failure flag */
}

h2=h;
killflag=ptr=h; /* save the pointer */
get_addr(row,col); /* get offset into screen memory */
t1=row;
t3=rows;
t4=cols<<1; /* allow for attributes */

while(t3>0) { /* while still rows to do */
while(t4>0) { /* while still cols within this row */

*h++ = *vid_ram++;
t4--;
}
t4=cols<<1;
t1++; /* point at next row */
t3--; /* decrement rows left to do */
get_addr(t1,col); /* find new offset into screen */
} /* and loop ... */

return(h2); /* show successful completion */

} /* end of qsave () */

/************************************************************************
* qrestore() gets a snapshot from the heap and places it on the screen *
* at the requested coords. *
***********************************************************************/

qrestore(row,col,rows,cols,kflag)
int row,col,rows,cols;
unsigned char *kflag;
{
register int t1,t3,t4;
register unsigned char *heap;

t1=row;
t3=rows;
t4=cols<<1;
get_addr(row,col); /* gen offset into screen ram */
heap=kflag;

while(t3>0) { /* while still rows to do */

while(t4>0) { /* while still cols within this row */
*vid_ram++ = *heap++; /* pull snapshot from heap */
t4--;
}
t4=cols<<1;
t3--; /* decrement rows left to do */
t1++; /* point at next row */
get_addr(t1,col); /* find new offset */
} /* and loop ... */

} /* end of qrestore() */

/*************************************************************************
* get_addr set the global pointer vid_ram to the cursor position passed *
* in row,col. *
************************************************************************/

void get_addr(row,col)
register int row,col;
{
if(row > 24 || col > 80 || col < 0 || row < 0) { /* if bad parm */

if(vmode == 7) /* set addr to start of appropriate */
vid_ram=(char *)0xb0000000L; /* card */
else
vid_ram=(char *)0xb8000000L;

return;
}
/* else calculate the appropriate offset into video ram */

if(vmode == 7) /* mono card */
vid_ram=(char *)(0xb0000000L + (row*160 + col*2));
else /* ega/cga card */
vid_ram=(char *)(0xb8000000L + (row*160 + col*2));


} /* end of get_addr() */

/****************************************************************************
* qbox() builds a box on the screen. *
* parms are : row - topmost row of box start *
* col - leftmost col of box start *
* rows - number of rows in box *
* cols - number of columns in box *
* wattr - window attribute, this is the area inside the *
* border *
* battr - border attribute. *
* border_select - border type. *
* *
* Note that the routine does not handle saving the screen before the box *
* is constructed and therefore may be considered as a replacement for *
* box() that was used previously. *
***************************************************************************/

qbox(row,col,rows,cols,wattr,battr,border_select)
int row,col,rows,cols,wattr,battr,border_select;
{
char tl,th,tr,lv,rv,bl,bh,br;

if(border_select == 0x0b) /* if no border set border attrib */
battr=wattr; /* set equal to window attrib */

if(border_select < 0 || border_select > 0x0b)
border_select = 0; /*trap bad border types - force to type 0 */

tl=brdr[border_select][TLC]; /* set various characters */
th=brdr[border_select][THC]; /* for selected border type */
tr=brdr[border_select][TRC];
lv=brdr[border_select][LVC];
rv=brdr[border_select][RVC];
bl=brdr[border_select][BLC];
bh=brdr[border_select][BHC];
br=brdr[border_select][BRC];

if((rows>2 || row==2) && (cols>2 || cols==2)) { /* bounds checking */
qwritev(row,col,battr,tl); /* top left corner */
qfill(row,col+1,1,cols-2,battr,th); /* top row */
qwritev(row,col+cols-1,battr,tr); /* top right corner */
qfill(row+1,col,rows-2,1,battr,lv); /* left hand border */
qfill(row+1,col+cols-1,rows-2,1,battr,rv); /* righthand border */
qwritev(row+rows-1,col,battr,bl); /* bottom left corner*/
qfill(row+rows-1,col+1,1,cols-2,battr,bh); /* bottom line */
qwritev(row+rows-1,col+cols-1,battr,br); /* bot right corner */
qfill(row+1,col+1,rows-2,cols-2,wattr,clear_char);/* inside window
filling */
return(0);
}
else
return(-1); /* could not draw box using specified parms */

} /* end of qbox() */

/* end of qwik routines */



  3 Responses to “Category : C Source Code
Archive   : PDW1231.ZIP
Filename : QWIK.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/