Category : Printer Utilities
Archive   : PCTOCT.ZIP
Filename : PRTSCR2.C

 
Output of file : PRTSCR2.C contained in archive : PCTOCT.ZIP

/* C routines for PrtScr program.
* This file contains the routines that read from the screen
* and format data for output to the printer.
*
* Save this files as PRTSCR2.C.
* Compile: cl /c /Gs Prtcrs2.c (MSC 5.1)
* or: qcl /c /Gs Prtscr2.c (QUICKC 2.0)
* plus: link /NOD Prtscr1 Prtscr2,Prtscr; (MS Link)
*
* or: tcc -N- -c Prtscr2.c (TC 2.0)
* tlink /n/c Prt2cr1 Prtscr2,PrtScr (TLINK)
*/

/* These definitions are from MSC/QC DOS.H file: */

#define FP_SEG(fp) (*((unsigned *)&(fp) + 1))
#define FP_OFF(fp) (*((unsigned *)&(fp)))

/* function prototypes: */
void textmode(void);
void lo_res(void);
void med_res(void);
void hi_res(void);
void prt_string(char *s);
extern void gc_out(int index, int value);
extern void prt_out(int ch);
int cga_4(int x, int y);
int cga_6(int x, int y);
int ega_clr(int x, int y);
int ega_mono(int x, int y);

/* External global data */
extern int vidmode, vidcols, vidrows;
extern int vidseg, vidoff;

int bytes; /* EGA graphics bytes-per-row */

/* textmode puts the screen at the current
printhead location. It uses wide print
if 40 columns or less are displayed, and
condensed print if more than 80 columns are
displayed.
*/

void textmode()
{
int far *textposn;
int x,y;
int bkgrnd, frgrnd;
int ch;
int vidword;

if (vidcols > 80)
prt_out(0x0f); /* start condensed mode */
if (vidcols <= 40)
prt_string("\x1bW\x01"); /* start expanded mode */
FP_SEG(textposn) = vidseg;
FP_OFF(textposn) = vidoff;
for (y = 0; y <= vidrows; y++) /* For each row... */
{
for (x = 1; x <= vidcols; x++) /* For each column ... */
{
vidword = *textposn++; /* Get char. & attribute */
bkgrnd = vidword >> 12;
frgrnd = (vidword >> 8) & 0xf;
if (bkgrnd != frgrnd) /* Don't show 'hidden' chars. */
{
ch = vidword & 0xff;
prt_out(ch);
}
else
prt_out(' ');
}
prt_string("\x0d\x0a"); /* Carriage return/line feed */
}
if (vidcols > 80)
prt_out(0x12); /* Cancel condensed mode */
if (vidcols <= 40)
{
prt_string("\x1bW"); /* Cancel expanded mode */
prt_out(0);
}
}


/* The graphics routines assume that the printhead is at the top
of a page -- they center the image between top/bottom and
left/right page edges
*/

void lo_res(void) /* 320 x 200 modes */
{
int (*get_pixel) (int x, int y); /* Function prototype */
int x,y,i;
int bkgrnd;
int printbyte;

if(vidmode < 6) /* Select get_pixel function: */
get_pixel = cga_4; /* CGA mode 4 */
else
{
get_pixel = ega_clr; /* or EGA color, 40-col mode */
bytes = 40;
}
bkgrnd = get_pixel(0,0); /* This color will print 'white' */
prt_string("\x0d\x1b\x33\x18"); /* Set 24/216 (8/72) line feeds */
for (i = 0; i < 10; i++)
prt_out(0x0a);

for (x = 319; x >= 3; x -=4)
{
prt_string("\x1bK\xb8\x01"); /* Ready to print 0x1B8 (440) chars. */
for (i = 0; i < 40; i++)
prt_out(0); /* 40 blanks make a margin */
for (y = 0; y < 200; y++)
{
printbyte = 0; /* Each byte represents 4 vid. cols. */
for (i = 0; i < 4; i++)
{
printbyte <<= 2; /* Shift old value left, then ... */
if (get_pixel(x-i,y) != bkgrnd)
printbyte |= 3; /* Add 0000 0011 if not bkgrnd color */
}
prt_out(printbyte); /* Send byte to printer twice */
prt_out(printbyte);
}
prt_string("\x0d\x0a"); /* Carriage return/line feed */
}
prt_out(0x0c); /* End with a form feed */
prt_string("\x1b\x32"); /* Cancel short line feeds */
}

