元ネタがアレであることを思えばこうなって至極当然ではあるのだけれども、同時に、少なからず驚きを以て迎えられると確信しているデモ動画を撮った。多重スクロールする画面が主人公のジャンプ挙動に合わせて縦にも動く、という、MSXのみならず、同世代のレトロPC向けゲームとしては極めて珍しい実装を試みてみた。それがわかる人には縦方向の動きが印象的に過ぎて、どこかで聴いたようだが混ぜるな危険なBGMや遅れて右から出てくる主人公よりさらにデカい僧兵風のオッサン......我ながら白々しい物言いだ......が返ってインパクト失ってるかも。言うか、今になって自分で気づいたのだが、どうもボクはこういうの......画面全体がダイナミックに動くが、実は技術的には大したコトはやっていなくて、でも一見してそれがわからない......をするのが好きなのだ。OUTERSPACEの視点移動、全部同じ発想である。逆に言えば、固定画面(スクロールの有無は直接は関係がない)でチマチマと小さなキャラクタが動くのは、まぁ自分でもそういうのを少なからず作っておいてアレゲだが、好みではない。そんなことはどうでもいい。ボクは嬉しがりなので、コレをどうやって実現しているか、について書き遺すのである、と言うか書きたいのである、と言うかこういうのを書きたくて技術的にはくだらないが際限なく面倒臭いことをやっているのである。閑話休題(まぁそんなことはどうでもいい、の別の言い)。上掲動画を見て何が起こっているのか、一発でわかった人は以降は読むに及ばない。わからなくても、「画面が縦にも動いている」という先入観をちょっと脇へ置いて、よくよく冷静に今一度動画を見てみると、ダイナミックに全体が動いているようではあるが、実は主人公のジャンプに合わせて前景と敵キャラクタがたかだか6ピクセル動いているだけだ、ということに気がつけば、何をやっているかは想像がつくだろう。MULTICOLORモードのネームテーブルに一工夫加えることで、画像データを比較的リニアに扱えるようにして実装されている。この結果何が起こるかというと、まず前提として、一般的にコンピュータの画面とビデオメモリ上のデータの対応関係は、横方向にリニアである。左端上とメモリアドレス先頭が対応し、右へ進むにつれてアドレスも増えて、右端に達すると一段下がった左端につながる、まぁ、そのような対応関係である。対して本作では、左上とメモリアドレス先頭が対応するところまでは同じだが、アドレスが1つ進むと対応する画面は1ピクセル下に進む。このとき、1つのメモリアドレスのデータ(1バイト)に対応するのは横に並んだ2つのピクセル、である。これが下へと続いていって、画面下に達すると、2ピクセル右へ進んで上端へ戻る。このような構造なので、前景(主人公や敵キャラクタよりも手前に表示されている、上掲動画で言えば橋の欄干部分)はどういうデータになっているかというと、縦方向に短冊のようになったものが16コで一組になっている。画面解像度は横方向64ピクセルなので本当は32コあるべきだが、見てわかるように同じ図柄を2回繰り返して表示しているので、データは半分の16コになる。このデータがまったく無圧縮であればデータ量は縦1行48バイト×16コの768バイトになる。前景は前景であるがゆえに面積の半分以上は透明、つまりなにもない部分なのであり、これを真正直にデータとして持つのはあまりにもったいないので、連続する透明部分は「透明部分がnピクセル続く」を意味する2バイトのデータに置き換えられている。これで、透明部分の比率にもよるが本来768バイト必要な前景データは1/5〜1/4くらいになる。その代わり、この短冊一本々々の先頭アドレスは、全体が不定長になることから、データを解釈しない限りは事前に予測できない。平たく言えば、全体の先頭アドレス+縦1行48バイト×横列、の計算で求めることができない、ということである。従って、別途インデックスを用意しておくことになる。Z80のアドレスは常に16ビットの範囲に収まるので、アドレス長は2バイトで固定である。従って、全体の先頭アドレス+アドレス長2バイト×横列=インデックスのアドレス、という計算が成り立つ。ここに、各列の圧縮済みデータの先頭アドレスを記録しておけば、前景表示用のサブルーチンは、ステージに対応する前景データの先頭アドレスさえ受け取れば、すべてのデータにアクセスできるようになる。このサブルーチンは、横2ピクセル毎に32回、全体の先頭アドレス+アドレス長2バイト×横列の計算で得たインデックスアドレスから順にデータを解釈し、スクリーンバッファ上に前景を書いたり透明部分を飛ばしたりする処理を48ピクセル分おこなうことになる。ここで漸く話が本題に戻るのだが、この文脈に「主人公のジャンプに合わせて前景がたかだか6ピクセル動いているだけ」を当てはめるとどうなるか。前景が縦方向に1ピクセル動くというのは、要するに各横列に対応するインデックスアドレスに対して、1つ増やせば読み出し開始位置が1つ進むから図柄は上に1ピクセル動くことになり、逆に減らせばその分だけ上に動くことになる。つきつめればたったこれだけの話なのだ。実際のデータ構造は上に例示したようになる。向かって右側、データ構造の上部にピンク色のセルが各列6つずつあるが、これが縦方向6ピクセルの動きと対応する。主人公のジャンプ高に応じ、たとえば、地面をあるいているときは赤い線で示した“本来の”先頭から読み出しが開始される。高くへジャンプしているときはピンク色の一番上のセルのデータから読み出しが開始され、結果6ピクセル図柄は下方向へ動いて表示される。これが上掲動画の縦方向の動きの正体である。このステージ(これが何処なのか、言わなくてもわかるよね?っつーかわかってくれ)は上空方向が開放なのでピンク色のセルはすべて000h=透明で埋まっているが、ここに何か具体的な図柄データを入れれば、たとえば、ジャンプすれば梁や屋根が見える、といった演出も可能になる。言うまでもないと思うが、ピンク色の部分で000hが連続しているのにここに圧縮をおこなっていないのは、単純にこの方が計算が楽であり、すると処理ロジックが短くなって結果として全体の速度に寄与するからである。そのためならば6ピクセル・バイト×16列=96バイトの無駄など......無駄など......あぁ、もったいない。それもともかくとして。前稿で「Excel上で見るのとMSX上で見るのは雰囲気が大きくことなるので、一旦ROMイメージに収蔵して動かしてみてからデザインを微修正することが頻繁に起こり、圧縮の都合上大抵の場合それは当該パターンの全データ入れ替えになるから、これまた死ぬほど面倒臭い」と書いたが、何ステージがデータを準備している間にだんだん慣れてきて、ソースコード上のダンプを直接触って修正できるようになってしまい、今更ながらちょっと自分の無駄な器用さに憂鬱になっている。投稿者メールコメントURL画像内の文字列(認証コード)を入力してください。認証コードを正しく入力するとコメントが反映されます。※大文字/小文字の区別はありません。コメントは新しいものから表示されます。コメント本文中とURL欄にURLを記入すると、自動的にリンクされます。“AutoPage”AutoPage最新お知らせ。