#author("2023-04-22T18:40:36+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色に戻しておくといいと思います。~ 次にフレームバッファについてですが、まあコード読んだ方がわかりやすいので~ ソースコードを見ていきましょう。~ ** モード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(MODE_4 | BG2_ENABLE | BACKBUFFER); をよく見てみると、BACKBUFFERなるものがあります。~ この指定はフレームバッファが2つあるうち、2を指定するものです。~ 1,2と、GBAの画面を切り替えるというわけですね。~ ためしにエミュレータのTools -> IO viewerでウィンドウを開き、~ 0x4000000-DISPCNT の 4bit目(Display Frame)のチェックを外し、~ Applyボタンを押してからウィンドウを閉じてみてください。~ 画面が変わっていることがわかると思います。~ ***動作画面 [#m958e69b] モード4で、240x160の画像の表示(フレーム2と1) #ref(clip_3.png,nolink) #ref(clip_4.png,nolink) ** 履歴 [#p6ae87c6] - 2014/12/21