Making「SBFZ」その4

Home PC-6001mkII Program etc

 このページでは、移植開始からの過程を書いています。

Making「SBFZ」 Top


2010/11/03〜08:BGMその2
 さてBGMの続きだ。

 BGMのデータを良く見ると、繰り返しだけではなく1回で終わる場合もあるようだ。これと、前回で足りなかった部分と合わせて以下のように4種類にステータスを増やす。
  • 00H:終了
  • 01H + ポインタ:ポインタ位置にonseiデータの位置を戻す
  • 02H:(初回設定用)チャンネルAと同じデータをチャンネルBにも置く
  • 03H:継続
 これらのステータスをBGMデータの後ろに置き、演奏時にステータスに応じた分岐をする。

 さて試しに1面のBGMを打ち込んで実行してみるか。...なぜか、そこかしこでPLAY文待ちと思われる一時停止が入る。そうならないように前回策を練ったつもりだったんだけどな。

 PLAY待ちが入るという事は、やはりPLAY文を頻繁に実行しているのだろう。という事で、PLAY文を鳴らすかどうかを判定する部分を重点的に見る。あれ、想定外の値が入っているぞ?

 少しして、ようやく原因がわかった。OR A, (nnnn)とやってたよ...。ZASMではなぜかエラーもなくアセンブルするものだから、全然気づかなかった。というわけで修正。

 話は前後するが、MZ版SBFZは10/25に動かした時点ではなぜか音が鳴っていなかった。その事をツイートした後にまた実行してみると、今度は音が鳴った。なぜ前は音が鳴らなかったのかが逆にわからなくなったが、ともかく原作のBGMを聞くことが出来た。

 資料にある楽譜よりも1オクターブ高い上、テンポもかなり速いようだ。その他、楽譜ではある休符の部分も音が鳴っているように聞こえる。この辺りは、またおいおい調整が必要だな。

2010/11/10〜13:色々実装
 さて、また見た目の作りこみをしよう。まずはボスから。

 ボスはダメージを受けると残り体力によって一部の色(1面ボスは口、2面ボスは目といった具合)が変化する。
 とりあえず3面ボスまでボスグラフィックと色変化部分を作成する。でもまだ微妙に色変化部分がおかしいなあ。この辺りはまた処理を見直すとするか。

 次に、ラウンドクリア処理を実装する。これでようやく1面から2面に進むことができる。

 さて次、ずっと先送りにしていたアニメ処理に移る。
 原作にある1面の滝アニメだが、mkIIではこのアニメを行うためのキャラクタがない。仕方がないので代替のキャラクタを探す。
 使えそうなのは、上下に二分する割合を変えたキャラクタ群ぐらいか。これを1段ずつ文字色と背景色を変えて描画するとそれらしくなるだろうか?よし実装!

画像

 まあ、こんなものか。原作と見比べない限りは特に違和感もなさげだ。

 次に自機の爆発処理に移る。自機爆発では、はじめに画面の反転処理を行う。色番号の順番がMZ-700と違うので不安ではあったが、反転させると結果的に同じ色になっているようだ。
 ただ、ワークにある背景の色を基準に色反転させているため、敵や敵弾の部分の色合いがおかしくなる。

画像

 ワーク画面でなく表示画面の色を読み込んで反転させれば良いのだろうが、ここで再三「0000H-7FFFHまでは読み込みと書き込みの場所が異なる」制限に引っかかる。さてどうしたものか?

2010/11/22:反転対策
 画面反転時の色の問題について対策を行う事にする。

 対策方法の一つは、にも少し書いた「読み込み先をVRAMに切り替える方法」がある。ただ、切り替えている間は当然ながらBASIC ROMが見れない。
 BGMは現状PLAY文の処理を流用しているので、
 PLAY文の処理を行う間はBASIC ROMが見えている必要がある。
 → PLAY文はタイマ割り込みでも処理が行われている。
 → タイマ割り込みの処理を行う間はBASIC ROMが見えている必要がある。
 → 対策として、読み込み先をVRAMに切り替えている間はタイマ割り込みを止める。
 → タイマ割り込みを止めている間はPLAY文の処理が進行しない。
 → PLAY文のテンポが(多少)不規則になる。
 となる(説明が長いな...)。ちょっとこちらの方法は避けたい。

 という事で、もう一つ考えていた対策方法を取ることにする。
 そもそも、VRAMが0000H〜7FFFHの間にあるからBASIC ROMと被って問題になるのだから、VRAMの位置を移動させちゃえ、という方法だ。

 幸いというか、mkIIのN60m-BASICモードでは0000H〜, 4000H〜, 8000H〜, C000H〜の4種類をVRAMとして使用できる。現状2画面を使用しているので、8000H〜, C000H〜 を使う処理に置き換えれば良い。一度完成した部分に手を加えるのは面倒だけど(^^;)。

画像

 というわけで、それなりに出来上がった。新たに使用するVRAMの分、メモリが圧迫されることになるけど、大丈夫かな?

