Making「ASALT」その3

Home PC-6001mkII Program etc

 このページでは、クリア処理以降の実装過程を書いています。

Making「ASALT」 Top


2009/04/11〜05/0x:クリア判定
 ここまで作った以上、避けられないであろうクリア処理。とりあえず実装方法を考える。

 まずクリア判定を決めよう。オリジナルでは砲台を倒したときにクリアになるのでこの辺り、薄紫色の部分にクリア判定を入れよう。面の途中にもクリア判定の色と同色が使われていたので、クリア判定用の色を、同じ色合いに見える別の色にする。

 とりあえずここまでで確認。クリア用の処理は当然まだ作っていないので、ジャンプの処理と同じになってしまうが、うまく判定できているようだ。

 さてここからが面倒だ。「ASSAULT」のクリア処理はかなり手間が掛かっている。大まかにクリア処理を列挙しただけでもこれだけの処理を行っている。
  1. ゴールへのルートに方向転換
  2. ゴールへのルートまで直進
  3. ゴールに方向転換
  4. リフターの準備位置まで直進
  5. リフターにつかまれる
  6. リフターにつかまれたままゴールに直進
  7. リフターに上まで持ち上げられる
  8. リフターを切り離し、ゴールに落ちていく
 ...面倒くさいと言った方が正確な心情か。ここからなんとなく後回しになったまま、また放って置かれた。

 そして5月。今年もP6オフをするとの連絡がHashiさんの掲示板であった。どう書こうかと迷ったが、「半分位作っているネタがある」と書き込む。

 さあこれで後へは引けなくなった。

2009/05/11:クリア処理その1
 ASSAULTのプレイ動画と見比べて、クリア処理を少しずつ進めていくことにする。

 はじめは、少しの間止まる処理だ。これまでジャンプ中等で使用していた自機のステータスをカウンタ代わりに使用する。ちなみに、この時点では以下のような値の割り振りになっている。
値範囲値の説明
00H通常状態
01Hジャンプ終了状態(連続ジャンプしない他は通常と同じ)
80H-ACHジャンプ中(拡大縮小データのアドレスと対応)

 これに、最初の待ち状態ステータス(02H-1FH)を追加する。これがカウントアップしている間は、その場に止まった状態にする。

 あ、それともう一つ文字表示だ。途中で何箇所か文字表示を行う部分が出てくるので、ある程度共通の処理にしておこう。文字データと表示処理を分離し、文字データの開始アドレスと文字数と文字色を指定すれば良いようにする。

 ついでにもう一つ、ゴールへのルートの方向転換する処理を追加する。ステータスは20H。もちろん、自機の方向によって右方向か左方向かに分かれるようにする。

 さて、動作を確かめよう。

画面

画面

 あ、そうか。文字を書いた後はメッシュキャラに戻さないとダメなんだった。まあ、これはもう少し棚上げしておこう(^_^;)。

2009/05/30:面データ圧縮
 以前にも書いた通り、この時点でマップデータのサイズは16KBある。

 せっかく作ったプログラム、実機でも試したいところだが、カセットで16KBだと結構時間がかかる。よし、ここらで面データの圧縮を考えようか。データ的にはスカスカなので、1/10位に収まらないかな?

 圧縮形式は、おなじみのRLE圧縮にする。面の壁部分が市松模様になっているので、2キャラを1組とすると少しは圧縮が効くのではという淡い期待を持って実装する事にする。

 ...まてよ、面データで使用した色数が16色以内だったら...
→ 色番号1〜16のような表現に変えれば、1キャラが4ビットで表現できる
→ 2キャラだとちょうど1バイト(8ビット)に収まる
→ (RLE圧縮前の)データ量が1/2になる!

 という事で、色数を数えてみる...全部で16色!10色くらいかと思っていたが、意外と使っていたようだ。とにかくギリギリ収まったので、これで行こう。

 面データの展開ルーチンをマシン語で作成し、合わせて圧縮面データを作成するプログラムをHSPで作成する。こういう小さいツールを作るにはHSPは便利だと思う。

 いざ圧縮すると959バイト、約1/17になった。思ったより短くなって満足、いやいや、まだ圧縮面の展開を試していないではないか。P6側で、このデータを展開してみる...うまくいっているようだ。改めて満足だ。

 あとはカセット用に実行しやすいようにメモリマップを微調整していこう。

