#include <stdio.h>
#include <mem.h>
#include <alloc.h>
#include <stdlib.h>
#include <conio.h>
#define VBE320X200X256 0X13
#define VBE640X480X256 0X101
#define VBE800X600X256 0X103
#define VBE1024X768X256 0X105
#define True 1
#define False 0
typedef struct
{
int width; /* 图像宽*/
int height; /* 图像高*/
int depth;
char type; /* 区别位图类型,'B'为256色位图,'M'为2色掩码位图*/
unsigned long ems_offset; /* EMS数据位置*/
} Bmp256; /* 256色BMP数据类型*/
int g_cur_vbe_page = 0;
/***********************************************************************************************
/* 设置系统调色板 */
/***********************************************************************************************/
void setpalette(char far *PaletteData)
{
struct REGPACK regs;
regs.r_ax=0x1012;
regs.r_bx=0;/*开始设置的颜色,一般为0,即从0号色开始获取*/
regs.r_cx=256;/*count为要获取的颜色数目,一般为256或16*/
regs.r_es=FP_SEG(PaletteData);
regs.r_dx=FP_OFF(PaletteData);
intr(0x10,®s);
}
//-----------------------------------------------------------
// 图形模式初始化子程序
//-----------------------------------------------------------
void _Cdecl InitGraph(void)
{
_AX = 0x4f02;
_BX = VBE800X600X256;
__int__(0x10);
if(_AH != 0)
{
puts("Can't Initialize the graphics mode!");
exit(1);
}
}
//-----------------------------------------------------------
// 关闭图形模式,回到文本模式子程序
//-----------------------------------------------------------
void _Cdecl CloseGraph(void)
{
_AX = 0x4f02;
_BX = 0x03;
__int__(0x10);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//显存换页函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl set_vbe_page(int page)
{
if (g_cur_vbe_page != page)
{
_BX = 0;
_DX = g_cur_vbe_page = page;
_AX = 0x4F05;
__int__(0x10);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//画点函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl PutPixel(int x,int y,int color)
{
long addr;
int page;
char far *videoptr = (char far *)0xa0000000L;
addr = (((unsigned long)y<<9L)+((unsigned long)y<<8L)+((unsigned long)y<<5L)+((unsigned long)(x)));
page = (int)(addr >> 16);
set_vbe_page(page);
*(videoptr+(unsigned int)(addr&0xffff))= color;
}
/**********************************************************************************************/
/* 设置256色图形系统调色版 */
/**********************************************************************************************/
void LoadDAC(FILE *fp)
{
unsigned char buffer[1024];
unsigned char dac[768]={0};
int n;
fread(buffer,1024,1,fp);
for (n=0;n<256;n++)
{
dac[n*3]=buffer[n*4+2]>>2;
dac[n*3+1]=buffer[n*4+1]>>2;
dac[n*3+2]=buffer[n*4]>>2;
}
setpalette(dac);
}
/**********************************************************************************************/
/* 显示BMP图像 */
/**********************************************************************************************/
Bmp256 Show_BMP(char *bmpfile)
{
int i,n,k,length;
unsigned char *buffer;
Bmp256 bmp={0};
FILE *fp;
if ((fp=fopen(bmpfile,"rb")) == NULL)
return (bmp);
if (getw(fp)!=19778) /* 检查标志位是否为"BM":256*'M'+'B' */
{
fclose(fp);
return (bmp);
}
fseek(fp,18,SEEK_SET); bmp.width=getw(fp); /* 获得图片宽度 */
fseek(fp,22,SEEK_SET); bmp.height=getw(fp); /* 获得图片高度 */
fseek(fp,28,SEEK_SET); bmp.depth=getw(fp); /* 获得图片色深 */
if (bmp.depth<=8) /* 若不是24位位图,开辟调色板数组 */
{
fseek(fp,54L,SEEK_SET);
LoadDAC(fp);
k=(bmp.width%4)?(4-bmp.width%4):0; /* 宽度修正值(补充:4-length%4) */
length = bmp.width+k;
for (n=0;n<bmp.height;n++)
{
fseek(fp,length,SEEK_SET);
fread(buffer,length,1,fp); /* 读取数据至buffer */
for(i = 0; i < length; i++)
PutPixel(i,n,buffer[i]);
}
}
close(fp);
return(bmp);
}
void main(void)
{
InitGraph();
Show_BMP("title0.bmp");
getch();
CloseGraph();
}