ビットマップファイルの解析とGBAへの応用

【24bitのビットマップファイル】
 今ペイントで右のような横3ドット、縦2ドットにそれぞれR・G・Bの配合でデータを作った。
 これは、24bitカラーのビットマップとしてセーブをした。
 あたりまえだが、各色のの成分が高いとその色の度合いが強くなっている。

セーブしたファイルをバイナリーエディターで読むと上のようになっている。
ここで元画像と比較すると
  • 0x0012:X軸の値
  • 0x0016:Y軸の値
  • 0x001C:カラー構成(0x18=24よって24bitカラー)
    ちなみに256色(8bitカラー)ビットマップではここの値は(0x08)となっている。
  • 0x0036:座標(0,1)の色(B:FF,G:00,R:00)
  • 0x0039:座標(1,1)の色(B:00,G:FF,R:00)
  • 0x003C:座標(2,1)の色(B:00,G:00,R:FF)
  • 0x003F:X座標を4で割ったあまりを冗長ビットとして付加
    この場合3%4=3なので3ビット付加されている。
  • 0x0042:座標(0,0)の色
  • 0x0045:座標(1,0)の色(B:FF,G:FF,R:FF)
  • 0x0048:座標(2,0)の色(B:00,G:00,R:00)
  • 0x004B:X座標を4で割ったあまりを冗長ビットとして付加
    この場合3%4=3なので3ビット付加されている。
となっているのがわかる。
 この「24bit(各色8bitx3)カラーデータファイル」でR,G,Bそれぞれの値を8で割った値(右に3ビットシフト)をGBAのVRAMに書き込めば、GBA上の画面に再現できるはず。
 つーわけでこの「BITMAP画像→GBA Mode3画像変換プログラム」(なるものを作ってみました。
Windows上で走ります。 ちゃちゃっと作っちゃいましたので、いろいろ手を抜いています。(≧∇≦)ぶぁっはっはっ!!

この変換ソフト、フリーなので配布はご自由に。ただしバグやら弊害に関しては一切責任をとりません。

"bit2gba.exe"
(BitMapファイルをGBA用にデータに変換するプログラム)
フリーなので配布はご自由に。ただしバグやら弊害に関しては一切責任をとりません。


<<24bitビットマップファイルの変換>>
  1. 起動して「BitMapFileOpen」ボタンをクリック
  2. 希望の”xxxx.bmp”ファイルを指定。
  3. 一応作るかどうか聞いてきます。
  4. 同じディレクトリーに”xxxx.h”というファイルができます。
  5. その中身がコンバートしたデータ(※)です。
    :16bitデータの配列名はファイル名を元に付けています。
    この場合で言うと・・・・→『xxxx[]』

【”bi2gba.exe”起動画面】
/*Exsample "GBA Mode3 Data Load Program"*/
/*"bit2gba.exe"で作成したデータをロードするサンプルプログラム*/
/*ただしデータが配列fight[]で定義されているものとする。*/
{
  u16 *dot_color; /*VRAMポインタ*/
  u8 y;       /*y軸0〜159*/
  DISPCNT=(DISP_MODE(3) | DISP_BG2); /*Mode3 のBG2に出力*/
  /*画面描写ルーチン 1ドットづつ打つ*/
  dot_color=(u16 *)0x06000000; /*VRAM BASE*/
  for(y=0;y<160;++y){
    u8 x; /*x軸0〜239*/
    for(x=0;x<240;++x){
        int no;
        no=240*y+x;
        /*定義データをVRAMへ展開*/
        *(dot_color+no)=fight[no];
    }
  }
}

【256色のビットマップファイル】
 上記と同じように256色でセーブされたビットマップファイルをバイナリーエディターで見てみる。
256色のビットマップファイルは
  1. ヘッダ(画面サイズ・ファイルサイズ等)「0x0000〜0x0035」
     これは、24bitビットマップファイルと同じ構成。
  2. パレット(256色分)「0x0036〜0x0435」
     256色のデータには4バイトなので、256x4=1024(0x400)のパレットデータが必ず必要となっている。
     1)のヘッダーが0x36なので1)と2)を合わせると0x436(サイズ値)になり、アドレス0x436番地から実際のデータ(3))になるのよねー。
  3. データ(パレット番号)「0x0436〜」
     これも24bitビットマップと同じように下のラインから上のラインへと定義されている。
で構成されていた。
 2)、3)のデータも24bitと同じように4バイト単位で区切られるように0x00を付けて冗長していた。
以上のことを踏まえると、
 例えばとある「256色の3x2のビットマップ」で中身が

なら、それは
92 B6 C4
00 B6 FF
として絵が構成していることを表しているわけやね。
 ここでパレット番号「C4」(0x043C)ならば、0x36+0xC4*4=0x0346なので、アドレス0x0346を見ると_
    0x0346:00 20 C0 00
となっていた。これはそれぞれB=00G=20,R=C0の色を持つパレットと定義されており、実際の色とみごとマッチした。(実にあたりまえなんだけれどね)

 ここまでわかれば、後はWindowsのソフトを書くだけです・・・ほほほ実はもうできていんるですねぇ。前回作った24bitBitMapの変換にこの機能も備わっています。
 ユーザが指定したビットマップファイルで、
  • 24bitのビットマップファイルなら、Mode3のデータ
  • 8bitのビットマップデータならMode4のデータ
を自動に判断して作るようになっています。
<<8bitビットマップファイルの変換>>
  1. 起動して「BitMapFileOpen」ボタンをクリック
  2. 希望の”xxxx.bmp”ファイルを指定。
  3. 一応作るかどうか聞いてきます。
  4. 同じディレクトリーに”xxxx.h”というファイルができます。
  5. その中身がコンバートしたデータ(※)です。
    :16bitデータの配列名はファイル名を元に付けています。
    この場合で言うと・・・・
    • 『xxxx_pal[]』:パレットデータ256色
    • 『xxxx_data[]』:画像データ(パレット番号)
/*Exsample "GBA Mode4 Data Load Program"*/
/*"bit2gba.exe"で作成したデータをロードするサンプルプログラム*/
/*ただしパレットデータが配列fight_pal[]で定義されているものとする。*/
/*ただし絵のデータが配列fight_data[]で定義されているものとする。*/

{
  u16 *ram_pointer; /*RAMポインタ*/
  DISPCNT=(DISP_MODE(4) | DISP_BG2); /*Mode4 のBG2に出力*/

  /*256色パレットデータの書き込み*/
  ram_pointer=(u16 *)0x05000000; /*パレット BASE*/
  u16 i; /*x軸0〜239*/
  for(i=0;i<256;++i){
    *(ram_pointer+i)=fight_pal[i];
  }

  /*絵のデータ(パレット番号)書き込み*/
  ram_pointer=(u16 *)0x06000000; /*VRAM BASE*/
  u8 y; /*y軸0〜159*/
  for(y=0;y<160;++y){
  u8 x; /*x軸0〜239*/
  for(x=0;x<120;++x){
    /*定義データをVRAMへ展開 2ドットいっぺんに打つのでx軸はその半分*/
    int no;
    no=120*y+x;
    *(ram_pointer+no)=fight_data[no];
    }
  }
  /*永久ループ*/
  while(1){
  }
}