Making「ASALT」その1

Home PC-6001mkII Program etc

 このページでは、作成開始から画面表示までの過程を書いています。

Making「ASALT」 Top


2008/10某日:はじめに
 あれは2008年の初めだったか、なにか回転モノを作りたいと宣言したような気がする。

 実際、頭の中の構想として一つ二つはあるのだが、なにぶん現バージョンでは表示がまだ遅いため、なかなか食指が動かないまま10月を迎えてしまった。

 いかんいかん。まずはもう少し出来る範囲で回転表示処理を高速化しよう。話はそれからだ。

2008/10/25:高速化その1
 「回転 mkII」のプログラムをもう少し高速化すべく、マシン語プログラムを見直す。
 とはいえ、前も何十回と見直しているプログラムなので、さほど速くなる部分が見当たらない。

 こんな時は、何かを犠牲にするトレードオフだ。現状のプログラムでは、マップ画面が64x64の大きさになっていて、座標(X,Y)のデータ(XとYの整数部値範囲は1バイトのため0-255)を取るときには以下の計算式で出している。
 A000H(画面データ開始アドレス) + MOD(X, 64) + MOD(Y, 64) * 64

 ここで思いきってマップ画面を横に広げて、256x64の大きさにする。とすると、計算式も以下のように変わる
 A000H(画面データ開始アドレス) + X + MOD(Y, 64) * 256

 計算式を出したところでさほどの違いは感じられないが、これをマシン語で表現する事で、その差は歴然とする。
変更前変更後
;A:Y座標(00H-0FFH)、H:X座標(00H-0FFH)
LD B, A ;Aの値を退避
RRCA
RRCA
AND 0C0H ;MOD(Y, 64) * 64 の下位バイト部分
LD C, A
LD A, B
AND 0FH ;MOD(Y, 64) * 64 の上位バイト部分
ADD A, 0A0H ;画面データ開始アドレスを加算
LD B, A ;画面データ上位バイト確定
LD A, H
AND 3FH ;MOD(X, 64)
ADD A, C ;画面データ下位バイト確定
LD C, A
;A:Y座標(00H-0FFH)、H:X座標(00H-0FFH)
AND 3FH ;MOD(Y, 64)






ADD A, 0A0H ;画面データ開始アドレスを加算
LD B, A ;画面データ上位バイト確定



LD C, H ;画面データ下位バイト確定

 もう一目瞭然だ。この処理が1画面分(800回)繰り返されるので、かなりステップ数を稼ぐことが出来た。

 マップデータのサイズが4KB→16KBと激増する事がどう影響するか若干の不安もあるが、これで行ってみよう。

2008/10/25:高速化その2
 もう一つ、姑息だが確実にステップ数削減を行う手段を入れてみる。それは「同じ処理を2回繰り返してループ数を減らす」だ。大層に書いた割りに、そう大した事ではないのだが...。

 要点部分だけマシン語で表現すると、以下のような感じだ。
変更前変更後
LD B, 28H ;横ループ40キャラ分
Loop1:
(1キャラ分描画処理)

DJNZ Loop1:
LD B, 14H ;横ループ40/2キャラ分
Loop1:
(1キャラ分描画処理 その1)
(1キャラ分描画処理 その2)
DJNZ Loop1:

 一見処理が増えているが変更後では「DJNZ Loop1:」x 20 だけステップ数が削減できる。
 同様の考えで、4回並べれば30回分削減でき、40回並べれば40回分削減できることになるが、プログラムサイズも増えるし、プログラムの修正も面倒になるので、2回までに抑えておく。

2009/01/15:高速化その3
 前回の作成から3ヶ月近く放置されていたが、また少しずつ始めてみよう。

 再開のきっかけになったのは、もう少しだけステップ数が削減できるポイントを思いついたからだ。それは「データを0000Hから置く」事だ。
 これまでは、データをA0000以降においていたが、データの格納位置を変える事で、「アドレスにA000Hを加える」事が不要になる。これで(8-1)x800=5,600ステップほど稼げる計算になる。

 ただ、0000Hからの部分は最終画面のVRAMとなっているため、画面数をもう一つ増やして一画面目(4000H〜)に表示を行うよう変更する。

 この時点で、最大14フレーム/秒ほどだっただろう(うろ覚え)。最初のバージョンより1.5倍は速くなっている。ひとまず高速化はここまでにし、本題に入る事にする。

2009/01/31:マップ表示
 回転の基礎部分が出来たところで、いよいよマップ表示に移る。

 まずはマップだ。どこかに「ASSAULT」のマップがあると良かったのだが見当たらなかった。仕方ないので、公開されていたプレイ動画と見比べつつ「D-Pixed」にてドット打ちをしていく...。まずはこんな感じか。

画面

 ちなみにだが、このグラフィックは256色BMPで、色のパレット番号をP6のメッシュ表示を行ったときに指定する値と一致させている。
 こうすると、BMPイメージを上下反転して保存し、データ部分(ヘッダとパレットデータを除いた部分)を切り出すだけでP6用のデータに置き換わる。これは、以前メッシュキャラをドットに見立てたキャラクタ表示を行ったときに編み出した技だ。

 合わせて、プログラム側にも修正を加える。これまで全画面(40x20)で表示していたものを横幅半分(20x20)の表示に変更する。処理を軽くする事が主な目的だが、プレイ動画でもおおよそ横幅半分だったのでまあ良いだろう。

 そして、いよいよ表示...。

画面

 ようやく出た!

 まだ回転しか出来ないし、回転の中心も全画面のときから変えていないのでおかしいのだが、やはり表示されるとやる気も出るものだ。
 プログラムとしてはむしろここから始まりなのだが、少しずつ追加して行こうと思う。

2009/02/01:暴走
 とりあえず回転の中心を修正。編集はあっさり終わったのだが、確認のために動かすとなぜか途中で止まってしまう。やった事は、掛け合わせる数を減らしただけで、特に誤動作する要素はないのだが。

 しばらくわからなかったが、ソースの修正でマシン語の開始アドレスがずれていたことにようやく気がついた。修正は、また後で行おう。

2009/02/05:拡大が...
 2/1に判明した問題点は、BASICからのマシン語呼び出しアドレスを変更してあっさり解決。さて、今回のプログラムで肝になる部分「拡大縮小」を組み込もうか。

 既に回転部分のプログラムはできているので、拡大縮小の考え方は比較的簡単だ。ようするに方向のデータに拡大縮小率を掛け合わせれば良い。

 今回は、この拡大縮小率も1バイトで収めたかったので、方向データを一旦2倍にしてそこから小数点以下データ(1バイト分)を掛け合わせることにする。これで、80Hを境に拡大/縮小が表現できるようになる。

 掛け算の処理を追加してみて様子を見てみる。すると、拡大は特に問題なく表示するのだが、縮小時に回転させるとなぜかミョーンとした表示になる。

画面

 もう一つ、回転の中心点がなぜかまた左端になってしまう。これらは直さないと話にならない...が...原因がよくわからない。

2009/02/11〜13:表示バグ修正
 縮小時の表示がおかしくなる件の原因がようやくわかった。

 方向データの上位1ビットには符号の情報が入っているが、1倍超を掛け合わせた時に桁あふれでこの部分まで来てしまったらしい。
 この部分は気をつけていたつもりだったが、別の部分でさらに数値を2倍している事がわかった。これでは桁あふれするはずだ。という訳で修正。

 後日、もう一つの原因もわかった。サブルーチン実行時にレジスタの内容が置き換わったまま戻さずにいた事が原因のようだ。これもさっくり修正する。


Making「ASALT」 その2