看到有前(钱)人发表了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 */

|