home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
graf
/
macpnt1.zip
/
VIDEO.C
< prev
next >
Wrap
Text File
|
1987-01-16
|
15KB
|
698 lines
/*
**********************************************************************
*
* VIDEO.C - routines to interface with the screen
*
* (c) Copyright 1987 by:
*
* Computerwise Consulting Services
* P.O. Box 813
* McLean, VA 22101
* (703) 280-2809
*
* All rights reserved.
*
* Permission is granted for personal use of this program, with the
* exception that the following potential users ARE EXPLICITLY DENIED
* PERMISSION TO RECEIVE, USE, OR TRANSFER THIS PROGRAM IN SOURCE OR
* OBJECT OR EXECUTABLE OR ANY OTHER FORM:
*
* 1) Lotus Development Corporation, and any employee thereof
* or consultant thereto;
*
* 2) ADAPSO, and any firm which is a member thereof, or any
* employee of such a firm.
*
* These two organizations have - in the opinion of CCS - acted as
* "software pirates" by continually and intentionally violating
* U.S. Copyright law, specifically by first "copy-protecting" software
* disks and then zealously prosecuting innocent users who exercised
* their rights under the law to make copies of their own property.
*
* Further, permission is granted to transfer this program only if
* it is transferred absolutely unmodified in any form.
*
**********************************************************************
*/
/*
* Determine what type of video adapter we have, and set screen_type
* appropriately.
*/
vtype()
{
/*
* First, check for EGA by using an EGA-only ROM BIOS call
*/
inregs.h.ah = 0x12; /* "Return EGA info" func */
inregs.h.bl = 0x10;
inregs.h.bh = 0xff; /* Garbage return value */
video();
if ( outregs.h.bh != inregs.h.bh )
{
/*
* Something came back, so we can assume that as EGA is present.
*/
screen_type = TYPE_EGA;
if ( outregs.h.bh == 1 )
{
fprintf(stderr, "\nSorry, but this program does not yet support a Monochrome");
fprintf(stderr, "\nmonitor attached to the EGA.");
exit(-1);
}
return;
}
/*
* Then check for MONO (HERCULES) or CGA according to type
* that the ROM BIOS thinks we have.
*/
inregs.x.ax = 0x0f00; /* "Get Video Mode" ROM BIOS func */
video();
if( outregs.h.al == 7 )
{
screen_type = TYPE_HERC; /* Mono mode, must be HERCULES */
}
else
{
screen_type = TYPE_CGA; /* Anything else, assume CGA */
}
}
/*
* Do INT 010H with inregs, outregs.
*/
video()
{
int86(0x10, &inregs, &outregs);
}
/*
* Browse through MACPAINT file that has already been read into mem_image.
*/
browse()
{
int newtop; /* New value for top from keypress */
int top; /* Logical image line number of top screen line */
int maxtop; /* Max legal value for top */
int keypress; /* What key he pressed */
/*
* Set value of maxtop per screen type
*/
switch( screen_type )
{
case TYPE_HERC:
maxtop = 719 - HERC_VERT;
break;
case TYPE_CGA:
/*
* Squeeze 2 Mac lines into 1 CGA screen line
*/
maxtop = 719 - (CGA_VERT * 2);
break;
case TYPE_EGA:
maxtop = 719 - EGA_VERT;
break;
}
newtop = 0; /* Start at top of image */
top = 1; /* Dummy (but different!) value to force redraw */
while(1)
{
/*
* Make sure that we're in GRAPHICS mode
*/
if ( cur_mode != GRAPHICS )
{
mode(GRAPHICS);
}
/*
* Redisplay picture only if we have moved
*/
if ( newtop != top )
{
show( top = newtop );
}
/*
* Get and process his keypress
*/
keypress = key();
switch( keypress )
{
case 0x4700: /* {Home} */
newtop = 0;
break;
case 0x4F00: /* {End} */
newtop = maxtop;
break;
case 0x4800: /* {Up} */
if ( top > 0 )
{
newtop = top - 1;
}
break;
case 0x5000: /* {Down} */
if ( top < maxtop )
{
newtop = top + 1;
}
break;
case 0x4b00: /* {Left} */
fg_color--;
palette();
break;
case 0x4d00: /* {Right} */
fg_color++;
palette();
break;
case 0x7300: /* {Ctrl-Left} */
bg_color--;
palette();
break;
case 0x7400: /* {Ctrl-Right} */
bg_color++;
palette();
break;
case 0x4900: /* {PgUp} */
if ( top >= JUMP )
{
newtop = top - JUMP;
}
else
{
newtop = 0;
}
break;
case 0x5100: /* {PgDn} */
if ( top < (maxtop - JUMP) )
{
newtop = top + JUMP;
}
else
{
newtop = maxtop;
}
break;
case 0x1970: /* p = print image */
case 0x1950: /* P = Print image */
print(); /* So print it */
top--; /* Force new display */
break;
case 0x1769: /* i = invert image */
case 0x1749: /* I = Invert image */
invert(); /* So invert it */
top--; /* Force new display */
break;
case 0x1177: /* w = write to disk */
case 0x1157: /* W = Write to disk */
writemac(); /* Write it out */
top--; /* Force new display */
break;
case 0x2d78: /* x = exit program */
case 0x2d58: /* X = eXit program */
time2quit = -1;
return;
case 0x011b: /* ESCAPE */
return;
default:
help(); /* Give him some help */
top--; /* Force redisplay */
}
}
}
/*
* Give help for browse mode
*/
help()
{
mode(TEXT);
fprintf(stderr, "\nKeys recognized while viewing a file:\n");
fprintf(stderr, "\n{Up} - move up 1 scan line");
fprintf(stderr, "\n{Down} - move down 1 scan line");
if ( (screen_type == TYPE_EGA) || (screen_type == TYPE_CGA) )
{
fprintf(stderr, "\n{Right} - increase foreground color");
fprintf(stderr, "\n{Left} - decrease foreground color");
}
if ( screen_type == TYPE_EGA )
{
fprintf(stderr, "\n{^Right} - increase background color");
fprintf(stderr, "\n{^Left} - decrease background color");
}
fprintf(stderr, "\n{PgUp} - move up %d scan lines", JUMP);
fprintf(stderr, "\n{PgDn} - move down %d scan lines", JUMP);
fprintf(stderr, "\n{Home} - move to top of picture");
fprintf(stderr, "\n{End} - move to bottom of picture");
fprintf(stderr, "\nI or i - invert picture");
fprintf(stderr, "\nP or p - print picture (abort it with any keypress)");
fprintf(stderr, "\nW or w - write picture to a MacPaint disk file");
fprintf(stderr, "\nX or x - exit program");
fprintf(stderr, "\nEscape - done with this picture, move to next MACPAINT");
fprintf(stderr, "\n filename that was specified on the command line");
fprintf(stderr, "\n\nAnything else gets this help screen");
fprintf(stderr, "\n\nPress RETURN...");
key();
}
/*
* Copy mem_image to actual, visible screen
* with logical line number n at top of screen.
*/
show(n)
int n; /* Logical line number at top of screen */
{
long screen_addr; /* A phony BYTE ptr */
register BYTE *p;
int i;
if ( screen_type == TYPE_HERC )
{
/*
* Display it on HERCULES adapter
*/
screen_addr = 0xb0000009L; /* Centered with 9 bytes on each side */
p = &mem_image[n][0]; /* To first input line */
for ( i = 0; i < HERC_VERT; i += 4 )
{
memcpy(screen_addr+0x0000L, p, (MAC_HORIZ/8));
p += (MAC_HORIZ/8); /* Up to next image line */
memcpy(screen_addr+0x2000L, p, (MAC_HORIZ/8));
p += (MAC_HORIZ/8); /* Up to next image line */
memcpy(screen_addr+0x4000L, p, (MAC_HORIZ/8));
p += (MAC_HORIZ/8); /* Up to next image line */
memcpy(screen_addr+0x6000L, p, (MAC_HORIZ/8));
p += (MAC_HORIZ/8); /* Up to next image line */
screen_addr += 90L; /* Up to next video line */
}
return;
}
if ( screen_type == TYPE_CGA )
{
/*
* Display it on CGA adapter. Because 200 lines distort the
* picture too much in the vertical direction, we cram 400
* MACPAINT lines into 200 screen lines by skipping every
* other one. If we're doing RLE images, this makes for some
* pretty ugly and rough images. But they'll print nicely.
* So buy an EGA.
*/
screen_addr = 0xb8000004L; /* Centered with 4 bytes on each side */
p = &mem_image[n][0]; /* To first input line */
for ( i = 0; i < CGA_VERT; i += 2 )
{
memcpy(screen_addr+0x0000L, p, (MAC_HORIZ/8));
p += ((MAC_HORIZ/8) + (MAC_HORIZ/8)); /* Cram 2 Mac lines into one */
memcpy(screen_addr+0x2000L, p, (MAC_HORIZ/8));
p += ((MAC_HORIZ/8) + (MAC_HORIZ/8)); /* Cram 2 Mac lines into one */
screen_addr += 80L; /* Up to next video line */
}
return;
}
if ( screen_type == TYPE_EGA )
{
/*
* Display it on EGA adapter
*/
screen_addr = 0xA0000004L; /* Centered with 4 bytes on each side */
p = &mem_image[n][0]; /* To first input line */
for ( i = 0; i < EGA_VERT; i++ )
{
memcpy(screen_addr, p, (MAC_HORIZ/8));
p += (MAC_HORIZ/8); /* Up to next image line */
screen_addr += 80L; /* Up to next video line */
}
return;
}
}
/*
* Get next keypress and return it. What comes back is exactly what the
* ROM BIOS gave us - scan code in upper, ASCII in lower. Lower = 0 if
* this is an extended keypress.
*/
key()
{
inregs.h.ah = 0;
int86( 0x16, &inregs, &outregs);
return( outregs.x.ax );
}
/*
* Erase entire screen (but only if in text mode)
*/
cls()
{
if ( cur_mode == TEXT )
{
inregs.x.ax = 0x0600; /* ROM BIOS "Erase Region" func */
inregs.x.cx = 0x0000; /* Line, column of top left */
inregs.x.dx = 0x184f; /* Line, column of bottom right */
inregs.h.bh = 7; /* Attribute to use */
video();
/*
* Position to row 0, column 0
*/
inregs.h.ah = 2; /* ROM BIOS "Position Cursor" func */
inregs.x.dx = 0x0000; /* Line, column of top left */
inregs.h.bh = 0; /* Page zero */
video();
}
}
/*
* Invert bits in mem_image. Special logic if we have up to 6 RLE images on
* the screen, which causes only the images to be reversed and not the
* whitespace between them. Special logic also to allow for StartupScreen
* images having only the image inverted, and not the border.
*/
invert()
{
register BYTE *p;
unsigned i;
static unsigned NEAR line,
NEAR col,
NEAR numline,
NEAR numcol;
if ( i = rle_pic ) /* Any RLE images on screen? */
{
/*
* Invert only the actual data for each RLE image
*/
if ( i > 6 ) i = 6; /* Max of 6 images on screen */
while( i-- )
{
invert_rle(i); /* Invert this image */
}
return;
}
/*
* Just invert every pixel on the screen, cause this is a MacPaint
* picture. If this is a StartupScreen image, then leave the border
* alone.
*/
p = &mem_image[0][0];
if ( data_type == RAW )
{
/*
* This is a StartupScreen image. Set up params to ignore
* the border around it.
*/
numline = end_of_image;
numcol = 64;
p += 4; /* Start 4 bytes into line */
}
else
{
/*
* Set up to do whole screen
*/
numline = MAC_VERT;
numcol = 72;
}
/*
* Now invert every byte within our limits
*/
for ( line = 0; line < numline; line++ )
{
for ( col = 0; col < numcol; col++ )
{
p[col] ^= 0xff;
}
p += (MAC_HORIZ/8); /* Up to start of next line */
}
}
/*
* Invert RLE image # n (0-5) in mem_image, leaving rest of screen unchanged.
*/
invert_rle(n)
int n;
{
register BYTE *p;
static int NEAR line,
NEAR col;
p = &mem_image[ RLE_LINE(n) ][ RLE_COL(n) ];
for ( line = 0; line < rle_vert[n]; line++ )
{
for ( col = 0; col < (rle_horiz[n]/8); col++ )
{
p[col] ^= 0xff;
}
p += (MAC_HORIZ/8); /* Up to next mem_image line, same start column */
}
}
/*
* Init video adapter for graphics or text mode
*/
mode(graphics)
int graphics; /* Non-zero for graphics mode, zero for text */
{
static BYTE herc_graphics[12] = /* 6845 regs to put HERCULES into graphics mode */
{
0x35, 0x2d, 0x2e, 0x07, 0x5b, 0x02, 0x57, 0x57, 0x02, 0x03, 0x00, 0x00
};
static BYTE herc_text[12] = /* 6845 regs to put HERCULES into text mode */
{
0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c
};
int i;
BYTE *p;
cur_mode = graphics; /* Save new mode */
if ( screen_type == TYPE_HERC )
{
/*
* Set up HERCULES board
*/
outp( 0x03b8, graphics ? 2 : 0x20 ); /* Screen off */
/*
* Init the 6845 directly
*/
p = graphics ? herc_graphics : herc_text; /* Point to right set of 6845 regs */
for ( i = 0; i < 12; i++ )
{
outp( 0x03b4, i ); /* Select right 6845 register */
outp( 0x03b5, *p++ ); /* Send right data to it */
}
/*
* Now clear the screen
*/
if (graphics)
{
memset(0xb0000000L, 0, 0x8000);
}
else
{
memset(0xb0000000L, 0x20, 0x4000);
}
/*
* Turn on the screen
*/
outp( 0x03b8, graphics ? 2+8 : 0x20+8 );
}
if ( screen_type == TYPE_CGA )
{
inregs.x.ax = (graphics) ? 6 : 3;
video();
if ( graphics )
{
palette(); /* Tell hardware about current colors */
}
}
if ( screen_type == TYPE_EGA )
{
inregs.x.ax = (graphics) ? 0x10 : 3;
video();
if ( graphics )
{
outp( 0x03c4, 2 ); /* Select reg 2 */
outp( 0x03c5, COLOR ); /* Select planes for our color */
palette(); /* Tell hardware about palette */
}
}
cls(); /* Clear text screen */
}
/*
* Pass current foreground and background colors to video adapter as palette
* values.
*/
palette()
{
if ( screen_type == TYPE_EGA )
{
inregs.x.ax = 0x1000; /* EGA BIOS "Set palette" func */
inregs.h.bl = 0; /* Background = color 0 */
inregs.h.bh = bg_color;
video();
inregs.h.bl = COLOR; /* Foreground = our enabled planes */
inregs.h.bh = fg_color; /* Set color for that plane combination */
video();
return;
}
if ( screen_type == TYPE_CGA )
{
outp( 0x03d9, fg_color ); /* Just set Color Register and hope */
}
}