2009/05/16〜27:クリア処理その2
 残りのクリア処理を、淡々と作成する。

 改めて思うが、ASSAULTの面クリア処理は数あるシューティングゲームの中でも指折りの凝り具合(と操作不能時間の長さ)だと思う。

 結局、以下のように自機のステータスをフル活用する感じの処理となった。
値範囲値の説明
00H通常状態
01Hジャンプ終了状態(連続ジャンプしない他は通常と同じ)
02H-1FH最初の待ち状態+クリアの文字列描画
→ 待ち終了時に文字列表示を止め、メッシュ再描画処理
20Hゴールへのルートに方向転換
→ 方向転換終了でステータスを28Hに変更
28Hゴールへのルートまで直進
→ 直進完了時に自機のY座標を微調整し、ステータスを30Hに変更
30H-37Hゴールに方向転換+「YOU ASSAULT ON...」文字列表示
38Hゴール入口まで直進
→ 直進完了時に自機のX座標を微調整し、ステータスを40Hに変更
40H-48Hリフターを画面外から移動
→ ステータス47Hで、文字列表示を止め、メッシュ再描画処理
49H-5EHゴールのシャッターを開ける
→ ステータス 49H-4EH:黒/白、4FH-53H:黒/灰、54H-5EH:黒/黒
5FHゴールまで直進
→ 直進完了時に自機のX座標を微調整し、ステータスを80Hに変更
80H-93Hリフトアップ(ジャンプルーチンを利用)
94H-ADHフォールアウト(ジャンプルーチンを利用)
→ 合わせて、80H-88Hでリフトを画面外まで移動
AEH-C9H次の面準備+フォールアウト続き
→ 合わせて「READY」文字列表示を行う
→ ステータスAEHの場合のみ、自機位置をスタート位置に戻し、
ゴールを閉じる
→ 終了時にメッシュ表示処理を行い、ステータスを00Hに変更
80H-ACH
D0H-FCH
(クリア処理に伴い、ステータス範囲変更)
ジャンプ中(拡大縮小データのアドレスと対応)

 これでも、一部は再現しきれていないけど、個人的には大満足だ。

 音が一切入っていない部分が大きな難点だが、オフ会までに日にちもないので、ひとまずこのあたりでまとめる事にしよう。

2009/06/03:メモリマップ修正
 現状のメモリマップは以下の通りだ。これをカセット版に直す事を見越して、少しでも隙間なく繋がった状態にしたい。
アドレス用途
0000-3FFF(展開後面データ)
E000-E3BE圧縮面データ
E3BF-EEFF(空き)
EF00-EF51圧縮面データ展開用プログラム
EF52-EFFF(空き)
F000-F07Fベクトルデータ
F080-F0FF当たり判定用データ
F100-F17F(空き)
F180-F1FFジャンプ用拡大縮小データ
F200-F6E0マシン語プログラム
F800-F819(ワーク用)

 圧縮面データの展開部分やプログラム実行後に作成される部分は置いといて、データとマシン語部分について考える。

 これまでのプログラムの都合上、データ部分には以下のしがらみがある。
  • ベクトルデータは、下位バイトが00H-7FH
  • 当たり判定用データは、下位バイトが80H-FFH
  • ジャンプ用拡大縮小データは、下位バイトが00H-7FH
 という事は...こうか。
アドレス移動後移動前
F000-F07F(空き)ベクトルデータ
F080-F0FF当たり判定用データ当たり判定用データ
F100-F17Fベクトルデータ(空き)
F180-F1FFジャンプ用拡大縮小データジャンプ用拡大縮小データ
F200-F6E0マシン語プログラムマシン語プログラム


2009/06/05:カセット版作成
 さて、いよいよカセット版の作成に移る。

 カセット版では、これまで何度か行っている、BASICリストの後ろにデータやマシン語プログラムをくっつける方式にする。この方式も以下のように欠点というか制限がある。
  1. BASICプログラムの修正に伴い、データやマシン語部分のアドレスもずれる。

  2. 途中で、00Hが10個以上繋がってはいけない。
    (00Hが10個来た時点で、プログラム読み込み完了してしまうため)

 1. は、はじめに本来動作していた場所(F080H-)にコピーする事で解決する。
