月刊I/Oなどで発表された3Dフライトシミュレータ「ザ・コックピット (THE COCKPIT)」をPC-6001mkII/6601/SRに移植してみました。
(2019.12.19 新しいバージョンを公開しました。バグ修正、SRでのバスリクエストON/OFF切替機能追加など)
PC-6001mkIIでザ・コックピット
I/O 1984年11月号 p242-251掲載のPC-8801用ザ・コックピットに対するパッチとデータ変換プログラムを作成しました。当該号は国会図書館に所蔵されているので、遠隔複写サービスの利用が可能です (要利用登録)。
うまく動かない場合やエラーが出る場合は、リスト3 (BASICプログラム) のパッチ当てに失敗した可能性が高いです。打ち間違いがないか確認し、もう一度mkckp.exeを実行してください。
航空機を操縦して夜間の空港に着陸します (表1)。機種、空港、風の強さ (1が最弱) を選んだ後、「3 ----- OPERATE」を選ぶとゲーム開始です。中央の丸印が現在進んでいる方向なので、これを滑走路に合わせるように、また各計器のずれ表示が中心付近になるように飛ぶとよいのではないかと思います (表2)。着陸にはいくつかの条件を満たす必要があり (表3)、着陸に成功するとComplete、失敗するとHaltと表示され、飛行経路と評価点が表示されます。
満点は100PTS
キー | 動作 | 効果 |
---|---|---|
カーソル左 | エルロン左 | 左にバンク |
カーソル右 | エルロン右 | 右にバンク |
カーソル上 | エレベータダウン | 機首を下げる |
カーソル下 | エレベータアップ | 機首を上げる |
SHIFT | ラダー左 | 左旋回 |
スペース | ラダー右 | 右旋回 |
q | スロットアップ | パワーアップ |
a | スロットダウン | パワーダウン |
MODE | バスリクエスト切替(SRのみ) |
位置 | 機能 | 理想コースとのずれ |
---|---|---|
上数字 | 磁気方位計 (MAG) | |
上2番目 | 設定方位偏差計 | 方位ずれ |
上内側 | ロール角表示計 | |
左上 | 対気速度計 (IAS) | |
左下 | 設定速度偏差計 | 速度ずれ |
左内側 | ピッチ角表示計 | |
左下隅 | 動翼指示計 | |
右上 | 気圧高度計 (ALT) | |
右下 | 昇降速度計 | |
右内側 | グライド・スロープ指針 | 高度ずれ |
下 | ローカライザ指針 | 左右ずれ |
パラメータ | 条件 |
---|---|
降下速度 | 3m/s以下 |
ピッチ角 | -1°から+12° |
バンク角 | 5°以下 |
取っ散らかってしまっている例。滑走路には平行に進入しましょう
88版から、VRAMアドレスと表示用データ (リスト1) の実行時格納アドレスを変更しました。
P6版アドレス | 88版アドレス | 内容 |
---|---|---|
0000-3FFF | (C000-FFFF) | VRAM |
4C00-6E2F | 2C00-4E2F | 表示用データ |
8000- | 8000- | BASICプログラム |
B9D0-D8FF | B9D0-D34F | マシン語プログラム |
DA00-E407 | DA00-E407 | ワークエリア |
F000-F7FF | 計算用テーブル |
原作のレベル3版ではおよそ8fpsの速度が出ているそうですが、88版を改造してP6mk2でとりあえず動く状態にした時点での速度は0.8fpsぐらいでした。流石にこれではゲームとして成立しないので、色々高速化を試みました。まずは表示部分についてです。
MZ-2000やPC-8801のザ・コックピットの表示部分は、1バイトないし2バイトのVRAM書き込みを行う基本サブルーチンがいくつかあり、これを呼び出すことですべての表示を行うようなプログラムになっています。よって他機種への移植の際には、ここにパッチを当てることでかなり楽に対応が可能です。このゲームが短期間で多くの機種に移植されたのは、最初のZ80移植版であるMZ-2000版がこうしたプログラム構造になっていたからこそでしょう。
しかし、1バイト書くたびにサブルーチンコールするので、描画時間は結構かかります。オリジナルであるレベル3のグラフィック画面は320x200ドット、横8ドット (1バイト) につき8色中1色というもので、1バイト書く時のコードはこんな感じでした。
この部分がすべて、MZ-2000やPC-8801版では次のようになっています。
処理量が全然違いますね。加えて、P6mk2で動かし始めた当初は、変更箇所を最小限にしたくて、色とドットパターンとVRAMアドレスをサブルーチン内で動的に変換していました。そりゃ遅くなるわけです。
データはあらかじめP6mk2用に変換しておくことにし、また計器表示の多くについては基本サブルーチンを呼ぶのをやめ、それぞれの計器に特化した形で一から書き直しました。このゲームには多数の計器がありますが、そのうちいくつかは数字の書かれた表示盤の上を針が動くのではなく、針が固定されて表示盤の方がスクロールするようになっています。これらについてはメインループ1回ごとに盤全体が描き直されるわけで結構な時間がかかるのですが、ほとんど単色なので、色による分岐を最初の1回にし各色専用のプログラムを書くことで、かなりの時間節約になりました。
夜間着陸であるという設定にすることで、少ない表示で美しい描画を行うのがこのゲームの肝なわけですが、それでも結構な数の光点表示が行われます。ループの度に三次元回転拡大演算を行うために多数の乗算処理が行われるので、この部分の高速化も行ってみました。
地上に見える光点は、地平線上に散らばる50個の街の灯と、滑走路を表す51個の光点から成り、これらに対しメインループ1回あたり合計数百回の1バイト×1バイト乗算が行われます。CPUとして6809を載せているレベル3版ではMUL命令一発なんですが、Z80では乗算処理を書いてやらないといけません。
従来のZ80移植版では、一般的な乗算のアルゴリズムである、シフトとビットテストと加算を8回繰り返す方法が使われています。今回の移植では、BookwormさんがP6でのリアルタイムポリゴン表示を行う時に使った方法を採ることにしました。以下の式変形を行うことで、テーブルを用いて乗算を行うやり方です。
ab=((a+b)/2)^2-((a-b)/2)^2
この方法だと、(n/2)^2 (n=0〜510) のテーブル約1KB (端数は必ずキャンセルするので、切り捨てて2バイトずつの値で良い) をあらかじめ用意しておくことで、加減算数回で1バイト×1バイトの乗算が行えます。まともにやるよりだいぶ速いです。
また、計算の順序を変えることで乗算の回数を減らすことができました。例えば、以下のような感じで変形できるところが何箇所かあります。端数処理の部分で計算結果が若干変わってしまう可能性があるので、できれば触りたくなかったんですが……。
変更前: X=(dy-2PSI*dx+2PHI*dz)/dx
変更後: X=(dy+2PHI*dz)/dx-2PSI
更に、元のプログラムでは1バイト×1バイトの他に2バイト×2バイトの乗算ルーチンがあるのですが、2バイト×2バイトもテーブル参照式に変更した上で、2バイト×1バイトと1バイト×2バイトの専用ルーチンも別に作り、数字の大きさによってはそちらに分岐するようにしました。分岐の分の負荷は増えますが、トータルでは若干速くなったようです。
乗算の他に、除算ルーチンもちょっとだけ高速化しました。ループ展開して更に引き戻し法を引きっ放し法に変更してあります。乗算をいじったほどの効果はなかったのですが、まあやれるだけのことをやるしかないのです。
キー入力についても少し工夫しました。P6ではカーソルキーやスペースキーの状態を調査するのに、以下の手順を踏む必要があります。
ざっくり調べた感じだと、調査が終了するまで1.3〜2.5ms程度かかるようです。この間何もせずに待つのも勿体ないので、調査コマンドを投げてから結果を見るまでに表示ルーチンなどを挟むことにしました。即応性が落ちることになりますが、元々キー入力ルーチン自体そんなに頻繁に呼ばれるほどの速度は出ていないないので、まあいいでしょう。
そんなこんなで色々いじって、現在の速度は3.8fps程度のようです。SRだと3.4fps程度でしょうか。レベル3版の半分程度ということで、最終的に航空機の速度や操作量を2倍にして、ゲームのテンポをレベル3と同程度になるようにしました。なので、直接の移植元である88版とは異なる操作感になっているかもしれません。
2019.12.19版では、SR用のバスリクエストON/OFF機能を追加してみました。スタート時にはON状態 (非SRと同じ)、MODEキーでON/OFF切り替えです。上述の操作量等も切り替えるようにしたので、ゲームの進行速度はあまり変化しないはずです。OFF時は描画頻度が倍程度になるので、ON時より滑らかに見えるのではないかと思います。誘導灯の速度が変わるので、それで現在どちらのモードなのかが確認できます。
トップ > 雑多なもの > PC-6001mkIIでザ・コックピットを