站内搜索

在DOS下显示16色位图的源程序

  /***********************************************
  *******在DOS下显示16位色位图源程序**************
  ***********************************************/
     #include <string.h>
     #include <stdio.h>
     #include <stdlib.h>
     #include <conio.h>
     #include <math.h>
     #include <fcntl.h>
     #include <bios.h>
     #include <dos.h>
     #include <io.h>
     #include <graphics.h>
     #define closegr closegraph
  /***********************************************
  *************位图文件头结构*********************
  ***********************************************/
  typedef struct
  {
   int id; /*两字节的内容用来识别位图的类型:
'BM' : Windows 3.1x, 95, NT, …
'BA' :OS/2 Bitmap Array
'CI' :OS/2 Color Icon
'CP' :OS/2 Color Pointer
'IC' : OS/2 Icon
'PT' :OS/2 Pointer
注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识"BM"就行
*/
   long filesize; /*用字节表示的整个文件的大小*/
   long reserved; /*保留,必须设置为0*/
   long dataoffset; /*从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量*/
   long headersize; /*位图信息头(Bitmap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:
28h - Windows 3.1x, 95, NT, …
0Ch - OS/2 1.x
F0h - OS/2 2.x
注:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。
*/
   long width; /*位图的宽度,以象素为单位*/
   long height;/*位图的高度,以象素为单位*/
   int Planes; /*位图的位面数(注:该值将总是1)*/
   int Pixe;   /*每个象素的位数
1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)
4 - 16 色位图
8 - 256 色位图
16 - 16bit 高彩色位图
24 - 24bit 真彩色位图
32 - 32bit 增强型真彩色位图
*/
   long Compression;    /*压缩说明:
0 - 不压缩 (使用BI_RGB表示)
1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示)
2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示)
3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)
*/
   long bmpDataSize; /*用字节数表示的位图数据的大小。该数必须是4的倍数*/
   long XPelsPerMeter;/*用象素/米表示的水平分辨率*/
   long YPelsPerMeter;/*用象素/米表示的垂直分辨率*/
   long ClrUsed; /*位图使用的颜色数。如8-比特/象素表示为100h或者 256*/
   long ClrImportant;   /*指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要*/
  }BMPHEAD;

  BMPHEAD BmpHead;
  char convert[16] = {0x0,0x4,0x2,0x6,0x1,0x5,0x3,0x7,0x8,0xc,0xa,0xe,0x9,0xd,0x3,0xf};/*BMP色彩与VGA色对照表*/
  unsigned char * bmp_data;
  int fp;

   /**********************************************
   ************ BGI初始化函数*********************
   **********************************************/
  void initgr(void)
{
  int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */
  registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */
  initgraph(&gd, &gm, "");
}
  /***********************************************
  *************位图文件头读取函数*****************
  ***********************************************/
  int read_bmp_head(char *bmp_filename)
  {
    if((fp=open(bmp_filename,O_RDONLY))==-1)/*打开位图文件*/
    {
      printf("%s%s",bmp_filename," is not found.");
      return 1;
    }
    read(fp,&BmpHead,sizeof(BMPHEAD));/*读取BMP文件的信息头*/
    if(BmpHead.id!=0x4d42)  /*判断是否是BMP文件*/
    {
      printf("%s%s","'",bmp_filename,"' is not BMPfile");
      return 1;
    }
    return 0;
  }
  /***********************************************
  **************纠正宽度函数**********************
  ***********************************************/
    int correct_width(int width)
  {
    int factual_width;
    if(width%4==0&&(width/4)%2==0);
    else while(width%4!=0||(width/4)%2!=0)width++;
    factual_width=width;
    return factual_width;
  }
  /***********************************************
  *************读位图文件并显示函数***************
  ***********************************************/
  void put_bmp(char * bmpfile,int x,int y)
  {
    int read_bmp_head_return,i,j,d=0,cn;
    bmp_data=(unsigned char *)malloc(BmpHead.bmpDataSize*sizeof(unsigned char));
    if((read_bmp_head_return=read_bmp_head(bmpfile))==1)
    {
      getch();
      exit(1);
      }
    lseek(fp,BmpHead.dataoffset,SEEK_SET);
    read(fp,bmp_data,BmpHead.bmpDataSize);/*读取颜色数据到缓冲区内*/
    cn=correct_width(BmpHead.width);
    for(i=BmpHead.height;i>0;i--)
    for(j=0;j<cn;)
    {
      putpixel(x+j++,y+i,convert[bmp_data[d]>>4]);/*用高4位画1个点*/
      putpixel(x+j++,y+i,convert[bmp_data[d]&0xf]); /*用低4位画1个点*/
      d++;
    }
    free(bmp_data);
    close(fp);
  }
  /***********************************************
  *************主函数*****************************
  ***********************************************/
  int main(void)
  {
    initgr();  
    put_bmp("pix.bmp",320,240);
    getch();
    closegr();
    return 0;
  }

 

