110gc -- DataScope Graphics Component

ライブラリ使用上の補足

ライブラリの雑多な補足事項

● Cのソースコードやドキュメント中に、 閉括弧 } の次に余分な ; がついていますが、 私のくせです。気にしないで下さい。

● 各関数の引数エラーチェックはほとんどありません。 例えば、開放したメモリブロックを再び開放したりしても、 メモリをぐしゃぐしゃにするだけで何もエラー報告しません。

● gcBitCopyなどで画面バッファビットマップを更新しても、 実際のLCD画面が直接書き代わるわけではありません。 このような場合に、つぎの3種類の書き換えのアプローチを取れると思います。

  1. 画面バッファへの更新を連続して行ない、 画面バッファすべてをLCDへ転送してしまう方法

    このアプローチが一番ラクです。 つまり、ゲームなどでは、一画面の内容をすべて書き換え、 最後にLCDへ画面すべてを転送します。

    scr= gcRgnRect(0, 0, 320, 200, 0); //全画面を表す領域
    ...
    //画面バッファビットマップの更新
    ...
    gcBitDisplay(gcBitLcd(), scr, 0, 0, 0, 0); //全画面のLCDへの転送
    
  2. 画面ビットマップを更新した直後にその領域を転送する方法

    gcBitFillなどで描画する都度、その領域をLCDへ転送する方法です。

    ...
    gcBitFill(gcBitLcd(), wanttofill, fx, fy);
    gcBitDisplay(gcBitLcd(), wanttofill, fx, fy, fx, fy);
    ...
    
  3. 変更を加えた領域を蓄積しておき、あとで一度に書き換える方法

    変更を加えた部分を蓄積する領域を定義しておき、 これを利用してLCD画面への更新を行なう方法です。
    変更領域が画面全体に及ぶ時は、なんのメリットもありませんので、 画面全体を書き換える方法を採用してください。

    update= gcRgnRect(0,0,0,0,0); //変更を加えた領域
    ...
    gcBitFill(gcBitLcd(), wanttofill, fx, fy);
    tr= gcRgnOr(update, wanttofill, 0, 0, fx, fy);
    gcRgnFree(update); update= tr;
    ...
    gcBitCopy(gcBitLcd(), picture, wanttocopy, cx, cy, px, py);
    tr= gcRgnOr(update, wanttocopy, 0, 0, cx, cy);
    gcRgnFree(update); update= tr;
    ...
    gcBitDisplay(gcBitLcd(), update, 0, 0); //LCDへの転送
    gcRgnFree(update);
    

● ヒープエリアとしてどの程度の量を確保したらよいかは、 確保してある描画領域(gcRgn)のデータ量次第です。 が、領域は結構大きくなります。 特に複雑な領域では、あっと言う間に4Kbを突破したりします。 4Kbの領域を演算するためにはその領域分のメモリは必要ですので、 合計で8Kbの領域が必要になります。 ヒープには、さらにその20〜30%増しのメモリが必要です。

● スプライトであるヌキ色の実現には、描画領域を用いる方法と、 gcBitOr-gcBitXorを用いる方法がありますが、 できるだけgcBitOr-gcBitXorを用いて下さい。
描画領域は、画面外への描画を阻止したりするのが目的であり、 特に、複雑な領域に対する描画はかなり遅くなります。 ただし、画面の半分を覆うようなでかいキャラクタを表示する場合で、 領域がそれほど複雑でなくかつスピードを重視しない場合は、 描画領域を用いる方がプログラムサイズは小さくなると思います。

● 現在のところ、110gcでは画面へ文字を出力することはできません。 gcBitのビットマップ形式はDS110OSのそれに合わせてありますので、 通常のAPIであるPutStr等を用いて描画してください。 この場合、画面バッファの更新とLCDへの反映は同時に行なわれます。
ゲームなどの場合は文字用の独自のビットマップを用意するのが 良いと思います。

● gcObjの構造体で最初のフィールド v は御想像の通り、vtableを示します。 COM (component object model) を睨んでいるのはまちがいのないところですが、 共有ライブラリの実現のためがメインだったりします。
でもC++でもないのにvtableを使うと呼びだしの記述が面倒でしょ? さらに問題なのが、先行定義した構造体へのポインタと、 実体定義した構造体へのポインタが別のものとみなされるという、 わけのわからんコンパイラのバグです。
というわけで、現在のところ全くの未使用です。 だれかgcc移植してくんないかな、いやマジで。

一般的なDS110プログラミングテクニック

● 変数の宣言方法と割り当てられるセクションは以下のようになります。
#pragma section area f_area
short a00;                     f_area    アプリ固有データ
short a01= 1;                  f_data    アプリ固有データ
const short a02= 1;            f_const   EEPROM
short af() {
  static short a10;            f_area    アプリ固有データ
  static short a11= 1;         f_data    アプリ固有データ
  static const short a12= 1;   f_const   EEPROM
  short a20;                   スタックかレジスタ
};
#pragma section area UserWork
short u00;                     UserWork  ワークエリア
short u01= 1;                  f_data    アプリ固有データ
const short u02= 1;            f_const   EEPROM
short uf() {
  static short u10;            UserWork  ワークエリア
  static short u11= 1;         f_data    アプリ固有データ
  static const short u12= 1;   f_const   EEPROM
  short u20;                   スタックかレジスタ
};
一般のパソコン上のC言語との相違点は以下のようになります。

● 開発キットのコンパイラのメッセージは、引数に -$ をつけると抑制されます。 さらに、環境変数 DOS4G=quiet をセットしておくと、DOS4G関連のメッセージも 抑制されます。

● ABSファイルからS24ファイルを作成する場合、 テンポラリファイルをたくさん作成しなくても次のような記述で十分です。

tuconv -Fs24 -rb ApInfo,,, -rb f_data,,, -rb f_code,,, -rb f_const,,, sample.abs
但し、この方法で変換すると、 小田桐さんのAppLoader1.0付属のS24toDSXでは変換できません。 実はわざわざ対応版を小田桐さんに作っていただき (大感謝)、 手元には対応版があったりします。いいでしょー。
小田桐さんに、ホームページへ置かせていただける許可をもらいました。 どうもありがとうございます。 こちらからダウンロードできます。
正式な対応版は小田桐さんからの次のAppLoaderのリリースに含まれると思います。