約一年ぶりの更新ですが、前置きもなく、ささっと行きます。。。
続いては、イース2のオープニングを象徴するかのような、リリアの振り向きのシーンです。
…といっても、インパクトのわりには全然たいしたことはやっておらず、1コマずつキャプチャーしたMSX2版の元絵をP6版に描きなおして、あとは単純にアニメーションさせているだけです。
枠の内側を描きかえています。速度的には大丈夫。
ベースの絵も入れると6コマです。
本物より少ないですが、まあ、十分かなあと。
こんな感じになりました。
次のアドル発見シーンは、特に何もしていないので省略。
そして、いよいよ天空へのスクロールシーンです。
たぶん、皆さんが興味があるのはここかなーと思ってはいたのですが、ブログでここにたどり着くまでに4年もかかってしまいました。。。すみません(^_^;)
これが全景です。
192(P6的には96)x1920ピクセルです。
まず、MSX2版の画像をキャプチャーして一枚の絵に繋げ、横の解像度を半分に落とし、セル分割して、いったい何パターンのセルで描かれているか調べてみました。
すると、なんとこれだけの大きなグラフィックにも関わらず、256パターンで収まったのです。つまり、1セルを1バイトで表すことができると。これには驚きました。
おそらく、MSX2版はそのような仕様で作られたのだと思いますが、ファルコムのデザイナーさんが、本当に素晴らしい仕事をされています。
さて。
1セル1バイトで表せるといっても、グラフィック全体では、パターンネームデータだけで横24×縦240=5760バイトも必要になります。さらに、各セルのグラフィックデータが1パターンあたり8バイト。256パターン弱で約2KB。
つまり、このシーンを再生するだけで、合計7KB以上のデータが必要になるのです。
この時点ですでにメモリはギリギリで、とても7KBものデータを入れる余裕はなく、「すべてのシーンをオンメモリで実装する」ということは、泣く泣く諦めざるをえませんでした。
その後、他のシーンなども圧縮することで、キャラクターのグラフィックデータはなんとかメモリに置けそうにはなったのですが、5KBのパターンネームデータを置くには、どう頑張ってもメモリが足りません。
かといって、ここで5KB分のデータをロードするとなると、数分間のロード待ちが発生し、明らかにテンポが損なわれてしまいます。
そこで、いかにロード時間を短くするか、いかに絵を止めないようにするかを、必死に考えてみました。
まず最初に考えたのは、分割ロードです。
例えば、
「1画面分スクロールするごとにロードする」
であれば、一度にロードするデータ量も少なくてすみますし、そこまでテンポが悪くなることもないだろう、と思いました。
しかし、実際はBIOSを使ってロードする場合、
「無音(3.4秒)+ヘッダマークのピー音(3.4秒)」
の、合計6.8秒の前置きが入ります。
この後に実データをロードするわけで、一画面ごとに7〜8秒のロード待ちが発生することになり…
全然ダメでした(T_T)
中途半端なところで画面が停止するのは思いっきり気になりますし、ロードの回数も多く、とにかくテンポが悪くなりすぎます。完全に制御をとめて、全部ロードしてからスクロールするほうがまだマシなくらいです。
なんとか前置きの6.8秒を短くできないだろうか。
空送りやヘッダマークの時間を極限まで短くしたら、ピーガガ、ピーガガ、ピーガガと連続して読めないだろうか。
そんなことを考えていたときに思いついたのが、
ストリーミング
でした。
考えたのは以下のような方法です。
1)メインルーチンでは、テープからデータをロードして、ひたすらRAMに書き込んでいく。
2)その裏で割り込みルーチンを走らせ、データを一定バイト読み込むごとに、画面を描き換える。
3)画面描き換えはすぐに終わらないので、メインルーチンを止めてしまうが、その間もテープは回り続けるので、データを取りこぼすことが予想される。
4)そこで、テープには予め描画処理時間分のダミーデータを挟んでおき、必要なデータは取りこぼさないようにする。
取りこぼすデータのバイト数を試行錯誤のうえ12〜13バイトと割り出し、ダミーデータは余裕を持たせて15バイトとしました。
実際にテープにセーブされているデータは、以下のようになっています。
「0E C1 D1 C7 C6 … 85 0E」と、描画エリアの横幅分(24バイト)のパターンネームデータが並んだ後に、ダミーデータの「FF」が15バイト並んでいます。
メインルーチンでは、テープを回しながら、ロードしたデータをRAMに書いていきます。ただし、データがダミーデータの「FF」だった場合はRAMには書かずに「FF」以外のデータが来るまで待ちます。つまり、24バイトロード→15バイト捨てる→24バイトロード→15バイト捨てる…を繰り返します。
割り込みルーチンは、逆に「FF」“以外”のデータのときは何もしないのですが、「FF」が来ると、メインルーチンで新規にロードした24バイトを最上段に加えて、画面を下側にスクロールさせます。この描画の間メインルーチンは止まりますが、テープは動いているので、12〜13バイト分、データを読みこぼします。
割り込みルーチンの描画が終わると、メインルーチンが動き、再びデータを読み始めますが、テープからはまだ残り数バイトあるダミーデータ「FF」が送られてきているので、そのまま必要なデータが送られてくるのを待ちます。
実際にはもう少しチューニングした流れになっていますが、これを繰り返すようにして実装してみたところ…
うまくいきました!!(ただし、エミュレーター上では)
テープが回ったまま、画面がスクロールしています!
テンポも損なっていませんし、完璧に近い流れです!
スクロールして画面内にイースの国が見えたときは、自分でも感動しました!
これで万事解決!
…とはいかず(T_T)
エミュレーターではうまく動作するのですが、実機ではどうしてもうまくいかないのです。
テープからのロードの裏でストリーム関連の割り込み処理をしつつ、さらにBGM再生も加わったせいで(「TO MAKE THE END OF BATTLE」の演奏は、処理的にもかなりいっぱいいっぱいなのです)、CPUが普通にテープからのデータをとりこぼすようになってしまったのです。
P6オフの参加者の皆さんに協力していただいた結果、
データの区切りであるストップビットを増やす
(つまり、ピーガー音に細工をしたWAVファイルを、PCで作成する)
という、当時では不可能な解決法を教えていただき、WAVファイルまで作ってくださいました。
※実機での動作検証をしていただいたときの流れはこちら
※jotさん作・感動の実機版動画はこちら
このように、私だけでなく皆さんの協力のおかげもあって、やっと実機でも動作するようになったのでした。
めでたしめでたし(^_^)
※ちなみに後日、「ストップビットを増やしたWAVファイル」を作成するツールを自作しました。
P6イース2オープニングの作り方一覧