OSECPU-ASKA入門 #0011
(0) はじめに
- 以下の記事はosecpu111dのWindows版を前提にしています。他の版を使っている場合は適宜読み替えてください。
(1) drawPointとfillOvalとdrawLine(ついでにmodeについて)
- api_drawPoint(mode, color, x, y); :
- 画面に点を打ちます。xとyは座標です。colorは色です。modeの意味はfillRectと同じです。画面からはみ出しちゃいけないというルールも同じです。
- 点の大きさを指定するパラメータはありません。大きな点を描きたいときは、fillOvalやfillRectで代用してください。
- api_fillOval(mode, color, xsiz, ysiz, x0, y0); :
- 画面に円もしくは楕円(だえん)を描きます。このパラメータ、実はfillRectと全く同じです。ではどういう円が描かれるかですが、このパラメータで指定される長方形を想像して、そこから角を削って丸くしてください。そのような円もしくは楕円が描画されます。
- ということで、 x0, y0 は円の中心ではなく、円の端(はし)でもなく、仮想的な長方形の左上の座標です。分かりにくくてすみません!
- api_drawLine(mode, color, x0, y0, x1, y1); :
- 画面に線を引きます。 x0, y0 が始点で、 x1, y1 が終点です。水平な線、垂直な線ももちろんかけますが、斜めもOKです。
- 線の太さなどを指定するパラメータはありません。太い線が引きたいときは、ずらしながら何本も引きましょう。
- modeについて:
- グラフィックス系命令の最初にいつも付いてくるmodeパラメータですが、MODE_COL24とMODE_COL3以外にどんな意味があるかを紹介します。
- MODE_PSET: PSET描画モード: もとの画素の色が何色であるかに関係なく、上書きします(デフォルト)。
- MODE_OR: OR描画モード: たとえば赤の上に緑で描画すると、黄色になります(0xff0000と0x00ff00のOR演算の結果が0xffff00になるから)。
- MODE_XOR: XOR描画モード
- MODE_AND: AND描画モード
- MODE_COL3: 色指定方法を8色モードに
- MODE_COL24: 色指定方法をフルカラーモードに
- 16: 画面外への描画をエラーにしないで無視させる(2014.06.20時点では未実装)
(2) とりあえずここまでで
- とりあえずここまでで、日本の国旗を描いたこのプログラムについてはほぼ分かったと思います。
api_fillRect(MODE_COL3, 7, 640, 480, 0, 0);
api_fillOval(MODE_COL3, 1, 300, 0, 320-150, 240-150);
- ちなみに引き算しているのは、円の中心を(320,240)にしたくて、そこから円の半径を引いて左上の座標を計算しているのです。引き算などしないで、170や90と直接書いても全く同じ結果になります。
- ここまでの説明だけで、この絵の色を変えることも中心の丸の大きさを変えることも、楕円(だえん)にすることも、きっとできるでしょう。
- さらには円を何個も重ねてダーツの的(まと)みたいな絵も描けるでしょうし、楕円の中に楕円を書いて、眼みたいなものだって描けるでしょう。アイデア次第で何でもできます。
- 点も描けますし線も引けます。
- 分からないのは変数の使い方だけです。
- どのプログラムに共通している最初の行の #include "osecpu_ask.h" は決まり文句みたいなものだと思ってください。
(3) 整数型変数
- C言語やそのほかの言語では整数型にたくさんの種類がありますが、OSECPU-ASKAは単純化されていて一種類しかありません。Int32sというものだけです。これで21億くらいまでの整数を表現できます。マイナスの数もOKです。
- OSECPU-ASKAでは原則として変数をメモリに割り当てることはしません(ここが他の言語とは違う!)。必ずレジスタに割り当てます。レジスタというのはCPUが持っている演算用の記憶域のことで、DRAMとかにあるメモリとは違うものです。このような仕様なので、変数のアドレスという概念はありません(メモリ上にないものはポインタで指し示すことができない)。
- 以下のような構文で変数を宣言することができます。
Int32s i:R00;
- これはiという変数を宣言しており、R00というレジスタに割り当てられます。要するに、iはR00の別名でしかないのです。
- 変数名は大文字小文字を区別しますので、iとIを使い分けることができます。
- レジスタ名はR00~R3Fまでが有効ですが(後ろの2桁は16進数になっている)、とりあえずR00~R1Fまでを自由に使うのがいいと思います。・・・これは言い換えれば32個しかないということでもあります。変数は最大で32個しか作れないのです!これはつらい!!
- でもx86のアセンブラの32bitモードとかだと8個しかなかったんです、だからOSECPUはこれでも相当に「リッチ」なのです。
- はい、そこの人、少ないとか嘆いていてはいけませんよ。page0035をよく読んでください。あなたのやりたいことのためには32個では不十分かもしれませんが、まずは32個で何か面白いことはできないかなと考えるのです。
- もちろんもっとたくさん使う方法はちゃんとありますが、いきなりそれを説明すると理解できないこと間違いなしので、まずは32個のレジスタを使いこなせるようになってからです。
- レジスタ名は必ず大文字でお願いします。r00では未定義の変数名だと思われてエラーになります。R0aもだめです。R0Aでお願いします。
- 変数宣言ですが、コンマで区切って一文で複数を宣言することもできます。
Int32s i:R00, j:R01, xyz:R02;
- なお、同じレジスタを割り当ててしまうというひどい(?)こともできます。
Int32s i:R00, j:R00, k:R00;
- この場合、iに代入したらjやkの値も変わってしまうことになります。というかR00に3つの別名を与えているだけなんですけどね。
- そうやって変数に狙った値が入れられるようになったら、それをAPIの呼び出しの際に利用することができます。
api_drawPoint(MODE_COL24, c, x, y);
- ええとここで注意なのですが、APIの呼び出しの際に変数を使うときは、できれば数式にならないようにしてほしいです。
api_drawPoint(0, x - 1, y, c); // こういうのはつらい.
- なんかもしかしたら数式入れても平気だったりするかもしれませんが、しかしそこはあまり得意じゃないことにかわりはないので、数式を入れる代わりに結果を一度別の変数に入れて、その変数を指定してもらえると助かります。
つづく
こめんと欄
|