本作のぶっ飛んだ特徴はやはり100人同時移動です。誰もがまさか動くはずないと思う事に挑戦しました。でも、私には最初から勝算がありました。だってPCGですよ?

100人を同時に動かす処理なんて、そりゃあ普通に作ったら無理でしょう。また、16x8の人間をドット単位で動かすのですから、どう考えても文字キャラ数が足りません。
一方で、PCGを書き換えると画面上に表示済の全ての絵が一気に置き換わります。画面に100人いても、PCG2個書き換えれば全てのキャラデザインが変わります。この特性を利用します。
人間が動くタイミングが全員同じである前提とします。100名いても移動方向は所詮は4方向です。各方向に専用のPCGを割り当てれば、アニメーションはプログラムで処理する必要はなくなります。

Newシティヒーローメイキング・インデックス
※ 自分的にはこちらが欲しいです。縦解像度1440は素晴らしい!

- PCG特化型ゲームデザイン
100人を同時に動かす処理なんて、そりゃあ普通に作ったら無理でしょう。また、16x8の人間をドット単位で動かすのですから、どう考えても文字キャラ数が足りません。
一方で、PCGを書き換えると画面上に表示済の全ての絵が一気に置き換わります。画面に100人いても、PCG2個書き換えれば全てのキャラデザインが変わります。この特性を利用します。
人間が動くタイミングが全員同じである前提とします。100名いても移動方向は所詮は4方向です。各方向に専用のPCGを割り当てれば、アニメーションはプログラムで処理する必要はなくなります。

上下左右各方向に4キャラ用意して、そのキャラのPCGを書き換えればナンボでも動くぞと、勇んでプログラミングを進めたのですが、想像以上に遅い PC-8001 の処理能力が…
PCGの書き換えは垂直ブランキング期間に行います。そうしないと画面に物凄いノイズが出るためです。垂直ブランキング期間は計算では3.33ms(多分)。こんなにあればポリゴンの1,000や2,000描けるのに、PC-8001よ、お前ときたらPCG14個しか書き換えられないのかよ…
※ 怪しいメーカー、調べたら中国の部品で製造しているフランス人が社長の日本企業でした。安いが正義ならご検討をw
- PCG8100を攻略する
PGC8100のダメなところを改めて検証してみます。まず、読み込みポートが無いので、現在どんなパターンになっているのか判定できないという仕様があります。そして、これが厄介なのですが、アドレス指定ポートにBEEPキーオンフラグが入っているのです。
おそらく、HAL研ではPCGは一度定義したら終わりという認識でハードを設計していたのだと思います。そのため、空いているビットとして、ここを使うしか無かったのだと思いますが、これにより現在演奏しているサウンドのキーオンフラグを、PCG定義時に設定しなければいけないのです。そして、ポート状態を読み込む方法はありません。つまり自前でポート出力データを管理しないといけないのです。
そして、追加調査の結果、このキーオンフラグを、PCG定義時に1ラインずつサウンドドライバのワークを参照して出力値にAND/ORしていたのが遅い理由だと分かりました。また、1キャラ8ライン分をループ制御して処理していました。

この部分の高速化を考えていきます。幸いな事に PC-8001 には割り込みがありません。そのため、サウンドドライバをこちらから呼び出さない限り、ワークの内容は読み込み時の値が保証されます。言い換えると、ワークから取り出したキーオンの状態が途中で変化する事はないのです。そのため、最初にキーオン状態を加味するようにプログラムを書き換えてしまえば、以後は毎回 AND OR する必要は無くなります。さらにループ展開もしてしまえば最高速ですよね?
ということで、PCG書き換えの開始を宣言するサブルーチンを用意しました。

そして、ループ展開しまくります。元々は10数行が100行以上に増大しますが、ここは妥協できません💦 結果、無事、垂直ブランキング期間で16個のPCG書き換えに成功しました!
おそらく、HAL研ではPCGは一度定義したら終わりという認識でハードを設計していたのだと思います。そのため、空いているビットとして、ここを使うしか無かったのだと思いますが、これにより現在演奏しているサウンドのキーオンフラグを、PCG定義時に設定しなければいけないのです。そして、ポート状態を読み込む方法はありません。つまり自前でポート出力データを管理しないといけないのです。
そして、追加調査の結果、このキーオンフラグを、PCG定義時に1ラインずつサウンドドライバのワークを参照して出力値にAND/ORしていたのが遅い理由だと分かりました。また、1キャラ8ライン分をループ制御して処理していました。

この部分の高速化を考えていきます。幸いな事に PC-8001 には割り込みがありません。そのため、サウンドドライバをこちらから呼び出さない限り、ワークの内容は読み込み時の値が保証されます。言い換えると、ワークから取り出したキーオンの状態が途中で変化する事はないのです。そのため、最初にキーオン状態を加味するようにプログラムを書き換えてしまえば、以後は毎回 AND OR する必要は無くなります。さらにループ展開もしてしまえば最高速ですよね?
ということで、PCG書き換えの開始を宣言するサブルーチンを用意しました。

そして、ループ展開しまくります。元々は10数行が100行以上に増大しますが、ここは妥協できません💦 結果、無事、垂直ブランキング期間で16個のPCG書き換えに成功しました!
- 実際の実装方法
技術的な問題は解決したので、実装方法の検討に入ります。
100人もいるので、一つ一つの処理も高速化したいです。ワークエリアも100人いるとデカくなるので、1人あたりのワークは極力小さくしたいです。いろいろ考えたのですが、人間は1人辺り3バイトのワークを用意する事にしました。
- 動方向に対してキャラを4個並べて置く。
- PCGを書き換える。
- 移動タイミングで後方の不要キャラが出たらそれを $00クリアする。
- 全部移動しきったらまた移動方向を決める。
100人もいるので、一つ一つの処理も高速化したいです。ワークエリアも100人いるとデカくなるので、1人あたりのワークは極力小さくしたいです。いろいろ考えたのですが、人間は1人辺り3バイトのワークを用意する事にしました。
座標はXYではなくアドレスで指定するようにします。当たり判定はVRAMアドレスサーチとします。そのため座標計算は不要となります。これにスタックによるスクリプト管理などのワザも加えて、2F ではありますが、100人同時移動が実現できました!
human: ; 逃げ惑う人間ワーク .anime db 0 ; アニメカウンタ .work REPT 100 ds 1 ; +0 現在の状態 ds 2 ; +1 描画アドレス ENDM
Newシティヒーローメイキング・インデックス
【Amazon】
IODATA モニター 27インチ WQHD ADSパネル 非光沢 (HDMI×3/DisplayPort×1/スピーカー付/3年保証/土日サポート/日本メーカー) EX-LDQ271DB
IODATA モニター 27インチ WQHD ADSパネル 非光沢 (HDMI×3/DisplayPort×1/スピーカー付/3年保証/土日サポート/日本メーカー) EX-LDQ271DB
アイ・オー・データ
2017-12-06
コメント