yasuokaの日記: Z80における「手抜き」回転行列の計算誤差
昨日の日記に対して、計算誤差はどうしたのか、という趣旨の御質問をいただいた。私(安岡孝一)の記憶が確かなら、何もやってなかった気がする。どのくらい誤差が出ていたのか、ちょっと確かめてみよう。
┌ 127/128 -1/8 ┐ ┌ x ┐
└ 1/8 127/128 ┘ └ y ┘
画面中心を(0,0)とするxy座標系において、cosθ=127/128, sinθ≒1/8の回転行列を用いて「手抜き」回転をおこなう。対象とするCPUがZ80なので、IXレジスタにx座標(上位8ビットが符号付整数、下位8ビットが256を分母とする分数)を、IYレジスタにy座標を入れることにすると、当時の私が組んだプログラムは、だいたい以下のような感じである。
DD E5 PUSH IX
FD E5 PUSH IY
E1 POP HL
7C LD A,H
2F CPL
57 LD D,A
7D LD A,L
2F CPL
CB 2A SRA D
1F RRA
CB 2A SRA D
1F RRA
CB 2A SRA D
1F RRA
5F LD E,A
DD 19 ADD IX,DE
7C LD A,H
2F CPL
07 RLCA
5F LD E,A
9F SBC A,A
57 LD D,A
FD 19 ADD IY,DE
E1 POP HL
54 LD D,H
7D LD A,L
CB 2A SRA D
1F RRA
CB 2A SRA D
1F RRA
CB 2A SRA D
1F RRA
5F LD E,A
FD 19 ADD IY,DE
7C LD A,H
2F CPL
07 RLCA
5F LD E,A
9F SBC A,A
57 LD D,A
DD 19 ADD IX,DE
C9 RET
(100,0)すなわちIX=6400H, IY=0000Hから始めると、このプログラムは190回呼び出されたところで、IX=18EDH, IY=9E1EHすなわち(24.92578125,-97.8828125)となり、誤差が1%を超える。まあ、100ドットあたり1ドット外へズレてしまうわけだ。ただ、この「手抜き」回転行列は、50回程度でほぼ1周してしまうので、190回も呼び出される可能性は極めて低い。だとすると、整数部1バイトのxy座標系において、計算誤差は1ドット未満におさまるので、アクションゲームに使う分には大丈夫、というのが、当時の私の判断だったように思う。でも、現代のアクションゲームだったら、座標系を整数部1バイトで済ませる、ってことがそもそも有り得ないかしら。
Z80における「手抜き」回転行列の計算誤差 More ログイン