#author("2023-05-24T19:09:38+09:00","","")
#author("2023-05-25T18:31:14+09:00","","")
* タイルモード2 [#mef3ef53]
前回のmode0を簡単にまとめてみました。合わせてmode1、mode2も載せておきます。色々モードの紹介していきましたが、個人開発で使うのはmode0か3が主流です。あとはほとんど使っていないように思います。他は参考程度に見てください。

*** mode0 [#t450ef33]
| サイズ           | 256*256~512*512                |
| 画面数           | 4 (BG0-3)                       |
| 色/パレット     | 16色*16パレット/256色*1パレット |
| キャラクタ定義数 | 1024                            |
| 伸縮回転         | 不可能                          |

*** mode1 [#t5bcbf48]
mode1には、伸縮回転可能なBG、不可能なBGの2種類があります。~

| サイズ           | 256x256~512x512                 | 128x128~1024x1024 |
| 画面数           | 2(BG0-1)                         | 1(BG2)             |
| 色/パレット      | 16色/16パレットor256色/1パレット | 256色/1パレット    |
| キャラクタ定義数 | 1024                             | 256                |
| 伸縮回転         | 不可能                           | 可能               |

*** mode2 [#g85b73fc]
| サイズ           | 128x128~1024x1024 |
| 画面数           | 2(BG2-3)           |
| 色/パレット     | 256色*1パレット    |
| キャラクタ定義数 | 256                |
| 伸縮回転         | 可能               |

GBATEKは次のように書かれています。こちらの方がわかりやすいかもしれません。
 
 The table summarizes the facilities of the separate BG modes (video modes).
 
   Mode  Rot/Scal Layers Size               Tiles Colors       Features
   0     No       0123   256x256..512x515   1024  16/16..256/1 SFMABP
   1     Mixed    012-   (BG0,BG1 as above Mode 0, BG2 as below Mode 2)
   2     Yes      --23   128x128..1024x1024 256   256/1        S-MABP
   3     Yes      --2-   240x160            1     32768        --MABP
   4     Yes      --2-   240x160            2     256/1        --MABP
   5     Yes      --2-   160x128            2     32768        --MABP

** モード0でBG0、BG1 [#d6db3825]
再度モード0にて、2つの絵をレイヤー表示してみます。まずメモリ領域(VRAM)に入るか確認をしながらやってみましょう。

- bg0kusa.png
#ref(bg0kusa.png,nolink)
- bg1kumo.png
#ref(bg1kumo.png,nolink)

画像のサイズは(240ではなく)256x160の16色です。タイルは32x20 = 640個。640個 * 32バイト(1タイル分のバイト数) = 20480バイト(0x5000)。全く同じ重複タイルも構わず使用します。マップは256x256ドットサイズを使うので32 * 32 * 2 = 2048バイト(0x800)となります。それでは対応表にうまく収まるよう、領域を確保してみます。
画像のサイズは(240ではなく)256x160の16色です。タイルは32x20 = 640個。640個 * 32バイト(1タイル分のバイト数) = 20480バイト(0x5000)。同じ重複タイルも構わず使用します。マップは256x256ドットサイズを使うので32 * 32 * 2 = 2048バイト(0x800)となります。それでは対応表にうまく収まるよう、領域を確保してみます。

- 対応表
| アドレス  | マップ | キャラクタ | 確保      |
| 0x6000000 | 0      | 0          | bg0(kusa) |
| 0x6000800 | 1      | 0          | bg0(kusa) |
| 0x6001000 | 2      | 0          | bg0(kusa) |
| 0x6001800 | 3      | 0          | bg0(kusa) |
| 0x6002000 | 4      | 0          | bg0(kusa) |
| 0x6002800 | 5      | 0          | bg0(kusa) |
| 0x6003000 | 6      | 0          | bg0(kusa) |
| 0x6003800 | 7      | 0          | bg0(kusa) |
| 0x6004000 | 8      | 1          | bg0(kusa) |
| 0x6004800 | 9      | 1          | bg0(kusa) |
| 0x6005000 | 10     | 1          |           |
| 0x6005800 | 11     | 1          | bg0 map   |
| 0x6006000 | 12     | 1          | bg1 map   |
| 0x6006800 | 13     | 1          |           |
| 0x6007000 | 14     | 1          |           |
| 0x6007800 | 15     | 1          |           |
| 0x6008000 | 16     | 2          | bg1(kumo) |
| 0x6008800 | 17     | 2          | bg1(kumo) |
| 0x6009000 | 18     | 2          | bg1(kumo) |
| 0x6009800 | 19     | 2          | bg1(kumo) |
| 0x600A000 | 20     | 2          | bg1(kumo) |
| 0x600A800 | 21     | 2          | bg1(kumo) |
| 0x600B000 | 22     | 2          | bg1(kumo) |
| 0x600B800 | 23     | 2          | bg1(kumo) |
| 0x600C000 | 24     | 3          | bg1(kumo) |
| 0x600C800 | 25     | 3          | bg1(kumo) |
| 0x600D000 | 26     | 3          |           |
| 0x600D800 | 27     | 3          |           |
| 0x600E000 | 28     | 3          |           |
| 0x600E800 | 29     | 3          |           |
| 0x600F000 | 30     | 3          |           |
| 0x600F800 | 31     | 3          |           |

うまく収まりましたね。レイヤー表示は上層がbg0、下層はbg3です。逆にすると当然、kusaタイルは表示されません。

** サンプルコード [#yfa302ad]
 #include "lib/gba.h"
 #include "res.h"
 
 #define BG_MAX_CNT 4
 
 typedef struct {
 	u32  mapBase;
 	u16* mapBaseAdr;
 	u32  tileBase;
 	u16* tileBaseAdr;
 } ST_BG;
 
 //---------------------------------------------------------------------------
 ST_BG Bg[BG_MAX_CNT];
 
 //---------------------------------------------------------------------------
 void WaitForVsync(void)
 {
 	while(*(vu16*)0x4000006 >= 160) {};
 	while(*(vu16*)0x4000006 <  160) {};
 }
 //---------------------------------------------------------------------------
 void BgInitMem(void)
 {
 	const u32 mapBase[]  = { 11, 12,  0,  0 };
 	const u32 tileBase[] = {  0,  2,  0,  0 };
 	vs32 i;
 
 	for(i=0; i<BG_MAX_CNT; i++)
 	{
 		Bg[i].mapBase     = MAP_BASE(mapBase[i]);
 		Bg[i].mapBaseAdr  = MAP_BASE_ADR(mapBase[i]);
 		Bg[i].tileBase    = TILE_BASE(tileBase[i]);
 		Bg[i].tileBaseAdr = TILE_BASE_ADR(tileBase[i]);
 	}
 
 	for(i=0; i<32*32; i++)
 	{
 		Bg[0].mapBaseAdr[i] = 0;
 		Bg[1].mapBaseAdr[i] = 0;
 		Bg[2].mapBaseAdr[i] = 0;
 		Bg[3].mapBaseAdr[i] = 0;
 	}
 
 	for(i=0; i<0x2000; i++)
 	{
 		Bg[0].tileBaseAdr[i] = 0;
 		Bg[1].tileBaseAdr[i] = 0;
 		Bg[2].tileBaseAdr[i] = 0;
 		Bg[3].tileBaseAdr[i] = 0;
 	}
 }
 //---------------------------------------------------------------------------
 void BgInit(void)
 {
 	BgInitMem();
 
 	REG_DISPCNT = (MODE_0 | BG0_ON | BG1_ON);
 
 	REG_BG0CNT = (BG_SIZE_0 | BG_16_COLOR | Bg[0].tileBase | Bg[0].mapBase);
 	REG_BG1CNT = (BG_SIZE_0 | BG_16_COLOR | Bg[1].tileBase | Bg[1].mapBase);
 }
 //---------------------------------------------------------------------------
 void BgSetTile(u32 bg, u16* pDat, u32 size)
 {
 	vu32 i;
 
 	for(i=0; i<size; i++)
 	{
 		Bg[bg].tileBaseAdr[i] = pDat[i];
 	}
 }
 //---------------------------------------------------------------------------
 void BgSetPal(u32 pal, u16* pDat)
 {
 	vu32 i;
 
 	for(i=0; i<16; i++)
 	{
 		BG_PALETTE[pal*16+i] |= pDat[i];
 	}
 }
 //---------------------------------------------------------------------------
 void BgSetMap(void)
 {
 	vu32 i;
 
 	for(i=0; i<32*20; i++)
 	{
 		Bg[0].mapBaseAdr[i] = i;
 		Bg[1].mapBaseAdr[i] = i | (1 << 12);	// バレット番号1を選択
 	}
 }
 //---------------------------------------------------------------------------
 int main(void)
 {
 	BgInit();
 
 	BgSetTile(0, (u16*)&bg0kusaTiles, bg0kusaTilesLen/2);
 	BgSetTile(1, (u16*)&bg1kumoTiles, bg1kumoTilesLen/2);
 
 	BgSetPal(0, (u16*)&bg0kusaPal);
 	BgSetPal(1, (u16*)&bg1kumoPal);
 
 	BgSetMap();
 
 	for(;;)
 	{
 		WaitForVsync();
 	}
 }

*** 動作画面 [#wf86950d]
#ref(1.png,nolink)

** 履歴 [#k82dbea7]
- 2023/04/26
- 2014/12/27

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