#author("2023-05-26T19:05:34+09:00","","")
#author("2023-05-26T19:08:03+09:00","","")
* ビットマップモード3 [#h05944c7]

前回のmode3を仕様っぽくまとめると以下の表になります。表にはフレームバッファ?パレット?伸縮回転?とちょっとワザとらしいですけど、新しい言葉を登場させてみました。これは次のmode4への布石です。パレット、フレームバッファはこのページで説明して、伸縮回転は後回しにします。

| サイズ           | 240*160 |
| フレームバッファ | 1       |
| 色/パレット     | 32768色 |
| 伸縮回転         | 可能    |

** mode4へ [#xb854b12]
mode4の仕様は以下のとおりです。変わったところはフレームバッファ及びパレットとなっています。

| サイズ           | 240*160         |
| フレームバッファ | 2               |
| 色/パレット     | 256色/1パレット |
| 伸縮回転         | 可能            |

mode3は1ドット2バイトとして、この2バイトで色を表現していました。対してmode4は1ドット1バイト。1バイトは色データではなくパレット番号と呼ばれるものを指定します。エミュレータのTools -> Palette viewを見てみましょう。

#ref(1.png,nolink)

色データは0x5000000から2バイトづつ、256個格納することができます。パレット番号とは256個のことを指します。さて、240*160ドットの画像データをmode3では76800(240*160*2)バイト必要だったのに対して、mode4は38400+512(240*160*1 + 256*2)と約半分になりました。当然、色の表現が乏しくなるのは避けられません。見栄えをよくするためには予め高性能な減色ツールを使って256色に戻しておくといいと思います。各パレット番号の色データはmode3と同じフォーマットです。

- Color Definitions
 Each color occupies two bytes (same as for 32768 color BG modes):
 
   Bit   Expl.
   0-4   Red Intensity   (0-31)
   5-9   Green Intensity (0-31)
   10-14 Blue Intensity  (0-31)
   15    Not used

次にフレームバッファについてですが、まあコード読んだ方がわかりやすいのでソースコードを見ていきましょう。なお画像ファイルの読み込み方法がわからない方は[[Doc.2 画像加工ツールgritの使い方>doc.2]]を先に見ておいてください。

** モード4での画像表示 [#x1cd77ab]

 #include "lib/gba.h"
 #include "res.h"
 
 //---------------------------------------------------------------------------
 void WaitForVsync(void)
 {
 	while(*(vu16*)0x4000006 >= 160) {};
 	while(*(vu16*)0x4000006 <  160) {};
 }
 //---------------------------------------------------------------------------
 void Mode4SetFrame(u16* img, u32 f)
 {
 	u16* fr;
 
 	if(f == 1)
 	{
 		fr = (u16*)0x6000000;
 	}
 	else
 	{
 		fr = (u16*)0x600A000;
 	}
 
 	u32 x, y;
 
 	for(y=0; y<160; y++)
 	{
 		for(x=0; x<240; x++)
 		{
 			fr[y*240+x] = img[y*240+x];
 		}
 	}
 }
 //---------------------------------------------------------------------------
 void Mode4SetPalette(u16* pDat)
 {
 	u16* pPalette = (u16*)0x05000000;
 	u32 i;
 
 	for(i=0; i<256; i++)
 	{
 		pPalette[i] = pDat[i];
 	}
 }
 //---------------------------------------------------------------------------
 int main(void)
 {
 	// モード設定
 	// 4bit目(BACKBUFFER)を1にすることで、フレーム2が有効になります
 	SetMode(MODE_4 | BG2_ENABLE | BACKBUFFER);
 
 	// 画像と色データの読み込み
 	Mode4SetFrame((u16*)&frame1Bitmap, 1);
 	Mode4SetFrame((u16*)&frame2Bitmap, 2);
 
 	Mode4SetPalette((u16*)&frame1Pal);
 
 	for(;;)
 	{
 	    WaitForVsync();
 	}
 }

画像ファイルを2つ読み込み、それぞれを0x6000000からの領域と、0x600A000からの領域に格納しています。SetMode()には特殊なフラグを設けています。
画像ファイルを2つ読み込み、それぞれを0x6000000からの領域と、0x600A000からの領域に格納しています。SetModeには特殊なフラグを設けています。

 SetMode(MODE_4 | BG2_ENABLE | BACKBUFFER);

BACKBUFFERフラグが登場しました。この指定はフレームバッファが2つあるうち、2を指定するものです。フレーム1,2と、GBAの画面を切り替えるというわけです。ためしにエミュレータのTools -> IO viewerでウィンドウを開き、0x4000000-DISPCNTの4bit目(Display Frame)のチェックを外し、Applyボタンを押してからウィンドウを閉じてみてください。画面が変化します。

#ref(2.png,nolink)

***動作画面 [#m958e69b]
#ref(3.png,nolink)

** 履歴 [#p6ae87c6]
- 2023/04/22
- 2014/12/21

トップ   差分 履歴 リロード   一覧 検索 最終更新   ヘルプ   最終更新のRSS