其实这篇资料几个月前就发过了,是在
论坛里发的,昨天一个朋友求这样程序,我让在坛子里以前的贴子里找,可是他说找不到了,我想想,也应该把它整理一下,放在正式的技术文栏中,我归类在了"用编程解决问题"专栏中,以后我们会不断更新这个专栏,专门的介绍一下编程在
无盘中的应用,其实
无盘中很多的相关问题光靠技巧是很难解决的,必须编写一些实用的程序;
根据网友提出的要求,修改了程序,不需要按任意键退出画面,而是设定了三秒钟的时间,三秒之后自动关闭,多长时间可以自已改程序最后的部分
/*----------------------*/
while(tm<3)
{
gettime(&end);
tm=(end.ti_hour-start.ti_hour)*3600+(end.ti_min-start.ti_min)*60+end.ti_sec-start.ti_sec;
}
/*这个循环条件小于3 就是秒数,你可以改成指定的时间*/
/*----------------------*/
//完整源程序如下:
#include "dos.h"
#include "fcntl.h"
#include "io.h"
#include "stdio.h"
#include "time.h"
#define TEXT_BIG_CURSOR 0
#define TEXT_NORMAL_CURSOR 7
#define SIZE16 32
unsigned int Vmode=0;
typedef struct /*16Mrgb像素类型*/
{
unsigned char b; /*黄色*/
unsigned char g; /*绿色*/
unsigned char r; /*红色*/
}rgb16M;
unsigned char nowpage,lastpage=8;
struct {
/* Mandatory information for all
VBE revisions */
unsigned int ModeAttributes; /* 模式属性 */
unsigned char WinAAttributes; /* 窗口 A 属性 */
unsigned char WinBAttributes; /* 窗口 B 属性 */
unsigned int WinGranularity; /* 窗口页粒度, KB为单位*/
unsigned int WinSize; /* 窗口大小, KB为单位*/
unsigned int WinASegment; /* 窗口 A 起始段地址 */
unsigned int WinBSegment; /* 窗口 B 起始段地址 */
unsigned char far *WinFuncPtr; /* 换页调用指针 */
unsigned int BytesPer
SCanLine; /* 每条扫描线所占的字节数 */
/*Mandatory information for
VBE 1.2 and above */
unsigned int XResolution; /* 水平分辨率 */
unsigned int YResolution; /* 垂直分辨率 */
unsigned char XCharSize; /* 字符宽度 */
unsigned char YCharSize; /* 字符高度 */
unsigned char NumberOfPlanes; /* 存储器位面个数 */
unsigned char BitsPerPixel; /* 每个像素所占位数 */
unsigned char NumberOfBanks; /* 显示段个数 */
unsigned char MemoryModel; /* 存储器模式类型 */
unsigned char BankSize; /* 显示段的大小,以KB为单位 */
unsigned char NumberOfImagePages; /* 可同时载入的最大满屏图像数 */
unsigned char reserve1; /* 为页面功能保留 */
/*Direct Color f
IElds(required for direct/6 and YUV/7 memory models)*/
unsigned char RedMaskSize; /* 红色所占的位数 */
unsigned char RedF
IEldPosition; /* 红色的最低有效位位置 */
unsigned char GreenMaskSize; /* 绿色所占的位数 */
unsigned char GreenF
IEldPosition; /* 绿色的最低有效位位置 */
unsigned char BlueMaskSize; /* 蓝色所占的位数 */
unsigned char BlueF
IEldPosition; /* 蓝色的最低有效位位置 */
unsigned char RevMaskSize; /* 保留色所占的位数 */
unsigned char RevF
IEldPosition; /* 保留色的最低有效位位置 */
unsigned char DirectColorModeInfo; /* 直接颜色模式的属性 */
/*Mandatory information for
VBE 2.0 and above*/
unsigned char far *PhysBasePtr; /* 可使用大的帧缓存时32位的物理地址指针 */
unsigned long Off
SCreenMemOffset; /* 帧缓存首址的32位偏移量 */
unsigned int Off
SCreenMemSize; /* 可用的,连续的显示缓冲区长度,KB为单位 */
/*Mandatory information for
VBE 3.0 and above*/
unsigned int LinBytesPer
SCanLine; /* 线性缓冲区扫描线的长度,以字节为单位 */
unsigned char BnkNumberOfImagePages; /* 使用窗口功能时显示页面数 */
unsigned char LinNumberOfImagePages; /* 使用大的线性缓冲区时显示页面数 */
unsigned char LinRedMaskSize; /* 使用大的线性缓冲区时红色所占的位数 */
unsigned char LinRedF
IEldPosition; /* 使用大的线性缓冲区时红色的最低有效位位置 */
unsigned char LinGreenMaskSize; /* 使用大的线性缓冲区时绿色所占的位数 */
unsigned char LinGreenF
IEldPosition; /* 使用大的线性缓冲区时绿色的最低有效位位置 */
unsigned char LinBlueMaskSize; /* 使用大的线性缓冲区时蓝色所占的位数 */
unsigned char LinBlueF
IEldPosition; /* 使用大的线性缓冲区时蓝色的最低有效位位置 */
unsigned char LinRevMaskSize; /* 使用大的线性缓冲区时保留色所占的位数 */
unsigned char LinRevF
IEldPosition; /* 使用大的线性缓冲区时保留色的最低有效位位置 */
unsigned char reserve2[194]; /* 保留 */
} ModeInfo;
/*
函数名:set_SVGA_mode
功能:设置Svga 模式
参数:1个,整型
返回值:字符
*/
unsigned char set_SVGA_mode(int vmode)
{
union REGS r;
r.x.ax=0x4f02;
r.x.bx=vmode;
int86(0x10,&r,&r);
return(r.h.ah);
}
/*
函数名:hide_text_cursor(void)
功能:隐藏文本状态下的光标
参数:无
返回值:无
*/
void hide_text_cursor(void)
{
union REGS r;
r.h.ah=1;
r.h.ch=32;
int86(0x10,&r,&r);
}
/*
函数名:hide_text_cursor(void)
功能:换页
参数:1个,寄存器字符型
返回值:无
*/
void selectpage(register char page) /*换页函数*/
{
union REGS r;
r.x.ax=0x4f05;
r.x.bx=0;
r.x.dx=page; /*选择页面*/
int86(0x10,&r,&r);
}
/*
函数名:show_text_cursor(char size)
功能:恢复出文本状态中的光标
参数:1个,整型
返回值:无
*/
void show_text_cursor(char size)
/*(10-17):自定义文本光标)*/
{
union REGS r;
r.h.ah=1;
r.h.cl=size;
r.h.ch=7;
int86(0x10,&r,&r);
}
/*
函数名:get_SVGA_mode()
功能:读取svga 模式
参数:无
返回值:无符号整型
*/
unsigned int get_SVGA_mode()
{
union REGS r;
r.x.ax=0x4f03;
int86(0x10,&r,&r);
return(r.x.bx);
}
/*
函数名:get_SVGA_mode()
功能:屏幕初始化
参数:无
返回值:整型
*/
int init16M()
{
Vmode=get_SVGA_mode();
hide_text_cursor();
if(set_SVGA_mode(0x111)) /*0x114改成0x111*/
{
printf("Sorry, Your graphics driver does not suppl
IEd.");
show_text_cursor(TEXT_NORMAL_CURSOR);
return 0;
}
return 1;
}
/*
函数名:write_video(long position,char value)
功能:填充视频
参数:2个,参数1:长整型 参数2:字符型
返回值:无
*/
void write_video(long position,char value)
{
nowpage=position/65536;
if(nowpage!=lastpage)
{
selectpage(nowpage);
lastpage=nowpage;
}
pokeb(0xa000,position%65536,value);
}
/*
函数名:putpoint16M(int x,int y,rgb16M color)
功能:16M真彩色 800*600写点
参数:3个,参数1:整型 参数2:型,参数3:(自定义结构体)16Mrgb像素类型
返回值:无
*/
void putpoint16M(int x,int y,rgb16M color)
{
unsigned int c;
unsigned int c1;
unsigned int c2;
unsigned char t1,t2;
register long temp=2*640l*y+2*x;
color.r=color.r>>3;
color.g=color.g>>2;
color.b=color.b>>3;
c1=(unsigned int)color.r<<11;
c2=(unsigned int)color.g<<5;
c=c1+c2+color.b;
t1=c/256;
t2=c%256;
write_video(temp,t2);
write_video(temp+1,t1);
}
/*
函数名:close16M()
功能:关闭真彩图型模式,还原文本模式
参数:无
返回值:无
*/
void close16M()
{
if(Vmode!=0)
{
set_SVGA_mode(Vmode);
show_text_cursor(TEXT_NORMAL_CURSOR);
}
}
void main()
{
register int wl,ll,bmpfp,i4,j,x0,y0;
int temp;
register char fix;
register rgb16M *buffer;
struct time start,end;
int tm=0;
if (init16M()==0)
exit(0);
if((bmpfp=open("logo.bmp",O_RDONLY|O_BINARY))==-1)
{
close16M();
exit(0);
}
lseek(bmpfp,18,SEEK_SET);
read(bmpfp,&temp,4);
wl=temp;
read(bmpfp,&temp,4);
ll=temp;
fix=(wl%4)?(4-wl%4):0;
x0=(640-wl)/2;y0=(480-ll)/2;
lseek(bmpfp,54,SEEK_SET);
buffer=malloc(wl*sizeof(rgb16M));
for(j=ll-1;j>=0;j--)
{
read(bmpfp,buffer,wl*3);
lseek(bmpfp,fix,SEEK_CUR);
for(i4=0;i4<wl;i4++)
putpoint16M(x0+i4,y0+j,buffer[i4]);
}
close(bmpfp);
gettime(&start);
while(tm<3)
{
gettime(&end);
tm=(end.ti_hour-start.ti_hour)*3600+(end.ti_min-start.ti_min)*60+end.ti_sec-start.ti_sec;
}
close16M();
}
/*本源程序请用TC 进行编译,VC++ bcb 下的编译均无法通过,如果你需要编译好的.exe 文件可以到我们群共享中下载,或者与我联系*/