看到有前(钱)人发表了DOS下的东西,咱也凑凑热闹,把毕业设计时用过的一个小东西也拿出来晾晾,别霉了!
这是一个DOS下直接写屏显示16点阵汉字的演示程序
功能由函数OutText()完成,该函数区别于大多数此类函数的特点如下
.支持视区剪裁输出
.支持屏幕任意位置输出(不局限于一般直接写屏方法640X480分辩率下的输出位置必须为8的整数倍)
.支持英文字母及数字的8X16点阵输出
.支持直接写屏下的彩色汉字输出
演示起见,未加入将字库读入XMS内存,并从XMS内存读取字模的代码,因此纯DOS下运行可能会频繁的读硬盘。
要得到有XMS支持的直接写屏功能,可查看EGL程序源代码。
(2001.10.13日注:这个EGL是学校时做的一个DOS下仿Window3.1的界面库(Easy Graphics Library)。很完整,菜单,对话框,鼠标,键盘,图形下闪烁光标,可移动窗口,XMS,动画,位图,编辑控制,检查框,单选钮,push按钮等等,都支持,现在看看那时真是狂热,没有配套磁盘的书中的例子,就用手硬敲。刚才我又大略看了一遍,真是TMD破腚百出,哎,都是过去的事了)
废话说了一大堆,又发了点小感慨,说正题吧,下面是代码,格式为了对齐,把tab全换成了空格,多见谅吧,可执行文件目录下需要hzk16与asc16两个字库文件(ucdos自带)及EGAVGA.BGI这个老东西,如果你硬盘上无这些东西,那请到http://www.csdn.net/filebbs/read_topic.asp?id=677下载打包后文档
补充一句吧,CSDN上卧虎藏龙,小人这点小代码牛人就见怪不怪吧,如果实在不痛快,以后在街上看到我就狗血喷头的骂一顿吧,在这先谢罪了
MSVCer(家宝)
/*
OutText.C,Turbo C 2.0
WangJiaBao Create
ShenYang Electric Power Institute,1997.09.19
*/
/*
WangJiaBao Modify for friend
ShenYang Thermo Power Plant,2001.04.20
*/
/*
WangJiaBao Modify for CSDN
ShenYang Thermo Power Plant,2001.10.13
*/
#include "dos.h"
#include "stdio.h"
#include "stdlib.h"
#include "graphics.h"
FILE *fp_hzk,*fp_asc;
/*
OutText()各参数意义:
x 字符串x轴坐标
y 字符串y轴坐标
color 字符串颜色
hz 字符串地址
*/
void OutText(int x,int y,unsigned char color,unsigned char *hz);
main()
{
int gd=VGA,gm=VGAHI;
int x,y,len,color,y8X8=2,y8X16=16,bottom=447;
int wl=120,wt=100,wr=520,wb=315; /* 视区坐标 */
unsigned long times=1,time1=0,time2=0;
unsigned char tmpstr[100],\
*errorhzk="\nError open hzk16\a",\
*errorasc="\nError open asc16\a",\
*goon="任意键继续演示",\
*viewport="演示OutText()函数的视区显示能力",\
*demoviewstr="在视区(%d,%d,%d,%d)内显示汉字,起点坐标为X=%d Y=%d",\
*fonts="比较8x8与8x16两种点阵ASCII码字符的输出效果",\
*hello="小人向各位CSDN的朋友问好",\
*report="%lu秒输出句子%lu次.",\
*enddemo="演示OutText()函数的高速写屏能力,任意键结束演示";
if( (fp_hzk=fopen("hzk16","rb"))==NULL ){ /* 打开16*16点阵汉字库文件 */
printf(errorhzk);
exit(1);
}
if( (fp_asc=fopen("asc16","rb"))==NULL ){ /* 打开ASCII码8*16点阵文件 */
printf(errorasc);
fclose(fp_hzk);
exit(1);
}
initgraph(&gd,&gm,"");
/* 1.演示OutText()函数的全屏输出及视区显示能力 */
setfillstyle(WIDE_DOT_FILL,BLUE);
bar(0,0,639,479);
setfillstyle(SOLID_FILL,WHITE);
bar(wl,wt,wr,wb);
setviewport(wl,wt,wr,wb,1); /* 定义视区 */
for(x=y=0;x<=15;x++,y+=16){
sprintf(tmpstr,demoviewstr,wl,wt,wr,wb,x,y);
OutText(x,y,BLUE,tmpstr);
}
setviewport(0,0,639,479,1); /* 重置视区 */
OutText(320-strlen(viewport)*4,60,YELLOW,viewport);
OutText(320-strlen(goon)*4,80,LIGHTCYAN,goon);
getch();
/* 2.演示图形模式下的ASCII码字符,以8X8点阵和8X16点阵输出之间的对比 */
setfillstyle(SOLID_FILL,BLACK);
bar(0,0,639,479);
x=0;
tmpstr[0]=tmpstr[1]='\0';
textcolor(WHITE);
do{
if( x>630 ){ y8X8+=48; y8X16+=48; x=0; }
outtextxy(x,y8X8,tmpstr);
OutText(x,y8X16,LIGHTCYAN,tmpstr);
x+=10;
}while( ++tmpstr[0]<255 );
OutText(320-strlen(fonts)*4,200,YELLOW,fonts);
OutText(320-strlen(goon)*4,220,LIGHTCYAN,goon);
getch();
/* 3.演示OutText()函数的高速输出能力 */
bar(0,0,639,479);
OutText(639-strlen(enddemo)*8,463,LIGHTCYAN,enddemo);
y=bottom;
randomize();
len=strlen(hello)*8;
time1=time(); /* 开始时刻 */
while( !kbhit() ){ /* 当无按键时执行 */
if( y>=bottom ){
y=0;
x=random(639-len);
color=random(15)+1;
bottom=bottom<=0?447:bottom-16;
}
bar(x-1,y-1,x+len,y+16);
OutText(x,y++,color,hello);
sprintf(tmpstr,"%lu",times++);
bar(0,463,strlen(tmpstr)*8,479);
OutText(0,463,WHITE,tmpstr); /* 计数 */
}
time2=time(); /* 结束时刻 */
getch();
bar(0,463,639,479);
sprintf(tmpstr,report,time2-time1,times);
OutText(0,463,LIGHTGREEN,tmpstr);
getch();
fclose(fp_hzk);
fclose(fp_asc);
closegraph();
}
void OutText(int x,int y,unsigned char color,unsigned char *hz)
{
long i;
char far *ptr;
int movebit,ybit;
struct viewporttype v;
unsigned char by[32],by1,by2,byte1,byte2,tmp,*byptr;
getviewsettings(&v);
x+=v.left; y+=v.top; /* 在视区内显示 */
if( x<0 || y<0 || x>=639 || y>=479 || x>=v.right || y>=v.bottom ) return;
ybit= y+15>=v.bottom?v.bottom-y:16; /* Y方向不超过视区的下边界 */
ybit= ybit<=0?0:ybit;
/* 采用写方式2 */
outportb(0x3ce,5); outportb(0x3cf,2);
/* 一次写4个位平面 */
outportb(0x3c4,2); outportb(0x3c5,255);
outportb(0x3ce,8);
while(*hz){
byte1=(unsigned char)*hz; byte2=(unsigned char)*(hz+1);
if( (byte1>=0xa1 && byte1<=0xfe)&&(byte2>=0xa1 && byte2<=0xfe) ){ /* 汉字 */
byptr=by;
if(x+15>v.right) break; /* 超出视区不显示 */
i=(byte1-0xa1)*94+byte2-0xa1;
i<<=5;
fseek(fp_hzk,i,SEEK_SET);
fread(by,32,1,fp_hzk); /* 读汉字点阵 */
/* 因为一个字节含有8个像素点,必须考虑到起始位置未处于x%8==0时的情况 */
/* 为此设置一个只从有效的x位置写起的偏移量movebit */
movebit=x%8; /* 起始位置在缓冲区中字节内相对偏移 */
for(i=0;i<ybit;i++){
ptr=MK_FP( 0xA000,(y+i)*80+x/8 );
by1=*byptr++; by2=*byptr++;
/* 将汉字点阵的两个字节写入缓冲区 */
/* 要写8个像点的掩码,此掩码即为汉字的点阵信息,第一个字节 */
outportb( 0x3cf,by1>>movebit );
tmp=*ptr; *ptr++=color; /* 将颜色值写入缓冲区 */
/* 要写8个像点的掩码,第二个字节 */
outportb( 0x3cf,(by1<<(8-movebit))|(by2>>movebit) );
tmp=*ptr; *ptr++=color;
/* 当汉字点阵正好充满两个字节,不对第三个字节操作 */
if( movebit!=0 ){
/* 要写8个像点的掩码 */
outportb( 0x3cf,by2<<(8-movebit) );
tmp=*ptr; *ptr=color;
}
} /* for end */
x+=16; hz+=2;
} /* if HZ end */
else{ /* 显示ASCII */
if(x+7>v.right) break; /* 超出视区不显示 */
fseek(fp_asc,byte1*16,SEEK_SET);
fread(by,16,1,fp_asc); /* 读ASCII码点阵 */
movebit=x%8; /* 起始位置在缓冲区字节内相对偏移 */
for(i=0;i<ybit;i++){
ptr=MK_FP( 0xA000,(y+i)*80+x/8 );
by1=*(by+i);
outportb( 0x3cf,by1>>movebit );
tmp=*ptr; *ptr++=color;
if( movebit!=0 ){
outportb( 0x3cf,by1<<(8-movebit) );
tmp=*ptr; *ptr++=color;
}
} /* for end */
x+=8; hz++;
} /* if ASCII end */
} /* while end */
tmp=tmp;
outportb(0x3ce,8); outportb(0x3cf,255);
outportb(0x3ce,5); outportb(0x3cf,0);
} /* OutText() end */
本文地址:http://com.8s8s.com/it/it29928.htm