- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2023-04-22T18:40:36+09:00","","")
#author("2023-04-22T19:13:38+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個のことです。~
色データは0x5000000から2バイトづつ、256個格納することができます。パレット番号とは256個のことです。さて、240*160ドットの画像データをmode3では76800(240*160*2)バイト必要だったのに対して、mode4は38400+512(240*160*1 + 256*2)と約半分にすることができました。当然、色の表現が乏しくなるのは避けられません。見栄えをよくするためには予め高性能な減色ツールを使って256色に戻しておくといいと思います。各パレット番号の色データはmode3と同じフォーマットです。~
さて、240*160ドットの画像データをmode3では76800(240*160*2)バイト必要だったのに対して、~
mode4は38400+512(240*160*1 + 256*2)と約半分にすることができました。~
当然、色の表現が乏しくなるのは避けられません。~
- 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
見栄えをよくするためには予め高性能な減色ツールを使って~
256色に戻しておくといいと思います。~
次にフレームバッファについてですが、まあコード読んだ方がわかりやすいのでソースコードを見ていきましょう。なお画像ファイルの読み込み方法がわからない方は[[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からの領域に格納しています。~
さらに~
画像ファイルを2つ読み込み、それぞれを0x6000000からの領域と、0x600A000からの領域に格納しています。SetMode()には特殊なフラグを設けています。~
SetMode(MODE_4 | BG2_ENABLE | BACKBUFFER);
をよく見てみると、BACKBUFFERなるものがあります。~
この指定はフレームバッファが2つあるうち、2を指定するものです。~
1,2と、GBAの画面を切り替えるというわけですね。~
よく見てみるとBACKBUFFERなるものがあります。この指定はフレームバッファが2つあるうち、2を指定するものです。1,2と、GBAの画面を切り替えるというわけです。~
ためしにエミュレータのTools -> IO viewerでウィンドウを開き、0x4000000-DISPCNT の 4bit目(Display Frame)のチェックを外し、Applyボタンを押してからウィンドウを閉じてみてください。画面が変化している思います。~
#ref(2.png,nolink)
ためしにエミュレータのTools -> IO viewerでウィンドウを開き、~
0x4000000-DISPCNT の 4bit目(Display Frame)のチェックを外し、~
Applyボタンを押してからウィンドウを閉じてみてください。~
画面が変わっていることがわかると思います。~
***動作画面 [#m958e69b]
モード4で、240x160の画像の表示(フレーム2と1)
#ref(clip_3.png,nolink)
#ref(clip_4.png,nolink)
-[[github:https://github.com/akkera102/gbadev-ja/tree/main/tut04%20%E3%83%93%E3%83%83%E3%83%88%E3%83%9E%E3%83%83%E3%83%97%E3%83%A2%E3%83%BC%E3%83%893]]
#ref(3.png,nolink)
** 履歴 [#p6ae87c6]
- 2023/04/22
- 2014/12/21