/*  这是上面程序的一个应用

XP WIN2000 可以不用再驱动鼠标了 */

#include "Conio.h"
#include<dos.h>
#include<stdio.h>
#include "graphics.h"
#define closegr closegraph

union REGS regs;
void initgr(void) /* BGI初始化 */
{
  int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */
  registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */
  initgraph(&gd, &gm, "");
}

int initmouse(int xmin,int xmax,int ymin,int ymax)
{
  int retcode;
  regs.x.ax=0;
  int86(0x33,&regs,&regs);
  retcode=regs.x.ax;
  if(retcode==0)/*ax=0 安装失败*/
  return 0;
  regs.x.ax=7;
  regs.x.cx=xmin;
  regs.x.dx=xmax;
  int86(0x33,&regs,&regs); /* 设置水平位置最大最小值*/
  regs.x.ax=8;
  regs.x.cx=ymin;
  regs.x.dx=ymax;
  int86(0x33,&regs,&regs);  /* 设置垂直位置最大最小值*/
  return retcode;
}
int read(int *mx,int *my,int *mbutt)  /*对鼠标的位置和按键状态函数*/
{
  int x0=*mx,y0=*my,buto=0;
  int xnew,ynew;
  do
{
    regs.x.ax=3;
    int86(0x33,&regs,&regs);/* 取按键状态及鼠标位置 */
    xnew=regs.x.cx;
    ynew=regs.x.dx;
    *mbutt=regs.x.bx;
}while(xnew==x0&&ynew==y0&&*mbutt==buto);/*等到状态改变*/
if(*mbutt>>2<<7)
{
  *mx=xnew;
  *my=ynew;
  return 2;   /*中键按下*/
}
else if(*mbutt>>1<<7)
{
  *mx=xnew;
  *my=ynew;
  return 1;  /*右键按下*/
}
else if(*mbutt<<7)
{
    *mx=xnew;
    *my=ynew;
    return -1;  /*左键按下*/
}
else
  {
*mx=xnew;
    *my=ynew;
    return 0;  /*无键按下*/
  }
}
void cursor(int x,int y,char *pic) /*画鼠标*/
{
   put_bmp(pic,x,y);
}
int mouse_move(int *x,int *y,int *button)
{
  int x0=*x,y0=*y,mouse_button;
  mouse_button=read(x,y,button);
  cursor(x0,y0,"pix.bmp");
  cursor(*x,*y,"pix.bmp");
  return mouse_button;
}
int mouse_bound(int *x,int *y,int m1,int n1,int m2)
{
  if(m1<*x&&*x<m2)
  {
    if(n1<*y&&*y<n1+20)return 0;
    }
    return 1;
  }
/****************************************************************
*****************************************************************
*****************************************************************

        把上面的函数加进来

*****************************************************************
*****************************************************************/
int main(void)
{
  int init_mouse_x=320,init_mouse_y=240,buttons,mouse_button,bound_betton;
  int bound_x,bound_y;
  initgr(); /* BGI初始化 */
  if(initmouse(0,639,0,479)==0) /* 鼠标初始化 */
  { /* 未安装鼠标处理*/
    exit(1);
  }
  else
  {
    cursor(init_mouse_x,init_mouse_y,"pix.bmp");
    do
    {
      mouse_button=mouse_move(&init_mouse_x,&init_mouse_y,&buttons);
      bound_x=init_mouse_x;bound_y=init_mouse_y;
      if(mouse_button==-1){
        bound_betton=mouse_bound(&bound_x,&bound_y,300,390,340);
        if(bound_betton==0)break;
      }

    }while(1);
  }
   closegr(); /* 恢复TEXT屏幕模式 */
  return 0;
}

  • 上一篇:Turbo C(V2.0)使用指南
  • 下一篇:一个简单的链表程序