home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 July / VPR9707B.ISO / DRIVER / IODATA / GA360 / DISK2.EXE / SAMPLE / BMPLOAD.C next >
Text File  |  1993-04-01  |  11KB  |  501 lines

  1. /************************************************************************
  2.     GA-1024A / GA-1280A グラフィックライブラリ サンプルソース
  3.         BMPLOAD.C
  4.  
  5.     BMPファイルロ-ダ
  6.  
  7.                 アイ・オー・データ機器 Device Inc...
  8. *************************************************************************/
  9. #include <stdio.h>
  10. #include <fcntl.h>
  11. #include <io.h>
  12. #include "gagraph.h"
  13.  
  14. /*
  15.  * header file for .bmp file header
  16.  */
  17. typedef    unsigned short    WORD;
  18. typedef    unsigned long    DWORD;
  19.  
  20. typedef    struct    tagBITMAPFILEHEADER {
  21.     WORD    bfType;
  22.     DWORD    bfSize;
  23.     WORD    bfReserved1;
  24.     WORD    bfReserved2;
  25.     DWORD    bfOffBits;
  26. } BITMAPFILEHEADER;
  27.  
  28. typedef    struct    tagBITMAPINFOHEADER {
  29.     DWORD    biSize;
  30.     DWORD    biWidth;
  31.     DWORD    biHeight;
  32.     WORD    biPlanes;
  33.     WORD    biBitCount;
  34.     DWORD    biCompression;
  35.     DWORD    biSizeImage;
  36.     DWORD    biXPelsPerMeter;
  37.     DWORD    biYPelsPerMeter;
  38.     DWORD    biCirUsed;
  39.     DWORD    biCirImportant;
  40. } BITMAPINFOHEADER;
  41.  
  42. typedef unsigned char  uchar;
  43. typedef unsigned short ushort;
  44. typedef unsigned int   uint;
  45. typedef unsigned long  ulong;
  46.  
  47. #define BUFF_SIZE 16*1024
  48.  
  49. static  uchar buff[BUFF_SIZE];          /* ファイルバッファ */
  50. static  uchar buff4[2048];
  51. static  uint  gaport;                /* GA-1024A/GA-1280A I/Oポ-トアドレス */
  52. static  volatile uchar far *ga_wind; /* グラフィックメモリウィンドウアドレス*/
  53. static  uchar lut[256*3];            /* パレットデ-タ */
  54.  
  55. static  int   gmode = 1;            /* 画面モ-ド 1:1024x768  2:640x480 */
  56.                                     /*           13:1024x768 15:640x480 */
  57. static  uint  colorMax;                /* 色数 */
  58. static  int      mode_flg = 0;
  59.  
  60. static    int      xsize,ysize,scan;
  61. static    int   bit;
  62. static    int   rsmode;
  63. static    int   idx;
  64. static    int      remain;
  65. static    char  *fname;
  66.  
  67. void    ginit();
  68. void    palinit();
  69. void    error(char *);
  70. int     gaload(int);
  71. void    rle_4(int);
  72. void    rle_8(int);
  73. void    nomal(int);
  74. int     freadline(int ,int *,int );
  75. void    wait(int);
  76.  
  77. /**************************************
  78.  
  79.     main()
  80.  
  81. ***************************************/
  82. void main(argc,argv)
  83. int   argc;
  84. char  *argv[];
  85. {
  86.     int handl;
  87.     int i, pal_flg;
  88.  
  89.  
  90.     fname = argv[1];
  91.     puts ("GA-1024A/GA-1280A BMP loader Ver 1.00  I・O DATA DEVICE Inc.");
  92.     if ( argc < 2 ) {
  93.         puts("usage : BMPLOAD <file> /xx");
  94.         puts("    /xx  = /8  ( 8 plane mode )");
  95.         puts("           /16 (16 plane mode )");
  96.         error("");
  97.     }
  98.     if ( argc > 3 ) error("パラメータ 無効");
  99.         if ( argv[2][0] == '/' ) {
  100.             if ( argv[2][1] == '1' && argv[2][2] == '6' ) {
  101.                 mode_flg = 1;
  102.                 gmode = 15;
  103.             }
  104.             else {
  105.                  if ( argv[2][1] == '8' )
  106.                     mode_flg = 0;
  107.                 else
  108.                     error("パラメータ 無効");
  109.             }
  110.         }
  111.  
  112.     if ((handl = open(argv[1], O_RDONLY | O_BINARY )) == -1) {
  113.         error("can't open file");
  114.     }
  115.     ginit();
  116.     gaload(handl);
  117.     while (1) {
  118.         switch (getch()) {
  119.             case 'C':
  120.             case 'c':    /* 画面モードを変える */
  121.             if ( mode_flg == 0 ) {
  122.                 if (gmode & 1)
  123.                          gmode++ ;
  124.                     else 
  125.                          gmode-- ;
  126.                 GAinit(gmode);        
  127.                 GAsetVisualPlane(-1);
  128.                 wait(40);            /* CRTが同期するまで待つ */
  129.                 palinit();
  130.                 GAsetVisualPlane(0);
  131.             }
  132.             else {
  133.                 if ( gmode == 15 )
  134.                     gmode -= 2;
  135.                 else
  136.                     gmode += 2;
  137.                 GAinit(gmode);
  138.             }
  139.                 continue;
  140.             case 'q':
  141.             case 'Q':    /* パレット設定を変更しないで終了 */
  142.                 pal_flg = PAL_USER;
  143.                 break;
  144.             default:
  145.                 pal_flg = PAL_DEF;
  146.                 break;
  147.         }
  148.         break;
  149.     }
  150.     GAcrtSel(CRT_PC);
  151.     GAterm( pal_flg );    /* 終了関数 */
  152.     exit(0);
  153. }
  154.  
  155. /***********************************************
  156.  
  157.     初期化
  158.  
  159. ************************************************/
  160. void ginit()
  161. {
  162.     struct VDCONFIG vd;
  163.  
  164.     if (GAinit(gmode)) error("GAINIT が常駐していません");
  165.     GAclrScreen();
  166.     GAgetVideoConfig((void far *)&vd);
  167.     gaport = vd.port ;    /* GA-1024A/GA-1280A レジスタのポート番号 */
  168.     ga_wind = (void far *) ((ulong)vd.ga_seg << 16); /* グラフィックメモリウィンドウアドレス */
  169.     GAcrtSel(CRT_GA);
  170. }
  171.  
  172. /***************************************************
  173.  
  174.     エラ-処理
  175.  
  176. ****************************************************/
  177. void error(s)
  178. char *s;
  179. {
  180.     puts(s);
  181.     GAcrtSel(0);
  182.     exit(1);
  183. }
  184.  
  185.  
  186. /****************************************************
  187.  
  188.     パレット設定
  189.  
  190. *****************************************************/
  191. void palinit()
  192. {
  193.     int i;
  194.     for (i=0 ; i < colorMax ; i++) { 
  195.         GAsetPalette((void far *)&lut[i*3],i);
  196.     }
  197. }
  198.  
  199.  
  200.  
  201. #define RED   2 
  202. #define GREEN 1 
  203. #define BLUE  0 
  204. /*****************************************************************
  205.  
  206.     画像データロード
  207.  
  208. *****************************************************************/
  209. int  gaload(handl)
  210. int  handl;
  211. {
  212.     int     i,j,k,rle_code;
  213.     long     lut_sz;
  214.     BITMAPFILEHEADER fh;
  215.     BITMAPINFOHEADER inf;
  216.  
  217. idx = 0;
  218. remain = 0;
  219.  
  220.         /* ファイルヘッダ */
  221.     if ( !read(handl,(char *)&fh,sizeof(BITMAPFILEHEADER))) goto endr;
  222.     if ( fh.bfType != 'B' + 'M'*256) {
  223.         puts("not BMP File!");
  224.         goto endr;
  225.     }
  226.     if ( !read(handl,(char *)&inf,sizeof(BITMAPINFOHEADER))) goto endr;
  227.     rle_code = inf.biCompression;
  228.     xsize = inf.biWidth ;
  229.     ysize = (inf.biHeight > 768) ? 768 : inf.biHeight ;
  230.     colorMax = inf.biCirUsed ? inf.biCirUsed : 256;
  231.     bit = inf.biBitCount;
  232.  
  233.     if (bit == 1) {      /* モノクロ */
  234.         scan = ((xsize + 31) / 8) & 0xfffc ;
  235.         rsmode = PLANE_MODE;
  236.         gmode = 7;   /* 1024x768 mono */
  237.         GAinit(gmode) ;
  238.     } else  if (bit == 4) {  /* 16色 */
  239.         scan = ((xsize + 7) / 2) & 0xfffc ;
  240.         rsmode = PIXEL_MODE;
  241.         colorMax = 16;
  242.         gmode = 3;   /* 1024x768 mono */
  243.         GAinit(gmode) ;
  244.     } else if (bit ==8 ) {        /*    256色 */
  245.         scan = (xsize + 3) & 0xfffc ;
  246.         rsmode = PIXEL_MODE;
  247.     } else if (bit == 24) {       /* 24Bit フルカラー */
  248.             scan = (xsize * 3 + 3) & 0xfffc ;
  249.             rsmode = PIXEL_MODE;
  250.             if ( mode_flg == 0 ) {
  251.                 colorMax = 6*6*6;
  252.                 idx = 0;
  253.                 for (i=0 ; i < 6 ; i++) {
  254.                     for (j=0 ; j<6 ; j++) {
  255.                         for (k=0 ; k<6 ; k++ ) {
  256.                             lut[idx++] = i * 0x33;    /* R */
  257.                             lut[idx++] = j * 0x33;    /* G */
  258.                             lut[idx++] = k * 0x33;    /* B */
  259.                         }
  260.                     }
  261.                 }
  262.             }
  263.     }
  264.     lut_sz = fh.bfOffBits - 54 ;
  265.  
  266.     if (bit != 24) {    
  267.         /* パレット設定             */
  268.         if (!read(handl,buff,(int)lut_sz)) goto endr;
  269.         for (i=0; i < colorMax ; i++ ) { 
  270.             lut[i*3+0] = buff[RED+  (i*4)];
  271.             lut[i*3+1] = buff[GREEN+(i*4)];
  272.             lut[i*3+2] = buff[BLUE+ (i*4)];
  273.         }
  274.     }
  275.     if ( mode_flg == 0 ) palinit();
  276.  
  277. #define BI_RGB  0
  278. #define BI_RLE8 1
  279. #define BI_RLE4 2
  280. /*---------------------------------------*/
  281. /*     画像をグラフィックメモリに展開する     */
  282. /*---------------------------------------*/
  283.  
  284.     switch(rle_code){
  285.         case BI_RGB  : 
  286.                 nomal(handl);
  287.                 break;
  288.         case BI_RLE8 :
  289.                 rle_8(handl);
  290.                 break;
  291.         case BI_RLE4 :
  292.                 rle_4(handl);
  293.                 break;
  294.         default:
  295.                 break;
  296.     }
  297.     close( handl );
  298.     return(0);
  299. endr:
  300.     close( handl );
  301.     error("error!  load abote");
  302. }
  303.  
  304.  
  305. /*****************************************************************
  306.  
  307.     圧縮フォーマット
  308.  
  309. ******************************************************************/
  310.  
  311. /*----------------------------------*/
  312. /*            << BI_RLE8 >>            */
  313. /*----------------------------------*/
  314.  
  315. void rle_8(int handl)
  316. {
  317.     uchar     count,color,i,endf=1;
  318.     uint    x,y;
  319.  
  320.     x=0;
  321.     y=ysize;
  322.     while(endf) {
  323.         if (read(handl,buff,2) == 0  ) return;
  324.         count = buff[0];
  325.         color = buff[1];
  326.         if ( count == 0 ) {
  327.             switch(color) {
  328.                 case 0:                        /* 改行 */
  329.                         x = 0;
  330.                         y--;
  331.                         break;
  332.                 case 1:                        /* 終了 */
  333.                         endf=0;
  334.                         break;
  335.                 case 2:                        /* (+x,+y) 移動 */
  336.                         read(handl,buff,2);
  337.                         x += buff[0];
  338.                         y += buff[1];
  339.                         break;
  340.                 default:                    
  341.                          count = color;
  342.                         read(handl,buff,((count+1) & 0x00fe));
  343.                         GArestoreImage(x,y,x+count-1,y,rsmode,(void far *)buff);
  344.                         x += count;
  345.                         break;
  346.             }
  347.         } else {
  348.                 for(i = 0; i < count; i++)    {
  349.                     buff[i] = color;
  350.                 }
  351.                 GArestoreImage(x,y,x+count-1,y,rsmode,(void far *)buff);
  352.                 x += count;
  353.         }
  354.     }
  355. }
  356.  
  357. /*----------------------------------*/
  358. /*            << BI_RLE4 >>            */
  359. /*----------------------------------*/
  360.  
  361. void rle_4(int handl)
  362. {
  363.     uchar     color_1,color_2,color,count,i,endf=1;
  364.     uint    x,y;
  365.  
  366.     x=0;
  367.     y=ysize;
  368.     while(endf) {
  369.         if (read(handl,buff,2) == 0  ) return;
  370.         count = buff[0];
  371.         color = buff[1];
  372.         if (count == 0) {
  373.             switch(color){
  374.                 case 0:
  375.                     x = 0;
  376.                     y--;
  377.                     break;
  378.                 case 1:
  379.                     endf=0;
  380.                     break;
  381.                 case 2:
  382.                     read(handl,buff,2);
  383.                     x += buff[0];
  384.                     y += buff[1];
  385.                     break;
  386.                 default:
  387.                     count = color;
  388.                     read(handl,buff4,((count/2+1) & 0x00fe));
  389.                     for(i = 0; i < count; i++){
  390.                         buff[i*2]   = buff4[i] >> 4;
  391.                         buff[i*2+1] = buff4[i] & 0x0f;
  392.                     }
  393.                     GArestoreImage(x,y,x+count-1,y,rsmode,(void far *)buff);
  394.                     x += count;
  395.                     break;
  396.             }
  397.         } else {
  398.                 color_1 = color >> 4;
  399.                 color_2 = color & 0x0f;
  400.                 for(i = 0; i < count; i+=2){
  401.                     buff[i]   = color_1;
  402.                     buff[i+1] = color_2;
  403.                 }
  404.                 GArestoreImage(x,y,x+count-1,y,rsmode,(void far *)buff);
  405.                 x += count;
  406.         }
  407.     }
  408. }
  409.  
  410.  
  411.  
  412. /*****************************************************************
  413.  
  414.     ノーマルフォーマット
  415.  
  416. ******************************************************************/
  417. void nomal(int handl)
  418. {
  419.  
  420.     int        yy,xx,i,j,k;
  421.  
  422.     for (yy=ysize-1;yy;yy--) {
  423.         if (freadline(handl,&idx,scan)==0) break ; 
  424.         if (bit == 4) {  /* 16色 */
  425.             for (xx=0 ; xx < xsize ; xx += 2) {
  426.                 buff4[xx  ] = buff[idx] >> 4 ;
  427.                 buff4[xx+1] = buff[idx++] & 0x0f ;
  428.             }
  429.             GArestoreImage(0,yy,xsize-1,yy,rsmode,(void far *)buff4);
  430.         } else    if (bit == 24) { /* フルカラ- -> 216色 */
  431.             for (xx=0 ; xx < xsize ; xx++,idx += 3) {
  432.                 if ( mode_flg == 0 ) {                                                                buff4[xx] =  ((buff[idx  ]+25) / 51)  
  433.                                + (((buff[idx+1]+25) / 51) * 6  )
  434.                                + (((buff[idx+2]+25) / 51) * 36 ) ;
  435.                 } else {
  436.                     *((ushort *)buff4 + xx) = 
  437.                                     ((buff[RED+idx]   & 0xf8) << 8) |
  438.                                     ((buff[GREEN+idx] & 0xfc) << 3) |
  439.                                     ((buff[BLUE+idx]  & 0xf8) >> 3) ;
  440.                 }
  441.             }
  442.             GArestoreImage(0,yy,xsize-1,yy,rsmode,(void far *)buff4);
  443.         } else {  /* モノクロ    256色 */
  444.             GArestoreImage(0,yy,xsize-1,yy,rsmode,(void far *)(buff+idx));  
  445.         }
  446.     }
  447. }
  448.  
  449.  
  450. /*****************************************************************
  451.  
  452.     1ライン分ファイルリード
  453.  
  454. ******************************************************************/
  455. int freadline( handl,idx,size)
  456. int  handl;
  457. int *idx;
  458. int  size;
  459. {
  460.     static int fp = 0;
  461.     int    ret = size;
  462.     
  463.     if (remain < size) {
  464.         fp = 0;
  465.         remain = ( BUFF_SIZE / size ) * size;
  466.         ret = read(handl,buff,remain);
  467.     } 
  468.     *idx = fp;
  469.     fp += size;
  470.     remain -= size;
  471.     return(ret);
  472. }
  473.  
  474.  
  475. /* グラフィック コントロ-ル レジスタ ポ-ト */
  476. #define CRTC_AR 0x1e00
  477. #define CRTC_CR 0x1f00
  478. /***********************************************************
  479.  
  480.     CRTC の垂直同期信号をカウントしてウエイトする
  481.  
  482. ************************************************************/
  483. void wait(int count) 
  484. {
  485. #if 0
  486.     int  i;
  487.     for (i=0 ; i < count ; i++) {
  488. #ifdef TURBO
  489.         outportb(CRTC_AR+gaport,31);       /* CRTC STATUS register */
  490.         while ( inportb(CRTC_CR+gaport) & 2) ;
  491.         while ( !(inportb(CRTC_CR+gaport) & 2)) ;
  492. #else
  493.         outp(CRTC_AR+gaport,31);       /* CRTC STATUS register */
  494.         while ( inp(CRTC_CR+gaport) & 2) ;
  495.         while ( !(inp(CRTC_CR+gaport) & 2)) ;
  496. #endif
  497.     }
  498. #endif
  499. }
  500.  
  501.