📄 graphfun.c
字号:
/*
前台收银程序作图函数库
本函数不调用C的图形函数,而直接采用操作显示卡的方法,从而可以减少内存
的占用量和提高显示速度
重庆运通资讯科技有限公司 蓝仕红 2000年11月
*/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <bios.h>
#include <math.h>
#include <fcntl.h>
#include <stdarg.h>
#include <user.h>
#include <graphfun.h>
#include <publ.h>
const int XOR_PUT=0x18; // 异或
const int COPY_PUT=0x0; // 复制
union REGS reg; // DOS中断调用参数
struct SREGS sreg;
/* -------------------键盘输入处理函数----------------------*/
//把一个输入放入消息缓冲区
void InBuffer(int type,unsigned RetKey,int x,int y)
{
if((CountS+1)%32==CountE) return; //缓冲区满,退出
MSG[CountS].type=type;
MSG[CountS].h.RetKey=RetKey;
MSG[CountS].x=x;
MSG[CountS++].y=y;
CountS%=32;
}
//获得键盘输入
unsigned GetInt16(void)
{
reg.x.ax=0;
int86x(0x16,®,®,&sreg);
return reg.x.ax;
}
//获得输入
void GetInput(void)
{
while(1)
{
if(CountS!=CountE) break; //缓冲区满
if(_bios_keybrd(1)) //键盘消息
{
GetInt16();
if(reg.h.al==0)
InBuffer(-2,reg.x.ax,0,0); //是功能键
else
{
if(reg.h.ah==0) //是汉字内码
InBuffer(-3,reg.x.ax,0,0);
else if(reg.h.al<0x20)
InBuffer(-1,reg.x.ax,0,0); //是控制键
else
InBuffer(0,reg.x.ax,0,0); //是ASCII码
}
break;
} //鼠标消息
}
}
//获取一个消息
Msg *Getkey(void)
{
short Temp;
if(CountS==CountE)
GetInput();
Temp=CountE++;
CountE%=32;
return &(MSG[Temp]);
}
//检查是否有消息
int BiosKey(void)
{
return(_bios_keybrd(1)||CountS!=CountE);
}
//清除消息缓冲区
void ClearKey(void)
{
CountS=CountE=0;
}
/* 第一:设置图形模式函数系列 */
//设置图形模式
void InitGraph(int INT10)
{
reg.x.ax=INT10;
int86x(0x10,®,®,&sreg); //调用中断
}
//关闭屏幕显示
void CloseScr(void)
{
_asm{
mov dx,0x3c4
mov al,1
out dx,al
mov dx,0x3c5
in al,dx
or al,0x20
mov dx,0x3c5
out dx,al
}
}
//打开屏幕显示
void OpenScr(void)
{
_asm{
mov dx,0x3c4
mov al,1
out dx,al
mov dx,0x3c5
in al,dx
and al,0xdf
mov dx,0x3c5
out dx,al
}
}
/* 第二部分:作图函数 */
/*往显示缓冲区中填写数据
LC-颜色
LW-线宽
WMODE-模式
LS-线类型
*/
void Line0(int sx,int sy,int ex,unsigned char LC,int LW,
int WMODE,unsigned char LS)
{
int lsx,lex,lst,let;
unsigned char n1,n2;
int Off;
_asm{
mov ax,ex
mov bx,sx
cmp ax,bx
// jl RETU
mov ax,sx
and ax,7
mov lsx,ax
mov ax,sx
mov cl,3
shr ax,cl
mov lst,ax
mov ax,ex
and ax,7
mov lex,ax
mov ax,ex
mov cl,3
shr ax,cl
mov let,ax
mov ax,sy
mov cl,6
shl ax,cl
mov bx,ax
mov ax,sy
mov cl,4
shl ax,cl
add ax,bx
mov Off,ax
mov dx,0x3ce
mov al,0
out dx,al
mov dx,0x3cf
mov al,LC
out dx,al
mov dx,0x3ce
mov al,1
out dx,al
mov dx,0x3cf
mov al,0xff
out dx,al
mov dx,0x3ce
mov al,3
out dx,al
mov dx,0x3cf
mov ax,WMODE
out dx,al
mov dx,0x3c4
mov al,2
out dx,al
// outportb(0x3c4,2)
mov dx,0x3c5
mov al,0xff
out dx,al
// outportb(0x3c5,0xff)
mov ax,let
cmp ax,lst
jnz CONT
jmp NEXT
CONT: xor ax,ax
mov al,0xff // if(let!=lst)
mov cx,lsx // {
shr al,cl // n1=m>>lsx
mov bl,LS
xor bh,bh
and ax,bx // n1=n1&LineStyle,
mov n1,al
mov al,0xff // n2=m<<(7-lex)
mov cx,7
sub cx,lex
shl al,cl
and ax,bx
mov n2,al // n2=n2&LineStyle
//
mov dx,0x3ce
mov al,8
out dx,al // outportb(0x3ce,8)
mov dx,0x3cf
mov al,n1
out dx,al // outportb(0x3cf,n1)
mov bx,Off
add bx,lst // k=OFF+lst
mov cx,LW
mov ax,0xa000 // for(j=0;j<n;j++)
mov es,ax // { c=peekb(SEG,k)
mov si,bx // pokeb(SEG,k,c)
CONT1: mov al,es:[si] // k+=80 }
mov es:[si],al
add si,80
loop CONT1
//
mov dx,0x3ce // outportb(0x3ce,8)
mov al,8
out dx,al
mov dx,0x3cf // outportb(0x3cf,n2)
mov al,n2
out dx,al
mov bx,Off // k=OFF+let
add bx,let
mov si,bx
mov ax,0xa000 // for(j=0;j<n;j++)
mov es,ax
mov cx,LW
CONT2: mov al,es:[si] // { c=peekb(SEG,k)
mov es:[si],al // pokeb(SEG,k,c)
add si,80 // k+=80 }
loop CONT2
mov dx,0x3ce // outportb(0x3ce,8)
mov al,8
out dx,al
mov dx,0x3cf
mov al,LS // outportb(0x3cf,LineStyle)
out dx,al
mov bx,Off // r=OFF+lst
add bx,lst
mov di,LW // for(j=0;j<n;j++)
mov dx,let
sub dx,lst
dec dx
mov ax,0xa000
mov es,ax
CONT3: mov si,bx // k=r
mov cx,dx // for(i=1;i<let-lst;i++)
CONT4: cmp cx,0
jz CONT6
inc si
mov al,es:[si] // c=peekb(SEG,k)
mov es:[si],al // pokeb(SEG,k,c) }
dec cx
jmp CONT4
CONT6: add bx,80
dec di
jnz CONT3
jmp EXIT
//
NEXT:mov bx,7 // else {
sub bx,lex // n1=m<<lsx
mov dx,bx
add bx,lsx // n1=n1>>(7-lex+lsx)
mov al,0xff
mov cx,lsx
shl al,cl
mov cx,bx
shr al,cl
mov cx,dx // n1=n1<<(7-lex)
shl al,cl
mov cl,LS // n1=n1&LineStyle
xor ch,ch
and al,cl
mov n1,al
mov dx,0x3ce // outportb(0x3ce,8)
mov al,8
out dx,al
mov dx,0x3cf // outportb(0x3cf,n1)
mov al,n1
out dx,al
mov bx,Off // k=OFF+lst
add bx,lst
mov ax,0xa000
mov es,ax
mov cx,LW // for(j=0;j<n;j++)
CONT5: mov al,es:[bx] // { c=peekb(SEG,k)
mov es:[bx],al // pokeb(SEG,k,c)
add bx,80 // k+=80
loop CONT5
EXIT: mov dx,0x3ce // outportb(0x3ce,3)
mov al,3
out dx,al
mov dx,0x3cf
mov al,0
out dx,al // outportb(0x3cf,0)
mov dx,0x3ce
mov al,8
out dx,al // outportb(0x3ce,8)
mov dx,0x3cf
mov al,0xff
out dx,al // outportb(0x3cf,0xff)
mov ax,0
nop
}
}
/*画一条直线*/
//sx,sy-直线的起点 ex,ey-直线的终点
int CurX,CurY; //当前点的位置
void Line(int sx,int sy,int ex,int ey,unsigned char LC,int LW,
int WMODE,unsigned char LS)
{
long kx,ky,r;
int TLW,Con=0;
int x=0,y=0,k=1,m=1,j;
CurX=ex,CurY=ey;
if(sy==ey)
{
if(sx>ex)
{ TLW=sx,sx=ex,ex=TLW;}
Line0(sx,sy,ex,LC,LW,WMODE,LS);
}
else if(sx==ex)
{
if(sy>ey)
{ TLW=sy,sy=ey,ey=TLW;}
TLW=LW;
LW=ey-sy+1;
Line0(sx,sy,ex,LC,LW,WMODE,LS);
LW=TLW;
}
else
{
kx=ex-sx+1,ky=ey-sy+1;
r=kx*kx+ky*ky;
j=(labs(ky)>labs(kx))? 1:0;
if(sx>ex) k=-k;
if(sy>ey) m=-m;
while(r>=x*(long)x+y*(long)y)
{
if(j)
x=(int)(y*kx/ky);
else
y=(int)(x*ky/kx);
if((LS>>(7-Con%8))&1)
Line0(sx+x,sy+y,sx+x,LC,LW,WMODE,LS);
if(j) y+=m;
else x+=k;
}
}
}
//画点
void Point(int sx,int sy,unsigned char Pco)
{
Line0(sx,sy,sx,Pco,1,COPY_PUT,0xff);
}
//画矩形
//sx,sy,ex,sy-坐标
//Co-填冲颜色,Type-填冲类型
void DrawBar(int sx,int sy,int ex,int ey,
unsigned char Co,unsigned char Type)
{
int i;
unsigned char CCo[2],LStyle;
if(Type==0xff) // 实线填充
Line0(sx,sy,ex,Co,ey-sy+1,COPY_PUT,0xff); // ey-sy+1=线的宽度
else // 非实线填冲
{
CCo[0]=(unsigned char)(Co&0xf);
CCo[1]=(unsigned char)((Co>>4)&0xf);
LStyle=Type;
for(i=0;i<=ey-sy;i++)
{
Line0(sx,sy+i,ex,CCo[0],1,COPY_PUT,LStyle);
LStyle=(unsigned char)~LStyle;
Line0(sx,sy+i,ex,CCo[1],1,COPY_PUT,LStyle);
}
}
}
//画矩形
//sx,sy,ex,ey-坐标
//FC-左上线颜色,BC-右下线颜色
void Rectangle(int sx,int sy,int ex,int ey,
unsigned char FC,unsigned char BC)
{
Line0(sx,sy,ex,FC,1,COPY_PUT,0xff); //上线
Line(sx,sy,sx,ey,FC,1,COPY_PUT,0xff); //左线
Line0(sx,ey,ex,BC,1,COPY_PUT,0xff); //下线
Line(ex,sy,ex,ey,BC,1,COPY_PUT,0xff); //右线
}
//画填冲矩形
void RectangleFill(int sx,int sy,int ex,int ey,
unsigned char FC,unsigned char BC,
unsigned char FillColor,unsigned char FillStyle)
{
DrawBar(sx,sy,ex,ey,FillColor,FillStyle);
Rectangle(sx,sy,ex,ey,FC,BC);
}
//显示有3D效果的矩形
void DrawBar3d(int sx,int sy,int ex,int ey,
unsigned char FC,unsigned char FS,
unsigned char BC,unsigned char BS,int Size,
unsigned char C1,unsigned char C2)
{
if(Size)
{
DrawBar(ex,sy+Size,ex+Size,ey+Size,BC,BS);
DrawBar(sx+Size,ey,ex+Size,ey+Size,BC,BS);
}
RectangleFill(sx,sy,ex,ey,C1,C2,FC,FS);
}
//显示园型
void Circel(int x,int y,int R,unsigned char Co,unsigned char Li,int Att)
{
int Di,Xi,Yi;
Di=3-2*R;
Xi=0,Yi=R;
do{
Di=(Di<0)? Di+(Xi<<2)+6:Di+((Xi-Yi)<<2)+10;
Xi=Xi+1;
Yi=(Di<0)? Yi:Yi-1;
if(Att)
{ Line0(x-Xi,y-Yi,x+Xi,Co,1,COPY_PUT,0xff);
Line0(x-Xi,y+Yi,x+Xi,Co,1,COPY_PUT,0xff); }
else
{ Point(x+Xi,y-Yi,Co);
Point(x-Xi,y-Yi,Co);
Point(x+Xi,y+Yi,Co);
Point(x-Xi,y+Yi,Co);}
}while(Xi<=Yi);
Xi=R,Yi=0;
Di=3-(R<<2);
do{
Di=(Di<0)? Di+(Yi<<2)+6:Di+((Yi-Xi)<<2)+10;
Yi=Yi+1;
Xi=(Di<0)? Xi:Xi-1;
if(Att)
{ Line0(x-Xi,y-Yi,x+Xi,Co,1,COPY_PUT,0xff);
Line0(x-Xi,y+Yi,x+Xi,Co,1,COPY_PUT,0xff); }
else
{ Point(x+Xi,y-Yi,Co);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -