C言語でスーファミ用のソフト開発(3)BGの表示

前回の続きです。

C言語でスーファミ用のソフト開発(2)Hello World - takuya matsubara blog

 

前回はhello_worldを改造して、オリジナルのフォントで表示しましたが、色を3色しか使っていません(透明色・白色・灰色)。せっかく16色のBG画面なのに、もったいないです。

 

そこで、16色のBG1を使わず、4色のBG3にテキストを表示することにします。

BG3を他よりも手前に表示するには、次のようにコードを書き換えます。

setMode(BG_MODE1, 0);

 ↓

setMode(BG_MODE1, BG3_MODE1_PRIORITY_HIGH);

 

makefile内の画像変換も16色→4色に変えます。

$(GFXCONV) -s 8 -o 16 -u 16 -p -e 0 -t bmp -i $<

$(GFXCONV) -s 8 -o 4 -u 4 -p -e 0 -t bmp -i $<

使い方については、ここに書いてあります。

https://github.com/alekmaul/pvsneslib/blob/master/tools/gfx4snes/readme.md

 

関数のBG番号を全部書き換えて、表示してみた結果がこちら。

パレットがおかしいです。

setPaletteColor関数を使って8,9,10番目のカラーを変更すると、うまく表示されましたが、バグなのか仕様なのかわかりません。console系関数は16色専用で、4色は非対応な気がします。

そこで、console系関数を使わず、直接VRAMに書き込むことにしました。

// BG3に文字表示
void bg3print(u8 x, u8 y, u8 *ptr)
{
    u16 vramaddr;
    u16 length=0;
    u8 *dst;
    dst = (u8 *)vramwork;
    // タイルマップに変換
    while(*ptr != 0){
        *dst++ = *ptr++ - 0x20;
        *dst++ = (1 << 5)+(PAL_TXT << 2);
           // priority bit + palette
        length += 2;
    }
    vramaddr = VRAM_TXTMAP+(32*y)+x;
    dmaCopyVram(vramwork, vramaddr, length);
}

たったこれだけのコードで済みます。一旦、タイル番号とパレットと反転情報をワークに格納して、それからdmaCopyVram関数でタイルマップに書き込んでいます。dmaCopyVramはVブランク中にDMA転送をやってくれるという便利な関数です。タイルマップの書き換えだけじゃなくて、パターンの書き換えにも使えます。

以上で、BG1が空いたので、何か表示してみます。

 

BG1に表示したい画像を用意します。

お絵描きソフトを使い、この画像を256×224ピクセルに縮小して、さらに16色に減色。16色のbmpファイルで保存します。

ファイル名を「resource_bg.bmp」とした場合、makefileの書式はこうなります。

resource_bg.pic: resource_bg.bmp
$(GFXCONV) -s 8 -o 16 -u 16 -e 1 -p -m -t bmp -i $<

この時点でパレット番号を決定している必要があります。この画像はパレット1に割り振ります。重複しないように、フォントはパレット0を使うことにします。

画像を変換すると、拡張子が「pic」「pal」「map」のファイルが生成されます。picがパターン、palがパレット、mapがタイルマップのバイナリファイルです。これらのバイナリデータをC言語ではグローバルな配列変数として扱います。詳しくは公式のWikiを参照してください。

https://github.com/alekmaul/pvsneslib/wiki/Backgrounds

 

画像の複雑さによって、パターンのサイズが変わってしまいます。そのまま変換すると、サイズが28KBになってしまいました。1枚だけなら表示可能ですが、複数枚を同時に表示したいので、もっと容量を節約することにします。

画像をアニメ調に塗りつぶすのが良い解決方法ですが、面倒なので、ここでは縮小するだけで済ませました。結果、7KBに落ちました。

 

まだVRAMに余裕があるので、BG2の画像も作ります。これも7KBくらいでした。こちらはパレット2を使うことにしました。

 

各データをVRAMに割り振ってみました。将来、スプライトを表示することを考えて、0x0000番地あたりを空けてあります。

 

出来上がったデモプログラムです。BG1とBG2がスクロールして、その上にBG3(テキスト)が表示されます。さすが、スーファミ。色彩が豊かです。

作ったコードはこちらです。

github.com

 

続き

nicotakuya.hatenablog.com