2013年6月1日土曜日

X-BASIC for iOSのごめんなさい(随時追記)

X-BASIC for iOSの、各種「ごめんなさい」部分を述べておきます。

関数の命名規則がバラバラ
pic_load()だったりpicLoader()だったり。前者はX68に多く、後者はApple的です。
今後、X68にない関数はApple的に統一していく予定です(V2.1でだいぶ行いました)。
すでに存在する関数名についも、互換性のためそのまま残します。
同一機能の関数に複数名称あるのは主にそのためです。


関数動作がX-BASIC/68と微妙に異なる
X-BASIC for iOS は基本的にX-BASIC/68やぺけーBASICと互換性がありますが、それは内部ステートメントと機種依存しない外部関数だけで、機種やOS依存の部分は、同名関数であっても同一動作をするとは限りません。

特に表示系はiOSや機種に強く依存するため、表示結果がX68と微妙に異なることが多々あります。おそらく特にわかりにくいのが透明の概念でしょう。

 X68では黒=透明であり、ページを重ねている場合はその部分は透けてみます。
逆に言えば、助けさせるためには黒で塗れば良いです。
ところが、iOSでは黒と透明は全く異なるものです。黒で塗った部分は、重ねあわさせても黒であり、透過しません。その上、透明度を持った色で「そのまま」描画しようとすると、元々そこにあったパターンと合成してしまいます。単純に 置き換わらないのです。
これを回避するにはblend()で合成方法を変更する必要があります。

X−BASIC for iOSはBASIC/68のプログラムをそのまま動かすことを目的としたのではなく、「iOSに比較的簡単に移植する」ことを目的としたため、必要以上にX68と動作が一緒になるようにはしていません。そのため、こういう部分があります。

もし「完全互換動作」を求める声が多ければ、それを別の外部関数として実装するという手もあるでしょうが、現在の状況では(時間的そして経済的に)不可能です。


意図しない範囲まで描画される
iOS版のグラフィック座標は実数です。これは何を意味するかというと、物理的なドットの間にも仮想的なドットが存在すると想定していると言うことです。これにより、アンチエイリアスなどを実現しています。

しかしこれがゆえに、指定した範囲よりも広く実描画されることがあります。なので、X68でドット単位で正確に領域を限定して描画していた物は、それが維持できなることがあります。具体的には、ある領域に描画して、その後そこを消そうとした場合、消したはずなのに一部残る、という現象が発生します。

残念ながら、この現象はアンチエイリアス機能をOFFにしても解消しません。描画方法をプログラム的に調整するしかありません。

一番手っ取り早いのは、描画をbitmap関数で行うことです。bitmap関数は整数座標であり、アンチエイリアスもないので、指定した座標に正確に描画されます。


fopen()のリターンが異なる
開発時に参考にしていた文献の間違いのため、X68版とリターン値の範囲が異なります。
X-BASIC/68では正常で>=0ですが、iOS版では>=1です。ただし、X68版のソースを動かす場合は範囲が広いだけなので問題にはなりません(だから余計に気がつかなかった)。
万が一、X68に移植することがあれば注意してください。

すでにiOS上の多数のサンプルで使われているため、変更できませんでした。

V2.5からfclose()/fcloseall()のリターン値の値が取説上(定数名として)変わっていますが、値そのものは同じです。


外部関数のエラーチェックが異なる
外部関数内におけるエラーチェックに関しては、重要なもの以外、ほとんど再現していません。理由は簡単で「いちいち調べるのが面倒だった」からです。
基本的には、X68版のほうがエラーチェックが厳しいので、それで動いていたものはiOS版でも大丈夫と思われます。
iOS版は引数の範囲が規定外だった時、多くの場合規定範囲内に自動的に補正するのでエラーは発生しません。
エラーが発生することを想定している場合は、呼び出し側でチェックしてください。

注意すべきはfopen()で、X68版ではファイルがオープンできない時外部関数エラーが発生して停止しますが、iOS版では標準ではリターン値としてエラーコードを返してくるだけでエラーは発生しません。
したがって、エラーで止まることを前提にして作られたプログラムは、必ずエラーチェックを追加する必要があります。
X68版iOS版
fp=fopen("file","r") fp=fopen("file","r")
if fp<=0 then print "file error":end
V2.6からはerror on2で、fopen()のファイルオープンエラーでも、エラーで停止させるように出来ます。

なお、X-BASIC/68のプログラムではfopen()のリターン値=ファイルポインタを得ずにfread()などのfp値に固定数値を与えている行儀の悪いものが散見されます(Oh!X掲載のプログラムにも結構あった)。
そういうものはすべからく誤動作しますので、必ずfopen()でfpを得てそれを与えるようにしてください(そういうプログラムはBCを通してCに変換するとほぼ確実に誤動作します)。



スプライト機能は重い
これはひとえに私の技量不足からくるものですが、X68のスプライト、特にBG画面との重ね合わせは、実現するにはかなり面倒な処理が必要です。スプライト機能をX68互換を捨てて実装すればもう少し高速化も可能だったかもしれませんが、ここだけは資産を生かすため出来るだけX68互換を維持したかったので、現在のようになっています。

BGを使わないようにすれば、多少省メモリと高速化されます。

現在のスプライトでは、iPad1においてはスプライトのみ(BGなし)を、移動せず固定的に表示するのが精一杯です。iPad2以降やiPod touch4ではCPUやGPUの性能向上や、画面サイズによりおよそ問題ない性能が出ています。

ただ、やはり重いのは重いので、電池の消耗が激しいです。

BGを使わなくても遅いです。BGとの重ね合わせは処理が重いのはわかっているのですが、スプライトのみで使っても異様に遅い原因はわかっていません。
シミュレーター上では十分な速度で動いていても、実機;特にiPad1/2ではものすごく遅いです。スプライト使わず、グラフィックで描いたほうが早いくらい。

移動せず、固定的に、重ねあわせられるもう1画面として使うのが関の山かもしれません。
現状では、限定された利用しかできないようです。ごめんなさい。
OpenGLなどで書きなおせば早くなるのかしら?
今のところ、その技量はないですが。

・・・

今後、思い出し次第追記します。

0 件のコメント:

コメントを投稿