2010/11/21〜26:ボスその3
 話は多少前後するが、3面以降のボスグラフィックを追加する。ああ、バックスラッシュがあれば5面ボスはもう少し良くなるのにな...。

 続いて、ボス攻撃の弾の調整。4面ボスは半透明にして...ってよくよく見ると半透明じゃないぞ?メッシュのうち1色は水色で、もう1色は紫と背景の色とをOR演算しているようだ。
 うむむどうしよう。処理は書くとして、弾のデータ形式をどうするかだな。今の所、色部分のデータは以下のように全てのビットを使用している。
  • bit 0〜3:文字色(全bitが0の場合は透明)
  • bit 4〜6:背景色(全bitが0の場合は透明)
  • bit 7:キャラクタ/セミグラ切り替え用
 ただ、今回は16色中8色(+透明)を使用しているため、透明以外はbit3が常に1になっている。透明以外でここが0の時はOR演算の処理を行う事にするか。

画像

 まあこんな感じか。続けて色変化処理に移る。4面までは良かったのだが、5面で問題が出た。文字色と背景色の両方が黒のパターンがある!
 前にも少し書いたが、今のキャラクタ描画処理ではキャラクタの背景色に黒は出せない。

 キャラクタ描画処理の変更も考えたが、遅くなりそうで気が進まない。
 悩んだ末、今回は力技で解決することにした。文字色/背景色の両方が黒の部分のみ、黒色のベタキャラにし、次(黒/透明)ではキャラクタも元に戻す。ボス処理は道中に比べて若干余裕があるので、速度も何とかなるだろう。

 さて、各面のアニメ処理もいい加減作成しないとな...。4面が大きく変えざるを得ないので、気が進まない。

2010/12/04〜08:アニメ
 各面のアニメーション処理を進める。前回完成したと思っていた1面アニメは、雲の移動が足りなかったので追加する。2面と3面も雲の移動のみなので割とあっさりと実装する。

 さて、またもや最難関の4面だ。全面中アニメの面積がもっとも多い上、mkIIにないキャラクタばかり使っているときたものだ。
 MZ版とそっくり同じにはもはや出来ないので、1面アニメで行った滝の処理をベースにアニメを組み立てていく。一箇所だけ全く違うアニメにしてみるか?

画像

 アニメ自身が重いので、流石にキャラクタ数が最大数出ると少し遅くなるな...ちょっとだけ速度改善してみるか。と思ってやり始めたものの、目に見えるほどは速度改善しなかった。まあいいや、5面アニメを先に仕上げよう。

 5面アニメはタイトル画面の応用なのでこれも簡単、と思いきや、色配置の関係で2ボスの脇(?)の部分がピカピカ光る。

画像

 そのままにしようかとも思ったが、とりあえず2ボス出現時のみアニメをOFFにする。

 続いて、ネストの一部を解消する。今の状態では、ROUND 1〜4とROUND 5でネストの深さが2つ分違うので、途中でゲームオーバーになった場合にネスト具合がどうなるのかよくわからなくなってくる。
 面初期時のルーチンから5面メインルーチンにジャンプしているのを、ルーチンを抜けてから判定でジャンプするよう変更。これでネストが1つ消えた。次に、ボスラッシュ時のボス番号退避をPUSH, POPからワークへの記録に変更。これでもう1つのネストも消えた。これで少しすっきりした。

 ついでに、エンディングも作成する。最後の住所が書いている部分を削ってゴニョゴニョっと。まだ時々描画画面を間違えている部分もあるが、概ねこんな所だろう。

2010/12/11〜18:BGMその3
 マシン語ソースをMZエミュの出力を参考に、BGMのデータを作成することにする。

 MZエミュで鳴っている1面BGMだが、何か違和感がある。休符の部分が詰められているような感じで鳴るので、4小節よりも短い周期になっている。
 SPACE BLUSTER FZ 資料のPDFにある楽譜の通りに直そうかとも思ったが、なるべく実際の環境に近づけたいのでMZエミュの出力を信用することにする。

 となると困った。これまでBGM出力の区切り単位は固定の長さにしていたのだが、やはり可変にすべきか?
 という事で、「チャンネルAデータ+ステータス」としていたものを「"チャンネルA","チャンネルB"+ステータス」にに変更し、プログラム部分を修正する。

 いざ実行してみると、なぜかポインタ戻しのステータスの場合のみ「?OM Error」が出る。
 PLAY文実行時(CALL 1EB3H実行時)にエラーとなるようだが、この部分ではステータスに限らず同じ処理をしているはずなのに...。
 出力するPLAY文のデータを注意深く見ても特に問題はない。
 ステータスの値を、CALL 1EB3H実行前に一時的に変えてもダメ。
 なのにデータの段階でステータスのみ変えると問題なく音が鳴る。
なんなんだこれは?

 2時間ほど散々試して、ようやく法則が見えてきた。理屈はともかく、CALL 1EB3H実行前にZフラグが立っているとエラーになるようだ。

 エラーが起きてなかった頃のマシン語ソースを読み直すと、色々と分岐はしているが、全ての 分岐でCALL 1EB3H実行時はZフラグが立っていなかった。
というわけで、暫定的にOR 0FFHを追加して様子を見る事にする。


その3 Making「SBFZ」 その5