もちろんBASICプログラムのサイズ変更がデータ/マシン語のコピー元アドレスに影響がある部分は変わらないが、そんなものはBASICのサイズが決まれば割り出せる。

 2. は、特にデータ部分で注意する必要がある。今回は、当たり判定用データが該当してしまう事がわかっているので、この部分だけビット反転したデータに変更し、コピー時にまたビット反転させるようにする。

 さて、確認...途中までしかロードされない。
 どうやら、ジャンプ用拡大縮小データの実際に使われていない部分で00Hが10個以上連続していたようだ。この部分をFFHに修正し、再度確認...OK!

 いよいよ、実機の確認だ。PCからP6に直接ロードしようとすると、音のバランスの関係か、途中でロードエラーになってしまう。まあ、どうせ実際のカセットに入れる予定だったので、PCからデータレコーダを通してカセットに録音しよう。しばらく使ってなかったからか、データレコーダがキュルキュル音を出しているが、大丈夫だろうか?

 改めて、データレコーダからP6にロード...うまくいった!!

画面

 この時点で、日付は6/6に変わっていた。このカセットと、念のためUSBにもプログラムを入れておこう。これでオフ会の準備は完了だ。

2009/06/06:オフ会
 カセットテープを土産に秋葉原に向かう。

 会場となる某カラオケ屋ではアテにしていたモニタが使えず残念だったが、66実機からPCに画面表示するキットのおかげでとりあえずカセットからのロードを行う事が出来た。

 そしていざ起動...歓声があがった。今回は見た目も凝った甲斐があって、評判も上々のようだった。でもやっぱり音がないとさびしいかな?この後、動画も公開しようと思っているので、何かしらの音を付けたいところだ。

 責任を取ってくださいね(^^)、と言われたが、まずは一区切りを入れてそこから考えようと思う。でも欲しいよね、グレネード。

2009/06/13〜06/21:公開
 動画で公開できるレベルにするために、自機の移動音とクリア時の音楽を入れよう。

 まず、ASSAULTのプレイ動画より実際の音がどうなっているか確認する。自機の移動音は動いている間だけ鳴っていると思い込んでいたが、実際は止まっている時は低いエンジン音、動き始めると最高速までエンジン音が上がる、と段階的になっていた。う〜ん、これはある程度反映すべきなんだろうな。

 さて、まず移動音だ。はじめに、移動音専用のステータスを用意する。音の段階を0(高)〜3(低)とし、カーソルキー上下を押した時にカウントダウン、それ以外ではカウントアップする。このステータス値に応じて、以下のように音を鳴らす。
  • ステータス値0:SOUND 1, 7:SOUND 0,0
  • ステータス値1:SOUND 1, 7:SOUND 0,128
  • ステータス値2:SOUND 1, 8:SOUND 0,0
  • ステータス値3:SOUND 1, 8:SOUND 0,128
 その他、クリア処理中(自機ステータス02H〜CFH)は自機移動音を鳴らさないようにする。
 この辺りの処理は、前回「ワイアノ」で作成した部分を流用したので、それほど難しくはなかった。

 次に、クリア時の音楽だ。音楽をSOUND相当の機能で鳴らすとなかなか面倒なので、BASICからPLAY文を実行して表示と重ねることにする。これも、ASSAULTのプレイ動画を参考にして少しだけ作ってみる。いざ表示と重ねてみると、テンポが遅い上にリズムがおかしい。

 原因はわかっている。回転画面の表示処理中に(PLAY文の正常実行に必要な)割り込みをOFFにしているからだ。とはいえ、いまさら割り込みを許可する処理にはとても変更できないので、なるべく影響が出なさそうな音楽に差し替える。まあ、どちらにしても耳コピーが出来なかったので音楽は変える必要があったのだが。

 こうして完成したプログラムを使って何度か動画を取り直し、ニコニコ動画に投稿する。合わせて「ASALT」の更新を行い、これも公開する。

 これで、ようやく一区切りがついた。まだもう少しできそうな部分もあるが、こちらはまたぼちぼちと考えていくことにする。


その2 Making「ASALT」 その4