- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2023-05-14T21:44:20+09:00;2023-04-26T19:16:56+09:00","","")
#freeze
#author("2023-05-25T18:31:14+09:00","","")
* タイルモード2 [#mef3ef53]
前回のmode0を簡単にまとめてみました。合わせてmode1、mode2も載せておきます。色々モードの紹介していきましたが、個人開発で使うのはmode0か3が主流です。あとはほとんど使っていないように思います。他は参考程度に見てください。~
前回の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 [#q9da4ef3]
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)に入るか確認をしながらやってみましょう。~
再度モード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タイルは表示されません。~
うまく収まりましたね。レイヤー表示は上層が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