C程序中图片调用技巧 摘要:介绍如何在C程序中调用图片,这将有助于加强C程序的界面的美观性. 关键词: VGA 、BMP、13h.h、TIMER.H、Logo。 一、问题的引入: C语言使用愈来愈普及,愈来愈深层次。Turbo C提供了更强的图形函数库,它支持微机CGA﹑EGA﹑VGA等多种图形适配器的各种图形模式,提供了绘制各种图形﹑输出各种字体的图形库函数,并具有丰富的对图形进行着色﹑填充的功能。在图形程序及软件的编制与开发中,Turbo C绘图已越来越受到广大用户的青睐。 Turbo C图形的实现是基于在Turbo C基本知识的基础上,在了解了这些之后,我们就可以运用基本作图函数来实现一些工作。但是Turbo C是基于DOS核心的,最多实现16种颜色的显示,所以实现的图形也是比较简单、单一的。而一些较复杂的图形,用Turbo C是无法实现的。但是我们可以通过另一种办法来实现,在C程序中调用图片,这样就可以省去了在C中绘制图形的麻烦,并且图片我们可以利用其他的工具进行更优化的处理。 二、问题解决的方法: 有了这个想法以后,马上查资料,在网上发现一个叫作《潜艇大站》的游戏,在里面有调用图片的功能,通过认真研究以后,终于分离出了这段代码。 三、程序功能说明: 在这段程序中,可以调用的图片格式为BMP。图片大小为:320*200。 四、关键程序介绍: 在主程序中调用了两个头文件,这两个头文件在C函数库中是没有的,其功能分别是:13h.h为VGA13h作图模式下的一些基本函数。timer.h为这个程序运行的时钟系统。在主程序中有三个子函数,分别为:StepIn(调色板渐入函数)、StepOut(调色板渐出函数)、Logo(显示开始画面函数)。在13h.h中包括的函数有Pset(向后台活动页写像素)、wait(等待键盘输入)、setmode(设置VGA 13H模式)、closemode(设置文本模式)、void setpal(设置调色板)、ScanKey(从键盘缓冲区内直接读出扫描码)、ClearScreen(画背景)、ReFresh(刷新屏幕)。在timer.h中包括的函数有:BiosTimer(获取BIOS计数器数值)、TimerEvent(时间事件)、CreateTimer(创建一个时钟)、KillTimer(删除一个时钟)、KillAllTimer(删除所有时钟)。 五、程序清单: 1.主程序: #include<stdio.h> #include<dos.h> #include<stdlib.h> #include"13h.h" #include"timer.h" int Step=0; BYTE PAL[256][3]; void StepIn() { int i; for(i=0;i<256;i++) setpal(i,PAL[i][0]*Step/64,PAL[i][1]*Step/64,PAL[i][2]*Step/64); Step++; if (Step>64) KillAllTimer(); } void StepOut() { int i; for(i=0;i<256;i++) setpal(i,PAL[i][0]*Step/64,PAL[i][1]*Step/64,PAL[i][2]*Step/64); Step--; if (Step<1) KillAllTimer(); } void Logo() { FILE *bmp; int i,r,g,b,x,y; setmode(); bmp=fopen("logo.bmp","rb"); fseek(bmp,54,SEEK_SET); for (i=0;i<256;i++) { PAL[i][2]=fgetc(bmp)>>2; PAL[i][1]=fgetc(bmp)>>2; PAL[i][0]=fgetc(bmp)>>2; fgetc(bmp); setpal(i,0,0,0); } for (y=0;y<200;y++) for (x=0;x<320;x++) pokeb(0xa000,y*320+x,fgetc(bmp)); fclose(bmp); CreateTimer(1,StepIn); while (ScanKey()!=57&&TimerUsed) TimerEvent(); Step=64; StepIn(); wait(); CreateTimer(1,StepOut); while (ScanKey()!=57&&TimerUsed) TimerEvent(); Step=0; StepOut(); closemode(); } void main() { Logo(); } 2.13h.h代码: # define BYTE unsigned char # define BOOL BYTE # define WORD unsigned int # define DWORD unsigned long # define TRUE 1 # define FALSE !TRUE WORD FONT_SEG; WORD FONT_OFF; void far * Video; void GetFontAdd() { struct REGPACK regs; regs.r_bx=0x0300; regs.r_ax=0x1130; intr(0x10,®s); FONT_SEG=regs.r_es; FONT_OFF=regs.r_bp; } void Pset(int x,int y,BYTE color) { if ((x>=0)&&(x<320)&&(y>=0)&&(y<200)) *((BYTE far*)Video+y*320+x)=color; } void wait() { _AX=0; geninterrupt(0x16); } void setmode() { _AX=0x13; geninterrupt(0x10); GetFontAdd(); } void closemode() { _AX=0x3; geninterrupt(0x10); } void setpal(int Color,BYTE r,BYTE g,BYTE b) { outportb(0x3c8,Color); outportb(0x3c9,r); outportb(0x3c9,g); outportb(0x3c9,b); } void locate(int Line,int Col) { _DH=Line; _DL=Col; _AH=2; _BX=0; geninterrupt(0x10); } BYTE ScanKey(void) { int start,end; WORD key=0; start=peek(0,0x41a); end=peek(0,0x41c); if (start==end) return(0); else { key=peek(0x40,start); start+=2; if (start==0x3e) start=0x1e; poke(0x40,0x1a,start); return(key/256); } } void ClearScreen() { int x,y; for (y=0;y<5;y++) for (x=0;x<320;x++) Pset(x,y,16); for (y=5;y<10;y++) for (x=0;x<320;x++) Pset(x,y,104); for (y=10;y<15;y++) for (x=0;x<320;x++) Pset(x,y,33); for (y=15;y<20;y++) for (x=0;x<320;x++) Pset(x,y,103); for (y=20;y<25;y++) for (x=0;x<320;x++) Pset(x,y,32); for (y=25;y<30;y++) for (x=0;x<320;x++) Pset(x,y,64); for (y=30;y<40;y++) for (x=0;x<320;x++) Pset(x,y,99); for (y=40;y<60;y++) for (x=0;x<320;x++) Pset(x,y,97); for (y=60;y<100;y++) for (x=0;x<320;x++) Pset(x,y,53); for (y=100;y<200;y++) for (x=0;x<320;x++) Pset(x,y,2); } void ReFresh(void) { movedata(FP_SEG(Video),FP_OFF(Video),0xa000,0,64000); } 3.timer.h代码: # define MAXTIMER 10 struct TM { DWORD Interval; DWORD LastTimer; BOOL Enable; BOOL Used; void (*Pointer)(); }; struct TM tmTM[MAXTIMER+1]; int TimerUsed=0; DWORD BiosTimer(void) { DWORD BIOSTIMER=0; BIOSTIMER=peek(0x0,0x46e); BIOSTIMER<<=8; BIOSTIMER+=peek(0x0,0x46c); return (BIOSTIMER); } void TimerEvent() { int i; DWORD TimerDiff; for (i=1;i<=MAXTIMER;i++) { if (tmTM[i].Used&&tmTM[i].Enable) { TimerDiff=BiosTimer()-tmTM[i].LastTimer; if (tmTM[i].Interval<=TimerDiff) { tmTM[i].Pointer(); tmTM[i].LastTimer=BiosTimer(); } } } } int CreateTimer(DWORD Interval,void (*Pointer)()) { int i=0; if (TimerUsed==MAXTIMER) return NULL; while (tmTM[++i].Used); tmTM[i].Pointer=Pointer; tmTM[i].Interval=Interval; tmTM[i].Enable=TRUE; tmTM[i].Used=TRUE; tmTM[i].LastTimer=BiosTimer(); TimerUsed++; return i; } void KillTimer(int *TimerID) { if (tmTM[*TimerID].Used) { TimerUsed--; tmTM[*TimerID].Used=FALSE; } *TimerID=0; } void KillAllTimer() { int i; for (i=0;i<=MAXTIMER;i++) tmTM[i].Used=FALSE; TimerUsed=0; } 六、结束语: 本篇文章介绍了在C程序调用图片的函数,通过这段函数可以美化C程序的界面。
|