void med_res(void) /* 640 x 200 modes */
{
int (*get_pixel) (int x, int y);
int x,y,i;
int bkgrnd;
int printbyte;

if (vidmode == 6) /* Select get_pixel function */
get_pixel = cga_6; /* CGA mode 6 or */
else
{
get_pixel = ega_clr; /* EGA 80-column mode */
bytes = 80;
}

bkgrnd = get_pixel(0,0);
prt_string("\x0d\x1b\x33\x18"); /* Set 8/72 line feeds */
for (i = 0; i < 10; i++)
prt_out(0x0a); /* Top margin */

for (x = 639; x >= 7; x -= 8)
{
prt_string("\x1bK\xb8\x01"); /* Ready for 440 graphics chars. */
for (i = 0; i < 40; i++)
prt_out(0); /* Margin of 40 blanks */
for (y = 0; y < 200; y++)
{
printbyte = 0; /* Clear output byte */
for (i = 0; i < 8; i++) /* Each byte represents 8 video cols. */
{
printbyte <<= 1; /* Shift old value left */
if (get_pixel(x-i,y) != bkgrnd)
printbyte |= 1; /* Add 0000 0001 if not bkgrnd color */
}
prt_out(printbyte); /* Send byte out twice */
prt_out(printbyte);
}
prt_string("\x0d\x0a"); /* Carriage return & line feed */
}
prt_out(0x0c); /* End with form feed */
prt_string("\x1b\x32"); /* Cancel short line feeds */
}


void hi_res(void) /* 640 x 350 video modes */
{
int (*get_pixel) (int x, int y);
int x,y,i;
unsigned bkgrnd;
unsigned printbyte;

if (vidmode == 0x0f)
get_pixel = ega_mono; /* EGA monochrome mode or ... */
else
get_pixel = ega_clr; /* EGA 80-col color mode */
bytes = 80;

bkgrnd = get_pixel(0,0);
prt_string("\x0d\x1b\x33\x15"); /* Set up 21/216 line feeds */
for (i = 0; i < 16; i++)
prt_out(0x0a); /* Top margin */

for (x = 639; x >= 7; x -= 8)
{
prt_string("\x1bK\x9f\x01"); /* Ready for 415 graphics chars */
for (i = 0; i < 65; i++)
prt_out(0); /* 65 blanks for margin */
for (y = 0; y <= 349; y++)
{
printbyte = 0; /* Clear output byte */
for (i = 0; i < 8; i++)
{
printbyte <<= 1; /* Shift old value to left */
if (bkgrnd != get_pixel(x-i,y))
printbyte |= 1; /* Add 0000 0001 if not bkgrnd color */
}
prt_out(printbyte); /* Send it out */
}
prt_string("\x0d\x0a"); /* Carriage return, line feed */
}
prt_out(0x0c); /* End with a form feed */
prt_string("\x1b\x32"); /* Cancel short line feeds */
}


int cga_4(int x, int y) /* Read one pixel from CGA mode 4 & 5 */
{
char byte;
char far *vid;

FP_SEG(vid) = 0xb800;
FP_OFF(vid) = vidoff + 0x2000 * (y%2) + 80 * (y/2) + x/4;
byte = *vid;
return (byte >> (6 - (x%4)*2) & 3);
}

int cga_6(int x, int y) /* Read one pixel from CGA mode 6 */
{
char byte;
char far *vid;
FP_SEG(vid) = 0xb800;
FP_OFF(vid) = vidoff + 0x2000 * (y%2) + 80 * (y/2) + x/8;
byte = *vid;
return (byte >> (7 - (x%8)) & 1);
}


int ega_clr(int x, int y) /* Read one pixel from EGA color screen */
{ /* Note: doesn't work with 64K EGA board */
char mask;
char far *vid;
int i, color;

FP_SEG(vid) = 0xa000;
FP_OFF(vid) = y * bytes + x / 8 + vidoff;
mask = (char)(0x80 >> (x % 8)); /* Select bit position to read */
color = 0;
gc_out(5,0); /* select read mode 0 */
for (i = 3; i >= 0; i--)
{
color <<= 1; /* Merge all 4 color bits */
gc_out(4,i);
if (*vid & mask)
color |= 1;
}
return color;
}

int ega_mono(int x, int y) /* Read one pixel from EGA mono screen */
{
char mask;
char far *vid;
int color;

FP_SEG(vid) = 0xa000;
FP_OFF(vid) = y * bytes + x/8 + vidoff;
mask = (char)(0x80 >> (x % 8));
color = 0;
gc_out(5,0);
gc_out(4,0);
if (*vid & mask)
color |= 1;
gc_out(4,2);
if (*vid & mask)
color |= 2;
return color;
}

void prt_string(char *s) /* Send a string to the printer */
{
while (*s)
prt_out(*s++);
}