home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
MODEL
/
GRAPH98.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-10
|
11KB
|
501 lines
#include <stdio.h>
#include <dos.h>
#ifdef __GNUC__
#include <pc.h>
#else
#include <conio.h>
#define outportb(port,value) outp(port,value)
#endif
#include "graph.h"
#define GRAPHIC_MODE_COLOR_16 2
#define GRAPH_ADDRESS_B (0xe00a8000)
#define GRAPH_ADDRESS_R (0xe00b0000)
#define GRAPH_ADDRESS_G (0xe00b8000)
#define GRAPH_ADDRESS_I (0xe00e0000)
static short paletdata[16];
static void graph_apage(int page);
static void graph_vpage(int page);
static void EGCset(int color);
#ifdef __GNUC__
#define far
static unsigned int longleftedge[32] = {
0xffffffff, 0xffffff7f, 0xffffff3f, 0xffffff1f,
0xffffff0f, 0xffffff07, 0xffffff03, 0xffffff01,
0xffffff00, 0xffff7f00, 0xffff3f00, 0xffff1f00,
0xffff0f00, 0xffff0700, 0xffff0300, 0xffff0100,
0xffff0000, 0xff7f0000, 0xff3f0000, 0xff1f0000,
0xff0f0000, 0xff070000, 0xff030000, 0xff010000,
0xff000000, 0x7f000000, 0x3f000000, 0x1f000000,
0x0f000000, 0x07000000, 0x03000000, 0x01000000,
};
static unsigned int longrightedge[32] = {
0x00000080, 0x000000c0, 0x000000e0, 0x000000f0,
0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
0x000080ff, 0x0000c0ff, 0x0000e0ff, 0x0000f0ff,
0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
0x0080ffff, 0x00c0ffff, 0x00e0ffff, 0x00f0ffff,
0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
0x80ffffff, 0xc0ffffff, 0xe0ffffff, 0xf0ffffff,
0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff,
};
#endif
static unsigned char charleftedge[8] = {
0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01
};
static unsigned char charrightedge[8] = {
0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
};
static void graph_line_1(int x1, int y1, int x2, int y2, int color)
{
int temp;
int i;
int offset;
int data;
unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
if (y1 > y2) {
temp = y1; y1 = y2; y2 = temp;
}
gram += offset = y1 * 80 + x1 / 8;
data = 0x80 >> (x1 % 8);
for (i = y2 - y1 + 1; i > 0; --i) {
if ( color == 18 )
*gram ^= data;
else
*gram = data;
gram += 80;
}
}
static void graph_line_2(int x1, int y1, int x2, int y2, int color)
{
int i;
int offset;
int data;
int diff;
int plus, minus;
unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
plus = (y1 - y2) * 2;
minus = (x2 - x1) * 2;
diff = plus / 2;
gram += offset = y1 * 80 + x1 / 8;
data = 0x80 >> (x1 % 8);
for (i = y1 - y2 + 1; i > 0; --i) {
if ( color == 18 )
*gram ^= data;
else
*gram = data;
gram -= 80;
if ((diff -= minus) < 0) {
if ((data >>= 1) == 0) {
data = 0x80;
gram++;
}
diff += plus;
}
}
}
static void graph_line_3(int x1, int y1, int x2, int y2, int color)
{
int i;
int offset;
int data;
unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
gram += offset = y1 * 80 + x1 / 8;
data = 0x80 >> (x1 % 8);
for (i = y1 - y2 + 1; i > 0; --i) {
if ( color == 18 )
*gram ^= data;
else
*gram = data;
gram -= 80;
if ((data >>= 1) == 0) {
data = 0x80;
gram++;
}
}
}
static void graph_line_4(int x1, int y1, int x2, int y2, int color)
{
int i;
int offset;
int diff;
int plus, minus;
int start, end;
unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
plus = (x2 - x1) * 2;
minus = (y1 - y2) * 2;
diff = plus / 2;
gram += offset = y1 * 80 + x1 / 8;
start = end = x1 % 8;
for (i = x2 - x1 + 1; i > 0; --i) {
end++;
if ((diff -= minus) < 0) {
if ( color == 18 )
*gram ^= charleftedge[start] & charrightedge[(end-1)];
else
*gram = charleftedge[start] & charrightedge[(end-1)];
gram -= 80;
if (end == 8) {
gram++;
end = 0;
}
start = end;
diff += plus;
} else if (end == 8) {
if ( color == 18 )
*gram++ ^= charleftedge[start];
else
*gram++ = charleftedge[start];
start = end = 0;
}
}
if (end != 0) {
if ( color == 18 )
*gram ^= charleftedge[start] & charrightedge[end-1];
else
*gram = charleftedge[start] & charrightedge[end-1];
}
}
static void graph_line_5(int x1, int y1, int x2, int y2, int color)
{
int i;
int offset1, offset2;
unsigned int *gram = (unsigned int *)GRAPH_ADDRESS_I;
offset1 = y1 * 20 + x1 / 32;
offset2 = y1 * 20 + x2 / 32;
gram += offset1;
if (offset1 == offset2) {
if ( color == 18 )
*gram ^= longleftedge[x1%32] & longrightedge[x2%32];
else
*gram = longleftedge[x1%32] & longrightedge[x2%32];
} else if (offset2 == offset1 + 1) {
if ( color == 18 )
{
*gram++ ^= longleftedge[x1%32];
*gram ^= longrightedge[x2%32];
}
else
{
*gram++ = longleftedge[x1%32];
*gram = longrightedge[x2%32];
}
} else {
if ( color == 18 )
*gram++ ^= longleftedge[x1%32];
else
*gram++ = longleftedge[x1%32];
for (i = offset2 - offset1 - 1;i > 0; --i) {
if ( color == 18 )
*gram++ ^= 0xffffffff;
else
*gram++ = 0xffffffff;
}
if ( color == 18 )
*gram ^= longrightedge[x2%32];
else
*gram = longrightedge[x2%32];
}
}
static void graph_line_6(int x1, int y1, int x2, int y2, int color)
{
int i;
int offset;
int diff;
int plus, minus;
int start, end;
unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
plus = (x2 - x1) * 2;
minus = (y2 - y1) * 2;
diff = plus / 2;
gram += offset = y1 * 80 + x1 / 8;
start = end = x1 % 8;
for (i = x2 - x1 + 1; i > 0; --i) {
end++;
if ((diff -= minus) < 0) {
if ( color == 18 )
*gram ^= charleftedge[start] & charrightedge[(end-1)];
else
*gram = charleftedge[start] & charrightedge[(end-1)];
gram += 80;
start = end;
diff += plus;
if (end == 8) {
gram++;
start = end = 0;
}
} else if (end == 8) {
if ( color == 18 )
*gram++ ^= charleftedge[start];
else
*gram++ = charleftedge[start];
start = end = 0;
}
}
if (end != 0) {
if ( color == 18 )
*gram ^= charleftedge[start] & charrightedge[end-1];
else
*gram = charleftedge[start] & charrightedge[end-1];
}
}
static void graph_line_7(int x1, int y1, int x2, int y2, int color)
{
int i;
int offset;
int data;
unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
gram += offset = y1 * 80 + x1 / 8;
data = 0x80 >> (x1 % 8);
for (i = y2 - y1 + 1; i > 0; --i) {
if ( color == 18 )
*gram ^= data ;
else
*gram = data ;
gram += 80;
if ((data >>= 1) == 0) {
data = 0x80;
gram++;
}
}
}
static void graph_line_8(int x1, int y1, int x2, int y2, int color)
{
int i;
int offset;
int data;
int diff;
int plus, minus;
unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
plus = (y2 - y1) * 2;
minus = (x2 - x1) * 2;
diff = plus / 2;
gram += offset = y1 * 80 + x1 / 8;
data = 0x80 >> (x1 % 8);
for (i = y2 - y1 + 1; i > 0; --i) {
if ( color == 18 )
*gram ^= data ;
else
*gram = data ;
gram += 80;
if ((diff -= minus) < 0) {
if ((data >>= 1) == 0) {
data = 0x80;
gram++;
}
diff += plus;
}
}
}
void graph_line(int x1, int y1, int x2, int y2, int color)
{
int temp;
if (y1 > y2) {
temp = x1; x1 = x2; x2 = temp;
temp = y1; y1 = y2; y2 = temp;
}
if (y2 < 0 || y1 > 399) {
return;
}
if (y1 < 0) {
x1 = (x1 * y2 - x2 * y1) / (y2 - y1);
y1 = 0;
}
if (y2 > 399) {
x2 = (x2 - x1) * (399 - y1) / (y2 - y1) + x1;
y2 = 399;
}
if (x1 > x2) {
temp = x1; x1 = x2; x2 = temp;
temp = y1; y1 = y2; y2 = temp;
}
if (x2 < 0 || x1 > 639) {
return;
}
if (x1 < 0) {
y1 = (y1 * x2 - y2 * x1) / (x2 - x1);
x1 = 0;
}
if (x2 > 639) {
y2 = (y2 - y1) * (639 - x1) / (x2 - x1) + y1;
x2 = 639;
}
/*
1 2 3
| /
| / 4
|/
.---5
\
\ 6
\
9 8 7
*/
EGCset( color );
if (x1 == x2) {
graph_line_1(x1, y1, x2, y2, color);
} else if (y1 == y2) {
graph_line_5(x1, y1, x2, y2, color);
} else if (y2 < y1) {
if (y1 - y2 > x2 - x1) {
graph_line_2(x1, y1, x2, y2, color);
} else if (y1 - y2 == x2 - x1) {
graph_line_3(x1, y1, x2, y2, color);
} else {
graph_line_4(x1, y1, x2, y2, color);
}
} else {
if (y2 - y1 < x2 - x1) {
graph_line_6(x1, y1, x2, y2, color);
} else if (y2 - y1 == x2 - x1) {
graph_line_7(x1, y1, x2, y2, color);
} else {
graph_line_8(x1, y1, x2, y2, color);
}
}
outportb(0x7c, 0 );
}
void graph_palet(int paletmode, int g, int r, int b)
{
int color ;
color = ( ( g >> 4 ) << 8 )|( ( r >> 4 ) << 4 )|( b >> 4 );
paletdata[paletmode & 15] = color;
outportb(0xa8, paletmode);
outportb(0xaa, color >> 8);
outportb(0xac, color >> 4);
outportb(0xae, color );
}
void graph_init( void )
{
union REGS in;
union REGS out;
int i;
in.h.ah = 0x42;
in.h.ch = 0xc0;
int86( 0x18, &in, &out ); /*graphic bios set gvram domain*/
#if 0
outportb( 0x68, 2 ); /*graphic mode = color*/
outportb( 0x68, 8 ); /*brp mode = 400line*/
outportb( 0x6a, 1 ); /*color = 8*/
#endif
in.h.ah = 0x40;
int86( 0x18, &in, &out );
outportb( 0x6a, 1);
for (i = 0; i < 8; ++i) {
graph_palet(i, (i&4) ? 255 : 0, (i&2) ? 255 : 0, (i&1) ? 255 : 0);
}
graph_apage(0);
graph_vpage(0);
graph_cls( 0 );
}
void graph_exit()
{
}
static void graph_apage(int page)
{
outportb(0xa6, page);
}
static void graph_vpage(int page)
{
outportb(0xa4, page);
}
void graph_cls( int color )
{
int i;
unsigned long far *p;
EGCset( color );
for (i = 8000, p = (unsigned long*)GRAPH_ADDRESS_I; i > 0; --i) {
*p++ = 0xffffffffUL;
}
outportb(0x7c, 0);
}
#define swap( a, b ) { int c ; c = a ; a = b ; b = c ; }
void graph_fill( int x1, int y1, int x2, int y2, int color )
{
int y ;
if ( x1 > x2 )
swap( x1, x2 );
if ( y1 > y2 )
swap( y1, y2 );
EGCset( color );
for( y = y1 ; y <= y2 ; y++ )
graph_line_5( x1, y, x2, y, color );
}
static void EGCset( int color )
{
if ( color == 18 ) {
outportb(0x7c, 0 );
} else if ( color >= 16 ) {
outportb(0x7c, 0xc7);
outportb(0x7e, 0 );
outportb(0x7e, 0 );
outportb(0x7e, 0 );
outportb(0x7e, (color & 15) ? 0xff : 0);
} else {
outportb(0x7c, 0xc0);
outportb(0x7e, (color & 1) ? 0xff : 0);
outportb(0x7e, (color & 2) ? 0xff : 0);
outportb(0x7e, (color & 4) ? 0xff : 0);
outportb(0x7e, (color & 8) ? 0xff : 0);
}
}
void graph_pattern( x, y, color, pat, h, v )
int x, y ;
int color ;
short *pat ;
int h, v ;
{
}
/* ボタン表示 */
void graph_box( x1, y1, x2, y2, sw )
int x1, y1, x2, y2 ;
int sw ;
{
if ( sw )
{
graph_line( x1, y1, x2, y1, 7 );
graph_line( x1, y1, x1, y2, 7 );
graph_line( x1, y2, x2, y2, 0 );
graph_line( x2, y1, x2, y2, 0 );
}
else
{
graph_line( x1, y1, x2, y1, 0 );
graph_line( x1, y1, x1, y2, 0 );
graph_line( x1, y2, x2, y2, 7 );
graph_line( x2, y1, x2, y2, 7 );
}
}