正直日記



2008/12/19

_ HBI によるラスタスクロールを極める(1)
あんまり書かないのもアレなんで、現代ではもう廃れてしまった技術の解説でも
ちょろっとやってみようかしら。

えーと、最初に軽く前提を。

まず、題名にある HBI とは Horizontal Blank Interrupt のことで、日本語だと
「水平帰線期間割り込み」とか言うらしい。略すときは HBI の他に H-INT とか
HBL と記述されたりもする。

昔のゲーム機はグラフィックコントローラに搭載された VRAM が少なかったりし
て、画面描画用のレンダリングバッファが1ライン分しか無かったりする。それ
を逆手に取って、1ラインを描き終えたグラフィックコントローラが次のライン
を描画し始める前に画面データを書き換えてやることで、様々な効果を生み出す
ことが出来るようになる。

(特にスクロール値の書き換えで行われるエフェクトは、俗にラスタスクロール
と呼ばれていて、ドラクエの旅の扉・スト2の地面・スペースハリアーの地面・
マリオカートのコースなどはラスタスクロールで実現されている。そんなこと知っ
てるって? そうだと思ったよ!)

そして冒頭で出てきた HBI を使うと、グラフィックコントローラが1ライン描き
終わったタイミングで割り込みが発生して、特定の関数が呼び出されるというわ
けだ。

前提終わり。

--

とりあえず今日はスト2の、パースが付いた地面を再現してみる。
まずはこういう画像を用意した。



ちなみに、実際に画面に表示されるのはこの範囲になる。



それぞれのラインの横幅からスクロール比率を計算しておき、スクロールテーブ
ルに足してやるだけ。あとは HBI で呼び出された関数からライン毎のスクロー
ル値を順次流しこめば、手前ほど速く横スクロールするようになる。

簡単だし要らないと思うけど、一応コードも書いてみる。

/* 1024で1ドット相当の固定小数点数 */ const int scroll_delta[] = { 1036,1049,1063,1077,1091,1105,1118,1132,1146,1160,1174,1188,1201,1215,1229,1243, 1257,1271,1284,1298,1312,1326,1340,1354,1367,1381,1395,1409,1423,1437,1450,1464, 1478,1492,1506,1520,1533,1547,1561,1575,1589,1602,1616,1630,1644,1658,1672,1685, 1699,1713,1727,1741,1755,1768,1782,1796,1810,1824,1838,1851,1865,1879,1893,1907, 1921,1934,1948,1962,1976,2004, }; static int raster_table[256] = { 0 }; static int next_line = 0; void HBlankFunc(void) { REG_BG0_X = raster_table[next_line] / 1024; next_line++; return; } int main() { BG_init(); IRQ_RegistFunc(INT_HBLANK, HBlankFunc); for (;;) { VBLANK_Wait(); KeyCheck(); if (key & KEY_RIGHT) { for (int i = 0; i < 96; i++) raster_table[i] += 1024; for (int i = 96; i < 160; i++) raster_table[i] += scroll_delta[i - 96]; } else if (key & KEY_LEFT) { for (int i = 0; i < 96; i++) raster_table[i] -= 1024; for (int i = 96; i < 160; i++) raster_table[i] -= scroll_delta[i-96]; } REG_BG0_X = raster_table[0] / 1024; next_line = 1; } }
GBA エミュレータで動くデータも用意してみた。 raster_test_sf2.zip 同じ手法でダライアスが遺伝のコロニー背景とかも再現できるかと思う。手間の 割りに見栄えがするので、みんなも 20 年前にタイムスリップして使いまくりま しょう! 多分続く。

sato > あなた、staticもconstも使っていて偉い。10円やる。  (2008/12/22 12:28:15)
> まぁ const は当然でしょう。static はどうかなー。  (2008/12/22 23:10:51)

最新
2010 | 01 04
2009 | 01 02 03 04 05 06 07 09 10 11 12
2008 | 01 02 03 04 05 06 07 08 09 10 11 12
2007 | 02 03 04 05 06 07 08 10 11 12
2006 | 01 02 03 04 05 06 07 08 09 10 11 12
2005 | 01 02 03 04 05 06 07 08 09 10 11 12